diff --git a/DECISIONS.md b/DECISIONS.md index de781c8..e7e9fca 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -4,6 +4,22 @@ Decisions listed in reverse chronological order. --- +## 2026-07-02: Brand refresh — Iris + Gold; glyphs may carry ONE gold gesture via a theme var + +**Context**: The brand kit in `assets/brand/` was replaced (2026 Iris + Gold refresh): body color moves from violet `#8b5cf6` to Iris `#5A3EF0`, volt lime `#CCFF00` is retired, and the "impulse" — the one thing Synapse adds — is now always Gold `#FFD23F`. The in-app glyphs previously had a hard rule: pure `currentColor`, never a baked color (`brand-icons.test.ts` failed on any `#`). The new glyph grammar puts the single gold gesture *inside* the glyphs, which that rule forbade. + +**Decision**: Glyph bodies stay `currentColor` (host UI supplies the ink), but each glyph may carry **one** gold gesture expressed only as `style="…var(--synapse-gold, #FFD23F)"`. The var is themed in `styles.css` (`body { --synapse-gold: #FFD23F }`, deepened to `#E8B419` on `.theme-light` for contrast on white). The test now strips the exact token `var(--synapse-gold, #FFD23F)` before asserting no `#` remains, so the canonical fallback is the *only* hex a glyph can bake. `synapse-main` stays impulse-free (neutral fallback); `synapse-actions` becomes the S-Signal at glyph weight (the brain mark is retired; the neuron remains the proposals mark). + +**Alternatives considered**: +- **Keep glyphs pure `currentColor`** — rejected; the refresh's whole grammar is "gold = what Synapse adds", and a mono glyph set can't say that. +- **Bake `#FFD23F` directly** — rejected; light themes need the deepened `#E8B419`, and a literal hex can't retheme. + +**Rationale**: The CSS var keeps one retunable source of truth per surface while the fallback keeps the assets self-contained (they render correctly outside Obsidian, e.g. on GitHub). + +**Impact**: `assets/brand/*` (all marks + glyphs), `src/brand-icons.ts` (regenerated bodies), `brand-icons.test.ts` (color rule), `styles.css` (gold tokens), README hero (animated banner) + sponsor badges (Iris/Gold). No behavior change beyond visuals. + +--- + ## 2026-06-29: Raw caught errors get the same redaction as strings (`redactError`) **Context**: `redactSecrets()` — the single redaction source (`shared/redact.ts`) — only operates on **strings**. Several console sinks log a caught value directly (`console.warn('…failed', err)` / `console.error('…', err)`), handing the bare `Error` object — and its `.stack`, which embeds `.message` — to the console. A secret echoed into an error message by an upstream API or a thrown exception would reach the console **verbatim**, bypassing redaction. This audit found five such raw-error sinks across audio, rem, elaboration, and shared. diff --git a/README.md b/README.md index 9b3c662..5e6797b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Synapse — More connections. Brighter thoughts. + Synapse — More connections. Brighter thoughts.

