Files
Lumotia/src/design-system/v0.3-quietware-tokens.css
Jake 6881aa800a v0.3 Phase 4l: semantic palette revision — Tiger Flame / Banana Cream / Sea Green / Steel Azure
Wren palette pass on 2026/05/15. Splits the role tokens away from
the prior bright/neon set toward a more grounded warm-and-cool
quartet, with explicit FILL + TEXT (signal + ink) pairs in light
mode so AA-on-cream stays cheap to consume.

Dark mode signals
  --color-info-signal     #6EA8FF  →  #064789  Steel Azure
  --color-danger-signal   #FF5A52  →  #F26430  Tiger Flame
  --color-success-signal  #00FF56  →  #519872  Sea Green
  --color-caution-signal  #FFCD00  →  #FCEC52  Banana Cream

Light mode (FILL = signal, TEXT = ink)
  --color-info-signal     #000AFF  →  #217AD5  +ink #1F73C9
  --color-danger-signal   #FF0700  →  #D55121  +ink #C54B1F
  --color-success-signal  #00D94A  →  #21D575  +ink #148348
  --color-caution-signal  #FFCD00  →  #D5A021  +ink #7E7414

Unchanged on purpose
  --color-bg              Coffee Bean #1F0812 was tried live and
                          rejected — R/G/B channels (31/8/18) read
                          as aubergine, not brown. Bg + grain held
                          at #12100E / 0.06 pending a true warm-brown
                          candidate.
  --color-*-border        Hue family unchanged from Phase 4j.
  --color-*-bg            Hand-tuned surface tints unchanged.
  HC variants             Out of scope for this pass.

