/* * Echo Dashboard — Design Tokens * Single source of truth for all CSS variables, fonts, and shared * mobile-modal behavior. Loaded via /echo/static/tokens.css on every * dashboard page (in addition to common.css for now). * * Token coverage: * - Colors (dark default + light theme override) * - Status palette (running, blocked, failed, complete, idle, * planning, pending, approved) * - Typography (Inter sans + JetBrains Mono mono, size scale) * - Spacing (8px grid) * - Radius scale * - Shadows / transitions */ /* ========================================================== @font-face — Inter (self-hosted, woff2 only) ========================================================== */ @font-face { font-family: 'Inter'; src: url('/echo/static/fonts/inter-400.woff2') format('woff2'); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: 'Inter'; src: url('/echo/static/fonts/inter-500.woff2') format('woff2'); font-weight: 500; font-style: normal; font-display: swap; } @font-face { font-family: 'Inter'; src: url('/echo/static/fonts/inter-600.woff2') format('woff2'); font-weight: 600; font-style: normal; font-display: swap; } @font-face { font-family: 'Inter'; src: url('/echo/static/fonts/inter-700.woff2') format('woff2'); font-weight: 700; font-style: normal; font-display: swap; } /* ========================================================== Tokens — dark theme (default) ========================================================== */ :root { /* Colors — dark surface */ --bg-base: #13131a; --bg-surface: rgba(255, 255, 255, 0.12); --bg-surface-hover: rgba(255, 255, 255, 0.16); --bg-surface-active: rgba(255, 255, 255, 0.20); --bg-elevated: rgba(255, 255, 255, 0.14); --text-primary: #ffffff; --text-secondary: #f5f5f5; --text-muted: #e5e5e5; --accent: #3b82f6; --accent-hover: #2563eb; --accent-subtle: rgba(59, 130, 246, 0.2); --border: rgba(255, 255, 255, 0.3); --border-focus: rgba(59, 130, 246, 0.7); --header-bg: rgba(19, 19, 26, 0.95); --success: #22c55e; --warning: #eab308; --error: #ef4444; /* Status palette — used by .status-pill[data-status] */ --status-running: rgb(34, 197, 94); /* green — running-ralph / running-manual */ --status-blocked: rgb(245, 158, 11); /* amber */ --status-failed: rgb(239, 68, 68); /* red */ --status-complete: rgb(156, 163, 175); /* slate (done = neutral) */ --status-idle: var(--text-muted); /* Status palette — extended (workflow states) */ --status-planning: rgb(167, 139, 250); /* violet — Echo is planning */ --status-pending: rgb(96, 165, 250); /* sky — awaiting approval */ --status-approved: rgb(234, 179, 8); /* gold — approved tonight */ /* Spacing — 8px grid */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px; --space-10: 40px; /* Typography */ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; --font-mono: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace; --text-xs: 0.75rem; --text-sm: 0.875rem; --text-base: 1rem; --text-lg: 1.125rem; --text-xl: 1.25rem; /* Radius */ --radius-sm: 4px; --radius-md: 8px; --radius-lg: 12px; --radius-full: 9999px; /* Shadows */ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3); --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4); --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.5); /* Motion */ --transition-fast: 0.15s ease; --transition-base: 0.2s ease; } /* ========================================================== Light theme override ========================================================== */ [data-theme="light"] { --bg-base: #f8f9fa; --bg-surface: rgba(0, 0, 0, 0.04); --bg-surface-hover: rgba(0, 0, 0, 0.08); --bg-surface-active: rgba(0, 0, 0, 0.12); --bg-elevated: rgba(0, 0, 0, 0.06); --text-primary: #1a1a1a; --text-secondary: #444444; --text-muted: #666666; --border: rgba(0, 0, 0, 0.12); --border-focus: rgba(59, 130, 246, 0.5); --accent-subtle: rgba(59, 130, 246, 0.12); --header-bg: rgba(255, 255, 255, 0.95); } /* ========================================================== Mobile modal — shared across all pages with .modal-overlay ========================================================== */ @media (max-width: 640px) { .modal-overlay { padding: 0; align-items: stretch; } .modal { max-width: 100vw !important; max-height: 100vh !important; border-radius: 0; height: 100vh; } .modal-header { position: sticky; top: 0; background: var(--bg-base); } .modal-footer { position: sticky; bottom: 0; padding-bottom: max(var(--space-4), env(safe-area-inset-bottom)); } .phase-stepper .phase-step:not(.active) span:not(.step-num) { display: none; } }