v0.3 Phase 4d/4e: palette revision + HC rendering contract
Round-4 feedback (2026-05-15) pulled the system away from the
color.adobe.com primaries toward muted-Material values, separated
brand accent from semantic caution, and reframed high-contrast as a
behavioural rendering contract rather than a palette override.
Two phases land together because the palette revision and the HC
contract are inherently linked — HC mode needs both palette overrides
AND behavioural-token overrides to deliver "different rendering
contract" semantics.
Phase 4d palette revision.
Dark mode (was wine-aubergine #2A1620, now brown-charcoal #12100E):
--color-bg #12100E
--color-bg-elevated #1A1713
--color-bg-card #211D18
--color-bg-input #181510
--color-sidebar #0F0E0C
--color-border #4A4035
--color-border-subtle #2C261F
Brand accent (new — was unset, fell through to v0.2 amber that
competed with semantic yellow):
Dark: --color-accent #C97845 (copper)
Light: --color-accent #9D5F32 (deeper copper)
Semantic colours (muted-Material, both modes):
Dark: danger #FF8A8A caution #F2C94C success #79D59B info #8AB4F8
Light: danger #B3261E caution #7A5D00 success #1B6B3A info #2457A6
Light mode work surface (slight paper tone, not pure white):
--color-bg-card #FFFDF8 (was #FFFFFF)
--color-bg-elevated #F6F1EA
Caution fill-only-on-cream rule retires. Ochre #7A5D00 passes AA
as foreground text on cream under the muted palette, so the single-
token-per-role convention applies across all four semantic colours
in both modes.
LumotiaNotice opacity rebalance:
Background tint 10% -> 8%
Outer border neutral subtle -> role at 40%
Icon --color-text -> role colour
Left bar role at 100% (unchanged)
Title / body --color-text (unchanged)
Phase 4e HC rendering contract.
Behavioural tokens published alongside palette:
--grain-opacity 0.06 dark / 0.07 light / 0 in HC
--shadow-strength 1 default / 0 in HC
--border-width-control 1px default / 2px in HC
--focus-ring-width 2px default / 3px in HC
--panel-radius 8px (reserved for future tightening)
--quietware-texture-opacity retained as a legacy alias pointing at
--grain-opacity so Phase 4c slider keeps working through the rename.
HC palette: pure-black or pure-white base, the other for borders,
single strong-focus blue #005FCC replaces accent. Brand atmosphere
steps aside. Selector splits via :not([data-theme="light"]) so
HC-light and HC-dark variants diverge cleanly.
Verified.
- npm run check: 0 errors, 0 warnings across 5706 files.
- Plan doc updated with full before/after tables, behavioural-token
contract table, and Phase 4c / 4d / 4e log sections.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -236,6 +236,77 @@ Architectural finding: the v0.2 `SettingsPage.svelte` (2 891 LOC after Phase 4a)
|
||||
|
||||
Rationale: phase 4a already delivers "one section at a time" under quietware. Renaming the eight tabs to match the canonical plan (Output / Vocabulary carved out as top-level) is labelling polish, not user-value. Page-skeleton sweep (Phase 5) delivers more visible improvement per LOC. Phase 4b will return after Phase 5 lands.
|
||||
|
||||
### Phase 4d — Palette revision per 2026-05-15 round 4 feedback. Landed 2026-05-15.
|
||||
|
||||
The color.adobe.com primaries (#FF0700 / #000AFF / #00FF56 / #FFCD00) earned vividness at the cost of brand identity and accent-vs-caution discipline. Round-4 feedback pulled the system back toward muted-Material values with a clear architectural split:
|
||||
|
||||
```
|
||||
Atmosphere = warm tactile surface
|
||||
Status = red / yellow / green / blue
|
||||
Brand = copper-clay amber accent (--color-accent, distinct from caution)
|
||||
Accessibility = high-contrast override is a different rendering contract
|
||||
```
|
||||
|
||||
Dark mode (revised, brown-charcoal instead of wine-aubergine):
|
||||
|
||||
| Token | Before (4c) | After (4d) |
|
||||
|---|---|---|
|
||||
| `--color-bg` | `#2A1620` | `#12100E` |
|
||||
| `--color-bg-elevated` | `#34222B` | `#1A1713` |
|
||||
| `--color-bg-card` | `#3E2A33` | `#211D18` |
|
||||
| `--color-sidebar` | `#1F0F18` | `#0F0E0C` |
|
||||
| `--color-accent` | (unset, fell through to v0.2) | `#C97845` |
|
||||
| `--color-danger` | `#FF2A24` | `#FF8A8A` |
|
||||
| `--color-caution` | `#FFCD00` | `#F2C94C` |
|
||||
| `--color-success` | `#00FF56` | `#79D59B` |
|
||||
| `--color-info` | `#7076FF` | `#8AB4F8` |
|
||||
|
||||
Light mode (revised, semantic values back to Material AA-friendly hues):
|
||||
|
||||
| Token | Before (4c) | After (4d) |
|
||||
|---|---|---|
|
||||
| `--color-bg-card` | `#FFFFFF` | `#FFFDF8` (warm white) |
|
||||
| `--color-bg-elevated` | `#F3EEE6` | `#F6F1EA` |
|
||||
| `--color-accent` | (unset) | `#9D5F32` |
|
||||
| `--color-danger` | `#C54B1F` | `#B3261E` |
|
||||
| `--color-caution` | `#FFCD00` (fill-only) | `#7A5D00` (passes as text) |
|
||||
| `--color-success` | `#00852D` | `#1B6B3A` |
|
||||
| `--color-info` | `#0047AB` | `#2457A6` |
|
||||
|
||||
The "caution fill-only on cream" rule retires under the muted palette. Ochre `#7A5D00` passes AA as foreground text against cream, so the same single-token-per-role convention applies across all four semantic colours in light mode.
|
||||
|
||||
LumotiaNotice opacity rebalance:
|
||||
|
||||
| Surface | Before | After |
|
||||
|---|---|---|
|
||||
| Background tint | role at 10% | role at 8% |
|
||||
| Outer border | neutral subtle | role at 40% |
|
||||
| Left bar | role full | role full (unchanged) |
|
||||
| Icon | `--color-text` | role colour |
|
||||
| Title / body | `--color-text` | `--color-text` (unchanged) |
|
||||
|
||||
### Phase 4e — High-contrast rendering contract. Landed 2026-05-15.
|
||||
|
||||
High-contrast is not a colour variant — it's a different rendering contract that the entire UI subscribes to. The tokens block now publishes behavioural variables alongside the palette overrides, so components can opt into the contract by reading them.
|
||||
|
||||
Behavioural tokens (defaults + HC values):
|
||||
|
||||
| Token | Default | HC |
|
||||
|---|---|---|
|
||||
| `--grain-opacity` | 0.06 (dark) / 0.07 (light) | 0 |
|
||||
| `--shadow-strength` | 1 | 0 |
|
||||
| `--border-width-control` | 1px | 2px |
|
||||
| `--focus-ring-width` | 2px | 3px |
|
||||
| `--panel-radius` | 8px | 8px (unchanged for now) |
|
||||
|
||||
`--quietware-texture-opacity` retained as a legacy alias pointing at `--grain-opacity` so Phase 4c controls keep working through the rename.
|
||||
|
||||
HC palette tweaks (round-4 feedback):
|
||||
|
||||
- **HC light** is now true pure-white background (`#FFFFFF`) + true pure-black text/borders (`#000000`). Brand atmosphere steps aside completely. Single strong-focus blue `#005FCC` replaces the accent.
|
||||
- **HC dark** stays pure black `#000000` with white borders, semantic muted hues that read clearly. Matches the v0.3 dark feel but at maximum legibility.
|
||||
- Hue-based selectors: `[data-design="quietware"][data-contrast="high"]` matches both base themes; the dark-base variant is scoped via `:not([data-theme="light"])` so light-base HC and dark-base HC can diverge.
|
||||
|
||||
### Phase 4c — Texture-opacity slider + high-contrast toggle. Landed 2026-05-15.
|
||||
|
||||
- New static grain overlay defined in `src/design-system/v0.3-quietware-tokens.css`. Fixed-position `body::after`, `mix-blend-mode: overlay`, opacity driven by `--quietware-texture-opacity`. Pattern generated inline via SVG `feTurbulence` (`baseFrequency=0.85`, `numOctaves=2`, `stitchTiles=stitch`). Tile size 240×240, repeated across viewport. `pointer-events: none` so the overlay never intercepts clicks. Active only under `html[data-design="quietware"]` and only on the dark and light modes — high-contrast forces opacity to 0.
|
||||
|
||||
@@ -10,29 +10,26 @@
|
||||
|
||||
Activation paths:
|
||||
1. Manual: add data-design="quietware" to <html> via dev tools.
|
||||
2. Build flag (Phase 2): VITE_LUMOTIA_QUIETWARE=1 will wire the
|
||||
2. Build flag (Phase 2): VITE_LUMOTIA_QUIETWARE=1 wires the
|
||||
attribute through +layout.svelte automatically.
|
||||
|
||||
--------------------------------------------------------------
|
||||
Palette source — Jake's color.adobe.com primaries, locked 2026-05-15:
|
||||
Palette — Phase 4d revision (2026-05-15 round 4 feedback).
|
||||
|
||||
#FF0700 red (--danger)
|
||||
#000AFF blue (--info)
|
||||
#00FF56 green (--success)
|
||||
#FFCD00 yellow (--caution)
|
||||
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.
|
||||
|
||||
Each primary is used literally where it clears WCAG AA on the
|
||||
relevant background. Where it does not (typically yellow and green
|
||||
on cream paper, blue on dark Coffee Bean) a text-safe sibling at
|
||||
the same hue and saturation is derived by adjusting lightness
|
||||
until 4.5:1 clears.
|
||||
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.
|
||||
|
||||
Caution stays a fill-only role on cream paper. Any darkened yellow
|
||||
reads as olive or mustard ("looks like poop", per Jake), which we
|
||||
refuse to ship. Pill backgrounds, dots, left-border accents and
|
||||
icons take --color-caution. Foreground text inside caution-coloured
|
||||
pills stays --color-text. This matches Material, GOV.UK and IBM
|
||||
Carbon practice.
|
||||
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.
|
||||
|
||||
Typography stack (V4 pairing, locked 2026-05-15):
|
||||
Work Sans -> body, UI, controls, headers
|
||||
@@ -70,55 +67,69 @@
|
||||
|
||||
/* ============================================================
|
||||
Quietware — dark mode default.
|
||||
Lifted Coffee Bean base. Jake's primaries used directly where
|
||||
they clear AA on the dark surface; lifted siblings for the rest.
|
||||
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[data-design="quietware"] {
|
||||
--color-bg: #2A1620;
|
||||
--color-bg-elevated: #34222B;
|
||||
--color-bg-card: #3E2A33;
|
||||
--color-bg-input: #281620;
|
||||
--color-border: #6B4D58;
|
||||
--color-border-subtle: #4E3742;
|
||||
--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: #8D8577;
|
||||
--color-text-tertiary: #908779;
|
||||
|
||||
/* --info and --danger lifted from primaries; pure red/blue too dark on dark bg. */
|
||||
--color-info: #7076FF; /* lifted from #000AFF, 4.64 AA */
|
||||
--color-danger: #FF2A24; /* lifted from #FF0700, 4.54 AA */
|
||||
/* --success and --caution use Jake's primaries directly; both already AAA on dark bg. */
|
||||
--color-success: #00FF56; /* Jake literal, 12.51 AAA */
|
||||
--color-caution: #FFCD00; /* Jake literal, 11.33 AAA */
|
||||
/* Brand accent. Copper-clay, distinct from semantic yellow. */
|
||||
--color-accent: #C97845;
|
||||
--color-accent-hover: #B96638;
|
||||
--color-accent-subtle: #C9784514;
|
||||
--color-accent-glow: #C9784525;
|
||||
|
||||
/* Semantic palette. Muted-Material hues. */
|
||||
--color-danger: #FF8A8A;
|
||||
--color-caution: #F2C94C;
|
||||
--color-warning: var(--color-caution);
|
||||
--color-success: #79D59B;
|
||||
--color-info: #8AB4F8;
|
||||
|
||||
--color-sidebar: #1F0F18;
|
||||
--color-nav-active: #3E2A33;
|
||||
--color-hover: #34222B;
|
||||
--color-overlay-dim: rgba(31, 8, 18, 0.7);
|
||||
--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;
|
||||
|
||||
/* Texture intensity. 0.06 baseline, slider range 0.05 to 0.08 in advanced. */
|
||||
--quietware-texture-opacity: 0.06;
|
||||
/* Phase 4e behavioural tokens — components opt into the rendering
|
||||
contract by reading these. Defaults preserve existing v0.3 feel. */
|
||||
--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.
|
||||
Cream paper base. Jake's blue passes AAA on cream as text and is
|
||||
used literally. The other three roles use text-safe siblings
|
||||
derived at the same hue and saturation (lightness shifted for AA).
|
||||
Caution is fill-only on cream by convention.
|
||||
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.
|
||||
============================================================ */
|
||||
:root[data-design="quietware"][data-theme="light"] {
|
||||
--color-bg: #FBF8F2;
|
||||
--color-bg-elevated: #F3EEE6;
|
||||
--color-bg-card: #FFFFFF;
|
||||
--color-bg-input: #F3EEE6;
|
||||
--color-bg-elevated: #F6F1EA;
|
||||
--color-bg-card: #FFFDF8;
|
||||
--color-bg-input: #F4EFE7;
|
||||
--color-border: #897D70;
|
||||
--color-border-subtle: #D8D0C4;
|
||||
|
||||
@@ -126,70 +137,106 @@
|
||||
--color-text-secondary: #5E574C;
|
||||
--color-text-tertiary: #74685B;
|
||||
|
||||
--color-info: #000AFF; /* Jake literal, 7.96 AAA on cream */
|
||||
--color-danger: #E60600; /* text-safe derived from #FF0700, 4.51 AA */
|
||||
--color-success: #00852D; /* text-safe derived from #00FF56, 4.51 AA */
|
||||
/* Caution is FILL ONLY on cream. Text inside caution pills uses --color-text. */
|
||||
--color-caution: #FFCD00; /* Jake literal, fill-only by convention */
|
||||
--color-accent: #9D5F32;
|
||||
--color-accent-hover: #854E29;
|
||||
--color-accent-subtle: #9D5F3214;
|
||||
--color-accent-glow: #9D5F3225;
|
||||
|
||||
--color-danger: #B3261E;
|
||||
--color-caution: #7A5D00;
|
||||
--color-warning: var(--color-caution);
|
||||
--color-success: #1B6B3A;
|
||||
--color-info: #2457A6;
|
||||
|
||||
--color-sidebar: #F3EEE6;
|
||||
--color-nav-active: #E8E2D6;
|
||||
--color-hover: #EAE4D8;
|
||||
--color-overlay-dim: rgba(29, 27, 24, 0.55);
|
||||
|
||||
--quietware-texture-opacity: 0.07;
|
||||
--grain-opacity: 0.07;
|
||||
--quietware-texture-opacity: var(--grain-opacity);
|
||||
--quietware-texture-color: rgba(29, 27, 24, 1);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Quietware — high-contrast mode.
|
||||
Same four hues retained so role recognition does not flip between
|
||||
modes. Saturation 80%, lightness 70%. Zero texture, no translucent
|
||||
overlays.
|
||||
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.
|
||||
============================================================ */
|
||||
:root[data-design="quietware"][data-contrast="high"] {
|
||||
--color-bg: #000000;
|
||||
--color-bg-elevated: #0A0A0A;
|
||||
--color-bg-card: #111111;
|
||||
--color-bg-input: #050505;
|
||||
--color-border: #FFFFFF;
|
||||
--color-border-subtle: #888888;
|
||||
: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: #FFFFFF;
|
||||
--color-text-secondary: #DADADA;
|
||||
--color-text-tertiary: #C8C8C8;
|
||||
--color-text: #000000;
|
||||
--color-text-secondary: #000000;
|
||||
--color-text-tertiary: #000000;
|
||||
|
||||
--color-info: #757AF0; /* 5.80 AA on black */
|
||||
--color-danger: #F07975; /* 7.70 AAA on black */
|
||||
--color-success: #75F09F; /* 14.72 AAA on black */
|
||||
--color-caution: #F0D875; /* 14.78 AAA on black */
|
||||
/* 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;
|
||||
|
||||
--color-sidebar: #000000;
|
||||
--color-nav-active: #1A1A1A;
|
||||
--color-hover: #1A1A1A;
|
||||
--color-sidebar: #FFFFFF;
|
||||
--color-nav-active: #000000;
|
||||
--color-hover: #F0F0F0;
|
||||
--color-overlay-dim: rgba(0, 0, 0, 0.85);
|
||||
|
||||
/* No texture in high contrast. Clarity over atmosphere. */
|
||||
/* Behavioural overrides. The contract bites here. */
|
||||
--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 instead of white.
|
||||
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;
|
||||
|
||||
--color-danger: #FF8A8A;
|
||||
--color-caution: #F2C94C;
|
||||
--color-success: #79D59B;
|
||||
--color-info: #8AB4F8;
|
||||
|
||||
--color-sidebar: #000000;
|
||||
--color-nav-active: #FFFFFF;
|
||||
--color-hover: #1A1A1A;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
Static grain overlay. Atmospheric texture across the whole viewport.
|
||||
Fixed position so it does not scroll. Tile pattern generated inline
|
||||
via SVG feTurbulence. Opacity driven by --quietware-texture-opacity
|
||||
(default 0.06 dark / 0.07 light, slider range 0.05 to 0.08 in
|
||||
advanced settings). mix-blend-mode overlay darkens shadows and
|
||||
brightens highlights, producing the soft notebook-paper effect.
|
||||
|
||||
pointer-events: none so clicks pass through. z-index 9999 places it
|
||||
above all content, but content remains fully interactive thanks to
|
||||
the pointer-events override.
|
||||
|
||||
No texture in high-contrast mode — the [data-contrast="high"] block
|
||||
above sets --quietware-texture-opacity to 0.
|
||||
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.
|
||||
============================================================ */
|
||||
:root[data-design="quietware"] body::after {
|
||||
content: "";
|
||||
@@ -198,7 +245,7 @@
|
||||
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(--quietware-texture-opacity);
|
||||
opacity: var(--grain-opacity);
|
||||
mix-blend-mode: overlay;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,19 +4,24 @@
|
||||
// scattered across pages. Four tones map to the semantic tokens.
|
||||
//
|
||||
// v0.3 Phase 3 update — left-bar accent pattern. The visible status
|
||||
// signal now lives on a 4-px solid left border in the tone colour
|
||||
// (100% opacity, fill-grade chroma); the surrounding container uses
|
||||
// a soft tone-tinted background and a subtle outer border. Icon,
|
||||
// title and body text all use --color-text so they remain legible
|
||||
// across every theme combination, including quietware light mode
|
||||
// where --color-caution is the bright #FFCD00 fill (would fail as
|
||||
// text on cream). Same accessibility role semantics retained.
|
||||
// signal lives on a 4-px solid left border in the tone colour, full
|
||||
// opacity. The surround uses a soft tone-tinted background + outer
|
||||
// border in the tone colour. Title and body text use --color-text;
|
||||
// icon uses the tone colour. Same accessibility role semantics
|
||||
// retained.
|
||||
//
|
||||
// v0.3 Phase 4d opacity rebalance (2026-05-15 round 4 feedback):
|
||||
// Background role colour at 8% (was 10%, less heavy)
|
||||
// Outer border role colour at 40% (was neutral subtle)
|
||||
// Left bar role colour at 100% (unchanged)
|
||||
// Icon role colour (reverted from --color-text once the
|
||||
// muted-Material palette landed; previous fill-only-
|
||||
// on-cream concern dissolved with the new ochre
|
||||
// #7A5D00 light-mode caution).
|
||||
// Title + body --color-text (unchanged)
|
||||
//
|
||||
// Pattern matches Material Design "banner with leading accent" and
|
||||
// IBM Carbon "inline notification" guidance: status colour on a
|
||||
// large fill surface (the bar), neutral foreground text. Works for
|
||||
// any tone in any theme regardless of WCAG-text contrast on the
|
||||
// role colour itself.
|
||||
// IBM Carbon "inline notification" guidance.
|
||||
import { Info, AlertTriangle, AlertOctagon, CheckCircle, X } from "lucide-svelte";
|
||||
import type { Snippet } from "svelte";
|
||||
|
||||
@@ -40,25 +45,33 @@
|
||||
classes = "",
|
||||
}: Props = $props();
|
||||
|
||||
const palette: Record<Tone, { bar: string; bg: string; icon: typeof Info }> = {
|
||||
const palette: Record<Tone, { bar: string; bg: string; border: string; iconColor: string; icon: typeof Info }> = {
|
||||
info: {
|
||||
bar: "border-l-info",
|
||||
bg: "bg-info/10",
|
||||
bg: "bg-info/8",
|
||||
border: "border-info/40",
|
||||
iconColor: "text-info",
|
||||
icon: Info,
|
||||
},
|
||||
caution: {
|
||||
bar: "border-l-caution",
|
||||
bg: "bg-caution/10",
|
||||
bg: "bg-caution/8",
|
||||
border: "border-caution/40",
|
||||
iconColor: "text-caution",
|
||||
icon: AlertTriangle,
|
||||
},
|
||||
danger: {
|
||||
bar: "border-l-danger",
|
||||
bg: "bg-danger/10",
|
||||
bg: "bg-danger/8",
|
||||
border: "border-danger/40",
|
||||
iconColor: "text-danger",
|
||||
icon: AlertOctagon,
|
||||
},
|
||||
success: {
|
||||
bar: "border-l-success",
|
||||
bg: "bg-success/10",
|
||||
bg: "bg-success/8",
|
||||
border: "border-success/40",
|
||||
iconColor: "text-success",
|
||||
icon: CheckCircle,
|
||||
},
|
||||
};
|
||||
@@ -73,10 +86,10 @@
|
||||
<div
|
||||
role={ariaRole}
|
||||
class="px-4 py-3 rounded-r-lg rounded-l-sm border border-l-4
|
||||
border-border-subtle text-[13px] flex items-start gap-2.5
|
||||
{tonePal.bar} {tonePal.bg} {classes}"
|
||||
text-[13px] flex items-start gap-2.5
|
||||
{tonePal.bar} {tonePal.border} {tonePal.bg} {classes}"
|
||||
>
|
||||
<ToneIcon size={16} class="mt-0.5 shrink-0 text-text" aria-hidden="true" />
|
||||
<ToneIcon size={16} class="mt-0.5 shrink-0 {tonePal.iconColor}" aria-hidden="true" />
|
||||
<div class="flex-1 min-w-0 leading-relaxed text-text">
|
||||
{#if title}
|
||||
<p class="font-semibold text-text mb-1">{title}</p>
|
||||
|
||||
Reference in New Issue
Block a user