Known issue
  Steel Azure #064789 on the dark bg sits around 2.06:1 — fails AA
  as text/icon. The role-token model has --color-info-ink (currently
  #9CC6FF, light blue) for that use case, but consumers reaching for
  --color-info-signal directly will read muddy. Retune of the info
  ink/signal split is owed separately. Documented inline.

npm run check: 0 errors.
2026-05-15 21:18:43 +01:00

769 lines
31 KiB
CSS

/* ============================================================
Lumotia v0.3 — Tactile Quietware tokens.
Phase 1 of the v0.3 release. Tokens only. No component refactors,
no layout changes, no behavioural shifts. The new palette and
typography activate only when html[data-design="quietware"] is set.
When the attribute is absent the runtime app behaves exactly as it
did in v0.2.
Activation paths:
1. Manual: add data-design="quietware" to <html> via dev tools.
2. Build flag (Phase 2): VITE_LUMOTIA_QUIETWARE=1 wires the
attribute through +layout.svelte automatically.
--------------------------------------------------------------
Phase 4g — four-tier semantic role tokens (2026-05-15 round 5).
One semantic role colour cannot do every UI job. Forcing
--color-caution to be both bright yellow (signal) AND accessible
text on cream (ochre) collapses the visible identity. Instead,
each role has four tier-specific tokens:
signal the brand-true colour for the role. Used for left
bars, large icons, dots, status pills, focus rings.
Looks like the role at a glance.
ink accessible text variant. Used ONLY when text itself
must carry the role colour (small chips, badges).
WCAG AA 4.5:1 on the surface it sits on.
border middle value. Visible as a notice or chip outline
but does not need to clear AA-text contrast.
bg hand-tuned pale tint surface. NOT a generic
color-mix derivation, because that produces muddy
results in mixed-luminance themes. Each value is
picked per theme so the surface stays clean.
Usage layer on top: --notice-{role}-{bar,icon,border,bg,title,body}.
Components reference the usage tokens so future per-usage
re-tuning does not require touching every site.
The source hue tokens stay (encoding role identity from Jake's
color.adobe.com palette). They are NEVER used in the runtime UI
directly. Use the tiered tokens.
Brand accent (--color-accent, copper-clay) remains distinct from
semantic yellow. Brand is action / Lumotia identity. Yellow is
caution / review.
Typography stack (V4 pairing, locked 2026-05-15):
Work Sans -> body, UI, controls, headers
Young Serif -> brand moments only (wordmark, empty-state hook)
JetBrains Mono -> logs, paths, model IDs
Source brief: docs/release/v0.3-tactile-quietware.md.
============================================================ */
@font-face {
font-family: 'Work Sans';
src: url('/fonts/work-sans-variable.woff2') format('woff2-variations'),
url('/fonts/work-sans-variable.woff2') format('woff2');
font-weight: 100 900;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Work Sans';
src: url('/fonts/work-sans-italic-variable.woff2') format('woff2-variations'),
url('/fonts/work-sans-italic-variable.woff2') format('woff2');
font-weight: 100 900;
font-style: italic;
font-display: swap;
}
@font-face {
font-family: 'Young Serif';
src: url('/fonts/young-serif.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
/* ============================================================
Phase 4j — colour-grammar correction (2026-05-15 round 8).
Five source hues + five complement sources. Never used directly
in component CSS; consumed only by role and component tokens.
Red record / error / destructive / blocked
Blue primary app action / info / processing
Green ready / saved / success
Yellow caution / needs review / pending
Orange Lumotia brand mark only, NOT default action
Component tokens are defined below in each theme block. Tonal
scales (red-50 .. red-950 etc.) will land in a focused future
commit; for now the component layer picks hand-tuned hex values
verified at WCAG AA on their target surface.
============================================================ */
:root[data-design="quietware"] {
--source-red: #FF0700;
--source-yellow: #FFCD00;
--source-green: #00FF56;
--source-blue: #000AFF;
--source-orange-brand: #F0620A;
--red-complement-source: #00F8FF;
--yellow-complement-source: #0032FF;
--green-complement-source: #FF00A9;
--blue-complement-source: #FFF500;
--orange-complement-source: #0A98F0;
/* Legacy alias retained for the v0.2 path. */
--semantic-red-source: var(--source-red);
--semantic-yellow-source: var(--source-yellow);
--semantic-green-source: var(--source-green);
--semantic-blue-source: var(--source-blue);
}
/* ============================================================
Root-level fallback notice tokens. When quietware is OFF the
v0.2 surface still gets sensible notice-* values derived from
the v0.2 --color-{role} tokens via color-mix. Quietware blocks
below override these with hand-tuned per-mode values.
============================================================ */
:root {
--notice-info-bar: var(--color-info);
--notice-info-icon: var(--color-info);
--notice-info-border: color-mix(in oklab, var(--color-info) 40%, transparent);
--notice-info-bg: color-mix(in oklab, var(--color-info) 8%, transparent);
--notice-danger-bar: var(--color-danger);
--notice-danger-icon: var(--color-danger);
--notice-danger-border: color-mix(in oklab, var(--color-danger) 40%, transparent);
--notice-danger-bg: color-mix(in oklab, var(--color-danger) 8%, transparent);
--notice-success-bar: var(--color-success);
--notice-success-icon: var(--color-success);
--notice-success-border: color-mix(in oklab, var(--color-success) 40%, transparent);
--notice-success-bg: color-mix(in oklab, var(--color-success) 8%, transparent);
--notice-caution-bar: var(--color-caution);
--notice-caution-icon: var(--color-caution);
--notice-caution-border: color-mix(in oklab, var(--color-caution) 40%, transparent);
--notice-caution-bg: color-mix(in oklab, var(--color-caution) 8%, transparent);
/* v0.2 fallback button-component tokens. When quietware is off these
keep components rendering with their existing v0.2 colours via the
v0.2 --color-accent / --color-danger semantic tokens. Quietware
blocks below override with the Phase 4j specific values. */
--button-record-bg: var(--color-danger);
--button-record-fg: #FFFFFF;
--button-record-border: var(--color-danger);
--button-record-wire: transparent;
--button-primary-bg: var(--color-accent);
--button-primary-fg: #FFFFFF;
--button-primary-border: var(--color-accent);
--button-primary-wire: transparent;
--button-danger-bg: var(--color-danger);
--button-danger-fg: #FFFFFF;
--button-danger-border: var(--color-danger);
--button-danger-wire: transparent;
--button-success-bg: var(--color-success);
--button-success-fg: #FFFFFF;
--button-success-border: var(--color-success);
--button-success-wire: transparent;
--button-caution-bg: var(--color-caution);
--button-caution-fg: #000000;
--button-caution-border: var(--color-caution);
--button-caution-wire: transparent;
--brand-accent: var(--color-accent);
--wire-width: 0px;
--wire-width-focus: 2px;
--wire-opacity-dark: 0;
--wire-opacity-light: 0;
--wire-opacity-focus: 0;
--wire-style: solid;
--focus-ring-color: var(--color-accent);
}
/* ============================================================
Quietware — dark mode default. Warm brown-charcoal atmosphere.
============================================================ */
:root[data-design="quietware"] {
/* Phase 4l — Wren palette revision, 2026/05/15. Role signals
swapped to Tiger Flame / Banana Cream / Sea Green / Steel Azure
(dark) and the FILL/TEXT pair set (light). Coffee Bean bg
candidate #1F0812 was tested live and rejected — its R/G/B
channels (31/8/18) sit on a purple-leaning hue, reading as
aubergine in the running window, not the labelled warm brown.
Bg + grain held at the prior values pending a true coffee-brown
candidate. Steel Azure contrast on dark fails AA (see notice on
--color-info-signal below) regardless of bg choice — retune of
the info ink/signal split is owed separately. */
--color-bg: #12100E;
--color-bg-elevated: #1A1713;
--color-bg-card: #211D18;
--color-bg-input: #181510;
--color-border: #4A4035;
--color-border-subtle: #2C261F;
--color-text: #F3EFE7;
--color-text-secondary: #BDB6A9;
--color-text-tertiary: #908779;
/* Phase 4j — primary action is BLUE; brand-accent (orange) defined
in the component-tokens block below and restricted to logo /
brand surfaces. --color-accent stays as the convenience alias for
primary action so v0.2 component callers (bg-accent etc.) get
blue under quietware. */
--color-accent: var(--blue-700);
--color-accent-hover: var(--blue-800);
--color-accent-subtle: color-mix(in srgb, var(--blue-700) 12%, transparent);
--color-accent-glow: color-mix(in srgb, var(--blue-700) 25%, transparent);
/* Four-tier role tokens. Signal carries the role's identity
(Tiger Flame / Banana Cream / Sea Green / Steel Azure under
Phase 4l); ink lightens for text legibility on dark; border is
a middle value; bg is a hand-tuned dark tint, not a color-mix.
Borders + bg tints retained from Phase 4j — they go with the
hue family rather than the specific shade. */
--color-info-signal: #064789;
--color-info-ink: #9CC6FF;
--color-info-border: #4D8DFF;
--color-info-bg: #101A2A;
--color-danger-signal: #F26430;
--color-danger-ink: #FF9B96;
--color-danger-border: #FF5A52;
--color-danger-bg: #2A1412;
--color-success-signal: #519872;
--color-success-ink: #7DFFA8;
--color-success-border: #00D94A;
--color-success-bg: #0D2415;
--color-caution-signal: #FCEC52;
--color-caution-ink: #FFE066;
--color-caution-border: #FFCD00;
--color-caution-bg: #29210A;
/* Backward-compat aliases. v0.2 callers of --color-danger etc.
get the signal variant by default. New code should reach for the
specific tier. */
--color-info: var(--color-info-signal);
--color-danger: var(--color-danger-signal);
--color-success: var(--color-success-signal);
--color-caution: var(--color-caution-signal);
--color-warning: var(--color-caution-signal);
/* Notice usage tokens. Components subscribe to these so future
per-usage retuning does not require touching every site. In dark
mode the notice icon uses signal (bright on dark surface);
title/body always neutral text. */
--notice-info-bar: var(--color-info-signal);
--notice-info-icon: var(--color-info-signal);
--notice-info-border: var(--color-info-border);
--notice-info-bg: var(--color-info-bg);
--notice-danger-bar: var(--color-danger-signal);
--notice-danger-icon: var(--color-danger-signal);
--notice-danger-border: var(--color-danger-border);
--notice-danger-bg: var(--color-danger-bg);
--notice-success-bar: var(--color-success-signal);
--notice-success-icon: var(--color-success-signal);
--notice-success-border: var(--color-success-border);
--notice-success-bg: var(--color-success-bg);
--notice-caution-bar: var(--color-caution-signal);
--notice-caution-icon: var(--color-caution-signal);
--notice-caution-border: var(--color-caution-border);
--notice-caution-bg: var(--color-caution-bg);
--color-sidebar: #0F0E0C;
--color-nav-active: #211D18;
--color-hover: #1A1713;
--color-overlay-dim: rgba(15, 14, 12, 0.7);
--font-family-body: 'Work Sans', system-ui, sans-serif;
--font-family-display: 'Young Serif', serif;
--font-family-mono: 'JetBrains Mono', monospace;
/* Phase 4e behavioural tokens for the HC rendering contract. */
--grain-opacity: 0.06;
--shadow-strength: 1;
--border-width-control: 1px;
--focus-ring-width: 2px;
--panel-radius: 8px;
--quietware-texture-opacity: var(--grain-opacity);
--quietware-texture-color: rgba(243, 239, 231, 1);
/* ----------------------------------------------------------
Phase 4j — wirelines (renamed from counterlines) and component
tokens for buttons (round-8 spec).
Wireline levels (unchanged):
Level 0 none panels, notices (default), content, disabled
Level 1 quiet controls, chips, active nav
Level 2 focus keyboard focus, recording state
Opacity bumped per round-8 (was 0.32/0.22/0.85; now 0.75/0.6/1.0)
so Level 1 reads at standard viewing without becoming noisy.
---------------------------------------------------------- */
--wire-width: 1px;
--wire-width-active: 2px;
--wire-width-focus: 2px;
--wire-opacity-dark: 0.75;
--wire-opacity-light: 0.6;
--wire-opacity-active: 0.9;
--wire-opacity-focus: 1;
--wire-opacity: var(--wire-opacity-dark); /* mode-aware resolver */
--wire-style: solid;
/* Legacy counterline aliases retained for Phase 4h/4i opt-in path. */
--counterline-width: var(--wire-width);
--counterline-width-focus: var(--wire-width-focus);
--counterline-opacity-dark: var(--wire-opacity-dark);
--counterline-opacity-light: var(--wire-opacity-light);
--counterline-opacity-focus: var(--wire-opacity-focus);
/* Component tokens — consume scale tokens only. Never raw hex.
Phase 4k: scale tokens defined in v0.3-quietware-scales.css. */
/* Record. Red mid-step on dark surface clears AA on white text. */
--button-record-bg: var(--red-600);
--button-record-fg: #FFFFFF;
--button-record-border: var(--red-700);
--button-record-wire: var(--red-complement-400);
/* Primary app action. Blue 600 on dark, AA on white. */
--button-primary-bg: var(--blue-700);
--button-primary-fg: #FFFFFF;
--button-primary-border: var(--blue-800);
--button-primary-wire: var(--blue-complement-400);
/* Destructive shares record fill but separate token for semantic clarity. */
--button-danger-bg: var(--red-600);
--button-danger-fg: #FFFFFF;
--button-danger-border: var(--red-700);
--button-danger-wire: var(--red-complement-400);
/* Success. green-800 chosen so white foreground clears AA 4.5:1. */
--button-success-bg: var(--green-800);
--button-success-fg: #FFFFFF;
--button-success-border: var(--green-900);
--button-success-wire: var(--green-complement-400);
/* Caution. Yellow 400 — bright enough to read, paired with near-black
foreground (yellow-950) so text passes AA on the yellow surface. */
--button-caution-bg: var(--yellow-400);
--button-caution-fg: var(--yellow-950);
--button-caution-border: var(--yellow-600);
--button-caution-wire: var(--yellow-complement-500);
/* Neutral — non-semantic, low-priority controls. */
--button-neutral-bg: var(--color-bg-elevated);
--button-neutral-fg: var(--color-text);
--button-neutral-border: var(--color-border-subtle);
--button-neutral-wire: transparent;
/* Disabled — flat, low-saturation, never carries a wireline. */
--button-disabled-bg: var(--color-bg-elevated);
--button-disabled-fg: var(--color-text-tertiary);
--button-disabled-border: var(--color-border-subtle);
--button-disabled-wire: transparent;
/* Progress component tokens. Track + fill per role. Default progress
= primary blue; success / caution / danger explicit. Disk-space
reads neutral by default and only escalates per threshold. */
/* Progress fills shifted lighter on dark surfaces so the bar
reads on the dark elevated track. */
--progress-track: var(--color-bg-elevated);
--progress-download-fill: var(--blue-400);
--progress-transcribing-fill: var(--blue-400);
--progress-success-fill: var(--green-500);
--progress-caution-fill: var(--yellow-500);
--progress-danger-fill: var(--red-500);
--progress-disk-fill: var(--color-text-tertiary);
--progress-disk-caution-fill: var(--yellow-500);
--progress-disk-danger-fill: var(--red-500);
/* Brand accent — orange-500. Restricted to logo / brand surfaces. */
--brand-accent: var(--orange-500);
--brand-accent-strong: var(--orange-600);
--brand-wire: var(--orange-complement-400);
/* Notice counterline tokens retired from defaults (LumotiaNotice
stays opt-in via the `counterline` prop). Tokens kept available
for the opt-in path; same value pattern as Phase 4i. */
--notice-info-counterline: color-mix(in srgb, var(--source-blue) calc(var(--wire-opacity-dark) * 100%), transparent);
--notice-danger-counterline: color-mix(in srgb, var(--red-complement-source) calc(var(--wire-opacity-dark) * 100%), transparent);
--notice-success-counterline: color-mix(in srgb, var(--green-complement-source) calc(var(--wire-opacity-dark) * 100%), transparent);
--notice-caution-counterline: color-mix(in srgb, var(--yellow-complement-source) calc(var(--wire-opacity-dark) * 100%), transparent);
--button-brand-counterline: var(--brand-wire);
/* Focus ring colour — defaults to primary blue. Components can
override per-context (eg. record-button focus could use red). */
--focus-ring-color: var(--button-primary-bg);
}
[data-wire-style="dotted"] {
--wire-style: dotted;
}
/* ============================================================
Quietware — light mode. Warm paper.
Caution signal stays bright #FFCD00; ink #7A5D00 only appears
when caution text itself must be coloured.
============================================================ */
:root[data-design="quietware"][data-theme="light"] {
--color-bg: #FBF8F2;
--color-bg-elevated: #F6F1EA;
--color-bg-card: #FFFDF8;
--color-bg-input: #F4EFE7;
--color-border: #897D70;
--color-border-subtle: #D8D0C4;
--color-text: #1D1B18;
--color-text-secondary: #5E574C;
--color-text-tertiary: #74685B;
/* Phase 4k — --color-accent points at scale-blue under light mode.
Brand accent (orange) defined alongside component tokens below. */
--color-accent: var(--blue-700);
--color-accent-hover: var(--blue-800);
--color-accent-subtle: color-mix(in srgb, var(--blue-700) 12%, transparent);
--color-accent-glow: color-mix(in srgb, var(--blue-700) 25%, transparent);
/* Four-tier role tokens, light mode. Phase 4l — Wren palette
revision 2026/05/15. Signal = FILL (vivid), ink = TEXT-safe
darker sibling that passes 4.5:1 on cream. Saturation/lightness
targeted on the locked Banana Cream anchor #D5A021 (S 73%, L 48%).
Borders + bg tints unchanged — they go with the hue family. */
--color-info-signal: #217AD5;
--color-info-ink: #1F73C9;
--color-info-border: #3A6BFF;
--color-info-bg: #EEF3FF;
--color-danger-signal: #D55121;
--color-danger-ink: #C54B1F;
--color-danger-border: #E13A32;
--color-danger-bg: #FFF0EF;
--color-success-signal: #21D575;
--color-success-ink: #148348;
--color-success-border: #159947;
--color-success-bg: #EAF8EE;
--color-caution-signal: #D5A021;
--color-caution-ink: #7E7414;
--color-caution-border: #D9A900;
--color-caution-bg: #FFF7D6;
--color-info: var(--color-info-signal);
--color-danger: var(--color-danger-signal);
--color-success: var(--color-success-signal);
--color-caution: var(--color-caution-signal);
--color-warning: var(--color-caution-signal);
/* In light mode the notice icon uses ink (the dark variant) so it
reads clearly against the pale -bg tint. Signal would wash out. */
--notice-info-bar: var(--color-info-signal);
--notice-info-icon: var(--color-info-ink);
--notice-info-border: var(--color-info-border);
--notice-info-bg: var(--color-info-bg);
--notice-danger-bar: var(--color-danger-signal);
--notice-danger-icon: var(--color-danger-ink);
--notice-danger-border: var(--color-danger-border);
--notice-danger-bg: var(--color-danger-bg);
--notice-success-bar: var(--color-success-signal);
--notice-success-icon: var(--color-success-ink);
--notice-success-border: var(--color-success-border);
--notice-success-bg: var(--color-success-bg);
--notice-caution-bar: var(--color-caution-signal);
--notice-caution-icon: var(--color-caution-ink);
--notice-caution-border: var(--color-caution-border);
--notice-caution-bg: var(--color-caution-bg);
--color-sidebar: #F3EEE6;
--color-nav-active: #E8E2D6;
--color-hover: #EAE4D8;
--color-overlay-dim: rgba(29, 27, 24, 0.55);
--grain-opacity: 0.07;
--quietware-texture-opacity: var(--grain-opacity);
--quietware-texture-color: rgba(29, 27, 24, 1);
/* Phase 4k — light-mode component tokens consume scale tokens at
slightly deeper steps for AA on cream paper. */
--button-record-bg: var(--red-700);
--button-record-fg: #FFFFFF;
--button-record-border: var(--red-800);
--button-record-wire: var(--red-complement-400);
--button-primary-bg: var(--blue-700);
--button-primary-fg: #FFFFFF;
--button-primary-border: var(--blue-800);
--button-primary-wire: var(--blue-complement-400);
--button-danger-bg: var(--red-700);
--button-danger-fg: #FFFFFF;
--button-danger-border: var(--red-800);
--button-danger-wire: var(--red-complement-400);
--button-success-bg: var(--green-800);
--button-success-fg: #FFFFFF;
--button-success-border: var(--green-900);
--button-success-wire: var(--green-complement-400);
--button-caution-bg: var(--yellow-400);
--button-caution-fg: var(--yellow-950);
--button-caution-border: var(--yellow-700);
--button-caution-wire: var(--yellow-complement-500);
--button-neutral-bg: var(--color-bg-elevated);
--button-neutral-fg: var(--color-text);
--button-neutral-border: var(--color-border-subtle);
--button-neutral-wire: transparent;
--button-disabled-bg: var(--color-bg-elevated);
--button-disabled-fg: var(--color-text-tertiary);
--button-disabled-border: var(--color-border-subtle);
--button-disabled-wire: transparent;
/* Progress fills shifted darker on cream so the bar reads on the
pale paper track. Success uses green-800 to clear 3:1 on cream. */
--progress-track: var(--color-bg-elevated);
--progress-download-fill: var(--blue-700);
--progress-transcribing-fill: var(--blue-700);
--progress-success-fill: var(--green-800);
--progress-caution-fill: var(--yellow-600);
--progress-danger-fill: var(--red-700);
--progress-disk-fill: var(--color-text-tertiary);
--progress-disk-caution-fill: var(--yellow-600);
--progress-disk-danger-fill: var(--red-700);
--brand-accent: var(--orange-500);
--brand-accent-strong: var(--orange-700);
--brand-wire: var(--orange-complement-400);
--wire-opacity: var(--wire-opacity-light); /* light-mode resolver */
/* Legacy notice counterline tokens — opt-in only. */
--notice-info-counterline: color-mix(in srgb, var(--source-blue) calc(var(--wire-opacity-light) * 100%), transparent);
--notice-danger-counterline: color-mix(in srgb, var(--red-complement-source) calc(var(--wire-opacity-light) * 100%), transparent);
--notice-success-counterline: color-mix(in srgb, var(--green-complement-source) calc(var(--wire-opacity-light) * 100%), transparent);
--notice-caution-counterline: color-mix(in srgb, var(--yellow-complement-source) calc(var(--wire-opacity-light) * 100%), transparent);
--button-brand-counterline: var(--brand-wire);
}
/* ============================================================
Quietware — high-contrast. Simple and brutal.
All notice -bg goes transparent; -bar/-icon/-border collapse
to a single source colour per role. Semantic recognition by
colour identity + label + icon shape, not by ambient tinting.
============================================================ */
:root[data-design="quietware"][data-contrast="high"],
:root[data-design="quietware"][data-theme="light"][data-contrast="high"] {
--color-bg: #FFFFFF;
--color-bg-elevated: #FFFFFF;
--color-bg-card: #FFFFFF;
--color-bg-input: #FFFFFF;
--color-border: #000000;
--color-border-subtle: #000000;
--color-text: #000000;
--color-text-secondary: #000000;
--color-text-tertiary: #000000;
--color-accent: #005FCC;
--color-accent-hover: #004BA0;
--color-accent-subtle: transparent;
--color-accent-glow: transparent;
--color-info-signal: #000AFF;
--color-info-ink: #000AFF;
--color-info-border: #000AFF;
--color-info-bg: transparent;
--color-danger-signal: #FF0700;
--color-danger-ink: #FF0700;
--color-danger-border: #FF0700;
--color-danger-bg: transparent;
--color-success-signal: #00B83E;
--color-success-ink: #007A2B;
--color-success-border: #00B83E;
--color-success-bg: transparent;
--color-caution-signal: #FFCD00;
--color-caution-ink: #7A5D00;
--color-caution-border: #FFCD00;
--color-caution-bg: transparent;
--color-info: var(--color-info-signal);
--color-danger: var(--color-danger-signal);
--color-success: var(--color-success-signal);
--color-caution: var(--color-caution-signal);
--color-warning: var(--color-caution-signal);
--notice-info-bar: var(--color-info-signal);
--notice-info-icon: var(--color-info-signal);
--notice-info-border: var(--color-info-border);
--notice-info-bg: transparent;
--notice-danger-bar: var(--color-danger-signal);
--notice-danger-icon: var(--color-danger-signal);
--notice-danger-border: var(--color-danger-border);
--notice-danger-bg: transparent;
--notice-success-bar: var(--color-success-signal);
--notice-success-icon: var(--color-success-ink);
--notice-success-border: var(--color-success-border);
--notice-success-bg: transparent;
--notice-caution-bar: var(--color-caution-signal);
--notice-caution-icon: var(--color-caution-ink);
--notice-caution-border: var(--color-caution-border);
--notice-caution-bg: transparent;
--color-sidebar: #FFFFFF;
--color-nav-active: #000000;
--color-hover: #F0F0F0;
--color-overlay-dim: rgba(0, 0, 0, 0.85);
--grain-opacity: 0;
--shadow-strength: 0;
--border-width-control: 2px;
--focus-ring-width: 3px;
--panel-radius: 8px;
--quietware-texture-opacity: 0;
--quietware-texture-color: rgba(0, 0, 0, 0);
/* HC contract: counterlines disabled for normal states. The HC
focus ring (2 px, full strong-blue) IS the tactile detail in
this mode. */
--counterline-width: 0;
--counterline-width-focus: 2px;
--counterline-opacity-dark: 0;
--counterline-opacity-light: 0;
--counterline-opacity-focus: 1;
--notice-info-counterline: transparent;
--notice-danger-counterline: transparent;
--notice-success-counterline: transparent;
--notice-caution-counterline: transparent;
--button-brand-counterline: transparent;
--button-danger-counterline: transparent;
--button-info-counterline: transparent;
--button-success-counterline: transparent;
--button-caution-counterline: transparent;
/* HC focus ring is the brand-strong blue, not a complement. */
--focus-ring-color: #005FCC;
/* HC progress fills — track is white, fills must be dark enough
for 3:1 contrast. (HC-dark sub-block overrides to bright shades
for the black surface.) */
--progress-track: var(--color-bg-elevated);
--progress-download-fill: var(--blue-700);
--progress-transcribing-fill: var(--blue-700);
--progress-success-fill: var(--green-800);
--progress-caution-fill: var(--yellow-700);
--progress-danger-fill: var(--red-700);
}
/* Dark-base high-contrast — black background, white borders. Used
when the user explicitly wants HC inside the dark theme. */
:root[data-design="quietware"][data-contrast="high"]:not([data-theme="light"]) {
--color-bg: #000000;
--color-bg-elevated: #000000;
--color-bg-card: #000000;
--color-bg-input: #000000;
--color-border: #FFFFFF;
--color-border-subtle: #FFFFFF;
--color-text: #FFFFFF;
--color-text-secondary: #FFFFFF;
--color-text-tertiary: #FFFFFF;
--color-accent: #75A8F0;
--color-accent-hover: #5C92E0;
/* HC dark inverts the contrast direction: signals are the lighter
end of each hue, not the saturated source. -bg stays transparent
so the black surface shows through directly. */
--color-info-signal: #8AB4F8;
--color-info-ink: #8AB4F8;
--color-info-border: #8AB4F8;
--color-info-bg: transparent;
--color-danger-signal: #FF8A8A;
--color-danger-ink: #FF8A8A;
--color-danger-border: #FF8A8A;
--color-danger-bg: transparent;
--color-success-signal: #79D59B;
--color-success-ink: #79D59B;
--color-success-border: #79D59B;
--color-success-bg: transparent;
--color-caution-signal: #F2C94C;
--color-caution-ink: #FFE066;
--color-caution-border: #F2C94C;
--color-caution-bg: transparent;
--color-info: var(--color-info-signal);
--color-danger: var(--color-danger-signal);
--color-success: var(--color-success-signal);
--color-caution: var(--color-caution-signal);
--color-warning: var(--color-caution-signal);
--notice-info-icon: var(--color-info-signal);
--notice-danger-icon: var(--color-danger-signal);
--notice-success-icon: var(--color-success-signal);
--notice-caution-icon: var(--color-caution-signal);
--color-sidebar: #000000;
--color-nav-active: #FFFFFF;
--color-hover: #1A1A1A;
/* HC-dark progress fills — track is black, fills must be light for 3:1. */
--progress-download-fill: var(--blue-300);
--progress-transcribing-fill: var(--blue-300);
--progress-success-fill: var(--green-400);
--progress-caution-fill: var(--yellow-400);
--progress-danger-fill: var(--red-400);
--progress-disk-fill: var(--color-text-secondary);
--progress-disk-caution-fill: var(--yellow-400);
--progress-disk-danger-fill: var(--red-400);
}
/* ============================================================
Static grain overlay. Reads --grain-opacity. Zero in HC mode by
contract. Fixed-position so it does not scroll.
============================================================ */
:root[data-design="quietware"] body::after {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 9999;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='240' height='240'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>");
opacity: var(--grain-opacity);
mix-blend-mode: overlay;
}
/* ============================================================
Reduced motion. Honour OS preference; quietware rules require it.
============================================================ */
@media (prefers-reduced-motion: reduce) {
:root[data-design="quietware"] * {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}