Phase 2: React scaffolding, self-hosted fonts, design tokens
Vite builds to dist/, deliberately not www/. www/ is still produced by sync-www.sh for the Phase 1 APK, which stays installable throughout the port; cutover is a one-line webDir change in capacitor.config.json. base is relative because Capacitor serves the bundle from the APK, where absolute asset paths would 404. index.html omits viewport-fit=cover on purpose. That string is what makes Capacitor's SystemBars plugin pass insets through to the page; without it the plugin pads the decor view and the layout is always between the status and gesture bars. Phase 1 learned this the hard way. Fonts are self-hosted for offline use, latin subsets only: three files at 68K, against the 133K Barlow costs today. Space Grotesk is variable, so one file covers 400-700. Dropped latin-ext and vietnamese. Carets are drawn as SVG, not typed. U+25BE and U+23EE sit outside every Latin subset and would fall back to a system font mid-label. base.css carries the settled palette and the measured vertical budget as tokens, so a component cannot quietly exceed it: 8 + 44 + 8 + 525 + 8 + 84 + 8 + 50 = 735 Verified: typecheck clean, 103 tests, vite build emits with the fonts copied, and www/ is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
102
src/styles/base.css
Normal file
102
src/styles/base.css
Normal file
@@ -0,0 +1,102 @@
|
||||
/* Design tokens and reset. The visual spec lives in CLAUDE.md. */
|
||||
|
||||
/* Latin subsets only. Space Grotesk is variable, so one file covers 400-700. */
|
||||
@font-face {
|
||||
font-family: "Space Grotesk";
|
||||
font-weight: 400 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src: url("/fonts/space-grotesk-var-latin.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Space Mono";
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src: url("/fonts/space-mono-400-latin.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Space Mono";
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
src: url("/fonts/space-mono-700-latin.woff2") format("woff2");
|
||||
}
|
||||
|
||||
:root {
|
||||
--font: "Space Grotesk", system-ui, sans-serif;
|
||||
--mono: "Space Mono", ui-monospace, monospace;
|
||||
|
||||
/* Direction A, manual. */
|
||||
--page: #e9e9e6;
|
||||
--body: #d2d2ce;
|
||||
--card: #f5f5f2;
|
||||
--ink: #111111;
|
||||
--muted: #6e6e69;
|
||||
--rule: #b5b5b0;
|
||||
--key: #f5f5f2;
|
||||
--pad: #1b1b1b;
|
||||
--pad-ink: #ededeb;
|
||||
--lcd: #c9d2c4;
|
||||
|
||||
/* One accent, one meaning: this control is live. */
|
||||
--accent: #ff4a00;
|
||||
--on-accent: #111111;
|
||||
|
||||
--outline: 2px solid var(--ink);
|
||||
--shadow: 4px 4px 0 var(--ink);
|
||||
--shadow-sm: 3px 3px 0 var(--ink);
|
||||
|
||||
/* The measured vertical budget at 360x735. Nothing may exceed it. */
|
||||
--gap: 8px;
|
||||
--strip-h: 44px;
|
||||
--panel-h: 525px;
|
||||
--info-h: 84px;
|
||||
--nav-h: 50px;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--page: #1a1a17;
|
||||
--body: #2e2e2a;
|
||||
--card: #2e2e2a;
|
||||
--ink: #ededeb;
|
||||
--muted: #8a8a85;
|
||||
--rule: #4a4a46;
|
||||
--key: #3e3e3a;
|
||||
--pad: #0e0e0c;
|
||||
--outline: 2px solid #000000;
|
||||
--shadow: 5px 5px 0 #000000;
|
||||
--shadow-sm: 3px 3px 0 #000000;
|
||||
}
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--page);
|
||||
color: var(--ink);
|
||||
font-family: var(--font);
|
||||
font-size: 16px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
button {
|
||||
font: inherit;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
Reference in New Issue
Block a user