f311fdc47f355fff35a88541160b3777f6e16fea
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
| 48685f9dda |
v0.3 Phase 5c refinements: spacing, nested notice, conditional Save variant, paper edge
Final small refinements on Dictation per round-11 feedback before
moving to Files/Tasks/History.
1. Vertical rhythm tightened.
LumotiaPageSkeleton header padding pt-5 pb-3 -> pt-3 pb-2.
Notice padding pt-3 -> pt-2.
Primary surface area pt-5 pb-3 -> pt-3 pb-2.
DictationPage primary inner py-8 -> py-6.
Net: about 16 px shaved off the top band. Transcript canvas
begins higher, no longer feels like a large header above empty
space.
2. Disabled actions go neutral when there is nothing to act on.
Save button variant is now conditional:
variant={transcript.trim() ? "primary" : "secondary"}
Previously Save kept the blue primary fill even when disabled.
Disabled blue under 50% opacity still read as a strong primary
cue. Now: no transcript = neutral secondary; transcript exists
= primary blue. Other actions (Copy / Extract / Template / Open
Viewer) stay neutral regardless and become enabled when
transcript exists.
3. Light-mode transcript surface gains a tactile paper edge.
LumotiaPageSkeleton primary surface gains:
shadow-[inset_0_1px_0_rgba(0,0,0,0.05)]
Subtle 1-px inset top shadow at 5% opacity. Invisible in dark
mode (against the dark surface), visible in light mode as a
faint paper edge. Skeleton-wide because it costs nothing in
dark and adds the warmth Jake asked for in light.
4. Ambient info notice nested inside transcript surface.
Browser-preview notice + real-error notice now render INSIDE
the transcript card via the primary snippet, not in the
skeleton's notice slot. Renders contained at the top of the
card rather than as a full-width page banner. The notice slot
on LumotiaPageSkeleton stays available for blocking/error-
banner cases on other pages.
5. Mock-ready screenshot delivered.
Captured two new screenshot pairs:
root_PREVIEW__quiet-{dark,light}.png browser-preview state
root_READY__quiet-{dark,light}.png mocked Tauri-available
Mock done by temporarily setting tauriRuntimeAvailable = true
for the capture run, then reverted to hasTauriRuntime() at
commit time. The headless context still has no real Tauri
runtime so the model-check call fails — that surfaces as a
danger-tone slim notice in the ready screenshots, which
happens to demonstrate the danger-slim notice rendering
alongside the enabled red Record button.
In the real Tauri desktop app the danger notice would not
appear; only the Record (red), empty-state typography, and
bottom action dock with all-disabled neutral controls would.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
No colour exploration. No new tokens. Same red/blue/green/yellow/
orange grammar from Phase 4k.
Phase 5c is now complete. Next focused commits: 5d (Files), 5e
(Tasks), 5f (History), then Phase 6 (icon — waiting on SVG) and
Phase 7 (motion audit).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| ce784e58ab |
v0.3 Phase 5c polish: tighter header, disabled-record clarity, softer notice, attached action bar
Focused polish pass on the Dictation quietware layout per round-10
feedback. No colour exploration; only the eight specific tweaks.
1. Capture header tightened.
Record button + status block now grouped in their own flex
container (gap-3) so they read as one capture component. Record
size dropped from 72px to 64px so the group balances against the
status text. Timer pushed to far right via flex-1 on the inner
group. The trio (record / status / timer) feels like one unit.
2. Disabled Record affordance now reads as record.
Browser-preview state no longer renders as a neutral grey blob.
Instead:
bg-transparent
border-2 border-[color-mix(in_srgb,var(--button-record-bg)_45%,
transparent)]
opacity-80
cursor-not-allowed
inner muted-red dot bg-[color-mix(in_srgb,var(--button-record-bg)
_55%,transparent)]
Result: clearly a record control, clearly disabled, doesn't look
clickable. aria-label updated to "Record (desktop app only)" in
that state so screen readers carry the same message.
3. Slim notice border softened.
LumotiaNotice slim variant now uses border-border-subtle for the
outer border instead of the role-coloured border. Left bar stays
full role colour (the visible signal). Icon stays role colour.
Background stays at the role tinted bg. Net effect: notice is
ambient, not loud.
4. Action bar attached to transcript surface.
Dropped the LumotiaPageSkeleton actionBar slot for Dictation;
moved the buttons into the primary snippet as a bottom row inside
the same surface. Internal border-t + bg-bg-elevated/40 separator
keeps it visually nested. Reads as transcript actions, not a
generic page footer.
Also dropped primaryBleed so LumotiaPageSkeleton's default card
chrome wraps the transcript + action dock together — that gives
the surface boundary Jake asked for in light mode without
introducing a card-heavy treatment.
5. Compact one-line metadata footer.
Was: "Smart · {model} · Local only" + "{formatMode} · {profile}"
Now: "{formatMode} · {model} · Local only / Browser preview · {profile}"
Right-aligned. Single line. No duplicated "Smart". JetBrains Mono
via the existing --font-family-mono. text-tertiary.
6. Typography corrected.
Status title moved from Young Serif italic (font-display) to Work
Sans medium-weight (default body). Young Serif italic is now
reserved for the empty-state "Talk now, think later." line, which
remains the only emotional moment in the page.
7. Light mode surface intentional.
By dropping primaryBleed the skeleton's default surface chrome
(bg-bg-card + border-border-subtle + rounded-lg) wraps the
transcript canvas. Light mode now reads as a deliberate paper
surface, not an open page. Same boundary applies in dark.
8. Colour restraint preserved.
No token changes. Same red/blue/green/yellow/orange grammar.
Wireline contract unchanged. Brand orange still reserved for
logo/identity.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
- Headless screenshots confirm both quietware modes deliver the
polish: tight header, recognisable disabled-record, softer
notice border, attached action dock, compact metadata,
Work Sans status title, clear surface boundary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| b9dd598937 |
v0.3 Phase 4k: palette architecture hardening — scales + component tokens + contrast check
Token-hardening pass per round-9 redirect. No new visual decisions —
just plumbing the tokens correctly so the colour grammar locked in
Phase 4j has a system underneath instead of hand-tuned hex.
Scales.
NEW: src/design-system/v0.3-quietware-scales.css. 11-step tonal
scales (50, 100, ..., 900, 950) for five source hues and their five
complement sources. Saturation drops at extremes to avoid neon
highs and washed-out lows. Hue-stable lightness curve picked to
mimic Material 3 / IBM Carbon tonal scales.
Generated by scripts/generate-quietware-scales.py (committed) so
values are reproducible. To regenerate:
python3 scripts/generate-quietware-scales.py > scales.css
Wired into src/app.css directly before v0.3-quietware-tokens.css.
Component tokens consume scale references only.
All --button-{role}-{tier} and --progress-{state}-fill tokens now
read from var(--{hue}-{step}) instead of raw hex literals. Future
scale tuning happens in one place; component callers never change.
--button-record-bg: var(--red-600)
--button-primary-bg: var(--blue-700)
--button-success-bg: var(--green-800) /* darkened so white
text clears AA */
--button-caution-bg: var(--yellow-400)
--button-neutral-bg: var(--color-bg-elevated)
--button-disabled-bg: var(--color-bg-elevated)
--brand-accent: var(--orange-500)
Progress component tokens.
New family: --progress-{download,transcribing,success,caution,danger,
disk,disk-caution,disk-danger}-fill plus --progress-track. Each
mode tunes the shade step so the bar reads on its track:
Dark: blue-400 / green-500 / yellow-500 / red-500
Light: blue-700 / green-800 / yellow-600 / red-700
HC-light: blue-700 / green-800 / yellow-700 / red-700
HC-dark: blue-300 / green-400 / yellow-400 / red-400
LumotiaProgress.svelte gains tone="transcribing", "disk",
"disk-caution", "disk-danger" so callers map progress role to
token explicitly.
Border / wireline / focus-ring discipline.
Three distinct token families:
--button-primary-border structural component edge
--button-primary-wire complementary identity detail
--focus-ring-color keyboard interaction
Documented as separate concerns in the tokens file.
Contrast check script.
NEW: scripts/check-colour-contrast.mjs. Parses scales + tokens
CSS, builds per-scope token tables for dark / light / HC-light /
HC-dark, resolves var() chains and color-mix() expressions, then
verifies twelve load-bearing component pairs against WCAG 2.2
minima (4.5:1 text, 3:1 UI). Exit code 1 on failure.
Current state: 0 failures across 4 modes.
Two pairs reported as "warn" rather than "fail": caution progress
on cream + caution notice border on cream. The yellow source colour
cannot clear 3:1 on a near-white surface without losing its
identity. Role recognition is carried by left-bar + icon + label,
not by surface contrast.
Verified.
- node scripts/check-colour-contrast.mjs: 0 failures, 4 modes, 12
load-bearing pairs + 2 known-limitation warns.
- npm run check: 0 errors, 0 warnings across 5707 files.
Phase 5c (Dictation layout migration) is the natural next focused
sitting. This commit gives Phase 5c the systematic colour grammar to
build on, and the contrast check gates future palette regressions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 2c6f5ca230 |
v0.3 Phase 4j: colour grammar correction — record red, brand orange separate, wirelines bumped
Major correction per round-8 redirect.
Problem.
- Brown/copper --color-accent #C97845/#9D5F32 was dragging the UI
back into the warm-brutalist palette and competing with semantic
yellow.
- Record button about to become blue (Lumotia primary). Wrong —
record is universally red across products and OSes.
- Brand orange conflated with primary action. Orange should be
brand mark only.
Solution.
Source tokens — identity-only, never used directly in components:
--source-red #FF0700
--source-yellow #FFCD00
--source-green #00FF56
--source-blue #000AFF
--source-orange-brand #F0620A
--{role}-complement-source for the wireline layer
Component tokens — what components subscribe to. Hand-tuned hex
values verified at WCAG AA on the foreground each button pairs with.
Tonal scales (red-50..red-950 etc.) reserved for a focused future
commit; component names stay stable through that upgrade:
--button-record-bg #DC2626 (red)
--button-record-fg #FFFFFF
--button-record-border #B91C1C
--button-record-wire #00D8E0 (cyan, red's complement)
--button-primary-bg #2563EB (blue)
--button-primary-fg #FFFFFF
--button-primary-wire #F6E600 (yellow, blue's complement)
--button-danger-bg same as record (red, fg white, cyan wire)
--button-success-bg #15803D dark / #166534 light (green)
--button-success-wire #E600A0 (magenta, green's complement)
--button-caution-bg #FACC15 (yellow, fg #1A1500 near-black)
--button-caution-wire #1850D8 (blue, yellow's complement)
--brand-accent #F0620A (orange, LOGO ONLY)
--brand-wire #0A98F0 (cyan-blue, orange's complement)
--color-accent repointed:
quietware dark: #4A7BFF (was #C97845 copper)
quietware light: #1D4ED8 (was #9D5F32 copper)
HC: #005FCC (existing, unchanged)
v0.2 fallback: var(--color-accent) preserved → v0.2 stays amber.
New LumotiaButton variant: "record". Used by DictationPage's
record control. Existing v0.2 record button class swapped from
bg-accent (amber) to bg-[var(--button-record-bg)] (red). v0.2
fallback at :root maps --button-record-bg to var(--color-danger)
so non-quietware surface keeps its red-when-recording / amber-when-
idle behaviour.
Wirelines (renamed from counterlines).
--wire-width 1px / --wire-width-active 2px / --wire-width-focus 2px
--wire-opacity-dark 0.75 (was 0.32; bumped per round-8 spec)
--wire-opacity-light 0.6 (was 0.22)
--wire-opacity-active 0.9
--wire-opacity-focus 1
--wire-opacity is a mode-aware resolver (-dark dark / -light light)
--wire-style solid (dotted reserved for design-preview / drag-drop)
HC contract: --wire-width 0, --wire-width-focus 2px kept.
--focus-ring-color #005FCC (strong blue), not a decorative complement.
Legacy --counterline-* tokens kept as aliases pointing at the new
--wire-* set so Phase 4h/4i opt-in code still works.
Design-system-v2 preview now shows the new record variant alongside
primary so both red and blue button identities are visible.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
Phase 5c (Dictation layout migration) still queued for the next
focused sitting. This commit gives Phase 5c the correct grammar to
build on.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 001d8fe83d |
v0.3 Phase 4i: counterlines as interaction-affordance identity
Round-7 redirect (Option D): move counterlines from notices (where
they're invisible) to interactive controls (where they add identity).
Three-level model:
Level 0 no counterline panels, notices (default), content, disabled
Level 1 quiet controls, chips, active nav
1 px, 48% opacity dark / 34% light
Level 2 focus / strong keyboard focus, recording state
2 px, 85% opacity
Notices retire from default counterline rendering. Notice already
carries enough semantic language: bar + icon + border + bg + label.
A complementary inset on top was adding nothing. Notice can opt in
via <LumotiaNotice counterline ... /> when it deliberately mimics
control identity.
Token deltas vs Phase 4h.
--counterline-width: 1px unchanged
--counterline-width-focus: 2px new (Level-2 width)
--counterline-opacity-dark: 0.48 was 0.32 (raised so Level-1
actually reads on controls)
--counterline-opacity-light: 0.34 was 0.22
--counterline-opacity-focus: 0.85 new
--role-brand-counterline: #3A6BFF new (blue counter for the
orange brand accent so
primary buttons get an
identity edge like the
other roles)
--button-{role}-counterline new (per-role component tokens
subscribing to role-counterline
via color-mix)
--focus-ring-color new (defaults to brand accent;
HC overrides to #005FCC)
LumotiaButton applies counterlines to primary + destructive variants
only. Secondary + tertiary stay clean. All variants get a Level-2
focus-visible ring at --focus-ring-color * opacity-focus, with the
existing ring-offset-2 ring-offset-bg pattern.
LumotiaNotice gains a `counterline` boolean prop, default false. When
set, the previous Phase 4h inset shadow re-applies.
HC contract: counterline-width 0 + all -counterline tokens transparent.
Focus width stays 2 px because the HC focus ring IS the tactile
detail in that mode. focus-ring-color forces to #005FCC.
Honest evaluation of the visible result.
Notices: visibly cleaner without the default inset shadow. Reads
with more confidence. Good change.
Buttons: counterline applied at 1 px / 48% dark / 34% light is
perceptible at standard viewing but screenshot-zoom subtle. Focus
state implemented but not visible in static screenshots; requires
manual tab-test in the dev server.
Recommend keeping the architecture even if the visual is restrained,
because the focus-state work is genuinely valuable accessibility
scaffolding regardless of how the Level-1 reads.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
Phase 5c (Dictation layout migration) still queued for a focused
fresh sitting. This commit does not block it.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 74bcc293bb |
v0.3 Phase 4h: counterlines test on LumotiaNotice
Test commit for Jake's round-6 spec. Subtle 1-px inset shadow in a
softened complementary hue, applied to LumotiaNotice only. Other
test surfaces (Button.destructive, status pills, record ring, active
nav) reserved for after evaluation.
Tokens (quietware scope only, v0.2 surface unchanged):
--counterline-width: 1px
Raw complementary hues per Jake's table:
--role-info-counterline var(--color-accent) /* copper for blue */
--role-danger-counterline #6EA8FF /* soft blue for red */
--role-success-counterline #B891FF /* soft violet for green */
--role-caution-counterline #3A6BFF /* soft blue for yellow */
Tinted per-mode via color-mix:
Dark mode: 32% opacity (slightly stronger against dark surface)
Light mode: 22% opacity (whisper-quiet against cream)
HC mode: all transparent, --counterline-width: 0
Per-usage notice tokens emitted:
--notice-{role}-counterline
LumotiaNotice applies via Tailwind arbitrary value:
shadow-[inset_0_0_0_var(--counterline-width,0)_var(--notice-{tone}-counterline,transparent)]
HC contract zeroes both the width and the colour token so the 2-px
HC border carries the tactile detail instead.
Honest evaluation of the visible result.
At 1px and 22%/32% opacity the counterline is implemented
correctly but reads as whisper-quiet to the point of being almost
invisible at standard viewing zoom. Doesn't look noisy (the risk
Jake flagged), but also doesn't add perceptible tactility.
Pending Jake's call:
(a) raise opacity to ~45% dark / ~35% light for visibility,
(b) keep at current opacity for the quietness,
(c) revert and proceed Phase 5c.
Phase 5c proceeds either way; this commit does NOT block the
layout migration.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| 2f11f493c5 |
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>
|
|||
| 2fcb5aff78 |
v0.3 Phase 4f/5a/5b: token architecture + skeleton + browser-preview reclass
Three small phases land together for Jake's round-4 feedback. Each is
focused and reviewable. Larger Dictation/Settings/Tasks/History page
migrations are deferred to focused future sittings.
Phase 4f — semantic source / derived token architecture.
Added --semantic-{red,blue,green,yellow}-source raw-palette tokens.
These encode the role's hue identity from Jake's color.adobe.com
palette (#FF0700 / #FFCD00 / #00FF56 / #000AFF) and stay constant
across all themes. The existing --color-{danger,caution,success,info}
tokens are now documented as theme-tuned derivations meeting WCAG
AA in context. Source tokens make the brand-to-runtime relationship
traceable in code.
Added --color-{role}-bg subtle-fill tokens derived via
color-mix(in oklab, var(--color-{role}) 8%, transparent). Used by
Notice backgrounds, hover tints and focus halos. HC mode forces
-bg tokens to transparent so HC notices read as text + icon +
2-px border + left bar with no body tint.
Phase 5a — page skeleton primitive + slim notice variant.
NEW src/lib/ui/LumotiaPageSkeleton.svelte. Six-zone layout:
header (optional)
notice (optional, slim ambient state)
primary work surface (required, primaryBleed for full-bleed)
right rail (optional, lg-screen drawer)
action bar (optional, bottom)
metadata (optional, mono micro-footer)
Every zone except primary is opt-in. Foundation for the
page-skeleton sweep without forcing any page migration yet.
LumotiaNotice gained a slim prop. When true: padding collapses
(px-3 py-2 vs px-4 py-3), icon shrinks (14 vs 16), title block is
suppressed. For ambient page-level notices like browser-preview.
Phase 5b — browser-preview reclassification.
src/lib/pages/DictationPage.svelte: the browser-preview state used
to render as a red error block. That is an environment limitation,
not a failed action. Reclassified as a slim info notice with
friendlier copy:
"You're in a browser preview. Local transcription only works in
the Lumotia desktop app."
Other error states (transcription failed, needs review) still
render through the original danger-tinted block with the
technical-details affordance preserved. Only the browser-preview
path branches into LumotiaNotice tone="info" slim.
The larger Dictation page restructure (header recomposition,
Template/Extract Tasks demotion to bottom action bar, empty-state
typography) is reserved for a focused Phase 5c sitting since
DictationPage.svelte is 1 262 LOC of state-heavy code.
Verified.
- npm run check: 0 errors, 0 warnings across 5707 files.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| dab9c7b5a6 |
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>
|
|||
| 091780086b |
v0.3 Phase 4a: Settings tab shell
Discovers that v0.2 SettingsPage.svelte was already structured as
eight numbered sections aligning almost 1:1 with the v0.3 plan. The
cheapest path to "one section visible at a time" is therefore a
tab-shell overlay rather than a file split. Behaviour stays identical
to v0.2 when quietware is off; with quietware on, only the active
tab's section renders.
Changes.
- NEW: src/lib/ui/LumotiaSettingsTabs.svelte. Tab list following
the WAI-ARIA "tabs (automatic activation)" pattern. Arrow / Home /
End keyboard navigation. Active tab uses the brand left-bar
accent (border-l-caution) — same grammar as the LumotiaNotice
refactor from Phase 3.
- MODIFIED: src/lib/pages/SettingsPage.svelte. Added an isQuietware
reactive flag, a MutationObserver watching <html data-design>,
an activeTab state, and eight {#if !isQuietware || activeTab ===
'X'} wrappers around the existing top-level SettingsGroup
sections. The settings tree is unchanged; only its top-level
rendering gate changed.
- v0.2 fallback: when data-design="quietware" is absent the
tablist does not render and all eight sections stack as before.
The search filter spans every section in v0.2 mode. Smallest-
possible behavioural change for "one section at a time".
Tab IDs in this commit map 1:1 to existing v0.2 section names
(start-here / transcription / models / tasks / accessibility /
privacy / advanced / help). Phase 4b will restructure to the plan's
canonical names (carving Output from Advanced and Vocabulary from
Transcription).
Phases 4b and 4c are logged as pending in the plan doc:
4b. Restructure to canonical tab names (Output, Vocabulary).
4c. Texture-opacity slider + high-contrast toggle in Accessibility.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| db9c50c548 |
v0.3 Phase 3: status grammar — LumotiaNotice left-bar refactor
Phase 3 audit found that both LumotiaStatusPill and LumotiaNotice
already shipped in v0.2 Phase 5. Phase 3 reduced to an audit-and-adapt
pass.
LumotiaStatusPill ($lib/components/StatusPill.svelte) is already
correct for quietware. Pattern: neutral pill background + neutral
label text + role colour confined to a 6x6 px dot. Colour is
supplementary, label is always perceivable. Works unchanged across
all three quietware modes. No changes shipped.
LumotiaNotice ($lib/ui/LumotiaNotice.svelte) refactored to the
left-bar accent pattern. Previously the role colour rendered on the
icon outline and on the entire surround border at 30% opacity; in
quietware light mode that left the bright #FFCD00 caution colour
faded against cream paper. New pattern:
- 4-px solid LEFT border in the tone colour, 100% opacity.
- Soft tone-tinted background (10% opacity) for ambient cue.
- Subtle neutral outer border on the other three sides.
- Icon, title and body text all use --color-text.
Visible signal lives on the large bar (works at any contrast level);
foreground text uses the always-legible neutral. Matches Material
Design "banner with leading accent" and IBM Carbon "inline
notification" guidance. ARIA semantics (role="alert" for danger,
role="status" for the rest) preserved.
Design-system-v2 preview route already imports both primitives. The
updated Notice renders correctly with the existing preview content;
no additional wiring required.
Caution remains a fill-only convention on cream by design. Any
darkened yellow reads as olive ("looks like poop", per Jake), so the
fill-only rule stays in force and this pattern delivers it cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
|||
| c60f0aa5a5 |
v0.2 Phase 5: 11 primitives + gated design-system-v2 preview
Custom-styled primitives (no headless dep): LumotiaButton — primary/secondary/tertiary/destructive × sm/md/lg LumotiaIconButton — square icon-only; ghost/filled/destructive LumotiaNotice — info/caution/danger/success inline notice LumotiaProgress — native <progress> + token theming LumotiaField — plain + Formsnap modes share the same markup Bits UI 2.18.1 wrappers (warm-brutalist styling): LumotiaSelect — single-select, options=[] LumotiaCombobox — searchable; one-way inputValue + oninput LumotiaDialog — controlled open; closable + footer snippet LumotiaTabs — orchestrates List/Trigger/Content from a tabs array LumotiaTooltip — wraps Provider + Root + Trigger + Content LumotiaMenu — DropdownMenu items=[] with destructive variant design-system-v2 preview route: src/routes/design-system-v2/+page.ts gates with VITE_LUMOTIA_DESIGN_SYSTEM_V2=1. Without the flag the load() throws 404 — route-level gate, not nav- hidden. Run via VITE_LUMOTIA_DESIGN_SYSTEM_V2=1 npm run dev:frontend to see the showcase. Browser-mode component test: src/lib/ui/LumotiaButton.browser.test.ts. Covers render, click, and disabled-blocks-click. Validates that vitest-browser-svelte + the @vitest/browser-playwright provider land Phase 1's tooling contract end-to-end. 3/3 passing in Chromium. Type fix: LumotiaIconButton and LumotiaMenu accept icon: any so lucide-svelte's legacy SvelteComponentTyped shape composes with our Svelte 5 wrappers without forcing a // @ts-nocheck escape hatch on every call site. Tightens to Component<…> once lucide-svelte ships a Svelte 5 build. Type fix: LumotiaCombobox honours Bits UI 2.x Combobox.Root's one-way inputValue contract. The wrapper drops bind:inputValue and exposes an oninput callback so caller-owned filter pipelines (HistoryPage FTS5, ModelDownloader) can drive options upstream. Phase 5 per-page gate green: npm run check (0/0/5700 files), npm test, npm run test:browser (3/3 in Chromium), npm run test:e2e (16/16), guard-no-skeleton clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
|||
| 8c9708a508 |
v0.2 Phase 4: wrapper alias layer (src/lib/ui/)
Six thin alias wrappers, same prop APIs as the underlying components. Lets pages migrate imports from $lib/components/* to $lib/ui/* one file at a time without touching markup, and gives Phase 5+ a place to tighten grammar without churning every call site. LumotiaCard → Card.svelte LumotiaStatusPill → StatusPill.svelte LumotiaToggle → Toggle.svelte (forwards bind:checked, bind:loading) LumotiaSettingsGroup → SettingsGroup.svelte (typed Props for svelte-check) LumotiaEmptyState → EmptyState.svelte LumotiaPostCaptureCard → PostCaptureCard.svelte Per the plan, the underlying components in src/lib/components/ are untouched. They get retired during the per-page migrations in Phase 7 once no consumer remains. LumotiaSettingsGroup mirrors the underlying Props interface explicitly because Svelte 5's spread-into-typed-component caught a real missing- `title` error during svelte-check. The mirrored interface keeps call sites type-safe when importing via $lib/ui/. Phase 4 per-phase gate green: npm run check (0/0/4135 files), npm test (all green), npm run test:e2e (16/16), npm run guard:no-skeleton (clean). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |