v0.3 Phase 4g: four-tier semantic tokens + notice usage layer
Round-5 feedback flagged the muddy result of forcing one --color-caution
to be both bright yellow (signal) and accessible text (ochre). The
single-token-per-role model collapsed the visible identity. Caution
notices ended up reading as brown/khaki surfaces because color-mix(
in oklab, var(--color-caution) 8%, transparent) over cream produced
muddy results whatever the source hex.
New architecture: four-tier per-role tokens, hand-tuned -bg surfaces,
plus usage-specific notice tokens on top.
Tier model — each semantic role publishes four tokens:
signal Brand-true colour. Left bars, large icons, dots, focus rings.
Looks like the role at a glance.
ink Accessible text variant. Used ONLY when text itself must
carry the role colour. WCAG AA 4.5:1 on its surface.
border Middle value. Visible chip/notice outline; not text-safe.
bg Hand-tuned pale tint surface. NOT a color-mix derivation.
Example, light-mode caution:
--color-caution-signal #FFCD00 (bright yellow)
--color-caution-ink #7A5D00 (ochre, for small text only)
--color-caution-border #D9A900 (mid gold)
--color-caution-bg #FFF7D6 (clean pale yellow tint)
--color-{role} retained as a backward-compat alias pointing at -signal.
v0.2 callers keep working; new code reaches for the specific tier.
Usage layer — components subscribe to usage-specific tokens, not
role-tier tokens directly:
--notice-{role}-bar left bar, signal-tier
--notice-{role}-icon signal in dark, ink in light, signal in HC
--notice-{role}-border outer border colour
--notice-{role}-bg hand-tuned pale surface
LumotiaNotice reads these via Tailwind arbitrary-value classes
(bg-[var(--notice-info-bg)] etc). v0.2 fallback values defined at
:root (outside quietware blocks) using color-mix from v0.2 --color-
{role} tokens so the Notice keeps rendering sensibly when quietware
is off.
HC contract — every -bg token forces to transparent. HC notices
render text + icon + 2-px border + left bar, no body tint. Brand
atmosphere steps fully aside.
Per Jake's round-5 spec: yellow stays yellow as the visible signal,
ochre only appears as small-text ink, and brown/khaki never
represents the caution role's primary visual identity again. Same
discipline applies to red/blue/green — each role has a clean
hand-tuned -bg pale tint per theme.
Verified — visible result.
Light caution notice: bright #FFCD00 bar + signal icon + ink-darkened
small icon + pale #FFF7D6 surface + #D9A900 border. Clean,
semantically clear, no mud.
Dark caution notice: bright #FFCD00 bar + signal icon + dark warm
#29210A surface + bright yellow border. Reads as yellow at a glance.
HC modes: no body tint, strong bordered notices, semantic colours
preserved as primary identifier alongside icon + label.
npm run check: 0 errors, 0 warnings across 5707 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -310,6 +310,47 @@ Foundation for the page-skeleton sweep without yet migrating any page. Two addit
|
||||
|
||||
- **`LumotiaNotice` `slim` prop** — collapses padding, drops the title block, smaller icon. For one-line ambient notices like browser-preview state.
|
||||
|
||||
### Phase 4g — Four-tier semantic tokens + notice usage layer. Landed 2026-05-15.
|
||||
|
||||
Round-5 feedback (2026-05-15) flagged the muddy result of forcing one `--color-caution` to be both bright yellow (signal) and accessible text (ochre). The single-token-per-role model collapsed the visible identity.
|
||||
|
||||
New architecture: four-tier per-role tokens with hand-tuned surfaces, plus usage-specific notice tokens on top.
|
||||
|
||||
**Tier model.** Each semantic role publishes four tier-specific tokens:
|
||||
|
||||
| Tier | Purpose | Example (light caution) |
|
||||
|---|---|---|
|
||||
| `signal` | Brand-true colour. Left bars, large icons, dots, focus rings | `#FFCD00` |
|
||||
| `ink` | Accessible text. Used ONLY when text itself must carry the role colour (small chips, badges). AA 4.5:1 on surface | `#7A5D00` |
|
||||
| `border` | Middle value. Visible chip/notice outline; does not need AA-text contrast | `#D9A900` |
|
||||
| `bg` | Hand-tuned pale tint surface. NOT a generic `color-mix` derivation | `#FFF7D6` |
|
||||
|
||||
CSS:
|
||||
|
||||
```css
|
||||
--color-{role}-signal
|
||||
--color-{role}-ink
|
||||
--color-{role}-border
|
||||
--color-{role}-bg
|
||||
```
|
||||
|
||||
`--color-{role}` retained as a backward-compat alias pointing at `-signal`. v0.2 callers keep working; new code reaches for the specific tier.
|
||||
|
||||
**Usage layer.** Components subscribe to usage-specific tokens, not role-tier tokens directly. This lets per-usage retuning happen in one place:
|
||||
|
||||
```css
|
||||
--notice-{role}-bar /* left bar background, signal-tier */
|
||||
--notice-{role}-icon /* signal in dark, ink in light, signal in HC */
|
||||
--notice-{role}-border /* outer border colour */
|
||||
--notice-{role}-bg /* hand-tuned pale surface tint */
|
||||
```
|
||||
|
||||
LumotiaNotice now reads these via Tailwind arbitrary-value classes (`bg-[var(--notice-info-bg)]` etc). v0.2 fallbacks defined at `:root` (outside quietware blocks) so the v0.2 surface keeps a sensible Notice render without depending on quietware.
|
||||
|
||||
**HC contract.** Every `-bg` token forces to `transparent`. Notices in HC render as text + icon + 2-px border + left bar with no body tint. Brand atmosphere steps fully aside.
|
||||
|
||||
Per Jake's round-5 spec: yellow stays yellow (visible signal), ochre only appears as small-text ink, and brown/khaki never represents the caution role's primary identity again.
|
||||
|
||||
### Phase 5b — Browser-preview reclassification. Landed 2026-05-15.
|
||||
|
||||
Targeted scope per Jake's round-4 feedback: the browser-preview state used to render as a red error block in `DictationPage.svelte`. That is an environment limitation, not a failed action. Reclassified as a slim info notice with friendlier copy:
|
||||
|
||||
@@ -14,22 +14,40 @@
|
||||
attribute through +layout.svelte automatically.
|
||||
|
||||
--------------------------------------------------------------
|
||||
Palette — Phase 4d revision (2026-05-15 round 4 feedback).
|
||||
Phase 4g — four-tier semantic role tokens (2026-05-15 round 5).
|
||||
|
||||
Atmosphere is warm brown-charcoal. Semantic colours are
|
||||
muted-Material hues, NOT max-saturation primaries. The brand
|
||||
accent (copper-clay) is intentionally distinct from caution
|
||||
(yellow) so the two warm attention colours do not collide.
|
||||
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:
|
||||
|
||||
Light-mode caution returns to ochre #7A5D00; this passes AA as
|
||||
text on cream and works with the left-bar Notice pattern. The
|
||||
earlier "fill-only on cream" rule applied to the bright #FFCD00
|
||||
primary; under muted-Material values that constraint dissolves.
|
||||
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.
|
||||
|
||||
High contrast is a rendering CONTRACT, not just a palette. Phase
|
||||
4e behavioural tokens (--grain-opacity, --shadow-strength,
|
||||
--border-width-control, --focus-ring-width, --panel-radius)
|
||||
accompany the palette override.
|
||||
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
|
||||
@@ -66,24 +84,8 @@
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Semantic source palette (Phase 4f, 2026-05-15).
|
||||
|
||||
These four hex values are the BRAND-identity source for the
|
||||
semantic system. They are NEVER used directly as text or fill
|
||||
in the runtime UI — each --color-{role} is a theme-tuned
|
||||
derivation that meets WCAG AA in its context. The source tokens
|
||||
exist so the relationship between brand-source and theme-derived
|
||||
is traceable in code (and so a future re-tune of one role does
|
||||
not require chasing every reference).
|
||||
|
||||
Red -> error, failed, destructive, blocked
|
||||
Yellow -> needs review, caution, missing setup, pending
|
||||
Green -> ready, saved, complete, safe
|
||||
Blue -> information, processing, neutral system guidance
|
||||
|
||||
The brand accent (--color-accent, copper-clay) is intentionally
|
||||
separate from semantic yellow. Brand is action / Lumotia
|
||||
identity. Yellow is caution / review.
|
||||
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;
|
||||
@@ -93,10 +95,35 @@
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Quietware — dark mode default.
|
||||
Warm brown-charcoal atmosphere. Reads as warm when you notice
|
||||
it, not coloured at first glance. Semantic and brand-accent
|
||||
palettes are deliberately separate.
|
||||
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;
|
||||
@@ -116,22 +143,61 @@
|
||||
--color-accent-subtle: #C9784514;
|
||||
--color-accent-glow: #C9784525;
|
||||
|
||||
/* Semantic palette. Derived from --semantic-{role}-source by
|
||||
lowering saturation/chroma and tuning lightness for AA on the
|
||||
dark surface. Each role keeps the source hue identity. */
|
||||
--color-danger: #FF8A8A; /* derived from --semantic-red-source #FF0700 */
|
||||
--color-caution: #F2C94C; /* derived from --semantic-yellow-source #FFCD00 */
|
||||
--color-warning: var(--color-caution);
|
||||
--color-success: #79D59B; /* derived from --semantic-green-source #00FF56 */
|
||||
--color-info: #8AB4F8; /* derived from --semantic-blue-source #000AFF */
|
||||
/* 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;
|
||||
|
||||
/* Subtle role fills for Notice backgrounds, hover tints, focus
|
||||
halos. ~8% role over the surface — passes through atmosphere
|
||||
without becoming a colour zone. */
|
||||
--color-danger-bg: color-mix(in oklab, var(--color-danger) 8%, transparent);
|
||||
--color-caution-bg: color-mix(in oklab, var(--color-caution) 8%, transparent);
|
||||
--color-success-bg: color-mix(in oklab, var(--color-success) 8%, transparent);
|
||||
--color-info-bg: color-mix(in oklab, var(--color-info) 8%, transparent);
|
||||
--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;
|
||||
@@ -142,25 +208,21 @@
|
||||
--font-family-display: 'Young Serif', serif;
|
||||
--font-family-mono: 'JetBrains Mono', monospace;
|
||||
|
||||
/* Phase 4e behavioural tokens — components opt into the rendering
|
||||
contract by reading these. Defaults preserve existing v0.3 feel. */
|
||||
/* 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;
|
||||
|
||||
/* Legacy alias — earlier Phase 4c name. Kept for transition. */
|
||||
--quietware-texture-opacity: var(--grain-opacity);
|
||||
--quietware-texture-color: rgba(243, 239, 231, 1);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Quietware — light mode.
|
||||
Warm paper base. Slight tone on the main work surface so the
|
||||
page does not read as a generic web app. Caution returns to
|
||||
ochre #7A5D00 — passes AA as text on cream under the muted
|
||||
palette.
|
||||
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;
|
||||
@@ -179,17 +241,55 @@
|
||||
--color-accent-subtle: #9D5F3214;
|
||||
--color-accent-glow: #9D5F3225;
|
||||
|
||||
/* Semantic palette — derivations for light mode, AA on cream. */
|
||||
--color-danger: #B3261E; /* derived from --semantic-red-source */
|
||||
--color-caution: #7A5D00; /* derived from --semantic-yellow-source */
|
||||
--color-warning: var(--color-caution);
|
||||
--color-success: #1B6B3A; /* derived from --semantic-green-source */
|
||||
--color-info: #2457A6; /* derived from --semantic-blue-source */
|
||||
/* 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-bg: color-mix(in oklab, var(--color-danger) 8%, transparent);
|
||||
--color-caution-bg: color-mix(in oklab, var(--color-caution) 8%, transparent);
|
||||
--color-success-bg: color-mix(in oklab, var(--color-success) 8%, transparent);
|
||||
--color-info-bg: color-mix(in oklab, var(--color-info) 8%, transparent);
|
||||
--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;
|
||||
@@ -202,11 +302,10 @@
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Quietware — high-contrast rendering contract.
|
||||
Different rendering CONTRACT, not just a colour override. The
|
||||
tactile brand steps aside entirely. No grain, no shadows,
|
||||
thicker borders, sharper focus rings. Pure black/white with a
|
||||
single strong-blue focus colour.
|
||||
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"] {
|
||||
@@ -221,32 +320,62 @@
|
||||
--color-text-secondary: #000000;
|
||||
--color-text-tertiary: #000000;
|
||||
|
||||
/* Accent collapses to the strong focus blue in HC. Brand
|
||||
identity steps aside. */
|
||||
--color-accent: #005FCC;
|
||||
--color-accent-hover: #004BA0;
|
||||
--color-accent-subtle: transparent;
|
||||
--color-accent-glow: transparent;
|
||||
|
||||
--color-danger: #B3261E;
|
||||
--color-caution: #7A5D00;
|
||||
--color-warning: var(--color-caution);
|
||||
--color-success: #1B6B3A;
|
||||
--color-info: #005FCC;
|
||||
|
||||
/* HC strips fill atmosphere. Notices become text + icon + 2-px
|
||||
border + left bar with no body tint. Maximum clarity. */
|
||||
--color-danger-bg: transparent;
|
||||
--color-caution-bg: transparent;
|
||||
--color-success-bg: 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);
|
||||
|
||||
/* Behavioural overrides. The contract bites here. */
|
||||
--grain-opacity: 0;
|
||||
--shadow-strength: 0;
|
||||
--border-width-control: 2px;
|
||||
@@ -256,8 +385,8 @@
|
||||
--quietware-texture-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* Dark-base high-contrast — black background instead of white.
|
||||
Used when the user explicitly wants HC inside the dark theme. */
|
||||
/* 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;
|
||||
@@ -273,10 +402,39 @@
|
||||
--color-accent: #75A8F0;
|
||||
--color-accent-hover: #5C92E0;
|
||||
|
||||
--color-danger: #FF8A8A;
|
||||
--color-caution: #F2C94C;
|
||||
--color-success: #79D59B;
|
||||
--color-info: #8AB4F8;
|
||||
/* 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;
|
||||
@@ -285,8 +443,7 @@
|
||||
|
||||
/* ============================================================
|
||||
Static grain overlay. Reads --grain-opacity. Zero in HC mode by
|
||||
contract. Fixed-position so it does not scroll. mix-blend-mode
|
||||
overlay produces the soft notebook-paper effect.
|
||||
contract. Fixed-position so it does not scroll.
|
||||
============================================================ */
|
||||
:root[data-design="quietware"] body::after {
|
||||
content: "";
|
||||
|
||||
@@ -49,33 +49,43 @@
|
||||
classes = "",
|
||||
}: Props = $props();
|
||||
|
||||
// v0.3 Phase 4g — notice usage tokens. Each tone reads four CSS
|
||||
// variables published by v0.3-quietware-tokens.css:
|
||||
// --notice-{tone}-bar left bar (signal-tier)
|
||||
// --notice-{tone}-icon icon colour (signal in dark, ink in light)
|
||||
// --notice-{tone}-border outer border colour
|
||||
// --notice-{tone}-bg hand-tuned pale tint surface
|
||||
//
|
||||
// v0.2 fallback values are defined at :root in the same tokens file
|
||||
// via color-mix from the v0.2 --color-{role} tokens, so the Notice
|
||||
// renders sensibly with or without quietware active.
|
||||
const palette: Record<Tone, { bar: string; bg: string; border: string; iconColor: string; icon: typeof Info }> = {
|
||||
info: {
|
||||
bar: "border-l-info",
|
||||
bg: "bg-info/8",
|
||||
border: "border-info/40",
|
||||
iconColor: "text-info",
|
||||
bar: "border-l-[var(--notice-info-bar)]",
|
||||
bg: "bg-[var(--notice-info-bg)]",
|
||||
border: "border-[var(--notice-info-border)]",
|
||||
iconColor: "text-[var(--notice-info-icon)]",
|
||||
icon: Info,
|
||||
},
|
||||
caution: {
|
||||
bar: "border-l-caution",
|
||||
bg: "bg-caution/8",
|
||||
border: "border-caution/40",
|
||||
iconColor: "text-caution",
|
||||
bar: "border-l-[var(--notice-caution-bar)]",
|
||||
bg: "bg-[var(--notice-caution-bg)]",
|
||||
border: "border-[var(--notice-caution-border)]",
|
||||
iconColor: "text-[var(--notice-caution-icon)]",
|
||||
icon: AlertTriangle,
|
||||
},
|
||||
danger: {
|
||||
bar: "border-l-danger",
|
||||
bg: "bg-danger/8",
|
||||
border: "border-danger/40",
|
||||
iconColor: "text-danger",
|
||||
bar: "border-l-[var(--notice-danger-bar)]",
|
||||
bg: "bg-[var(--notice-danger-bg)]",
|
||||
border: "border-[var(--notice-danger-border)]",
|
||||
iconColor: "text-[var(--notice-danger-icon)]",
|
||||
icon: AlertOctagon,
|
||||
},
|
||||
success: {
|
||||
bar: "border-l-success",
|
||||
bg: "bg-success/8",
|
||||
border: "border-success/40",
|
||||
iconColor: "text-success",
|
||||
bar: "border-l-[var(--notice-success-bar)]",
|
||||
bg: "bg-[var(--notice-success-bg)]",
|
||||
border: "border-[var(--notice-success-border)]",
|
||||
iconColor: "text-[var(--notice-success-icon)]",
|
||||
icon: CheckCircle,
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user