:root {
  --bg: #0d1117;
  --bg-card: #161b22;
  --bg-soft: #1c232c;
  --line: #2a323d;
  --fg: #e6edf3;
  --fg-dim: #8b98a5;
  --accent: #4cc9a0;
  --accent-dim: #2f8f72;
  --warn: #f0a44a;
  --danger: #e5534b;
  --work: #4cc9a0;
  --rest: #58a6ff;
  --radius: 14px;
  --pad: 14px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-text-size-adjust: 100%;
}

body {
  padding-bottom: calc(64px + env(safe-area-inset-bottom));
}

.app-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px var(--pad);
  background: rgba(13, 17, 23, .92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.app-header h1 { margin: 0; font-size: 17px; letter-spacing: .2px; }

.badge {
  font-size: 11px;
  color: var(--fg-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px 9px;
  white-space: nowrap;
}

main { padding: var(--pad); max-width: 760px; margin: 0 auto; }

.view { display: flex; flex-direction: column; gap: 14px; }
[hidden] { display: none !important; }

/* ------------------------------- cards ------------------------------- */
.card {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--pad);
}
.card.danger { border-color: #4a2725; }
.card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.card-head h2 { margin: 0; font-size: 14px; text-transform: uppercase; letter-spacing: .8px; color: var(--fg-dim); }

.pill {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .6px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--bg-soft);
  color: var(--fg-dim);
  border: 1px solid var(--line);
}
.pill-live { color: #0d1117; background: var(--accent); border-color: var(--accent); }
.pill-work { color: #0d1117; background: var(--work); border-color: var(--work); }
.pill-rest { color: #0d1117; background: var(--rest); border-color: var(--rest); }
.pill-warn { color: #0d1117; background: var(--warn); border-color: var(--warn); }

/* ------------------------------- stats ------------------------------- */
.stat-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.stat {
  background: var(--bg-soft);
  border-radius: 10px;
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.stat-label { font-size: 11px; text-transform: uppercase; letter-spacing: .7px; color: var(--fg-dim); }

.stat-value {
  font-size: 20px;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stat-value small { font-size: 12px; font-weight: 500; color: var(--fg-dim); }
/* An odd tile count leaves a hole in the last row — let the orphan fill it. */
.stat-grid > .stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
.stat-lg .stat-value { font-size: 30px; }
@media (min-width: 560px) {
  .stat-grid { grid-template-columns: repeat(3, 1fr); }
  .stat-lg { grid-column: span 1; }
}
/* The live session figures are read at arm's length while moving, so their size is
   the user's call (Settings → Session display). Scoped to the tracker: the Stats
   page is read standing still and keeps the base sizes. */
#view-tracker .stat-label { font-size: calc(11px * var(--session-scale, 1)); }
#view-tracker .stat-value { font-size: calc(20px * var(--session-scale, 1)); }
#view-tracker .stat-value small { font-size: calc(12px * var(--session-scale, 1)); }
#view-tracker .stat-lg .stat-value { font-size: calc(30px * var(--session-scale, 1)); }
/* Horizontal padding stays fixed while the type scales — scaling it too is what ate
   the width that the numbers needed. Vertical padding still follows the type. */
#view-tracker .stat { padding: calc(8px * var(--session-scale, 1)) var(--stat-pad); }

/* The column count follows the type size, not the other way round: two columns that
   clip "12.48 km" defeat the point of enlarging it. The minimum is derived from the
   widest value the tracker can show — elapsed past an hour, "1:07:32", measured at
   103px per 100% of scale, carried at 107 for a little font-metric slack — plus the
   tile's own padding. So the grid keeps two columns for exactly as long as that value
   fits and drops to one when it stops fitting, instead of clipping. Tabular figures
   make every h:mm:ss the same width, so a 3-hour run is no wider than a 1-hour one.
   min() keeps the track from exceeding the container on very narrow screens. */
#view-tracker .stat-grid {
  --stat-pad: 12px;
  grid-template-columns: repeat(auto-fit, minmax(
    min(100%, calc(107px * var(--session-scale, 1) + 2 * var(--stat-pad))), 1fr));
}

/* Phone: buy the numbers back the space the chrome was holding. Trimming the page,
   card, gap and tile padding frees ~34px of text width per column, which is what lets
   150% stay two columns on a 393px screen instead of stacking. */
@media (max-width: 480px) {
  main { padding: 8px; }
  #view-tracker .card { padding: 8px; }
  #view-tracker .stat-grid { --stat-pad: 8px; gap: 6px; }
}

/* ------------------------------ buttons ------------------------------ */
.btn-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.btn {
  flex: 1 1 0;
  min-width: 92px;
  appearance: none;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--fg);
  border-radius: 11px;
  padding: 13px 14px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: transform .06s ease, opacity .15s ease;
}
.btn:active:not(:disabled) { transform: scale(.98); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: #08130f; }
.btn-danger { background: var(--danger); border-color: var(--danger); color: #fff; }
.btn-ghost { background: transparent; }
.btn-sm { flex: 0 0 auto; min-width: 0; padding: 6px 14px; font-size: 18px; line-height: 1; }

.msg {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 10px;
  background: #2a2119;
  border: 1px solid #4a3a22;
  color: var(--warn);
  font-size: 13px;
}
.msg.ok { background: #16241f; border-color: #234437; color: var(--accent); }
.msg.err { background: #2a1a19; border-color: #4a2725; color: var(--danger); }

.hint { margin: 12px 0 0; font-size: 12px; color: var(--fg-dim); }
.foot { font-size: 12px; color: var(--fg-dim); text-align: center; padding: 0 8px 8px; }

/* ------------------------------ summary ------------------------------ */
.summary { margin-top: 16px; border-top: 1px solid var(--line); padding-top: 14px; }
.summary h3 { margin: 0 0 10px; font-size: 13px; text-transform: uppercase; letter-spacing: .7px; color: var(--fg-dim); }
.summary-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px 14px; font-size: 14px; }
.summary-grid div { display: flex; justify-content: space-between; gap: 10px; border-bottom: 1px dashed var(--line); padding-bottom: 4px; }
.summary-grid span:first-child { color: var(--fg-dim); }
.summary-grid span:last-child { font-variant-numeric: tabular-nums; }

.route-preview { margin-top: 12px; }
.route-preview svg { width: 100%; height: auto; display: block; background: var(--bg-soft); border-radius: 10px; }

/* Clickable trace: a plain button wrapper so keyboard and tap both work. */
.route-figure {
  display: block;
  width: 100%;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 10px;
  background: transparent;
  cursor: zoom-in;
  text-align: left;
  -webkit-tap-highlight-color: transparent;
}
.route-figure:hover, .route-figure:focus-visible { border-color: var(--accent-dim); outline: none; }
.route-hint { margin: 6px 0 0; font-size: 11px; color: var(--fg-dim); text-align: center; }

/* Speed legend — swatches carry the ramp, the ends carry the pace. */
.legend { margin-top: 8px; }
.legend-scale { display: flex; gap: 2px; height: 8px; }
.legend-scale i { flex: 1 1 0; border-radius: 2px; }
.legend-labels {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-top: 5px;
  font-size: 10px;
  color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.legend-mid { text-transform: uppercase; letter-spacing: .5px; }

/* Enlarged route */
.map-modal { align-items: stretch; padding: 12px; padding-bottom: calc(12px + var(--chrome-gap, 0px)); }
.map-modal-box {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin: auto;
  width: 100%;
  max-width: 760px;
  max-height: 100%;
  overflow-y: auto;
}
.map-modal-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}
.map-modal-head h3 { margin: 0; font-size: 14px; line-height: 1.35; }
.route-big svg { width: 100%; height: auto; display: block; background: var(--bg-soft); border-radius: 10px; }
.route-facts {
  margin: 10px 0 0;
  font-size: 13px;
  color: var(--fg-dim);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.speed-chart + .speed-chart { margin-top: 8px; }
.speed-chart {
  margin-top: 14px;
  border: 1px solid transparent;
  border-radius: 10px;
  background: var(--bg-soft);
  cursor: crosshair;
}
.speed-chart:focus-visible { border-color: var(--accent-dim); outline: none; }
.speed-chart svg { width: 100%; height: auto; display: block; }
.route-readout {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--fg-dim);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.route-readout.is-selected { color: var(--fg); font-weight: 600; }

/* ------------------------------- timer ------------------------------- */
.timer-display { text-align: center; padding: 6px 0 12px; }
#timerRemaining {
  display: block;
  font-size: 52px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
}
.timer-round { font-size: 12px; text-transform: uppercase; letter-spacing: .8px; color: var(--fg-dim); }
.progress { height: 6px; background: var(--bg-soft); border-radius: 999px; overflow: hidden; }
.progress-bar { height: 100%; width: 0; background: var(--accent); transition: width .2s linear; }
.progress-bar.rest { background: var(--rest); }

/* ------------------------------- deezer ------------------------------ */
.deezer-host iframe { display: block; width: 100%; border: 0; border-radius: 10px; }
.deezer-host a.btn { display: block; text-align: center; text-decoration: none; }
.deezer-empty { font-size: 13px; color: var(--fg-dim); }

/* ------------------------------- charts ------------------------------ */
.chart { margin-top: 4px; }
.chart svg { width: 100%; height: auto; display: block; overflow: visible; }
.chart-empty { font-size: 13px; color: var(--fg-dim); padding: 20px 0; text-align: center; }

.table-wrap { overflow-x: auto; margin-top: 12px; }
.table { width: 100%; border-collapse: collapse; font-size: 13px; white-space: nowrap; }
.table th, .table td { text-align: right; padding: 7px 8px; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
.table th { color: var(--fg-dim); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: .6px; }
.table th:first-child, .table td:first-child { text-align: left; }

.seg { display: flex; gap: 4px; background: var(--bg-soft); border-radius: 10px; padding: 3px; overflow-x: auto; }
.seg-wide { margin-bottom: 12px; }
.seg-btn {
  flex: 1 1 auto;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--fg-dim);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.seg-btn.is-active { background: var(--bg-card); color: var(--fg); box-shadow: 0 1px 3px rgba(0,0,0,.4); }

/* ------------------------------ run list ----------------------------- */
.run-list { display: flex; flex-direction: column; gap: 8px; }
.run-item {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-soft);
  border-radius: 10px;
  padding: 10px 12px;
}
.run-item .run-main { flex: 1 1 auto; min-width: 0; }
.run-date { font-size: 13px; font-weight: 600; }
.run-meta { font-size: 12px; color: var(--fg-dim); font-variant-numeric: tabular-nums; }
.icon-btn {
  appearance: none;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--fg-dim);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 13px;
  cursor: pointer;
}
.icon-btn:hover { color: var(--danger); border-color: var(--danger); }
.empty { color: var(--fg-dim); font-size: 13px; text-align: center; padding: 16px 0; }

/* ------------------------------ calendar ----------------------------- */
.cal-head { justify-content: space-between; }
.cal-head h2 { flex: 1 1 auto; text-align: center; font-size: 15px; text-transform: none; letter-spacing: 0; color: var(--fg); }
.cal-dow, .cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-dow { margin-bottom: 4px; }
.cal-dow span { text-align: center; font-size: 10px; text-transform: uppercase; letter-spacing: .5px; color: var(--fg-dim); }
.cal-cell {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 9px;
  background: var(--bg-soft);
  border: 1px solid transparent;
  color: var(--fg-dim);
  font-size: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  padding: 2px;
  cursor: default;
}
.cal-cell.blank { background: transparent; }
.cal-cell.has-run { background: rgba(76, 201, 160, .14); border-color: var(--accent-dim); color: var(--fg); cursor: pointer; }
.cal-cell.today { outline: 1px solid var(--rest); outline-offset: -1px; }
.cal-cell.selected { border-color: var(--accent); background: rgba(76, 201, 160, .28); }
.cal-day-num { font-weight: 600; }
.cal-badge { font-size: 9px; font-variant-numeric: tabular-nums; color: var(--accent); line-height: 1; }
.cal-month-summary { margin-top: 12px; font-size: 12px; color: var(--fg-dim); text-align: center; font-variant-numeric: tabular-nums; }

.day-run { border-top: 1px solid var(--line); padding-top: 12px; margin-top: 12px; }
.day-run:first-child { border-top: 0; padding-top: 0; margin-top: 0; }
.splits { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.split {
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  background: var(--bg-soft);
  border-radius: 7px;
  padding: 4px 8px;
  color: var(--fg-dim);
}
.split b { color: var(--fg); font-weight: 600; }

/* ------------------------------- fields ------------------------------ */
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; flex: 1 1 120px; }
.field > span { font-size: 12px; color: var(--fg-dim); }
.field input {
  background: var(--bg-soft);
  border: 1px solid var(--line);
  color: var(--fg);
  border-radius: 10px;
  padding: 11px 12px;
  font-size: 15px;
  width: 100%;
}
.field input:focus { outline: 2px solid var(--accent-dim); outline-offset: -1px; }
.field input[type="range"] {
  padding: 0;
  height: 34px;
  background: transparent;
  border: 0;
  accent-color: var(--accent);
}
.field > span b { color: var(--fg); font-variant-numeric: tabular-nums; }
.field-row { display: flex; gap: 10px; flex-wrap: wrap; }
.check { display: flex; align-items: center; gap: 8px; font-size: 14px; }
.sound-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

/* Which readouts appear on the Tracker */
.tile-picker { border: 0; margin: 4px 0 0; padding: 0; }
.tile-picker legend { padding: 0; font-size: 12px; color: var(--fg-dim); }
.tile-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 6px 12px;
  margin-top: 8px;
}
.tile-option {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  padding: 6px 8px;
  border-radius: 8px;
  background: var(--bg-soft);
  cursor: pointer;
}
.tile-option input { width: 18px; height: 18px; accent-color: var(--accent); flex: 0 0 auto; }
.btn-mini {
  appearance: none;
  border: 1px solid var(--line);
  background: var(--bg-soft);
  color: var(--fg);
  border-radius: 8px;
  padding: 7px 16px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.btn-mini:hover { border-color: var(--accent); color: var(--accent); }
.check input { width: 18px; height: 18px; accent-color: var(--accent); }

/* ------------------------------- pocket ------------------------------ */
/* Pure black, not a dark grey: on OLED that is the difference between pixels
   drawing power and not. Above the tab bar and the dialogs, because its whole job
   is to be the only thing the screen will respond to. */
.pocket {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: #000;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  padding: 5vh 20px calc(5vh + env(safe-area-inset-bottom));
  touch-action: none;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}
.pocket-dim {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  height: 100%;
  opacity: .2;
  transition: opacity .35s ease;
}
/* The dim layer centres its children, which makes them shrink-wrap — so the readout
   block has to claim the width explicitly or the grid only ever finds room for one
   column. */
/* Centre the readouts in whatever room is left above the slider, so a short list does
   not float at the top of a black screen and a long one still clears the handle. */
.pocket-body {
  width: 100%;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 0;
}

/* Every readout the user picked for the Tracker, on black. Two columns as soon as
   there is more than one, so a long list stays readable without scrolling — and the
   sheet must never scroll, since scrolling is a touch it is supposed to swallow. */
.pocket-face {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 3.2vh 6vw;
  width: 100%;
  text-align: center;
}
.pocket-stat { min-width: 0; }
.pocket-value {
  display: block;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.05;
  color: #fff;
  white-space: nowrap;
}
.pocket-value small { font-size: .42em; font-weight: 500; margin-left: .15em; }
.pocket-label {
  display: block;
  margin-top: 6px;
  font-size: 11px;
  letter-spacing: .8px;
  text-transform: uppercase;
  color: #fff;
  opacity: .65;
}
/* Fewer chosen readouts, bigger type. */
.pocket-face.size-xl .pocket-value { font-size: clamp(48px, 17vw, 92px); }
.pocket-face.size-lg .pocket-value { font-size: clamp(34px, 11vw, 60px); }
.pocket-face.size-md .pocket-value { font-size: clamp(30px, 10vw, 52px); }
.pocket-face.size-xl { grid-template-columns: 1fr; }
.pocket-note {
  margin: 3.4vh 0 0;
  text-align: center;
  font-size: 12px;
  letter-spacing: .6px;
  text-transform: uppercase;
  color: #fff;
}
.pocket-track {
  position: relative;
  width: min(320px, 86vw);
  height: 62px;
  border: 1px solid #333;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  touch-action: none;
}
.pocket-hint {
  font-size: 13px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: #777;
  pointer-events: none;
}
.pocket-handle {
  position: absolute;
  left: 4px;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: #1c232c;
  border: 1px solid #3a4453;
  color: #e6edf3;
  font-size: 26px;
  line-height: 52px;
  text-align: center;
  touch-action: none;
}
.pocket-track.is-dragging .pocket-handle { background: #2a323d; }
/* Nothing behind the sheet should scroll while a thigh is pressed against it. */
body.is-pocketed { overflow: hidden; }

.head-actions { display: flex; align-items: center; gap: 8px; }

/* ------------------------------- tabbar ------------------------------ */
.tabbar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 30;
  display: flex;
  background: rgba(22, 27, 34, .96);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--line);
  padding-bottom: env(safe-area-inset-bottom);
  /* --chrome-gap is how far the layout viewport extends below the visible one when
     the browser's URL bar slides in; without this the bar sits under it, showing only
     its top half. No transition: it must track the URL bar, not trail it. */
  transform: translateY(calc(-1 * var(--chrome-gap, 0px)));
  will-change: transform;
}
.tab {
  flex: 1 1 0;
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--fg-dim);
  padding: 9px 4px 11px;
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
}
.tab-ico { font-size: 17px; line-height: 1; }
.tab.is-active { color: var(--accent); }

/* ------------------------------- modal ------------------------------- */
.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(0, 0, 0, .6);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  /* Same correction as the tab bar: keep the box inside the *visible* viewport. */
  padding-bottom: calc(20px + var(--chrome-gap, 0px));
}
.modal-box {
  background: var(--bg-card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 18px;
  max-width: 380px;
  width: 100%;
}
.modal-box h3 { margin: 0 0 8px; font-size: 16px; }
.modal-box p { margin: 0; font-size: 14px; color: var(--fg-dim); }
