/* Tokens, themes, fonts, and global element defaults. Loaded first. */
/* The site's four families, declared here because every stylesheet below uses them.
   They used to live in landing.css, which worked only because base.html loads all of
   these on every page -- the moment anything loaded per-page instead, every page but
   the landing would have fallen back to system sans. */
@font-face {
  font-family: 'Rajdhani';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/rajdhani-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Staatliches';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/staatliches-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/worksans-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('../fonts/worksans-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/worksans-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Work Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/worksans-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/spacemono-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/spacemono-700.woff2') format('woff2');
}

:root {
  color-scheme: light;
  /* Moss Line default palette -- 2026-09-15 repaint: warm paper/cream reading surfaces,
     evergreen structure, orange focus/primary-action accent. Role -> token mapping:
     Ink -> --text, Pine -> --panel-2, Moss -> --accent-dim, Paper -> --panel,
     Cream -> --bg, Orange -> --accent, Yellow -> --pop, Muted green-gray -> --muted,
     Danger red -> --error. The three alternate presets below (ember/blue/dark) are
     dark looks a user can opt into -- redesigned 2026-09-17 to each read cleanly on
     their own terms (see the per-theme comments below), not reflow this default. */
  --bg: #e7dfcd;
  --bg-2: #ddd3bd;
  --panel: #f5f1e7;
  --panel-2: #203a2d;
  --seam: rgba(24,39,30,0.14);
  /* A solid, quiet rule for long reading collections.  --seam remains useful for
     very soft component edges; use --divider where scan order depends on the line. */
  --divider: #aeb9a4;
  --text: #18271e;
  /* Every color below is darkened from its literal mockup value where needed to clear
     4.5:1 text contrast against --bg/--panel -- the mockup names the *role*, not a
     pixel-exact hex, as the durable decision. */
  --muted: #4d5951;
  --accent: #a34817;
  --accent-hover: #b8551f;
  --action: #e2874b;
  --action-hover: #eb9a68;
  --action-contrast: var(--text);
  /* Informational ride/state accent. Separate from orange links and buttons so a
     calendar entry never masquerades as an action. */
  --event: #8a611f;
  --event-contrast: #fbf7ee;
  --accent-dim: #58724e;
  /* Warm paper tone reads on the darkened --accent/--accent-hover fills above -- a dark
     ink-colored label does not, once accent itself is dark enough to work as text. */
  --accent-contrast: #fbf7ee;
  --error: #9d473b;
  --success: #2f6b45;
  /* Secondary highlight color for stamps and headings. */
  --pop: #7d5a13;
  --pop-dim: #8a6b1f;
  /* Form-field surface -- distinct from --panel so a bordered field reads as an input,
     not another card, against the paper background. */
  --field-bg: #fbf9f3;
  /* Diagonal background texture line color -- ink-tinted on the light default, white on
     the dark alternate presets below. */
  /* A trace drawn on the dark --panel-2 surface (currently the elevation profile). Its
     own token because the right colour is a different one per preset: --accent is the
     bright hue on the three dark presets, but on this light one --accent is the dark rust
     and measures ~2:1 against pine green, so the warm --action carries it instead. Every
     preset below is >= 4.5:1 on its own --panel-2. */
  --chart-line: var(--action);
}

