/* ============================================================================
   B7 Tracker — elev.css
   Owner: elevation module (public/js/elev.js).

   Styles ONLY the inside of #elev. The strip's own box, height and position
   belong to base.css; nothing here touches #elev itself.

   Everything consumes the tokens from base.css — no token is redefined.

   State classes elev.js puts on .ev (the module root):
     .is-ready    course geometry has been laid out; the chart is visible
     .is-compact  short strip (mobile) — smaller type, two gridlines
     .is-narrow   < 340 px wide — the right-hand readout drops its ascent chip
     .is-scrub    the reader is dragging along the profile
     .has-rp      there is a trail to replay, so the transport is shown
     .is-rp-on    the replay is armed (playing or paused)
     .is-playing  the animation is running
   .is-narrow and .is-scrub are deliberately unstyled: the narrow readout is
   thinned in JS (it changes content, not just looks) and scrubbing already
   reads through .ev-racer.is-dim. They stay on the DOM as debugging state.

   And on .ev-head:
     .is-rp       the band is showing the replay readout
     .is-proj     that readout is a projection, not something that happened

   The SVG uses two kinds of sizing on purpose:
     * geometry (x/y/width/r/stroke widths) is authored in user units, which
       equal CSS pixels because elev.js keeps viewBox === the measured box;
     * font-size for grid and checkpoint labels is set from JS as an SVG
       presentation attribute, so it can follow the compact/tall layout. It is
       deliberately NOT set here — a CSS rule would override the attribute and
       break the label-width measurements.
   ========================================================================= */


/* ============================================================================
   1. SHELL
   ========================================================================= */

#elev .ev {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  overflow: hidden;
  background: var(--bg-2);
}

/* The profile only appears once the course geometry has been laid out, so a
   half-built chart never flashes on screen. */
#elev .ev-svg,
#elev .ev-head {
  visibility: hidden;
}
#elev .ev.is-ready .ev-svg,
#elev .ev.is-ready .ev-head {
  visibility: visible;
}

#elev .ev-svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Loading / unavailable state. */
#elev .ev-empty {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-3);
  color: var(--fg-3);
  font-family: var(--font-sans);
  font-size: var(--fs-2);
  text-align: center;
}


/* ============================================================================
   2. READOUT BAND (HTML overlay across the top of the strip)
   Height is set from JS so it matches the plot's top padding exactly.
   Monospaced with tabular figures: the numbers must not jitter while the
   reader drags a finger along the profile.
   ========================================================================= */

#elev .ev-head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding-left: calc(var(--s-3) + env(safe-area-inset-left, 0px));
  padding-right: calc(var(--s-3) + env(safe-area-inset-right, 0px));
  overflow: hidden;
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--fg-3);
  pointer-events: none;
  transition: height var(--dur) ease;
}
#elev .ev:not(.is-compact) .ev-head { font-size: 13px; }

#elev .ev-row {
  display: flex;
  align-items: baseline;
  min-width: 0;
  white-space: nowrap;
}
#elev .ev-row-l { flex: 0 0 auto; }
#elev .ev-row-r {
  flex: 0 1 auto;
  overflow: hidden;
  /* Keeps clear of the replay transport floating in the same corner. */
  padding-right: var(--ev-ctl-w, 0px);
}

#elev .ev-sep {
  margin: 0 5px;
  color: var(--fg-3);
  opacity: .45;
}

#elev .ev-s { color: var(--fg-2); }

/* Leading value: the racer's / cursor's distance. */
#elev .ev-s.v   { font-weight: 700; }
#elev .ev-s.pos { color: var(--accent-2); }
#elev .ev-s.cur { color: var(--fg); }
#elev .ev-s.rem { color: var(--fg-2); }
#elev .ev-s.asc { color: var(--fg-2); }
#elev .ev-s.ok  { color: var(--ok); font-weight: 700; }

/* Gradient severity at the cursor. */
#elev .ev-s.g.up { color: var(--warn); }
#elev .ev-s.g.dn { color: var(--info); }

/* Static caption used before there is any racer data. */
#elev .ev-s.k {
  color: var(--fg-3);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* A small accent dot ties the readout to the marker on the profile. */
#elev .ev-s.pos::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 6px;
  border-radius: var(--r-full);
  background: var(--accent);
  vertical-align: baseline;
}


/* ============================================================================
   2b. REPLAY READOUT
   The same band, taken over while a replay sample is on screen. Wide strips
   keep it on one dense line; narrow ones split it in two and the band grows
   into the chart, so it is given a solid ground and a hairline to sit on.
   ========================================================================= */

#elev .ev-rp { display: none; }

#elev .ev-head.is-rp {
  align-items: stretch;
  background: var(--bg-2);
  box-shadow: 0 1px 0 var(--line);
}
#elev .ev-head.is-rp .ev-row-l,
#elev .ev-head.is-rp .ev-row-r { display: none; }

