/* =================================================================== Marathon — Editorial-Quant design system ------------------------------------------------------------------ Inspiration: long-form data journalism (FT, Quartz), terminal instruments (Bloomberg), and Belarusian / Soviet print typography. The aesthetic is confident, dense, and serif-led on display surfaces. =================================================================== */ :root { /* ----- Spacing scale (4-pt base, doubled at 16+) ----- */ --m-space-1: 4px; --m-space-2: 8px; --m-space-3: 12px; --m-space-4: 16px; --m-space-5: 24px; --m-space-6: 32px; --m-space-7: 48px; --m-space-8: 64px; --m-space-9: 96px; /* ----- Radius — sharp by default, soft variants for inputs ----- */ --m-radius-sharp: 0; --m-radius-xs: 2px; --m-radius-sm: 4px; --m-radius-md: 6px; --m-radius-lg: 10px; /* ----- Typography ----- */ --m-font-display: "IBM Plex Serif", "PT Serif", Georgia, serif; --m-font-body: "IBM Plex Sans", "PT Sans", system-ui, sans-serif; --m-font-mono: "JetBrains Mono", "IBM Plex Mono", "Fira Code", Consolas, monospace; /* ----- Colors — light (parchment) chassis ----- */ --m-c-ink: #0f172a; --m-c-ink-2: #1e293b; --m-c-ink-soft: #475569; --m-c-paper: #fafaf7; --m-c-paper-2: #f5f4ef; --m-c-paper-3: #ebe9e1; --m-c-rule: #e7e5e4; --m-c-accent: #d97706; --m-c-accent-soft: #f59e0b; --m-c-anomaly: #dc2626; --m-c-positive: #15803d; --m-c-info: #0369a1; /* Tabular numerals for everywhere odds/scores appear */ --m-num-feature: "tnum" 1, "lnum" 1, "ss01" 1; } /* Dark theme overrides (applied via class on or via MudThemeProvider) */ .mud-theme-dark, [data-theme="dark"] { --m-c-ink: #f5f5f4; --m-c-ink-2: #e7e5e4; --m-c-ink-soft: #a8a29e; --m-c-paper: #1c1917; --m-c-paper-2: #0c0a09; --m-c-paper-3: #292524; --m-c-rule: #292524; --m-c-accent: #fbbf24; --m-c-accent-soft: #fcd34d; --m-c-anomaly: #f87171; --m-c-positive: #4ade80; --m-c-info: #38bdf8; } /* =================================================================== Base =================================================================== */ html, body { margin: 0; padding: 0; background: var(--m-c-paper-2); color: var(--m-c-ink); font-family: var(--m-font-body); font-feature-settings: var(--m-num-feature); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; } body { /* Subtle paper grain — 1px mottled noise, rendered cheaply via SVG. */ background-image: radial-gradient(circle at 25% 12%, rgba(217, 119, 6, 0.035), transparent 45%), radial-gradient(circle at 88% 78%, rgba(15, 23, 42, 0.040), transparent 50%), url("data:image/svg+xml;utf8,"); background-attachment: fixed; } .mud-theme-dark body, [data-theme="dark"] body { background-image: radial-gradient(circle at 25% 12%, rgba(251, 191, 36, 0.045), transparent 45%), radial-gradient(circle at 88% 78%, rgba(56, 189, 248, 0.030), transparent 50%), url("data:image/svg+xml;utf8,"); } #app { min-height: 100vh; display: flex; flex-direction: column; } /* =================================================================== Numerals — always tabular for odds tables and score readouts =================================================================== */ .m-num, .mud-table tbody td, .mud-data-grid tbody td, [data-numeric] { font-feature-settings: var(--m-num-feature); font-variant-numeric: tabular-nums lining-nums; } .m-mono { font-family: var(--m-font-mono); font-feature-settings: var(--m-num-feature); letter-spacing: 0; } /* =================================================================== Editorial markers — kicker label + serif display lockup =================================================================== */ .m-kicker { font-family: var(--m-font-mono); text-transform: uppercase; letter-spacing: 0.18em; font-size: 0.6875rem; color: var(--m-c-accent); font-weight: 500; display: inline-block; padding-bottom: var(--m-space-1); border-bottom: 1px solid var(--m-c-accent); } .m-display { font-family: var(--m-font-display); font-weight: 300; letter-spacing: -0.022em; line-height: 1.05; color: var(--m-c-ink); } .m-rule { border: 0; border-top: 1px solid var(--m-c-rule); margin: var(--m-space-5) 0; } .m-rule--double { border: 0; border-top: 3px double var(--m-c-rule); margin: var(--m-space-5) 0; } /* =================================================================== Cards — paper-like, borders not shadows =================================================================== */ .m-card { background: var(--m-c-paper); border: 1px solid var(--m-c-rule); border-radius: var(--m-radius-xs); padding: var(--m-space-5); position: relative; } .m-card--accented { border-left: 3px solid var(--m-c-accent); } .m-card--anomaly { border-left: 3px solid var(--m-c-anomaly); } /* =================================================================== Stat block — large number, mono, kicker on top =================================================================== */ .m-stat { display: flex; flex-direction: column; gap: var(--m-space-2); } .m-stat__value { font-family: var(--m-font-mono); font-feature-settings: var(--m-num-feature); font-size: clamp(2rem, 4vw, 3rem); font-weight: 500; line-height: 1; color: var(--m-c-ink); letter-spacing: -0.02em; } .m-stat__label { font-family: var(--m-font-body); font-size: 0.8125rem; color: var(--m-c-ink-soft); text-transform: none; letter-spacing: 0; } .m-stat__delta { font-family: var(--m-font-mono); font-size: 0.75rem; color: var(--m-c-positive); } .m-stat__delta--down { color: var(--m-c-anomaly); } /* =================================================================== Page-load reveal — one orchestrated entrance, respects motion prefs =================================================================== */ @keyframes m-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } .m-rise { animation: m-rise 480ms cubic-bezier(0.2, 0.7, 0.2, 1) both; } .m-rise-1 { animation-delay: 40ms; } .m-rise-2 { animation-delay: 100ms; } .m-rise-3 { animation-delay: 180ms; } .m-rise-4 { animation-delay: 260ms; } .m-rise-5 { animation-delay: 340ms; } @media (prefers-reduced-motion: reduce) { .m-rise, .m-rise-1, .m-rise-2, .m-rise-3, .m-rise-4, .m-rise-5 { animation: none !important; } } /* =================================================================== Focus rings — deliberate, accent, never invisible =================================================================== */ :focus-visible { outline: 2px solid var(--m-c-accent); outline-offset: 2px; } .mud-button:focus-visible, .mud-icon-button:focus-visible { outline: 2px solid var(--m-c-accent); outline-offset: 2px; } /* =================================================================== Layout primitives — asymmetric content grid =================================================================== */ .m-shell { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--m-space-5); padding: var(--m-space-5) clamp(var(--m-space-4), 4vw, var(--m-space-7)); max-width: 1480px; width: 100%; margin: 0 auto; } .m-grid--asym { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: var(--m-space-5); } @media (max-width: 960px) { .m-grid--asym { grid-template-columns: 1fr; } } .m-grid--three { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: var(--m-space-4); } /* =================================================================== AppBar wordmark + dateline =================================================================== */ .m-brand { display: flex; align-items: baseline; gap: var(--m-space-3); } .m-brand__mark { font-family: var(--m-font-display); font-weight: 500; font-size: 1.375rem; letter-spacing: -0.02em; line-height: 1; } .m-brand__mark::first-letter { color: var(--m-c-accent); } .m-brand__dateline { font-family: var(--m-font-mono); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.16em; color: var(--m-c-ink-soft); border-left: 1px solid var(--m-c-rule); padding-left: var(--m-space-3); } /* =================================================================== Drawer — narrow, dark, mono labels =================================================================== */ .m-nav__group { padding: var(--m-space-3) var(--m-space-4); font-family: var(--m-font-mono); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.18em; color: rgba(231, 229, 228, 0.55); } .m-nav__link { display: flex; align-items: center; gap: var(--m-space-3); padding: var(--m-space-3) var(--m-space-4); color: rgba(231, 229, 228, 0.85); text-decoration: none; font-size: 0.9375rem; border-left: 2px solid transparent; transition: background 120ms ease, border-color 120ms ease, color 120ms ease; } .m-nav__link:hover { background: rgba(217, 119, 6, 0.10); color: #ffffff; } .m-nav__link.active { color: #ffffff; background: rgba(217, 119, 6, 0.14); border-left-color: var(--m-c-accent); } .m-nav__link .mud-icon-root { font-size: 1.1rem; } /* =================================================================== Locale switcher — segmented control =================================================================== */ .m-segmented { display: inline-flex; border: 1px solid var(--m-c-rule); border-radius: var(--m-radius-xs); overflow: hidden; background: var(--m-c-paper); } .m-segmented__btn { appearance: none; border: 0; background: transparent; padding: 6px 12px; font-family: var(--m-font-mono); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.14em; color: var(--m-c-ink-soft); cursor: pointer; transition: background 120ms ease, color 120ms ease; } .m-segmented__btn + .m-segmented__btn { border-left: 1px solid var(--m-c-rule); } .m-segmented__btn:hover { color: var(--m-c-ink); } .m-segmented__btn.is-active { background: var(--m-c-ink); color: var(--m-c-paper); } .mud-theme-dark .m-segmented__btn.is-active, [data-theme="dark"] .m-segmented__btn.is-active { background: var(--m-c-accent); color: var(--m-c-paper-2); } /* =================================================================== Settings page — section ledger =================================================================== */ .m-section { border: 1px solid var(--m-c-rule); background: var(--m-c-paper); margin-bottom: var(--m-space-5); } .m-section__head { display: flex; align-items: baseline; justify-content: space-between; padding: var(--m-space-4) var(--m-space-5); border-bottom: 1px solid var(--m-c-rule); background: var(--m-c-paper-2); } .m-section__head h2 { margin: 0; font-family: var(--m-font-display); font-weight: 400; font-size: 1.25rem; letter-spacing: -0.012em; } .m-section__body { padding: var(--m-space-5); display: grid; gap: var(--m-space-4); } .m-field-row { display: grid; grid-template-columns: 240px minmax(0, 1fr); align-items: start; gap: var(--m-space-4); } @media (max-width: 720px) { .m-field-row { grid-template-columns: 1fr; } } .m-field-row__hint { font-family: var(--m-font-mono); font-size: 0.75rem; color: var(--m-c-ink-soft); line-height: 1.4; } /* =================================================================== Anomaly badge — load-bearing for Phase 7 =================================================================== */ .m-anomaly { display: inline-flex; align-items: center; gap: var(--m-space-2); padding: 2px 8px; background: rgba(220, 38, 38, 0.10); color: var(--m-c-anomaly); border: 1px solid currentColor; border-radius: var(--m-radius-xs); font-family: var(--m-font-mono); font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.14em; } .m-anomaly__pulse { width: 6px; height: 6px; background: currentColor; border-radius: 50%; animation: m-pulse 1.6s ease-in-out infinite; } @keyframes m-pulse { 0%, 100% { opacity: 0.4; transform: scale(1); } 50% { opacity: 1; transform: scale(1.2); } } @media (prefers-reduced-motion: reduce) { .m-anomaly__pulse { animation: none; opacity: 1; } }