:root {
  --ink: #0a0d10;
  --surface: #12161b;
  --surface-raised: #1a2027;
  --surface-hover: #212832;
  --surface-2: #171c22;
  --line: #232b33;
  --line-soft: #1a2027;
  --text-primary: #edf1f4;
  --text-secondary: #8b96a3;
  --text-tertiary: #7a8593;
  /* Secondary text that must still read at a glance (menu labels, card facts):
     --text-secondary/-tertiary are for hints and are too dim for that. */
  --text-soft: #c3ccd6;
  --accent: #00e676;
  --accent-strong: #2bff97;
  --accent-soft: rgba(0, 230, 118, 0.12);
  --accent-line: rgba(0, 230, 118, 0.35);
  --violet: #8b7bff;
  --violet-soft: rgba(139, 123, 255, 0.14);
  --purple: #b57bff;
  --amber: #f5a623;
  --amber-soft: rgba(245, 166, 35, 0.1);
  --critical: #ff5470;
  --critical-soft: rgba(255, 84, 112, 0.1);
  --gold: #ffc94a;
  --gold-soft: rgba(255, 201, 74, 0.12);
  --silver: #c9d3dc;
  --silver-soft: rgba(201, 211, 220, 0.1);
  --bronze: #d68a56;
  --bronze-soft: rgba(214, 138, 86, 0.12);
  --paper: #f4f2ee;
  --paper-raised: #ffffff;
  --paper-line: #e4e0d8;
  --paper-text: #1c1a17;
  --paper-text-2: #6b665c;
  --radius-md: 10px;
  --radius-lg: 16px;
  --font-display: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SF Mono", "SFMono-Regular", "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;

  /* Aurora borealis accents — atmosphere + data-viz only, never buttons/CTAs */
  --aurora-green: #00e676;
  --aurora-teal: #16e8b0;
  --aurora-cyan: #2fc7ff;
  --aurora-violet: #8b7bff;
  --aurora-magenta: #d66bff;
  --aurora-red: #ff5470;
  --aurora-amber: #f5a623;

  /* Lap-comparison chart identity, fixed order, never cycled -- validated
     as a set (not theme-adaptive, same as the aurora-* accents above),
     checked with --pairs all since any two lap traces can sit next to each
     other anywhere on the track map. Slots 1-4 clear the full CVD target
     (worst pair ΔE >= 11.3) and the normal-vision floor (worst pair
     ΔE >= 20). Slot 5 (amber) still clears the normal-vision floor (worst
     pair ΔE 20.0, green<->violet) but only reaches the CVD *floor* band
     against green (ΔE 6.9 deutan, vs. the usual >= 8 target) -- legal per
     the palette method only because it ships with secondary encoding
     (every highlighted lap already gets a legend chip and a "Vuelta N"
     tooltip label, not color alone). A 6th slot has no such near-miss
     candidate left, so a 6th+ compared lap is drawn as unstyled background
     context instead of a new hue (see telemetry_session_detail.html). */
  --lap-color-1: var(--aurora-green);
  --lap-color-2: var(--aurora-cyan);
  --lap-color-3: var(--aurora-violet);
  --lap-color-4: var(--aurora-red);
  --lap-color-5: var(--aurora-amber);

  /* Outer halo for the small moving markers (.chart-hover-dot,
     .track-map-start). Those already carry an --ink ring, which separates them
     from the background but not from the bright lap-coloured line they travel
     along -- and on lap 1 the dot and its line are the same --aurora-green, so
     the dot disappears into it. The fill has to stay the lap's own colour (that
     is what ties the dot to its lap), so the contrast has to come from outside.
     Flips with the theme, like --ink itself. */
  --marker-halo: rgba(255, 255, 255, 0.85);

  /* Dark radial-gradient falloff behind hero/page-head sections */
  --bg-glow: #101820;
  --glow-opacity: 0.5;
  --glow-blend: screen;

  /* Card surface gradient end-stop, and hover border for interactive edges */
  --card-gradient-end: #10141a;
  --line-hover: #333d49;

  /* Translucent sticky topbar/toolbar backdrop */
  --glass-bg: rgba(10, 13, 16, 0.85);
}

