Design record #
tilde.style — initiated 2026-06-17. Rebuilt as a three-style switcher 2026-07-21 (see Provenance).
Design intention #
- What is this site for? The homepage for the tilde.style toolkit itself — its job is to demonstrate what the toolkit produces, not to commit to one metaphor the way a real tilde site would.
- Who tends it? Torsten — alone.
- What physical space does it remind you of? Not one space — three, shown side by side: a pond garden, a bonfire clearing, a glider aloft. A visitor picks one and the whole page becomes it.
- What should a visitor feel in the first 10 seconds? That these are real, distinct, lived-in design languages — not palette swatches. The photo strip under each gallery card exists to prove that at a glance.
- What would feel completely wrong here? Corporate design language,
scale-first vocabulary, anything that feels like a product launch. Also
wrong: treating the switcher itself as license to mix seasons/styles
silently anywhere else — see
tend.md's season-mixing section, which names this page as the one deliberate, declared exception.
Active configuration: theme switcher, not a single style #
This page is the specific, named exception in the toolkit's own guidance
(skill/reference/tend.md): "build a real theme switcher only when a
site's actual job is to demonstrate the style system itself... not as the
default answer to a season-mixing bug." A real tilde site should still
commit to one style. This one is the toolkit's own kitchen sink.
Three styles ship, each fully documented — and fully self-contained — in its own directory. This file no longer duplicates their palettes/typography/ components, and neither does the CSS:
- Gardening —
styles/gardening/style.md+styles/gardening/style.css - Bonfire —
styles/bonfire/style.md(+style-v0.1.mdfor the pre-grounded original) +styles/bonfire/style.css - Sailplane —
styles/sailplane/style.md+DESIGN.md+styles/sailplane/style.css
index.html links all four stylesheets (site.css + the three
styles/{name}/style.css). This is genuinely just CSS's own cascade doing
the work — the browser merges everything it loads into one rule set before
resolving conflicts, regardless of how many files it came from, so there
was never a need to hand-concatenate them into one site.css. Each style's
tokens are scoped to its own [data-theme="…"] selector (not a shared
:root), so two styles could even reuse a token name without collision —
confirmed non-colliding by name anyway, but the scoping makes that
guaranteed rather than just currently-true.
site.css itself now owns only what's unique to this page and nothing
style-specific: the reset, the gallery/contact-sheet layout, the switcher
chrome, and the .theme-panel show/hide toggle. Adding a fourth style is:
write styles/newstyle/style.css, add one <link> line, add one gallery
card + panel + switcher button — no existing file needs editing.
Tooling (added 2026-07-21): ./wiggle + ./wiggle-verify #
That last paragraph used to be a recipe a human followed by hand. It's now
code: two Cobra CLIs, source under tools/cmd/wiggle/ and
tools/cmd/wiggle-verify/ (a Go module — go.work at the repo root wires
it into the workspace), built via make build (see the repo-root
Makefile; both compiled binaries are gitignored).
Named wiggle, not toolkit or tilde-style-tools. ~ is informally
called "squiggle"/"wiggle" for its wavy shape, so the name is grounded in
the actual tilde character this whole project is about — and as a verb it
describes what using it does: click a different style, the whole page
wiggles into a new shape (matching the homepage's own framing: "click one
to see the whole page become it"). Styles get noun/gerund names (Gardening,
Bonfire, Sailplane, things); the tool that operates on them gets a verb.
Modeled loosely on hmans/beans' CLI
structure (the same beans this project's own .beans/ tracking already
runs on) — thin main.go per binary, Cobra subcommands, one binary per
weight class. Credit where due: reading its actual source (not just its
README) is where the two-binary split and the PersistentPreRunE shared-init
pattern came from.
Two binaries, split by dependency weight (same reasoning as beans
splitting beans-serve/beans-tui out from core beans): verify needs
chromedp — a full headless-Chrome automation stack — while add/link
need almost nothing. Splitting them means the everyday tool
(./wiggle, ~6MB) never links in a browser-automation dependency it
doesn't use; ./wiggle-verify (~13MB) carries that weight alone, and isn't
needed for the common case of just adding a style.
./wiggle add <name>— scaffoldsstyles/<name>/style.csswith loud placeholder-magenta tokens: scaffolded, not designed. Never touchesindex.html. The toolkit's own central constraint ("you bring the design intention, the AI executes it") still applies to filling it in — this only removes the copy-paste, never invents a metaphor../wiggle link <name>— wires an existingstyles/<name>/style.cssintoindex.htmlat four marker comments (<!-- tools/cmd/addstyle:links -->etc. — seeindex.htmlitself):<link>, gallery card, switcher button, placeholder panel. Requires the file fromaddto already exist. Splittingadd/linkmeans a style can be drafted and iterated on before it's wired into the live page at all, or a style built by/tilde-style languagesome other way can be linked in without re-scaffolding it../wiggle add morphing # ... design it for real, replace the placeholder tokens ... ./wiggle link morphing --tagline "Transition as content, not decoration." --chip easing./wiggle-verify— the regression harness, driving real Chrome viachromedp(Go's equivalent of Playwright/Puppeteer, CDP-based). No subcommand layer — this binary only ever does one thing. Discovers every style straight from the live DOM (no hardcoded theme list — a new style added byadd/linkor by hand is covered automatically), clicks each switcher button for real, and asserts: exactly one panel visible, a non-transparent computed background, the gallery-card/switcher-button three-way sync, and that the choice survives a reload (the localStorage contract).--screenshots <dir>optionally drops a full-page PNG per theme — chromedp already drives the browser, so an artifact per theme is one more action, not a separate manual step../wiggle-verify --screenshots /tmp/tilde-style-shots
The background-transparency check exists because of a real incident: a
stray */ inside a CSS comment (styles/*/, meaning "each style's own
directory") closed the comment early and silently dropped tilde.style's
entire :root token block, so every var(--token) background resolved to
nothing. It was caught by eye, from a screenshot, after the fact. verify
would have caught it the moment it shipped.
Page structure #
#gallery— a static strip of 3.gallery-cardbuttons (not a rotating carousel — deliberately simultaneous, so all three are visible at once). Each card carries its own colors, a real named component as a chip (Lernhappen / kindling / Variometer), and a contact-sheet photo strip: two small real photographs the style's palette was sampled from, so the "grounded in a real photo, not a mood board" claim is checkable at a glance, not just asserted in prose.#style-switcher— sticky nav, three buttons, mirrors the gallery's selection.- Three
.theme-panel[data-theme]blocks — full page (header/main/footer) per style,display:noneunless.active. Only the selected panel's markup is visible; the other two stay in the DOM (simplest correct approach for a small, single-page site — no need for lazy mounting). setTheme()— one shared JS function syncs switcher buttons, gallery cards, and panels together, persists the choice tolocalStorage['tilde-style-theme'], and restores it on load.
Photo provenance (added 2026-07-21) #
Every style's palette is sampled from real photographs, not invented — copied into the project as durable assets rather than left as session scratch files or external URLs:
| Style | Photos | Source |
|---|---|---|
| Gardening | styles/gardening/photos/pond-teich-morgen.jpg, pond-overview.jpg |
The literal pond behind chatbot-garden's Teich-Morgen palette (also used in ~/chatbot-garden/backend/ui/assets/pond/) |
| Bonfire | styles/bonfire/photos/funkenflug-sparks.jpg, erntetag-gathering.jpg |
A long-exposure night shot of sparks (Funkenflug) and a real Erntedank harvest-festival bonfire in daylight (Erntetag) |
| Sailplane | styles/sailplane/photos/dusk-tideline.jpg, aloft-cloud-deck.jpg |
Dusk on the Vancouver tideline, and the view above the cloud deck from an actual glider flight |
All resized to a max 900px edge and stripped of EXIF before committing (originals were camera-resolution, up to 8MB — unnecessary for a 56px thumbnail). Referenced both as the gallery cards' contact-sheet strip and named explicitly in each panel's own Styles section copy, so the claim appears at both the point of proof (thumbnail) and the point of assertion (prose).
Anti-patterns #
- Corporate chrome — Stripe gradients, Notion toggles, Linear dark mode out of context
- Scale-first vocabulary — no "users", "growth", "engagement", "onboarding"
- Product launch aesthetics — no countdown CTAs, no "Get started free", no hero animations
- Cold palette without warmth — no slate-and-teal, no purple gradients
- Infinite scroll
- Authorless generation — no AI output without recorded intention in this file or a style's own
style.md - Silent season/style mixing anywhere but here — this page is the named exception; a real tilde site commits to one style
- Letting the switcher become an excuse to skip grounding — every style added here must still pass through
/tilde-style languageand get its own real metaphor + (ideally) real photos, not just a plausible palette
Motion #
- Minimal. Panel switching is instant (no crossfade) — deliberate, since a transition between three unrelated visual worlds reads as a glitch, not polish.
- Hover transitions on cards/links:
150ms–300ms easemax. - All animations have a
prefers-reduced-motion: reducecounterpart.
Known gaps #
- Mobile nav pattern for
#style-switchernot yet stress-tested beyond the existing gallery breakpoint at 720px. - Only 2 photos shown per style; more exist for Bonfire/Sailplane (Immich,
~/Pictures/sailing/) if a deeper "provenance" page is ever built. - No defined grid for multi-column layouts beyond what each style's own
style.mdspecifies.
Provenance #
- v0.1 (2026-06-17–2026-07-20) — single-style homepage, Bonfire only,
night-first, no
dawnmode built. Superseded, not deleted: preserved asstyles/bonfire/style-v0.1.md. - v0.2 (2026-07-21) — rebuilt as the three-style gallery + switcher described above, once Gardening and a properly-grounded Sailplane/Bonfire v0.2 all existed as real, documented, contributed styles worth showing side by side. Photo contact-sheets added same day, after the initial switcher build shipped without them.