cyberine
Design notes

Website theme decision - Dracula, dark-only; rebuild epic shelved

SUPERSEDED 2026-08-27 (same day). The palette half of this note is no longer current: the user ran /nf-design-system heavy, rejected the rethemed interface, and locked a new direction — "Parallel Cut", theme-aware light+dark, on Next.js + Fumadocs. The live source of truth is website-master.md; read that first.

This note is kept, not deleted, because it still explains two things nothing else records: WHY the Dracula retheme happened (a three-way colour contradiction between two files in the same theme dir and the TUI), and why the rebuild epic was shelved. The reopen condition it names — "a marketing surface with conversion goals" — is exactly what was asked for, so the shelve decision was superseded by a changed premise, not overruled.

Everything below is history. Do not treat its palette, its force-dark decision, or its "the epic is shelved" status as current.

Decided 2026-08-27 by the user, in one sitting, after the three-way color contradiction below was surfaced. This note exists so the question is not re-opened from scratch: the site's palette is settled, and the custom-site rebuild is deliberately NOT happening right now.

What was wrong

The VitePress theme disagreed with itself, and neither half agreed with the TUI:

SourceClaimed identity
docs/.vitepress/theme/index.ts (header comment)"cyan + hexagon fleet mark, dark-first"
docs/.vitepress/theme/custom.css (header + tokens)warm cream/bone paper, warm charcoal ink, amber-gold #E0A82E, light-first
src/tui/theme.tsClaude brand orange #ff9933 (deliberate, see below)

Two files in the same theme directory declared opposite directions, and the site shipped the amber light theme while its own entry point described a cyan dark one.

T664 (SITE-REBUILD-DIRECTION), authored by gpt-5.6-sol, framed the fix as "the site mixes a warm Anthropic-inspired theme with Cyberine's cyan dark identity". That framing was already stale: CLAUDE.md records an explicit user decision of 2026-06-23 making the TUI mirror Claude Code's dark-daltonized scheme 1:1 including its orange accent, and that decision explicitly superseded the earlier "cyan-only / never Claude orange" rule. So "cyan is Cyberine's identity" was no longer true when T664 was written, and building a prototype on it risked rejection at the T665 approval gate.

The decision

Palette: Dracula. Dark-only. No light variant, no appearance toggle.

Neither cyan nor amber nor the TUI's orange. Dracula is a third, deliberate answer: a dark-native developer palette that does not have to reconcile with the TUI's Claude-mirroring orange, because the site and the TUI are now understood as different surfaces rather than one brand system that drifted apart.

Implementation (all landed 2026-08-27):

  • docs/.vitepress/theme/custom.css - official Dracula spec tokens (#282a36 bg, #f8f8f2 fg, #6272a4 comment, #bd93f9 purple as brand, #ff79c6 pink for the hero name, semantic green/yellow/red mapped onto tip/warning/danger callouts). Declared on :root, .dark together - see the pre-paint note below.
  • docs/.vitepress/config.mts - appearance: 'force-dark'. The toggle is removed on purpose: a toggle whose light side is unstyled is a bug surface, not a feature.
  • docs/.vitepress/config.mts - markdown: { theme: 'dracula' }. Shiki bundles dracula, so code blocks join the palette at no dependency cost. A single theme, not a light/dark pair, because a pair would ship one dead half under force-dark.
  • docs/.vitepress/theme/components/HomeSections.vue - the three hardcoded warm-charcoal shadows (rgba(31,30,28,...)) recast in Dracula's darker shade (rgba(16,17,23,...)), which avoids the muddy halo a warm or neutral-black shadow leaves on #282a36.

Typography was left alone (Newsreader serif display). The retheme was scoped to color; changing type is a separate decision.

Why :root, .dark and not just .dark

appearance: 'force-dark' is applied by VitePress client-side at runtime - the static HTML ships <html lang="en-US" dir="ltr"> with no dark class. Tokens declared only under .dark would leave the first paint on VitePress's light defaults, i.e. a white flash on every cold load. Declaring the palette on :root, .dark together means the correct colors are present before any JS runs.

Verified in the built output: assets/style.*.css contains :root,.dark{--vp-c-bg: #282a36;...} at byte ~111986, well after VitePress's own .dark{--vp-c-bg:#1b1b1f} at byte ~6253, so the override wins in both states. No amber token (#E0A82E, #f0eee6, #1f1e1c) survives anywhere in dist/.

Do not add a light block without actually styling it. A half-built light theme is the exact failure this decision closes.

The rebuild epic is shelved, not cancelled

T664-T672 (direction -> approval -> Next.js/Fumadocs scaffold -> design system -> homepage -> docs migration -> cutover -> launch -> asset kit) are shelved as [backlog], not marked forbidden. forbidden in this repo's manifest means "must never be built" (it is used for the ToS-violating OAuth tasks); shelving is a priority call that can be reversed.

Rationale: the epic's premise needed a color decision that has now been made far more cheaply. Nine tasks, a framework migration, and a hosting decision were the expensive path to fixing an incoherent stylesheet.

What would reopen it: a real need the current VitePress site cannot serve - a marketing surface with conversion goals, a docs experience VitePress structurally cannot deliver, or a brand system spanning site + TUI + assets. Aesthetic dissatisfaction alone is not enough; that is what this retheme addressed.

Knock-on for T675 (docs discoverability)

T675's code half is already done and verified: per-page og: metadata ships on all pages, and sitemap + robots.txt + canonical URLs are implemented but dormant behind the CYBERINE_DOCS_ORIGIN env var (unset -> those tags are omitted, because a wrong canonical URL is worse than a missing one).

T675 previously carried a conflict: T671 (SITE-REBUILD-LAUNCH) was the task for choosing a domain and host, and T670 would have retired VitePress entirely - so standing up VitePress hosting could have been wasted work. Shelving the epic settles that conflict in T675's favour: VitePress is now the long-term site, so T675 owns the hosting decision outright.

Remaining for T675 is a user decision only - pick a host and public origin, confirm that publishing these docs publicly is intended (it is an outward-facing action), then set CYBERINE_DOCS_ORIGIN in the deploy job and add a publish step. No further code is needed. Recipe and both-ways verification commands are in USAGE.md under "Discoverability - CYBERINE_DOCS_ORIGIN".