/* ============================================================ 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 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; } /* ============================================================ Semantic source hues. Identity-only, never used directly. Each --color-{role}-{tier} is a hand-tuned derivation. ============================================================ */ :root[data-design="quietware"] { --semantic-red-source: #FF0700; --semantic-yellow-source: #FFCD00; --semantic-green-source: #00FF56; --semantic-blue-source: #000AFF; } /* ============================================================ 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); } /* ============================================================ Quietware — dark mode default. Warm brown-charcoal atmosphere. ============================================================ */ :root[data-design="quietware"] { --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; /* Brand accent. Copper-clay, distinct from semantic yellow. */ --color-accent: #C97845; --color-accent-hover: #B96638; --color-accent-subtle: #C9784514; --color-accent-glow: #C9784525; /* Four-tier role tokens. Signal stays bright (the role's identity); ink lightens for text legibility on dark; border is a middle value; bg is a hand-tuned dark tint, not a color-mix derivation. */ --color-info-signal: #6EA8FF; --color-info-ink: #9CC6FF; --color-info-border: #4D8DFF; --color-info-bg: #101A2A; --color-danger-signal: #FF5A52; --color-danger-ink: #FF9B96; --color-danger-border: #FF5A52; --color-danger-bg: #2A1412; --color-success-signal: #00FF56; --color-success-ink: #7DFFA8; --color-success-border: #00D94A; --color-success-bg: #0D2415; --color-caution-signal: #FFCD00; --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); } /* ============================================================ 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; --color-accent: #9D5F32; --color-accent-hover: #854E29; --color-accent-subtle: #9D5F3214; --color-accent-glow: #9D5F3225; /* Four-tier role tokens, light mode. Bg values hand-picked as clean pale tints, not muddy color-mix products. */ --color-info-signal: #000AFF; --color-info-ink: #0033A0; --color-info-border: #3A6BFF; --color-info-bg: #EEF3FF; --color-danger-signal: #FF0700; --color-danger-ink: #B3261E; --color-danger-border: #E13A32; --color-danger-bg: #FFF0EF; --color-success-signal: #00D94A; --color-success-ink: #006B2D; --color-success-border: #159947; --color-success-bg: #EAF8EE; --color-caution-signal: #FFCD00; --color-caution-ink: #7A5D00; --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); } /* ============================================================ 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); } /* 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; } /* ============================================================ 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,"); 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; } }