#elev .ev-head.is-rp .ev-rp {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  min-width: 0;
}

/* The transport floats over the right end of the band; every readout stops
   short of it instead of sliding underneath. */
#elev .ev-rp-1,
#elev .ev-rp-2 {
  padding-right: var(--ev-ctl-w, 0px);
  overflow: hidden;
}

/* Second line: the terrain and the effort, one notch quieter than the clock. */
#elev .ev-rp-2 {
  font-size: 0.92em;
  color: var(--fg-3);
}

/* Tighter than the live readout — this row carries twice as many values. */
#elev .ev-rp .ev-sep { margin: 0 4px; }

#elev .ev-s.el   { color: var(--fg-2); }
#elev .ev-s.km   { color: var(--accent-2); }
#elev .ev-s.pace { color: var(--fg-2); }

/* Projection: a different colour, a "~" on the value and the word for it, so
   nothing here can be mistaken for something that actually happened. */
#elev .ev-s.eta  { color: var(--warn); }
#elev .ev-s.proj {
  color: var(--warn);
  opacity: .9;
}
#elev .ev-head.is-proj .ev-s.v.eta { font-weight: 700; }


/* ============================================================================
   2c. REPLAY TRANSPORT
   A floating control cluster in the top-right corner — over open sky, since
   the course ends low and the right edge of the chart is empty there.
   ========================================================================= */

#elev .ev-ctl {
  position: absolute;
  top: 5px;
  right: calc(var(--s-2) + env(safe-area-inset-right, 0px));
  z-index: 3;
  display: none;
  align-items: center;
  gap: var(--s-1);
}
#elev .ev.has-rp.is-ready .ev-ctl { display: flex; }

/* Speed and the way back to live only exist once the replay is armed. */
#elev .ev:not(.is-rp-on) .ev-speed,
#elev .ev:not(.is-rp-on) .ev-live { display: none; }

/* Dense-toolbar padding: the band is only ~30 px of clear space, and every
   pixel the transport gives back is a pixel of readout. The 36 px tap target
   from .btn.sm is untouched. */
#elev .ev-ctl .btn {
  box-shadow: var(--shadow-1);
  padding: 0 var(--s-2);
  gap: var(--s-1);
}
#elev .ev-ctl .btn.icon { padding: 0; }
#elev .ev-speed { font-variant-numeric: tabular-nums; }

#elev .ev-ic {
  display: block;
  width: 16px;
  height: 16px;
  fill: currentColor;
}
#elev .ev-ic-pause { display: none; }
#elev .ev.is-playing .ev-ic-play { display: none; }
#elev .ev.is-playing .ev-ic-pause { display: block; }

/* Scrubbing is the point of the strip while the replay is armed. */
#elev .ev.is-rp-on .ev-hit { cursor: ew-resize; }


/* ============================================================================
   3. PROFILE — grid, area, ridge line
   ========================================================================= */

/* Gridlines are painted beneath the filled area, so they only ever show in
   the empty sky above the ridge. */
#elev .ev-gline {
  stroke: var(--line-strong);
  stroke-width: 1;
  stroke-opacity: .55;
  shape-rendering: crispEdges;
}
#elev .ev-glab {
  fill: var(--fg-3);
  font-family: var(--font-mono);
  font-weight: 600;
  stroke: var(--bg-2);
  stroke-width: 3;
  stroke-linejoin: round;
  paint-order: stroke fill;
}

#elev .ev-area { stroke: none; }
#elev .ev-area.ev-todo { fill: var(--fg-3); fill-opacity: .15; }
#elev .ev-area.ev-done { fill: var(--accent); fill-opacity: .32; }

#elev .ev-line {
  fill: none;
  stroke-linejoin: round;
  stroke-linecap: round;
}
#elev .ev-line.ev-todo {
  stroke: var(--fg-3);
  stroke-width: 1.4;
  stroke-opacity: .85;
}
#elev .ev-line.ev-done {
  stroke: var(--accent-2);
  stroke-width: 2;
}
#elev .ev:not(.is-compact) .ev-line.ev-done { stroke-width: 2.25; }


/* ============================================================================
   4. GRADIENT SEVERITY SHADING
   Vertical bars clipped to the filled area. Climbs lighten, descents cool.
   Deliberately faint: it should read as texture, never as another data series.
   ========================================================================= */

#elev .ev-st { stroke: none; }
#elev .ev-st-up { fill: var(--fg); }
#elev .ev-st-dn { fill: var(--info); }

#elev .ev-st-l0 { fill-opacity: .045; }
#elev .ev-st-l1 { fill-opacity: .075; }
#elev .ev-st-l2 { fill-opacity: .105; }
#elev .ev-st-l3 { fill-opacity: .14; }