/* Light theme — toggled via the floating button, persisted in localStorage.
   Structural + semantic tokens only; every page reads through these instead
   of hardcoding colors, so the toggle works everywhere without per-page CSS. */
:root[data-theme="light"] {
  --ink: #f5f3ee;
  /* Inverted with --ink: on a light ground the marker's ring is pale, so its
     halo has to be the dark one. */
  --marker-halo: rgba(10, 13, 16, 0.55);
  --surface: #ffffff;
  --surface-raised: #fbfaf7;
  --surface-hover: #efece3;
  --surface-2: #f1efe7;
  --line: #e2ded2;
  --line-soft: #ece9df;
  --text-primary: #1c1a17;
  --text-secondary: #6b665c;
  --text-tertiary: #706a5c;
  --text-soft: #4a463f;

  --accent: #078a53;
  --accent-strong: #06a862;
  --accent-soft: rgba(7, 138, 83, 0.1);
  --accent-line: rgba(7, 138, 83, 0.32);

  --violet: #6a58e0;
  --violet-soft: rgba(106, 88, 224, 0.1);
  --purple: #8347d6;
  --amber: #b06a0c;
  --amber-soft: rgba(176, 106, 12, 0.1);
  --critical: #d13a5c;
  --critical-soft: rgba(209, 58, 92, 0.1);

  --gold: #9c7213;
  --gold-soft: rgba(156, 114, 19, 0.12);
  --silver: #6c7480;
  --silver-soft: rgba(108, 116, 128, 0.1);
  --bronze: #9c5527;
  --bronze-soft: rgba(156, 85, 39, 0.12);

  --bg-glow: #ffffff;
  --glow-opacity: 0.22;
  --glow-blend: multiply;

  --card-gradient-end: #f1efe7;
  --line-hover: #c9c2af;

  --glass-bg: rgba(255, 255, 255, 0.82);
}

/* Atmospheric aurora glow — drop as the first child of a
   `position:relative; overflow:hidden; isolation:isolate` container. */
.aurora-glow {
  position: absolute;
  inset: -20%;
  z-index: -1;
  filter: blur(60px);
  opacity: var(--glow-opacity);
  pointer-events: none;
  background:
    radial-gradient(closest-side, var(--aurora-green), transparent 70%) 15% 20% / 55% 65% no-repeat,
    radial-gradient(closest-side, var(--aurora-teal), transparent 70%) 45% 0% / 50% 60% no-repeat,
    radial-gradient(closest-side, var(--aurora-violet), transparent 70%) 75% 30% / 55% 65% no-repeat,
    radial-gradient(closest-side, var(--aurora-magenta), transparent 70%) 60% 60% / 45% 55% no-repeat;
  mix-blend-mode: var(--glow-blend);
  animation: aurora-drift 18s ease-in-out infinite alternate;
}
@keyframes aurora-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(2%, -3%, 0) scale(1.08); }
}
@media (prefers-reduced-motion: reduce) {
  .aurora-glow { animation: none; }
}

/* Full-bleed background stack: the aurora gradient alone, or a looping
   video over it when settings.LANDING_HERO_VIDEO_URL is configured (see
   core.context_processors.hero_background). Originated on the landing
   page (core/templates/core/pilot_directory.html) and shared here so any
   page can drop in the same three-`<div>` markup that template uses --
   see login.html for a second page doing exactly that.

   Fixed rather than absolute: intended as a whole-page background, so
   fixed keeps it steady behind a page's own topbar/nav too, reading as
   full-bleed instead of starting below a header band. */
