cf9eecc895
The kit (SKILL.md, ethos.tokens.css, ethos-icons.svg, .oxlintrc.json) lived inside frontend/ — the exact dir freestyle runs scaffold into. vite refuses a non-empty target, so every session improvised a stash-aside (frontend_backup/, frontend_temp/) and left scratch dirs behind. Move the kit to a sibling design-system/ so frontend/ starts clean, and deliver it via the L0 conventions channel (project.toml) rather than seeding files in the scaffold target: copy the token/icon assets in (don't read them), SKILL.md for rules only. Un-ignore frontend/ so scaffolded output is tracked going forward. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HMbPmZZjcXhR2crU82zZ8S
123 lines
5.0 KiB
CSS
123 lines
5.0 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
|
||
}
|
||
*/
|