34f3c2888f
Nine screens against orchestra-ui-spec.md and the accepted mockups, on the ethos design system: signal violet #8F7AE5, the routing fork motif, the 64px rail and 56px top bar, mono for every machine value and sans for every human one. Each screen was built by its own agent against a fixed foundation, so the shell, tokens and primitives have one author and the screens cannot drift into nine dialects. Real data only. Where no endpoint exists the screen says which one it needs instead of inventing a value. That is most of what was learned here: Steer / Correct is disabled because nothing records a human decision from the web, take-control is disabled because nothing forwards keystrokes to a pane, context occupancy is missing from three screens, and projects can show no repo, remote, quality gate or verification policy because those live only in config.jsonc. Three bugs the render caught that no computed value would have: The previous stylesheet fought every shared class name and leaked properties the new rules never mention, which is how position:fixed survived on .topbar. It is now scoped under .legacy and applies only to the login route, which also stops its green accent and its backdrop-filter from reaching the console. Go marshals a zero time.Time as "0001-01-01T00:00:00Z" and omitempty does not omit a struct, so absent timestamps arrived populated-looking and rendered as "739855d ago". Stripped once at the API boundary every screen reads through, with a test. Long machine ids overflowed their cards and painted under the next one. Verified by rendering: chromium screenshots of the dashboard, tasks, task detail, terminal, workers and review at 1440px, and the dashboard at 390px. Geist is still not on disk, so both stacks fall back to the system faces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CVbaKucEYBjMqVeUgJUsc1
137 lines
5.5 KiB
CSS
137 lines
5.5 KiB
CSS
/* ═══════════════════════════════════════════════════════════════
|
||
ETHOS — tokens
|
||
Shared design language for the kvmx.ru apps.
|
||
|
||
The neutral system (ramp, type, motion, radii, shadow) is shared by
|
||
every app and does not change. The only per-app difference is the
|
||
accent (one hue) and the motif (one geometric signature).
|
||
|
||
NEW APP: do not invent the accent silently. Ask the operator for the
|
||
accent name + hex and the motif, then add one [data-app] block at the
|
||
bottom using the TEMPLATE. Fonts are self-hosted (subset + woff2,
|
||
immutable caching) — no font CDN.
|
||
═══════════════════════════════════════════════════════════════ */
|
||
|
||
@font-face {
|
||
font-family: 'Geist';
|
||
src: url('/fonts/Geist-Variable.woff2') format('woff2');
|
||
font-weight: 100 900; font-display: swap;
|
||
}
|
||
@font-face {
|
||
font-family: 'Geist Mono';
|
||
src: url('/fonts/GeistMono-Variable.woff2') format('woff2');
|
||
font-weight: 100 900; font-display: swap;
|
||
}
|
||
|
||
:root {
|
||
/* ── neutral ramp — warm, brown-tinted (dark, default) ── */
|
||
--bg-0: #14110D; /* deepest room */
|
||
--bg-1: #1B1712; /* surface */
|
||
--bg-2: #221D17; /* raised */
|
||
--bg-3: #2C261D; /* hover / raised */
|
||
--bg-4: #372F24; /* pressed / high */
|
||
|
||
--line: rgba(244, 234, 220, 0.09); /* hairline */
|
||
--line-hi: rgba(244, 234, 220, 0.16); /* hairline emphasized */
|
||
|
||
--text-hi: #F4EEE4; /* human primary (sans) */
|
||
--text-mid: #B4AA98; /* human secondary (sans) */
|
||
--text-lo: #756C5C; /* human tertiary / idle */
|
||
--text-machine: #9C917D; /* machine default (mono) */
|
||
|
||
/* ── type ── */
|
||
--sans: 'Geist', -apple-system, system-ui, sans-serif;
|
||
--mono: 'Geist Mono', ui-monospace, 'SF Mono', Menlo, monospace;
|
||
|
||
/* mono numerics: apply on any element using --mono */
|
||
/* font-feature-settings: "tnum" 1, "zero" 1; letter-spacing: -0.01em; */
|
||
|
||
/* ── motion — mechanical, no bounce ── */
|
||
--ease: cubic-bezier(0.2, 0, 0, 1);
|
||
--fast: 130ms;
|
||
--med: 170ms;
|
||
|
||
/* ── radii ── */
|
||
--r-sm: 8px;
|
||
--r-md: 12px;
|
||
--r-lg: 18px;
|
||
--r-xl: 24px;
|
||
|
||
/* ── elevation: depth from light, never blur ── */
|
||
--shadow-soft: 0 2px 8px rgba(0,0,0,0.35), 0 12px 32px rgba(0,0,0,0.28);
|
||
--shadow-lift: 0 4px 14px rgba(0,0,0,0.40), 0 20px 48px rgba(0,0,0,0.34);
|
||
|
||
/* ── accent slot ──
|
||
Neutral fallback so an app with no [data-app] is never unstyled.
|
||
Real values come from the per-app block below. Accent is a SIGNAL
|
||
(active state, focus ring, primary action, one lit detail) — never a
|
||
fill-everything wash. */
|
||
--accent: var(--text-mid);
|
||
--accent-hi: var(--text-hi);
|
||
--accent-dim: rgba(244, 234, 220, 0.10);
|
||
--accent-line: rgba(244, 234, 220, 0.24);
|
||
--accent-glow: rgba(244, 234, 220, 0.14);
|
||
}
|
||
|
||
/* ── light theme — warm, off-white (kept off cream to dodge the AI-cream tell) ── */
|
||
[data-theme="light"] {
|
||
--bg-0: #F1ECE3;
|
||
--bg-1: #EAE4D8;
|
||
--bg-2: #E2DACB;
|
||
--bg-3: #D7CDBB;
|
||
--bg-4: #C9BDA7;
|
||
|
||
--line: rgba(28, 22, 14, 0.10);
|
||
--line-hi: rgba(28, 22, 14, 0.18);
|
||
|
||
--text-hi: #1B1712;
|
||
--text-mid: #544C3E;
|
||
--text-lo: #877E6C;
|
||
--text-machine: #6B6252;
|
||
|
||
--shadow-soft: 0 2px 8px rgba(60,45,25,0.10), 0 12px 32px rgba(60,45,25,0.08);
|
||
--shadow-lift: 0 4px 14px rgba(60,45,25,0.12), 0 20px 48px rgba(60,45,25,0.10);
|
||
}
|
||
|
||
/* ═══════════════════════════════════════════════════════════════
|
||
PER-APP OVERRIDES — one small block each. Accent + optional motif
|
||
hooks only; never touch the neutral ramp.
|
||
═══════════════════════════════════════════════════════════════ */
|
||
|
||
/* muzick — reference app · honey amber · waveform */
|
||
[data-app="muzick"] {
|
||
--accent: #EDA24E;
|
||
--accent-hi: #F5B667;
|
||
--accent-dim: rgba(237, 162, 78, 0.14);
|
||
--accent-line: rgba(237, 162, 78, 0.32);
|
||
--accent-glow: rgba(237, 162, 78, 0.22);
|
||
|
||
/* motif hook: cool content-art gradient so art carries color, amber stays signal */
|
||
--np-art: radial-gradient(120% 120% at 22% 14%, #7FB3BC 0%, #2F6E7A 42%, #1C4552 78%, #14262E 100%);
|
||
}
|
||
|
||
/* ── TEMPLATE — copy for a new app AFTER intake with the operator ──
|
||
[data-app="APPNAME"] {
|
||
--accent: #RRGGBB; // the operator's chosen hue
|
||
--accent-hi: #RRGGBB; // ~ +10–14% lightness
|
||
--accent-dim: rgba(R, G, B, 0.14); // active-state backgrounds
|
||
--accent-line: rgba(R, G, B, 0.32); // accent hairlines
|
||
--accent-glow: rgba(R, G, B, 0.22); // restrained ambient pool
|
||
// optional motif hooks (gradients / seeds) go here, app-specific
|
||
}
|
||
*/
|
||
|
||
/* orchestra — signal violet · routing fork
|
||
Accent and motif come from orchestra-ui-spec.md, chosen by the operator. */
|
||
[data-app="orchestra"] {
|
||
--accent: #8F7AE5;
|
||
--accent-hi: #A291EC;
|
||
--accent-dim: rgba(143, 122, 229, 0.14);
|
||
--accent-line: rgba(143, 122, 229, 0.32);
|
||
--accent-glow: rgba(143, 122, 229, 0.22);
|
||
|
||
/* motif hook: the routing fork, one path splitting and rejoining. Used by
|
||
the app mark, phase transitions and empty states. */
|
||
--fork-line: rgba(143, 122, 229, 0.55);
|
||
}
|