# Synapse @@ -416,8 +416,8 @@ Then run `npm run dev` to rebuild automatically on changes. Reload Obsidian (Cmd Synapse is free and open source. If it has earned a place in your workflow, you can support continued development: -[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-GitHub-8b5cf6?logo=github)](https://github.com/sponsors/dustinkeeton) -[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-5b21b6?logo=buymeacoffee&logoColor=white)](https://www.buymeacoffee.com/dustinkeeton) +[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-GitHub-5A3EF0?logo=github)](https://github.com/sponsors/dustinkeeton) +[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-FFD23F?logo=buymeacoffee&logoColor=0A0718)](https://www.buymeacoffee.com/dustinkeeton) ## License diff --git a/assets/brand/README.md b/assets/brand/README.md index 57000fc..3068189 100644 --- a/assets/brand/README.md +++ b/assets/brand/README.md @@ -1,90 +1,47 @@ -# Synapse brand assets +# Synapse brand kit — Iris + Gold (2026 refresh) -Canonical visual assets for Synapse. The full brand guidelines — palette, typography, voice/tone, name treatment, and mark usage rules — live in [`.claude/skills/brand-guidelines/SKILL.md`](../../.claude/skills/brand-guidelines/SKILL.md); read that before using or modifying anything here. +Drop-in replacement for `assets/brand/`. The S is now **fired**: an action-potential spike in gold slashes the synaptic cleft of the iris S. One system, two tiers. -## Inventory +## Palette -| Asset | Description | Use for | -|-------|-------------|---------| -| `icon.svg` | "The S-Signal" mark — 256×256 viewBox, transparent background, flat palette colors only | Plugin icon contexts, avatars, favicons, anywhere square **above ~24px** | -| `icon-small.svg` | Optical-size cut of the S-Signal — 256×256 viewBox, transparent, flat palette only. Widened cleft, enlarged volt bead on a thinned Gap Black chip, plain open receptor terminal (ring dropped) | Renders **at or below ~24px**: 16px favicons, 16–24px list/UI icons | -| `icon-mono.svg` | In-app **proposals** identity mark — a single-color `currentColor` **neuron** (dendrites → filled soma → axon carrying one impulse) on a **`0 0 100 100` viewBox**, no palette colors. Registered as the `synapse` icon by `registerSynapseIcons()` (`src/brand-icons.ts`), kept byte-synced with this file's inner content. Intentionally diverges from the S-Signal — see [In-app neuron/brain marks](#in-app-neuronbrain-marks) | Color-stripping surfaces: Obsidian ribbon/UI (the `synapse` icon), and any monochrome context | -| `glyphs/*.svg` | The Synapse **UI glyph set** — 13 mono `currentColor` icons on **`0 0 100 100` viewBox**, flat, no palette colors. Feature/action glyphs for the Synapse Actions sidebar and commands (see [Glyph set](#glyph-set-glyphs) below) | Registered via `registerSynapseIcons()` in `src/brand-icons.ts`; rendered by the host UI and feature-tinted in the Synapse Actions sidebar | -| `icon-accepted.svg` | **Accept-state** cut of the S-Signal — 256×256, transparent, flat palette only. The cleft is bridged in violet (gap jumped) and the single Impulse Volt spark has **landed in the receptor**, now closed/filled instead of an open ring | The **accepted** outcome of a proposal: accept-button confirmation, accepted-link badges, the end frame of the accept-flash. Pairs with `icon.svg` (open) — not the default identity. Use **above ~24px** | -| `banner.svg` | README hero — 1280×320, self-contained dark background, mark + wordmark + tagline | Top of README; safe on both GitHub light and dark themes | -| `social-preview.svg` / `social-preview.png` | GitHub social preview (og:image) — 1280×640 full-bleed dark, hero-scale mark + wordmark + "for Obsidian" + standing tagline; PNG is the uploadable render (<1 MB) | Repo Settings → Social preview; link unfurls (Slack/Discord/X). Critical ink stays ≥64px from edges (client crops/rounding). Not for the README (that is `banner.svg`); don't crop or overlay text | +| Role | Value | Use | +|------|-------|-----| +| Iris | `#5A3EF0` | Brand body (arcs, soma, receptor), UI accents | +| Gold | `#FFD23F` | The impulse — the only color Synapse insists on everywhere | +| Gold (light surfaces) | `#E8B419` | Same hue, deepened for contrast on white | +| Ground | `#0A0718` | Brand dark; also the spike's chip on light backgrounds | +| Ion | `#F3F0FF` | Text on dark | +| Lilac | `#B7A8FF` | Secondary text on dark | +| App body | `currentColor` | In-app marks/glyphs inherit the theme's ink | -### Size cutover: canonical vs small cut +**Volt lime (`#CCFF00`) is retired.** The old violet `#8b5cf6` is superseded by Iris. -Use **`icon.svg`** above ~24px and **`icon-small.svg`** at ~24px and below. Below ~24px the canonical spark — the firing moment that carries the whole brand story — merges into the S spine and disappears. `icon-small.svg` deliberately sacrifices letterform polish (wider cleft, fatter bead, plainer receptor) to keep one clearly visible lime point in the gap down to 16px. Above ~24px that trade is unnecessary and the canonical mark's full directional comet and open receptor ring read cleanly — use it there. +## Two tiers -Both color variants are for surfaces that **keep** color. For surfaces that strip it, use `icon-mono.svg` (below). +- **Identity tier** (README, social, store, avatars): full-color marks — `icon.svg`, `icon-small.svg` (≤24px), `icon-accepted.svg`, `banner.svg` / `banner-animated.svg`, `social-preview.svg`. +- **Theme tier** (ribbon, sidebars, commands): `icon-mono.svg` + `glyphs/` — body is `currentColor`, impulse is `var(--synapse-gold, #FFD23F)`. Define in `styles.css`: -### Monochrome in-app marks (`icon-mono.svg`, `glyphs/synapse-actions.svg`) +```css +body { --synapse-gold: #FFD23F; } +.theme-light { --synapse-gold: #E8B419; } +``` -Obsidian's ribbon and UI render icons as a single `currentColor` silhouette — gradients and palette colors are discarded. `icon-mono.svg` (the `synapse` proposals mark, now a **neuron**) and `glyphs/synapse-actions.svg` (the actions launcher, a **brain**) are built for exactly that: every stroke and fill is `currentColor`, so the host UI's text color drives them (Ion White on dark, Gap Black on white — verified on both). Both carry a single round-capped **impulse** and **intentionally diverge from the canonical S-Signal** (see [In-app neuron/brain marks](#in-app-neuronbrain-marks)); they are no longer mono cuts of it. +## The glyph grammar (Topology) -They are authored on a **`0 0 100 100`** viewBox (not the family's 256) because that is Obsidian's `addIcon` convention — each file's inner content is the literal string registered by `registerSynapseIcons()` in `src/brand-icons.ts`. **Keep them in sync:** if you edit an asset, update its registered body (and vice-versa); `brand-icons.test.ts` fails on drift. Use these only on color-stripping or monochrome surfaces; anywhere color survives, use `icon.svg` / `icon-small.svg`. +Soma (filled) = what exists · ring (open) = what's proposed · line = connection · **gold = what Synapse adds** (the act, or on Enrich, the added metadata). Verb → shape: expand=fan · attach=gold leaves · condense=merge · file=tree · run-all=cascade · examine=dive · format=wave→line · link=bridge. -### Glyph set (`glyphs/`) - -The `glyphs/` folder holds the **Synapse UI glyph set**: 13 monochrome `currentColor` icons, one per feature/action, authored on the same **`0 0 100 100`** viewBox as `icon-mono.svg`. Their inner content is registered via **`registerSynapseIcons()` in `src/brand-icons.ts`** (alongside the `synapse` body, which stays byte-synced with `icon-mono.svg`). The host UI supplies the color, and the **Synapse Actions sidebar tints each glyph per feature** (elaboration→blue, enrichment→green, organize→orange, deep-dive→purple, rem→pink, summarize→red, tidy→orange, video→yellow, main→muted). Never bake palette colors in — they are `currentColor` only. - -| Glyph | Subject | -|-------|---------| -| `synapse-elaboration` | Stub note + lines growing outward (expand a stub into a full note) | -| `synapse-enrichment` | Note + short connector stubs ending in open terminals (attach metadata) | -| `synapse-organize` | A note filed into a folder | -| `synapse-deep-dive` | Note + magnifier penetrating the page (examine one note in depth) | -| `synapse-summarize` | Lines condensing inward into a note (mirror of elaboration) | -| `synapse-tidy` | A note whose ragged lines resolve to flush-aligned (normalize/align) | -| `synapse-rem` | Two notes (filled source + outlined relation) joined by one link | -| `synapse-video` | Media panel + play triangle (external media/tooling) | -| `synapse-main` | A plain note — neutral fallback, deliberately low-energy | -| `synapse-transcribe` | Audio waveform + note (sound → linked text; also the Transcribe ribbon) | -| `synapse-fire` | A folder with one bold arrow sweeping through it (run all features over a directory) | -| `synapse-checkpoints` | Resume triangle + a broken ring (manage/resume interrupted runs) | -| `synapse-actions` | A **brain** with one impulse across it (the Synapse actions launcher / command center) | - -These are line/silhouette glyphs that share one system: a ~76×76 live area, a single stroke weight (~8 at the artboard), round caps and joins throughout, one consistent rounded-rect radius for panels/folders, and **one canonical note shape** (a rounded portrait page) used identically wherever a note appears. Solid fill marks the single *subject* of each action; everything else is outlined. **Exception:** `synapse-actions` is now a **brain** in-app identity mark carrying one impulse (see [In-app neuron/brain marks](#in-app-neuronbrain-marks)); the other twelve glyphs stay impulse-free and contain no spark, cleft, or "S". - -### Accept-state variant (`icon-accepted.svg`) - -The canonical mark encodes the proposal-approval safety model as geometry: the impulse jumps toward an **open, unfilled receptor ring** — a proposed connection, not yet accepted. `icon-accepted.svg` is that mark resolved to the moment of **accept**: the charged cleft is bridged in Synapse Violet (the gap has been jumped — the connection is made) and the single Impulse Volt spark has **landed in the receptor**, which is now **closed/filled** instead of an open ring. The spark sheds its directional comet taper and settles into a round bead at rest, seated in the receptor with its Gap Black chip intact so the lime survives on white. - -It is still **one volt element** — the landed bead is the only lime in the composition. Use it only to show the **accepted** outcome (accept-button confirmation, accepted-link badge, the end frame of the accept-flash); it is a state *pair* with `icon.svg` (open/proposed), **not** a replacement default identity. Size it like the canonical mark — **above ~24px**; it has no dedicated small cut. - -The **open → closed motion spec** (the accept-flash) lives in the brand guidelines under *Accept-flash motion spec*: timing, what the single volt element does frame-to-frame, how the receptor fills, the explicit one-volt-rule compliance, and the no-glow/no-blur rule. It is spec only — not wired into any UI. - -## The mark in one sentence - -An "S" traced by a neural impulse: two violet synaptic arcs broken by a charged cleft, one Impulse Volt spark (`#CCFF00`) firing left-to-right across the gap, from a filled source ball toward an open receptor ring that closes only on accept. +Exceptions: `synapse-main` is deliberately impulse-free (neutral fallback). `synapse-actions` is the S itself at glyph weight — the brain is retired; the neuron (`icon-mono`) remains the proposals mark. ## Hard rules -- Use only palette colors (see guidelines). Never recolor the mark or detach the spark. **Exception:** `icon-mono.svg` and everything in `glyphs/` are intentionally single-color `currentColor` — no palette colors, no lime accent, no Gap Black chip. They are the color-agnostic variants; the rules below about the volt spark and its chip do not apply to them. -- **Impulse on the in-app identity marks only.** `synapse` (`icon-mono.svg`, neuron) and `synapse-actions` (brain) each carry one round-capped impulse; no other `glyphs/` icon may contain a spark, lime, cleft, or an "S" silhouette. -- **One volt element per composition** — the spark is the only bright accent, ever. -- On white backgrounds the spark keeps its Gap Black outline/chip; never remove it. -- The mark is flat — no glows, blurs, drop shadows, or gradients in the mark itself. -- Don't place text over the banner or crop it. +- One gold gesture per composition (Enrich's leaf set counts as one gesture). +- On white, the identity spike keeps its Ground chip; never remove it. +- Flat only — no glows, blurs, shadows; gradients allowed on backgrounds, never in the mark. +- Use `icon-small.svg` at or below ~24px; the canonical spike merges below that. +- Keep `glyphs/` byte-synced with `registerSynapseIcons()` in `src/brand-icons.ts`. -## Verifying changes +## Notes -Assets are hand-written SVG. After any edit, render and inspect before committing (macOS, no dependencies): - -```sh -qlmanage -t -s 1024 -o /tmp .svg # writes /tmp/.svg.png — open and check -``` - -Check dark (`#131019`) and white backgrounds, plus a ~48px copy for small-size legibility. For the `glyphs/` set, **16px is the design size** — render each glyph at ~16px *and* ~48px on both backgrounds and confirm crisp single-color legibility; reduce detail (never thin strokes below ~6.25 at the 100 artboard) if a glyph muddies at 16px. The `designer` agent (`.claude/agents/designer.md`) does this loop automatically. - -## Wanted (not yet produced) - -- _Nothing currently open. The UI glyph set (`glyphs/`), the accept-state variant (`icon-accepted.svg`), and the accept-flash motion spec are done; see above._ - -## In-app neuron/brain marks - -> **In-app neuron/brain marks (divergent from the S-Signal).** `icon-mono.svg` (the `synapse` glyph) and `glyphs/synapse-actions.svg` are now in-app identity marks drawn around a **neuron** (proposals) and a **brain** (the actions launcher / command center), each carrying a single round-capped impulse. They **intentionally diverge from the canonical S-Signal** — they are no longer mono cuts of it. The full-color S-Signal family (`icon.svg`, `icon-small.svg`, `icon-accepted.svg`, `banner.svg`, `social-preview.*`) is unchanged and remains the canonical identity. -> -> **Sanctioned motifs.** For these two `currentColor` in-app marks only, **neuron, brain, and electricity (impulse/charge)** are sanctioned — a deliberate, scoped relaxation of the brain/neuron ban. It does not extend to the full-color S-Signal or the rest of the `glyphs/` set, which stay neuron-/brain-/spark-free. +- `banner-animated.svg` loops the spike draw-on (SMIL — plays in GitHub READMEs). +- `accept-flash.svg` + `accept-flash.md` — the proposed→accepted motion: 700ms, spike morphs into a bead that lands in the receptor while the cleft bridges. Spec only; not wired into UI. +- Rasterize `social-preview.svg` to PNG (≤1MB) before uploading to repo settings, e.g. `qlmanage -t -s 1280 -o /tmp kit/social-preview.svg`. diff --git a/assets/brand/accept-flash.md b/assets/brand/accept-flash.md new file mode 100644 index 0000000..026b1c3 --- /dev/null +++ b/assets/brand/accept-flash.md @@ -0,0 +1,28 @@ +# Accept-flash — motion spec (Iris + Gold) + +The transition from **proposed** (`icon.svg`: live spike, open receptor) to **accepted** (`icon-accepted.svg`: bridged cleft, gold seated in a closed receptor). Total **700 ms**, played once on accept, `fill: freeze`. + +| Phase | Time (ms) | What moves | Easing | +|---|---|---|---| +| Charge | 0–120 | Spike pumps: stroke 11 → 13 → 11 (amplitude, not scale) | ease-out | +| Jump | 120–260 | Spike collapses tail-first (dash-offset 0 → length); a gold bead (r13) emerges at its head | cubic-bezier(.3, 0, .9, 1) | +| Travel | 260–480 | Bead rides the axon path into the terminal | cubic-bezier(.2, 0, .55, 1) | +| Bridge | 300–420 | Iris bridge draws across the cleft behind the bead (dash-offset 80 → 0) | ease-in-out | +| Land | 480–620 | Bead settles r18 → 15; receptor ring pops stroke 14 → 18 → 14 | ease-out, one overshoot, no bounce | +| Rest | 620–700 | Hold. End state ≡ `icon-accepted.svg` | — | + +Bead path (256 grid): `M174 133 L177.4 141.9 A46 46 0 0 1 107 200.9 L85.7 177.8` + +## Rules + +- **One gold element at all times.** The spike morphs into the bead — they never coexist for more than one frame. +- **No glow, no blur, no shadow.** Energy is geometry: amplitude, overshoot, squash. +- Motion only on dash-offset, transform, and motion-path (compositor-friendly). +- Never longer than 700 ms — longer reads as ceremony, not confirmation. +- `prefers-reduced-motion`: replace with a 120 ms crossfade from open to accepted. No travel. + +## Implementations + +- **SMIL reference**: `accept-flash.svg` (looping demo: 600 ms open hold → flash → 1.1 s accepted hold → reset; production plays once and freezes). +- **Obsidian (CSS)**: bead as an element with `offset-path` set to the bead path; spike collapse via `stroke-dashoffset` transition; gate with `matchMedia('(prefers-reduced-motion: reduce)')`. +- End state must compose identically to `icon-accepted.svg` — the flash is a transition between the two shipped marks, never a third look. diff --git a/assets/brand/accept-flash.svg b/assets/brand/accept-flash.svg new file mode 100644 index 0000000..c6615a1 --- /dev/null +++ b/assets/brand/accept-flash.svg @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/brand/banner-animated.svg b/assets/brand/banner-animated.svg new file mode 100644 index 0000000..92f500c --- /dev/null +++ b/assets/brand/banner-animated.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + synapse + More connections. Brighter thoughts. + \ No newline at end of file diff --git a/assets/brand/banner.svg b/assets/brand/banner.svg index 0d5ebe9..206eec7 100644 --- a/assets/brand/banner.svg +++ b/assets/brand/banner.svg @@ -1,38 +1,34 @@ - - + + - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - + + + + + + + + - - - synapse - - - More connections. Brighter thoughts. - + synapse + More connections. Brighter thoughts. + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-actions.svg b/assets/brand/glyphs/synapse-actions.svg index 1f9f101..54133d1 100644 --- a/assets/brand/glyphs/synapse-actions.svg +++ b/assets/brand/glyphs/synapse-actions.svg @@ -1,7 +1,7 @@ - - - - - - + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-checkpoints.svg b/assets/brand/glyphs/synapse-checkpoints.svg index 94bb08e..08e7bb8 100644 --- a/assets/brand/glyphs/synapse-checkpoints.svg +++ b/assets/brand/glyphs/synapse-checkpoints.svg @@ -1,4 +1,4 @@ - - - + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-deep-dive.svg b/assets/brand/glyphs/synapse-deep-dive.svg index c37f975..46005bf 100644 --- a/assets/brand/glyphs/synapse-deep-dive.svg +++ b/assets/brand/glyphs/synapse-deep-dive.svg @@ -1,7 +1,6 @@ - - - - - - + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-elaboration.svg b/assets/brand/glyphs/synapse-elaboration.svg index ef3cd3f..c49e135 100644 --- a/assets/brand/glyphs/synapse-elaboration.svg +++ b/assets/brand/glyphs/synapse-elaboration.svg @@ -1,6 +1,9 @@ - - - - - + + + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-enrichment.svg b/assets/brand/glyphs/synapse-enrichment.svg index 3bca56b..6cce7e8 100644 --- a/assets/brand/glyphs/synapse-enrichment.svg +++ b/assets/brand/glyphs/synapse-enrichment.svg @@ -1,10 +1,9 @@ - - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-fire.svg b/assets/brand/glyphs/synapse-fire.svg index 2cf431c..27c0d9d 100644 --- a/assets/brand/glyphs/synapse-fire.svg +++ b/assets/brand/glyphs/synapse-fire.svg @@ -1,4 +1,7 @@ - - - + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-main.svg b/assets/brand/glyphs/synapse-main.svg index 055a2ed..17331f8 100644 --- a/assets/brand/glyphs/synapse-main.svg +++ b/assets/brand/glyphs/synapse-main.svg @@ -1,6 +1,5 @@ - - - - - + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-organize.svg b/assets/brand/glyphs/synapse-organize.svg index 5c4aa6b..259dacb 100644 --- a/assets/brand/glyphs/synapse-organize.svg +++ b/assets/brand/glyphs/synapse-organize.svg @@ -1,4 +1,9 @@ - - - + + + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-rem.svg b/assets/brand/glyphs/synapse-rem.svg index f411baa..79284b7 100644 --- a/assets/brand/glyphs/synapse-rem.svg +++ b/assets/brand/glyphs/synapse-rem.svg @@ -1,5 +1,7 @@ - - - - + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-summarize.svg b/assets/brand/glyphs/synapse-summarize.svg index 668c219..abca942 100644 --- a/assets/brand/glyphs/synapse-summarize.svg +++ b/assets/brand/glyphs/synapse-summarize.svg @@ -1,6 +1,10 @@ - - - - - + + + + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-tidy.svg b/assets/brand/glyphs/synapse-tidy.svg index a35fb03..3e752eb 100644 --- a/assets/brand/glyphs/synapse-tidy.svg +++ b/assets/brand/glyphs/synapse-tidy.svg @@ -1,7 +1,6 @@ - - - - - - + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-transcribe.svg b/assets/brand/glyphs/synapse-transcribe.svg index e0e2347..4fac4d7 100644 --- a/assets/brand/glyphs/synapse-transcribe.svg +++ b/assets/brand/glyphs/synapse-transcribe.svg @@ -1,6 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/assets/brand/glyphs/synapse-video.svg b/assets/brand/glyphs/synapse-video.svg index de08bcf..5a497da 100644 --- a/assets/brand/glyphs/synapse-video.svg +++ b/assets/brand/glyphs/synapse-video.svg @@ -1,4 +1,6 @@ - - - + + + + + \ No newline at end of file diff --git a/assets/brand/icon-accepted.svg b/assets/brand/icon-accepted.svg index 0dacd9d..5d18ae6 100644 --- a/assets/brand/icon-accepted.svg +++ b/assets/brand/icon-accepted.svg @@ -1,8 +1,8 @@ - - - - - - - + + + + + + + \ No newline at end of file diff --git a/assets/brand/icon-mono.svg b/assets/brand/icon-mono.svg index 2634bfd..3d64057 100644 --- a/assets/brand/icon-mono.svg +++ b/assets/brand/icon-mono.svg @@ -1,5 +1,3 @@ - - - - + + \ No newline at end of file diff --git a/assets/brand/icon-small.svg b/assets/brand/icon-small.svg index edbcf0c..30cfba4 100644 --- a/assets/brand/icon-small.svg +++ b/assets/brand/icon-small.svg @@ -1,6 +1,7 @@ - - - - - + + + + + + \ No newline at end of file diff --git a/assets/brand/icon.svg b/assets/brand/icon.svg index 8305d6f..8280e8f 100644 --- a/assets/brand/icon.svg +++ b/assets/brand/icon.svg @@ -1,7 +1,10 @@ - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/assets/brand/social-preview.png b/assets/brand/social-preview.png index d2dea4d..ab7d877 100644 Binary files a/assets/brand/social-preview.png and b/assets/brand/social-preview.png differ diff --git a/assets/brand/social-preview.svg b/assets/brand/social-preview.svg index 5467865..848cac8 100644 --- a/assets/brand/social-preview.svg +++ b/assets/brand/social-preview.svg @@ -1,39 +1,34 @@ - - + + - - - - - - - - - + + + + + + - - - - - + + + + + + - - - - - - - + + + + + + + + - - - synapsefor Obsidian - - - More connections. Brighter thoughts. - + synapsefor Obsidian + More connections. Brighter thoughts. + \ No newline at end of file diff --git a/docs/plans/donation-sponsorship-plan.md b/docs/plans/donation-sponsorship-plan.md index b347613..39117dd 100644 --- a/docs/plans/donation-sponsorship-plan.md +++ b/docs/plans/donation-sponsorship-plan.md @@ -131,11 +131,11 @@ Placement: **near the bottom**, after Features / Install / Usage — never in th Synapse is free and open source. If it has earned a place in your workflow, you can support continued development: -[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-GitHub-8b5cf6?logo=github)](https://github.com/sponsors/dustinkeeton) -[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-5b21b6?logo=buymeacoffee&logoColor=white)](https://www.buymeacoffee.com/) +[![Sponsor on GitHub](https://img.shields.io/badge/Sponsor-GitHub-5A3EF0?logo=github)](https://github.com/sponsors/dustinkeeton) +[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-FFD23F?logo=buymeacoffee&logoColor=0A0718)](https://www.buymeacoffee.com/) ``` -(Badge colors above use the brand violets — Synapse Violet `#8b5cf6` and Threshold Violet `#5b21b6` — so the section reads as part of the identity rather than stock badge clutter.) +(Badge colors above use the brand palette — Iris `#5A3EF0` and Gold `#FFD23F` — so the section reads as part of the identity rather than stock badge clutter.) ### d) Settings panel (optional, non-intrusive) diff --git a/package-lock.json b/package-lock.json index 404d9eb..6371935 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "synapse", - "version": "1.0.7", + "version": "1.0.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "synapse", - "version": "1.0.7", + "version": "1.0.10", "license": "AGPL-3.0-only", "devDependencies": { "@emnapi/core": "^1.7.1", @@ -5104,6 +5104,7 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -6395,7 +6396,6 @@ "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "dev": true, "license": "ISC", - "peer": true, "bin": { "yaml": "bin.mjs" }, diff --git a/src/brand-icons.test.ts b/src/brand-icons.test.ts index dc17060..a89c45a 100644 --- a/src/brand-icons.test.ts +++ b/src/brand-icons.test.ts @@ -44,13 +44,18 @@ describe('brand-icons', () => { } }); - it('draws every glyph as a non-empty currentColor silhouette with no baked palette color', () => { + it('draws every glyph as a currentColor silhouette; gold only via the theme var', () => { for (const [name, body] of Object.entries(SYNAPSE_ICONS)) { expect(body, name).toBeTruthy(); - // Color comes from the host UI (mono ribbon/palette, CSS tint in the - // sidebar) — the bodies must use currentColor and never a hardcoded hex. + // Body ink comes from the host UI via currentColor; the only other color + // allowed is the impulse gold, and only through the theme var (with its + // canonical fallback) so styles.css can retune it per light/dark surface. expect(body, name).toContain('currentColor'); - expect(body.includes('#'), `${name} must not bake a hex color`).toBe(false); + const withoutGold = body.split('var(--synapse-gold, #FFD23F)').join(''); + expect( + withoutGold.includes('#'), + `${name} must not bake a color outside var(--synapse-gold, #FFD23F)`, + ).toBe(false); } }); diff --git a/src/brand-icons.ts b/src/brand-icons.ts index 7313102..ef10214 100644 --- a/src/brand-icons.ts +++ b/src/brand-icons.ts @@ -2,8 +2,9 @@ * Bespoke Synapse icon glyphs, registered with Obsidian's `addIcon` (#349). * * Each value is SVG *inner content* on the `0 0 100 100` viewBox `addIcon` - * expects, drawn in `currentColor` — the host UI supplies the color (ribbon/ - * palette render mono; the Synapse actions sidebar tints per feature via CSS). + * expects. Bodies are drawn in `currentColor` — the host UI supplies the ink — + * while the impulse (the one gold gesture per glyph, 2026 Iris+Gold refresh) + * is `var(--synapse-gold, #FFD23F)`, themed per surface in `styles.css`. * * The glyph NAMES are the contract in `src/commands/icons.ts` (`FEATURE_ICONS` * + the per-action `icon` overrides in the registry); keep this map in lockstep @@ -17,46 +18,45 @@ import { addIcon } from 'obsidian'; /** - * Monochrome `currentColor` in-app proposals mark: a NEURON (dendrites, a filled - * soma, and an axon carrying one round-capped impulse), built around the brand's - * impulse/charge idea (#349 review). Mirrors `assets/brand/icon-mono.svg` and - * INTENTIONALLY diverges from the canonical full-color S-Signal (`icon.svg` etc.), - * which is unchanged. Do not recolor; the color comes from the host UI via - * `currentColor`. + * In-app proposals mark: a NEURON (dendrites, a filled soma, and an axon + * carrying the impulse), built around the brand's impulse/charge idea (#349 + * review). Mirrors `assets/brand/icon-mono.svg` — body in `currentColor`, the + * axon spike in the gold var — and INTENTIONALLY diverges from the canonical + * full-color S-Signal (`icon.svg` etc.). Do not recolor the body; its ink + * comes from the host UI via `currentColor`. */ export const SYNAPSE_ICON_SVG = - ' ' + - ' ' + - ''; + ''; /** * name -> inner SVG content for every Synapse-registered glyph. Keys MUST match * the names in `src/commands/icons.ts` and the ribbon/view references in - * `src/main.ts` / `src/views/synapse-actions-view.ts`. The per-feature and - * per-action glyphs share one line-icon system (round caps/joins, one stroke - * weight, a canonical note shape, filled = the action's subject). The two in-app - * identity marks `synapse` (neuron) and `synapse-actions` (brain) each carry a - * round-capped impulse and intentionally diverge from the canonical S-Signal; - * the remaining glyphs stay impulse-free. + * `src/main.ts` / `src/views/synapse-actions-view.ts`. One line-icon system + * (round caps/joins, one stroke weight) speaking the Topology grammar: filled + * soma = what exists, open ring = what is proposed, line = connection, and the + * single gold gesture = what Synapse adds (`var(--synapse-gold, #FFD23F)`). + * `synapse-main` is deliberately impulse-free as the neutral fallback. */ export const SYNAPSE_ICONS: Readonly> = { // In-app proposals identity mark — neuron (proposals ribbon + proposal views). synapse: SYNAPSE_ICON_SVG, - // Launcher (Synapse actions ribbon + sidebar view = brain) + per-action overrides. - 'synapse-actions': ' ', - 'synapse-transcribe': ' ', - 'synapse-fire': ' ', - 'synapse-checkpoints': ' ', - // Per-feature default glyphs. - 'synapse-main': ' ', - 'synapse-elaboration': ' ', - 'synapse-enrichment': ' ', - 'synapse-organize': ' ', - 'synapse-deep-dive': ' ', - 'synapse-summarize': ' ', - 'synapse-tidy': ' ', - 'synapse-rem': ' ', - 'synapse-video': ' ', + // Launcher (Synapse actions ribbon + sidebar view) — the S-Signal itself at + // glyph weight (the brain mark is retired; the neuron remains the proposals mark). + 'synapse-actions': ' ', + // Per-action override glyphs. + 'synapse-transcribe': ' ', + 'synapse-fire': ' ', + 'synapse-checkpoints': ' ', + // Per-feature default glyphs (synapse-main is deliberately impulse-free). + 'synapse-main': ' ', + 'synapse-elaboration': ' ', + 'synapse-enrichment': ' ', + 'synapse-organize': ' ', + 'synapse-deep-dive': ' ', + 'synapse-summarize': ' ', + 'synapse-tidy': ' ', + 'synapse-rem': ' ', + 'synapse-video': ' ', }; /** diff --git a/styles.css b/styles.css index 7a76f70..97a5666 100644 --- a/styles.css +++ b/styles.css @@ -47,6 +47,20 @@ --synapse-color-video-rgb: 220, 180, 70; } +/* + * Brand impulse gold (2026 Iris+Gold refresh). Every registered glyph draws + * its body in currentColor and its single gold gesture in this var (see + * src/brand-icons.ts / assets/brand/README.md). Deepened on light surfaces + * for contrast against white. + */ +body { + --synapse-gold: #FFD23F; +} + +.theme-light { + --synapse-gold: #E8B419; +} + /* * Cap the height of embedded videos so portrait-oriented content * (TikTok, Instagram Reels, phone recordings) does not dominate the note.