.hero-bg {
  position: fixed; inset: 0; z-index: 0; overflow: hidden;
  background-color: var(--ink);
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
/* .aurora-glow normally sits at z-index:-1 so it can hide behind its
   container's own background; here it IS the fallback background, so it
   has to come forward. It stays under the video when there is one. */
.hero-bg .aurora-glow { z-index: 0; opacity: 0.55; }
.hero-video {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 1;
}
/* Two strengths. The gradient fallback is already dark and even, so it only
   needs a light wash -- going heavier there just muddies it. Real footage is
   bright and busy, so `.has-media` (set by the template whenever a video or
   poster is configured) steps the whole scrim up; measured against an actual
   race photo, small text over it was illegible at the lighter setting. */
.hero-scrim {
  position: absolute; inset: 0; z-index: 2;
  background:
    linear-gradient(180deg, rgba(10,13,16,0.82) 0%, rgba(10,13,16,0.42) 30%, rgba(10,13,16,0.42) 62%, rgba(10,13,16,0.88) 100%);
}
.hero-bg.has-media .hero-scrim {
  background:
    linear-gradient(180deg, rgba(10,13,16,0.9) 0%, rgba(10,13,16,0.62) 26%, rgba(10,13,16,0.66) 58%, rgba(10,13,16,0.94) 100%);
}
:root[data-theme="light"] .hero-scrim {
  background:
    linear-gradient(180deg, rgba(245,243,238,0.86) 0%, rgba(245,243,238,0.55) 30%, rgba(245,243,238,0.55) 62%, rgba(245,243,238,0.9) 100%);
}
:root[data-theme="light"] .hero-bg.has-media .hero-scrim {
  background:
    linear-gradient(180deg, rgba(245,243,238,0.92) 0%, rgba(245,243,238,0.74) 26%, rgba(245,243,238,0.78) 58%, rgba(245,243,238,0.95) 100%);
}
@media (prefers-reduced-motion: reduce) {
  /* Hiding the element rather than pausing it: the poster is set as the
     container's background too, so this still lands on the intended still
     frame instead of a blank box. (.aurora-glow's own animation is already
     turned off above.) */
  .hero-video { display: none; }
}

/* Gradient-border ring — add alongside a badge class that already sets
   border-radius; leaves the badge's own background/color untouched. */
.aurora-ring {
  position: relative;
  border-color: transparent;
  background-clip: padding-box;
}
.aurora-ring::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(120deg, var(--aurora-green), var(--aurora-cyan), var(--aurora-violet));
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* Native widgets (scrollbars, the open <select> list, date pickers, unstyled
   checkboxes) follow the theme instead of staying browser-white. */
:root { color-scheme: dark; }
:root[data-theme="light"] { color-scheme: light; }

* { box-sizing: border-box; }
html, body { height: 100%; }
/* The canvas colour is set on <html> itself, not left to body's background propagating to it: body is only one
   viewport tall (height:100% above) and anything past that rendered on a different shade -- the band that
   looked like stacked pages. */
html { background: var(--ink); }
/* <main> paints the page colour too: with the aurora animating inside, Chrome rasterises it on its own layer and
   its box showed as a lighter block against the canvas (seen on /galeria/ and /dashboard/). */
main#contenido { background: var(--ink); }
/* The page base -- colours, type, glow. It lives here, not in each page's own
   stylesheet, because a page that links none of those (or the wrong one) came
   out white with the browser's serif: Fotógrafo, Mis fotos, the "coming soon"
   page. Page stylesheets may still override it for a special layout. */
body {
  margin: 0;
  /* no-repeat + fixed: html/body are height:100%, so the gradient's box is one
     viewport tall and would otherwise tile again every screen of scrolling. */
  background: var(--ink);
  color: var(--text-primary);
  font-family: var(--font-display);
  -webkit-font-smoothing: antialiased;
  font-size: 15px;
  line-height: 1.5;
}

h1, h2, h3 { margin: 0; text-wrap: balance; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; border: none; background: none; color: inherit; }
button:focus-visible, a:focus-visible, input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}
.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* Floating theme toggle — added once in base.html, present on every page. */
.theme-toggle {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 100;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  color: var(--text-secondary);
  display: grid;
  place-items: center;
  box-shadow: 0 8px 22px -8px rgba(0, 0, 0, 0.5);
  transition: color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.theme-toggle:hover { color: var(--text-primary); border-color: #333d49; transform: translateY(-1px); }
.theme-toggle svg { grid-area: 1 / 1; width: 18px; height: 18px; }
.theme-toggle .icon-sun { display: none; }
:root[data-theme="light"] .theme-toggle .icon-sun { display: block; }
:root[data-theme="light"] .theme-toggle .icon-moon { display: none; }