/* Theme presets replace the full palette; Moss Line is the default. Each must define the
   complete token set, including --field-bg added in the 2026-09-15 repaint
   above -- a user theme preset must define the complete token set.

   2026-09-17 redesign: these three were carried over from before the 2026-09-15 repaint
   with only enough patching to not break (new tokens copied from old --accent, no
   contrast pass). That silently miscolored two things sitewide, not just per-theme
   preference: --action/--action-contrast double as both the button-on-fill pair AND the
   plain h2 heading color (components.css's h2 has no background of its own), so an
   old near-black --action-contrast rendered every h2 almost invisibly against these
   near-black panels; and --error/--success were never redefined at all here, so all
   three dark presets were silently inheriting Moss Line's cream-tuned reds/greens meant
   for a light background. Both are fixed below, alongside genuinely distinct per-theme
   identities instead of three variations on the same orange.

   Every dark theme below reuses one mechanism to solve the h2 problem: --action-contrast
   and --accent-contrast are both `var(--text)` -- the same light ink used for body text --
   never a hardcoded near-black. That only works if --action itself is darkened enough
   for light text to sit on it: each --action below was chosen to clear 4.5:1 against its
   own --text (the WCAG AA bar for normal text, since button labels aren't reliably large/
   bold enough to claim the 3:1 large-text exception -- see 2026-09-21 contrast audit)
   while still reading as a distinct, on-brand fill, so --action is noticeably deeper/more muted
   than --accent in every preset here, not a copy of it. --accent-dim is chosen as a
   distinct structural hue per theme (mirroring Moss Line's own accent=orange/
   accent-dim=moss-green split above), not just a darkened --accent, both for its own
   subtle-border role and so route_map.js's 4-color palette (--accent/--pop/--accent-dim/
   --error) stays visually distinct per file. */
[data-theme="ember"] {
  /* Campfire coal: warm near-black, orange links, and a genuinely deeper burnt-rust
     button fill (not a copy of --accent) so `var(--text)` reads on it. Pop stays the
     bright campfire yellow -- distinct from both oranges. Structural accent-dim moves to
     a muted rust-brown, letting route lines/borders read as "ember embers", not identical
     shades of the same orange. */
  color-scheme: dark;
  --bg: #15130f;
  --bg-2: #1a1712;
  --panel: #1e1a16;
  --panel-2: #241f19;
  --seam: rgba(255,255,255,0.08);
  --divider: #5b5147;
  --text: #f0ece6;
  --muted: #a89c8f;
  --accent: #e2793d;
  --accent-hover: #ec8b54;
  --action: #ab511f;
  --action-hover: #d66c2c;
  --action-contrast: var(--text);
  --event: #c99a42;
  --event-contrast: #1a1406;
  --accent-dim: #6e4020;
  --accent-contrast: var(--text);
  --error: #e05244;
  --success: #7fae5c;
  --pop: #f2c94c;
  --pop-dim: #8a6b1f;
  --field-bg: #100c08;
  --chart-line: var(--accent);
}

[data-theme="blue"] {
  /* Harbor: deep navy dusk, a lighthouse-lamp blue for links, and a darker harbor-water
     blue for button fills so light text reads on them. Pop stays the amber harbor-light
     (blue's complement). Structural accent-dim moves to a deep pier teal instead of a
     darker blue, so it doesn't just look like a third shade of the same accent. */
  color-scheme: dark;
  --bg: #0c131a;
  --bg-2: #101c26;
  --panel: #16212c;
  --panel-2: #1c2a38;
  --seam: rgba(255,255,255,0.09);
  --divider: #4b6372;
  --text: #e8eef3;
  --muted: #8ea3b5;
  --accent: #4db3e8;
  --accent-hover: #64c0ec;
  --action: #20739a;
  --action-hover: #3993bd;
  --action-contrast: var(--text);
  --event: #b78a3f;
  --event-contrast: #04121a;
  --accent-dim: #1f5d52;
  --accent-contrast: var(--text);
  --error: #e2634f;
  --success: #4fae82;
  --pop: #e8a33d;
  --pop-dim: #8a611f;
  --field-bg: #08131a;
  --chart-line: var(--accent);
}

