diff --git a/packages/web/index.html b/packages/web/index.html index fbae6dd..b2bd427 100644 --- a/packages/web/index.html +++ b/packages/web/index.html @@ -4,6 +4,21 @@ Involute +
diff --git a/packages/web/src/App.tsx b/packages/web/src/App.tsx index b17c874..68e2471 100644 --- a/packages/web/src/App.tsx +++ b/packages/web/src/App.tsx @@ -108,10 +108,10 @@ function getStoredTheme(): ThemeMode { return storedTheme; } } catch { - // Ignore localStorage failures and fall back to dark. + // Ignore localStorage failures and fall back to the Atelier light default. } - return 'dark'; + return 'light'; } function persistTheme(nextTheme: ThemeMode) { diff --git a/packages/web/src/styles/app.css b/packages/web/src/styles/app.css index e824f3b..dd5c81c 100644 --- a/packages/web/src/styles/app.css +++ b/packages/web/src/styles/app.css @@ -1,15 +1,25 @@ -@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&family=Geist+Mono:wght@400;500&display=swap'); +/* ============================================================ + Involute UI — aligned to the Lumen Design System. + Warm "Atelier" light (default) + "Vault" dark, IBM Plex, and the + quiet-utility ethos: flat backgrounds, 1px hairline borders doing + the structural work, shadows only on the outer shell + popovers, + no gradients / blur / emoji, hover = tint not movement. + ============================================================ */ +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Sans+SC:wght@400;500;600;700&display=swap'); :root { - --font-sans: "Geist", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; - --font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace; - - --r-1: 3px; - --r-2: 4px; - --r-3: 6px; - --r-4: 8px; - --r-5: 8px; - --r-6: 8px; + --font-sans: "IBM Plex Sans", "IBM Plex Sans SC", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; + --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; + --font-serif: "Iowan Old Style", "Songti SC", "Source Han Serif SC", Georgia, "Times New Roman", serif; + + /* radius scale — Lumen: controls 10, panels 12, cards 16, shell 20, pill 999. + Micro elements (code, keycaps) stay tighter. */ + --r-1: 6px; + --r-2: 8px; + --r-3: 10px; + --r-4: 12px; + --r-5: 16px; + --r-6: 20px; --sidebar-w: 224px; --content-gutter: 16px; @@ -17,9 +27,10 @@ --pad-y: 8px; --row-h: 32px; - --ease: cubic-bezier(0.2, 0, 0, 1); - --dur-1: 80ms; - --dur-2: 120ms; + /* motion — restrained; 120–180ms, color/opacity/width only */ + --ease: cubic-bezier(0.4, 0, 0.2, 1); + --dur-1: 120ms; + --dur-2: 150ms; --dur-3: 180ms; } @@ -44,89 +55,96 @@ --row-h: 36px; } +/* ===== LIGHT (default) — "Atelier": warm parchment + terracotta ===== */ :root, +[data-theme="light"] { + color-scheme: light; + + --bg: #f7f6f2; + --bg-raised: #fffdfa; + --bg-hover: #f2ede4; + --bg-active: #eae3d7; + --bg-sunken: #efece5; + --bg-overlay: rgba(31, 26, 23, 0.24); + + --border: #e7e1d8; + --border-strong: #cdc4b6; + --border-subtle: #efece5; + + --fg: #1f1a17; + --fg-muted: #443a32; + --fg-dim: #71675d; + --fg-faint: #b0a89d; + + --accent: #9f4f24; + --accent-fg: #fffdfa; + --accent-weak: rgba(159, 79, 36, 0.1); + --accent-border: rgba(159, 79, 36, 0.24); + + --danger: #b04545; + --danger-weak: rgba(176, 69, 69, 0.1); + --success: #2f7d52; + --success-weak: rgba(47, 125, 82, 0.1); + --warn: #a85e10; + --info: #2563bb; + + /* elevation — only shell + pop; inline cards carry none */ + --shadow-sm: none; + --shadow-md: 0 12px 36px rgba(31, 26, 23, 0.06); + --shadow-lg: 0 16px 48px rgba(31, 26, 23, 0.12); + + --selection: rgba(159, 79, 36, 0.14); + + --prio-urgent: #b04545; + --prio-high: #a85e10; + --prio-med: #71675d; + --prio-low: #a99f93; + --prio-none: #cdc4b6; +} + +/* ===== DARK — "Vault": near-black + deep blue + cyan ===== */ [data-theme="dark"] { - --bg: #1a1a2e; - --bg-raised: #1e1e34; - --bg-hover: #25253d; - --bg-active: #2c2c46; - --bg-sunken: #151528; - --bg-overlay: rgba(0, 0, 0, 0.55); - - --border: #334155; - --border-strong: #3e4c63; - --border-subtle: #252540; - - --fg: #e2e8f0; - --fg-muted: #94a3b8; - --fg-dim: #64748b; - --fg-faint: #475569; - - --accent: #d4c5a0; - --accent-fg: #0f0f1a; - --accent-weak: rgba(212, 197, 160, 0.1); - --accent-border: rgba(212, 197, 160, 0.2); - - --danger: #e5484d; - --danger-weak: rgba(229, 72, 77, 0.12); - --success: #65b881; - --success-weak: rgba(101, 184, 129, 0.12); - --warn: #f5a524; - --info: #7c88ff; - - --shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.4); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.3), 0 0 0 1px var(--border); - --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.5), 0 0 0 1px var(--border); - - --selection: rgba(212, 197, 160, 0.2); - - --prio-urgent: #ef4444; - --prio-high: #f97316; - --prio-med: #eab308; - --prio-low: #3b82f6; - --prio-none: #475569; -} + color-scheme: dark; -[data-theme="light"] { - --bg: #fbfbfa; - --bg-raised: #ffffff; - --bg-hover: #f3f3f1; - --bg-active: #ebeae7; - --bg-sunken: #f6f5f3; - --bg-overlay: rgba(18, 18, 18, 0.24); - - --border: #e5e3df; - --border-strong: #d4d2cd; - --border-subtle: #efeeea; - - --fg: #1a1a1a; - --fg-muted: #5a5a5a; - --fg-dim: #8a8a8a; - --fg-faint: #bcbcbc; - - --accent: #8b7a52; + --bg: #0a0e16; + --bg-raised: #11161f; + --bg-hover: #1c2432; + --bg-active: #161c27; + --bg-sunken: #0c1119; + --bg-overlay: rgba(0, 0, 0, 0.58); + + --border: #1f2937; + --border-strong: #2c3a4f; + --border-subtle: #161c27; + + --fg: #e6edf5; + --fg-muted: #c2cfde; + --fg-dim: #7d8aa0; + --fg-faint: #55606f; + + --accent: #3b82f6; --accent-fg: #ffffff; - --accent-weak: rgba(139, 122, 82, 0.08); - --accent-border: rgba(139, 122, 82, 0.25); + --accent-weak: rgba(59, 130, 246, 0.16); + --accent-border: rgba(59, 130, 246, 0.3); - --danger: #d42d35; - --danger-weak: rgba(212, 45, 53, 0.1); - --success: #3f8d5a; - --success-weak: rgba(63, 141, 90, 0.12); - --warn: #c47609; - --info: #4f5bd5; + --danger: #f472b6; + --danger-weak: rgba(244, 114, 182, 0.14); + --success: #22c55e; + --success-weak: rgba(34, 197, 94, 0.15); + --warn: #fbbf24; + --info: #06b6d4; - --shadow-sm: 0 1px 0 rgba(0, 0, 0, 0.04); - --shadow-md: 0 4px 16px rgba(0, 0, 0, 0.06), 0 0 0 1px var(--border); - --shadow-lg: 0 16px 48px rgba(0, 0, 0, 0.08), 0 0 0 1px var(--border); + --shadow-sm: none; + --shadow-md: 0 12px 36px rgba(0, 0, 0, 0.55); + --shadow-lg: 0 18px 52px rgba(0, 0, 0, 0.7); - --selection: rgba(139, 122, 82, 0.18); + --selection: rgba(59, 130, 246, 0.22); - --prio-urgent: #d42d35; - --prio-high: #c47609; - --prio-med: #5a5a5a; - --prio-low: #8a8a8a; - --prio-none: #bcbcbc; + --prio-urgent: #f472b6; + --prio-high: #fbbf24; + --prio-med: #7d8aa0; + --prio-low: #55606f; + --prio-none: #2c3a4f; } * { @@ -151,6 +169,7 @@ body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-feature-settings: "ss01", "cv11"; + /* Flat warm background — no gradients, no imagery, no grid texture. */ } a { @@ -158,6 +177,12 @@ a { text-decoration: none; } +/* Focus — 3px accent outline at 2px offset (Lumen :focus-visible). */ +:focus-visible { + outline: 3px solid color-mix(in srgb, var(--accent) 32%, transparent); + outline-offset: 2px; +} + button, input, select, @@ -254,7 +279,7 @@ kbd { height: 100vh; flex-direction: column; justify-content: space-between; - border-right: 1px solid var(--border-subtle); + border-right: 1px solid var(--border); background: var(--bg-sunken); padding: 10px 8px 8px; } @@ -1427,7 +1452,6 @@ kbd { box-shadow: none; cursor: grab; transition: - transform var(--dur-2) var(--ease), border-color var(--dur-2) var(--ease), background var(--dur-2) var(--ease); touch-action: none; @@ -2743,7 +2767,7 @@ kbd { align-items: center; justify-content: space-between; gap: 12px; - border-bottom: 1px solid var(--border-subtle); + border-bottom: 1px solid var(--border); background: var(--bg-sunken); padding: 10px var(--content-gutter); } @@ -3181,6 +3205,5 @@ kbd { } .dialog-modal::backdrop { - background: rgba(0,0,0,0.5); - backdrop-filter: blur(2px); + background: var(--bg-overlay); }