/* ===================================================================
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; }
}