[data-theme="dark"] {
  /* True black, and now its own graphic identity instead of a blacker copy of Ember's
     orange: a stark electric cyan for links, dimmed to a deep teal for button fills so
     light text reads on them, and a hot-magenta pop for a genuinely second hue (not a
     yellow next to another warm tone). Structural accent-dim goes to a deep indigo --
     with cyan accent, magenta pop and indigo structure this reads as a distinct
     "graphic/neon" mode, and gives route_map.js four clearly separable hues. */
  color-scheme: dark;
  --bg: #0a0a0a;
  --bg-2: #121212;
  --panel: #161616;
  --panel-2: #1d1d1d;
  --seam: rgba(255,255,255,0.08);
  --divider: #555555;
  --text: #f2f2f0;
  --muted: #999999;
  --accent: #2dd4bf;
  --accent-hover: #5ee4d1;
  --action: #1a7c6d;
  --action-hover: #26a68f;
  --action-contrast: var(--text);
  --event: #d9a441;
  --event-contrast: #100b02;
  --accent-dim: #4c3a8a;
  --accent-contrast: var(--text);
  --error: #f24444;
  --success: #4ade80;
  --pop: #f472b6;
  --pop-dim: #99315f;
  --field-bg: #050505;
  --chart-line: var(--accent);
}

* {
  box-sizing: border-box;
}

html {
  overflow-x: hidden;
  /* Without this, a page tall enough to need a vertical scrollbar has ~15px less
     width to center content in than a short page that doesn't -- every margin:auto
     element (.nav, main, ...) shifts a few px depending on whether that specific
     page's content happens to scroll, so the nav bar visibly moved between e.g. the
     landing page (scrolls) and a short auth page (doesn't). Reserving the gutter on
     every page, scrolling or not, keeps centering identical site-wide. */
  scrollbar-gutter: stable;
}

/* Every <details> disclosure toggle on the site hides the native marker and uses its
   own indicator/treatment instead -- shared here instead of repeated per component
   (nav account menu, discussion reply/post menus, auth help,
   footer contact). Each still sets its own font/color/spacing on top of this.
   .details-summary (Events detail page, see events.css) is the one deliberate
   exception -- it keeps the native browser triangle instead. */
summary:not(.details-summary) {
  cursor: pointer;
  list-style: none;
}
summary:not(.details-summary)::-webkit-details-marker {
  display: none;
}

body {
  margin: 0;
  min-height: 100vh;
  max-width: 100vw;
  overflow-x: hidden;
  background: var(--bg);
  background-image:
    radial-gradient(ellipse 900px 480px at 18% -8%, color-mix(in srgb, var(--accent-dim) 9%, transparent), transparent 60%);
  background-attachment: fixed;
  color: var(--text);
  font-family: 'Space Mono', 'Work Sans', ui-monospace, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

/* Keep the corner glow subtle on narrow screens. */
@media (max-width: 640px) {
  body {
    background-image:
      radial-gradient(ellipse 520px 320px at 18% -8%, color-mix(in srgb, var(--accent-dim) 7%, transparent), transparent 60%);
  }
}

img, video {
  max-width: 100%;
  height: auto;
}

/* Shared visible-keyboard-focus primitive -- a highly visible outline, not a subtle glow,
   so focus reads the same on dark/light/image-adjacent surfaces. Deliberately :focus-visible
   (not :focus) so it shows for keyboard navigation without adding a ring to every mouse
   click. Component-specific rules (e.g. input's border-color change) may add to this, not
   replace it. */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}

/* Default: any link is visually distinct (accent color) from static text.
   Component-specific overrides below must not fight this — buttons and links must
   look obviously clickable. */
/* Base link rule. landing.css intentionally overrides it inside .moss-line. */
a {
  color: var(--accent);
  text-decoration: none;
}

/* Links are uppercase labels; nested prose is reset below. */
a:not(.btn) {
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

a:hover, a:focus-visible {
  text-decoration: underline;
}

/* A linked section heading ("Latest Videos" etc.) should read the same as a plain one
   ("Rides") -- only the global `a { color: var(--accent) }` rule made them diverge. */
h2 a {
  color: inherit;
}

/* Every server-rendered timestamp ([data-timestamp], see relative_time.js) reads as a
   digital-readout mono figure sitewide, not just on the landing page. */
[data-timestamp] {
  font-family: 'Space Mono', ui-monospace, monospace;
  font-variant-numeric: tabular-nums;
}