#elev .ev-st-dn.ev-st-l0 { fill-opacity: .05; }
#elev .ev-st-dn.ev-st-l1 { fill-opacity: .07; }
#elev .ev-st-dn.ev-st-l2 { fill-opacity: .09; }
#elev .ev-st-dn.ev-st-l3 { fill-opacity: .115; }


/* ============================================================================
   5. CHECKPOINTS
   ========================================================================= */

#elev .ev-guide {
  stroke: var(--fg);
  stroke-width: 1;
  stroke-opacity: .07;
  shape-rendering: crispEdges;
}

#elev .ev-tick {
  stroke: var(--fg-3);
  stroke-width: 1.4;
  stroke-linecap: round;
}
#elev .ev-tick.is-major { stroke-width: 2; }
#elev .ev-tick.is-done  { stroke: var(--accent); }
#elev .ev-tick.is-next  { stroke: var(--fg); }

#elev .ev-cplab {
  fill: var(--fg-3);
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: .01em;
}
#elev .ev-cplab.is-major { fill: var(--fg-2); font-weight: 700; }
#elev .ev-cplab.is-done  { fill: var(--accent); }
#elev .ev-cplab.is-major.is-done { fill: var(--accent-2); }
#elev .ev-cplab.is-next  { fill: var(--fg); font-weight: 700; }

/* Off-screen width probe. Always measured at the heaviest weight a label can
   use, so placement reserves slightly too much space rather than too little. */
#elev .ev-measure {
  font-weight: 700;
  pointer-events: none;
}


/* ============================================================================
   6. RACER MARKER
   ========================================================================= */

#elev .ev-rline {
  stroke: var(--accent);
  stroke-width: 1.5;
  stroke-opacity: .45;
}
#elev .ev-rhalo {
  fill: var(--accent);
  fill-opacity: .22;
}
#elev .ev-rdot {
  fill: var(--accent);
  stroke: var(--bg);
  stroke-width: 2;
}

#elev .ev-pill-r { fill: var(--accent); }
#elev .ev-pilltx-r {
  fill: var(--on-accent);
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Dimmed while the reader is scrubbing somewhere else on the profile. */
#elev .ev-racer {
  transition: opacity var(--dur) ease;
}
#elev .ev-racer.is-dim { opacity: .45; }

/* Dead tracker battery / lost fix. */
#elev .ev-racer.is-lost .ev-rdot  { fill: var(--warn); }
#elev .ev-racer.is-lost .ev-rhalo { fill: var(--warn); }
#elev .ev-racer.is-lost .ev-rline { stroke: var(--warn); }
#elev .ev-racer.is-lost .ev-pill-r { fill: var(--warn); }

/* Finished. */
#elev .ev-racer.is-done .ev-rdot   { fill: var(--ok); }
#elev .ev-racer.is-done .ev-rhalo  { fill: var(--ok); }
#elev .ev-racer.is-done .ev-rline  { stroke: var(--ok); }
#elev .ev-racer.is-done .ev-pill-r { fill: var(--ok); }


/* ============================================================================
   7. SCRUB CURSOR
   ========================================================================= */

#elev .ev-cline {
  stroke: var(--fg);
  stroke-width: 1;
  stroke-opacity: .8;
  stroke-dasharray: 2 3;
}
#elev .ev-cdot {
  fill: var(--fg);
  stroke: var(--bg);
  stroke-width: 2;
}
#elev .ev-pill-c {
  fill: var(--surface-2);
  stroke: var(--line-strong);
  stroke-width: 1;
}
#elev .ev-pilltx-c {
  fill: var(--fg);
  font-family: var(--font-mono);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Scrubbed past where he has actually run: everything switches to the
   projection colour and a finer dash, matching the readout. */
#elev .ev-cursor.is-proj .ev-cline {
  stroke: var(--warn);
  stroke-dasharray: 1 4;
  stroke-opacity: .9;
}
#elev .ev-cursor.is-proj .ev-cdot { fill: var(--warn); }
#elev .ev-cursor.is-proj .ev-pill-c {
  fill: var(--bg-3);
  stroke: var(--warn);
}
#elev .ev-cursor.is-proj .ev-pilltx-c { fill: var(--warn); }


/* ============================================================================
   8. INPUT SURFACE
   Covers the whole strip. `touch-action: pan-y` is the key line: a vertical
   swipe still scrolls the page, while a horizontal drag is delivered to us as
   pointer events for scrubbing.
   ========================================================================= */

#elev .ev-hit {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  touch-action: pan-y;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  cursor: crosshair;
}
@media (hover: none) {
  #elev .ev-hit { cursor: default; }
}
#elev .ev-hit:focus { outline: none; }
#elev .ev-hit:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -3px;
}


/* ============================================================================
   9. MOTION
   Nothing here animates geometry; the only transition is the marker's dim.
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
  #elev .ev-racer,
  #elev .ev-head { transition: none; }
}
