/* tracked telemetry — operate-mode UI, Gruvbox look. Dark first, light theme
   fully readable. Colour still means "a compared lap" in the chrome: which
   compared lap gets which slot (0-4) is only ever decided in JS
   (state.js's lapColor()), which sets it inline per element. --lap0..--lap4
   below are the same five values as CSS custom properties, purely so
   static, non-JS-driven decoration (the logo mark) can reference "the lap
   palette" without duplicating hex values — they are never themselves used
   to colour an actual compared lap. Everywhere else, colour carries a fixed
   role: --accent marks the active tab and any "ink fill" control, --hi
   marks kicker labels and headline figures, --tag marks corner/sector
   identity (purple, never a lap colour), and --best marks the fastest value
   in a table's scope (yellow). Square corners throughout — every corner is
   sharp, nothing here is rounded. */

:root,
:root[data-theme="dark"] {
  --bg: #1d2021;
  --panel: #282828;
  --panel2: #32302f;
  --line: #3c3836;
  --line2: #504945;
  --text: #ebdbb2;
  --muted: #a89984;
  --dim: #a08f7c;
  --focus: #fabd2f;
  --best: #fabd2f;
  --warn: #fabd2f;
  --bad: #fb4934;
  --hi: #fabd2f;
  --tag: #d3869b;
  --accent: #fe8019;
  --on-accent: #1d2021;
  --lap0: #fe8019;
  --lap1: #4cc9e0;
  --lap2: #b8bb26;
  --lap3: #fbf1c7;
  --lap4: #7aa2f7;
  --font: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, monospace;
  --dot: "Doto", "IBM Plex Mono", monospace;
}

:root[data-theme="light"] {
  --bg: #fbf1c7;
  --panel: #f9f5d7;
  --panel2: #f2e5bc;
  --line: #ebdbb2;
  --line2: #d5c4a1;
  --text: #3c3836;
  --muted: #504945;
  --dim: #665c54;
  --focus: #8f5a00;
  --best: #8f5a00;
  --warn: #8f5a00;
  --bad: #9d0006;
  --hi: #8f5a00;
  --tag: #8f3f71;
  --accent: #af3a03;
  --on-accent: #fbf1c7;
  --lap0: #af3a03;
  --lap1: #0e7c91;
  --lap2: #79740e;
  --lap3: #504945;
  --lap4: #2a5bd7;
}

* {
  box-sizing: border-box;
}
html,
body {
  height: 100%;
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 13.5px/1.4 var(--font);
  font-variant-numeric: tabular-nums;
}
a {
  color: var(--text);
  text-decoration: underline;
}
h1,
h2,
h3 {
  font-family: var(--font);
  font-weight: 600;
  margin: 0 0 8px;
}
h2 {
  font-size: 22px;
}
h3 {
  font-size: 17px;
}
button,
select,
input {
  font: inherit;
  color: var(--text);
  background: var(--panel2);
  border: 1px solid var(--line2);
  padding: 5px 9px;
}
button {
  cursor: pointer;
}
button:hover {
  border-color: var(--muted);
}
button:focus-visible,
select:focus-visible,
input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
}
button.primary,
.btn.primary {
  background: var(--text);
  border-color: var(--text);
  color: var(--bg);
  font-weight: 600;
}
label {
  color: var(--muted);
  font-size: 13px;
  display: block;
  margin-bottom: 3px;
}
fieldset {
  border: 1px solid var(--line);
  margin: 0 0 12px;
}
legend {
  color: var(--muted);
  font-family: var(--font);
  font-size: 13px;
  padding: 0 6px;
}
.btn {
  background: var(--panel2);
  border: 1px solid var(--line2);
  color: var(--text);
  font: 500 12.5px var(--font);
  padding: 4px 9px;
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover {
  border-color: var(--muted);
}

/* Doto numerals: big headline figures and stat-block numbers everywhere
   (Overview's spec strip and lap-replay chrome, the .stat blocks) share this
   family + weight; each caller still sets its own font-size/line-height. */
.dm {
  font-family: var(--dot);
  font-weight: 900;
  letter-spacing: -0.02em;
}

/* ============================================================ app shell */
.app {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  grid-template-rows: auto auto minmax(0, 1fr);
  height: 100vh;
  overflow: hidden;
}
.app.picker-hidden {
  grid-template-columns: 0 minmax(0, 1fr);
}
.app.picker-hidden aside.picker {
  display: none;
}

/* ---------------------------------------------------------------- header */
header.top {
  grid-column: 1 / 3;
  grid-row: 1;
  display: flex;
  align-items: center;
  gap: 14px;
  height: 52px;
  padding: 0 14px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
}
/* The logo lockup (wordmark + tagline + mark) is the app's identity: it
   never hides to make room for tabs or controls, it is scaled to the one
   52px row. On narrow windows the tabs that don't fit move into the
   Advanced menu (see .tabs). */
header.top .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  height: 100%;
  padding-right: 4px;
  color: inherit;
  text-decoration: none;
}
header.top .brand b {
  display: block;
  font: 700 24px/0.95 var(--font);
  letter-spacing: -0.035em;
}
header.top .brand b em {
  font-style: normal;
  color: var(--accent);
}
header.top .brand small {
  display: block;
  color: var(--muted);
  font-size: 10.5px;
  font-family: var(--font);
  font-weight: 400;
  margin-top: 3px;
  line-height: 1.2;
  white-space: nowrap;
}
header.top .brand .mark {
  flex: none;
  display: block;
  width: 64px;
  height: 26px;
}
/* The place control (place-menu.js). Where a place's own tabs show, a plain
   Discover | Analyze switch: the current place in full text with an orange
   icon, the other muted. Inside a day, "Analyze ▾" instead, whose menu lists
   both places and their sections. Neither takes the orange underline: that
   marks only the tab for the page you're on. */
.place-switch {
  display: flex;
  align-items: center;
  gap: 2px;
  height: 100%;
}
.place-switch .pl {
  display: flex;
  align-items: center;
  gap: 6px;
  height: var(--hdr-ctl, 32px);
  padding: 0 8px;
  border-radius: var(--hdr-radius, 4px);
  color: var(--muted);
  font: 600 12px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  text-decoration: none;
  white-space: nowrap;
}
.place-switch .pl:hover {
  color: var(--text);
  background: var(--panel2);
}
.place-switch .pl.on {
  color: var(--text);
}
.place-switch .pl .ico {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.place-switch .pl.on .ico {
  stroke: var(--accent);
}
.place-switch .pl-sep {
  width: 1px;
  height: 14px;
  background: var(--line2);
}
/* Analyze: the switch on Your days, the menu button inside a day. */
header.top:not(.days-mode) .places.has-menu .place-switch,
header.top.days-mode .places .place-btn {
  display: none;
}
.places {
  display: flex;
  align-items: center;
  flex: none;
  height: 100%;
}
.place-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  height: var(--hdr-ctl, 32px);
  padding: 0 8px;
  background: transparent;
  border: 0;
  border-radius: var(--hdr-radius, 4px);
  color: var(--text);
  font: 600 12px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  cursor: pointer;
}
.place-btn:hover,
.place-btn.open {
  background: var(--panel2);
}
.place-btn .ico {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.place-btn .caret {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: var(--muted);
  stroke-width: 2;
  transition: transform 0.12s;
}
.place-btn.open .caret {
  transform: rotate(180deg);
}
a.tabs-menu .tab,
.tabs-menu a.tab {
  text-decoration: none;
}
/* Inside a day: the day's own title (track, then date and best lap) with a
   square back arrow to Your days, so the way back never reads as a tab. */
.day-title {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 0 12px 0 0;
  margin-right: 4px;
  border-right: 1px solid var(--line2);
  align-self: center;
  height: 32px;
}
.day-title .dt-back {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line2);
  border-radius: var(--hdr-radius, 4px);
  color: var(--muted);
  cursor: pointer;
}
.day-title .dt-back:hover {
  color: var(--text);
  border-color: var(--muted);
}
.day-title .dt-back .ico {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.day-title .dt-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  white-space: nowrap;
}
.day-title b {
  font: 700 14px/1.15 var(--font);
  color: var(--text);
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.day-title small {
  font: 400 11.5px/1.25 var(--font);
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.nav-div {
  flex: none;
  width: 1px;
  height: 24px;
  background: var(--line2);
}
a.tab {
  text-decoration: none;
}
/* Laptop widths: the day's tabs drop their icons and the day title its
   date line, so every calm view stays in the row before any moves into
   Advanced. */
@media (max-width: 1480px) {
  .tabs .tab[data-view] .ico { display: none; }
}
@media (max-width: 1180px) {
  .day-title small { display: none; }
  header.top .brand small { display: none; }
}
/* On Your days the Analyze section tabs show; inside a day, the day's title
   (with its way back to Your days) and the day's own views. */
header.top.days-mode .tabs .tab[data-view],
header.top.days-mode .tabs .tab.adv,
header.top.days-mode .tabs .day-title,
header.top:not(.days-mode) .tabs .tab.sect {
  display: none;
}
/* Tabs: uppercase mono labels with a line icon, the active one marked by an
   accent underline. The dense views live in the Advanced menu at the row's
   right end (app.js fitTabs), which also takes calm tabs that don't fit, so
   the row never scrolls or clips. Tabs and every header control share one
   32px height (--hdr-ctl); header controls and the menu have a slight 4px
   radius (--hdr-radius). */
header.top {
  --hdr-ctl: 32px;
  --hdr-radius: var(--radius-ctl);
}
.tabs {
  display: flex;
  align-items: stretch;
  gap: 4px;
  height: 100%;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}
/* Two rows (app.js fitTabs): the logo and controls on the 72px row, the view
   tabs on a 44px row under them, when they don't fit side by side. */
header.top.two-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-rows: 72px 44px;
  height: auto;
  column-gap: 16px;
}
header.top.two-row .hdr-controls {
  justify-self: end;
  align-self: center;
  max-width: 100%;
  overflow-x: auto; /* phone widths: the controls scroll rather than clip */
  scrollbar-width: none;
}
header.top.tight .hdr-controls .seg button:not(.on) {
  display: none;
}
.tabs .ctrl.in-tabs {
  align-self: center;
  flex: none;
  margin-left: auto;
}
.tabs .ctrl.in-tabs .btn {
  display: inline-flex;
  align-items: center;
  height: var(--hdr-ctl);
  border-radius: var(--hdr-radius);
  font: 600 12px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
}
.tabs .ctrl.in-tabs + .tab.adv {
  margin-left: 8px;
}
header.top.two-row .tabs {
  grid-column: 1 / -1;
  grid-row: 2;
  height: 44px;
  margin: 0 -16px;
  padding: 0 8px;
  border-top: 1px solid var(--line);
}
.tabs .tab {
  position: relative;
  display: flex;
  align-items: center;
  flex: none;
  gap: 6px;
  height: 100%;
  background: transparent;
  border: 0;
  color: var(--muted);
  font: 600 12px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0 8px;
  white-space: nowrap;
  cursor: pointer;
}
.tabs .tab[hidden] {
  display: none;
}
.tabs .tab:hover {
  color: var(--text);
}
.tabs .tab::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 0;
  height: 3px;
  border-radius: 2px 2px 0 0;
  background: transparent;
}
.tabs .tab.active,
.tabs .tab.on {
  color: var(--text);
}
.tabs .tab.active::after,
.tabs .tab.on::after {
  background: var(--accent);
}
.tabs .tab .ico,
.tabs-menu .tab .ico {
  width: 17px;
  height: 17px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tabs .tab.active .ico,
.tabs .tab.on .ico {
  color: var(--accent);
}
/* The Advanced menu button sits at the row's right end, against the
   controls' divider. */
.tabs .tab.adv {
  margin-left: auto;
}
.tabs .tab.adv .caret {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  transition: transform 0.12s;
}
.tabs .tab.adv.compact .t {
  display: none;
}
.tabs .tab.adv.open {
  color: var(--text);
}
.tabs .tab.adv.open .caret {
  transform: rotate(180deg);
}
.tabs-menu {
  position: fixed;
  z-index: 50;
  display: flex;
  flex-direction: column;
  min-width: 220px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--line2);
  border-radius: 6px;
}
.tabs-menu[hidden] {
  display: none;
}
.tabs-menu .menu-h {
  padding: 8px 10px 6px;
  color: var(--dim);
  font: 600 11px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
}
.tabs-menu .menu-h:not(:first-child) {
  margin-top: 6px;
  border-top: 1px solid var(--line);
  padding-top: 12px;
}
.tabs-menu .tab {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: 34px;
  padding: 0 10px;
  background: transparent;
  border: 0;
  border-radius: 4px;
  color: var(--muted);
  font: 600 12.5px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  cursor: pointer;
}
.tabs-menu .tab:hover {
  background: var(--panel2);
  color: var(--text);
}
.tabs-menu .tab.active {
  color: var(--text);
  background: var(--panel2);
}
.tabs-menu .tab.active .ico {
  color: var(--accent);
}
.tabs-menu kbd {
  margin-left: auto;
  padding-left: 16px;
  color: var(--dim);
  font: 500 11px var(--mono);
}
.hdr-controls {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: none;
  margin-left: auto;
  height: var(--hdr-ctl);
}
/* Actions (Import, Share, settings, Sign in): plain icon-and-label, no box,
   so nothing button-shaped sits among the tabs. A rounded wash on hover. The
   signed-in account is your initials in a small square. A rule sets the
   actions apart from the tabs. */
header.top .hdr-controls {
  gap: 4px;
  padding-left: 12px;
  border-left: 1px solid var(--line2);
}
.hdr-controls .btn.act {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: var(--muted);
  padding: 0 8px;
}
.hdr-controls .btn.act:hover,
.hdr-controls .btn.act.on,
.hdr-controls .btn.act[aria-expanded="true"] {
  background: var(--panel2);
  color: var(--text);
}
.hdr-controls .btn.act .ico {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hdr-controls .btn.avatar {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  margin-left: 4px;
  padding: 0;
  border-radius: 6px;
  font: 600 11px var(--mono);
  letter-spacing: 0.02em;
}

/* Settings: units, theme and the AI coach behind one gear button. */
.settings {
  position: relative;
}
.hdr-controls .set-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--hdr-ctl);
  padding: 0;
}
.set-btn .ico {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hdr-controls .set-btn.act {
  justify-content: center;
  width: var(--hdr-ctl);
  padding: 0;
}
.set-menu {
  position: fixed;
  z-index: 50;
  display: grid;
  gap: 10px;
  min-width: 250px;
  padding: 12px;
  background: var(--panel);
  border: 1px solid var(--line2);
  border-radius: 6px;
}
.set-menu[hidden] {
  display: none;
}
.set-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--hdr-ctl);
}
.set-lab {
  color: var(--dim);
  font: 600 11px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.ctrl {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 100%;
}
.ctrl[hidden] {
  display: none;
}
.ctrl-lab {
  color: var(--dim);
  font: 600 11px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  white-space: nowrap;
}
.hdr-controls .btn,
.hdr-controls select,
.hdr-controls .seg button {
  font: 600 12px var(--mono);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.hdr-controls a.btn {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.hdr-controls .btn,
.hdr-controls select {
  border-radius: var(--hdr-radius);
  height: var(--hdr-ctl);
  padding: 0 10px;
}
.hdr-controls .seg {
  border-radius: var(--hdr-radius);
  height: var(--hdr-ctl);
}
.hdr-controls .seg button {
  padding: 0 10px;
}
.seg {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  border: 1px solid var(--line2);
  overflow: hidden;
}
.seg button {
  background: transparent;
  border: 0;
  color: var(--muted);
  font: 500 12.5px var(--font);
  padding: 5px 8px;
  cursor: pointer;
}
.seg button + button {
  border-left: 1px solid var(--line2);
}
.seg button.on {
  background: var(--text);
  color: var(--bg);
}

/* ---------------------------------------------------------------- picker */
aside.picker {
  grid-column: 1;
  grid-row: 2 / 4;
  background: var(--panel);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
}
.picker-h {
  flex: none;
  padding: 14px 14px 10px;
  border-bottom: 1px solid var(--line);
}
.picker-h h2 {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin: 0 0 4px;
}
.picker-h .hint {
  margin: 0 0 10px;
}
.picker-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.picker-body {
  flex: 1;
}
.sess {
  border-bottom: 1px solid var(--line);
}
.sess-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  text-align: left;
  background: var(--panel2);
  border: 0;
  padding: 7px 14px;
  cursor: pointer;
  color: var(--text);
  position: sticky;
  top: 0;
}
.sess-toggle:hover {
  background: var(--panel2);
  filter: brightness(1.08);
}
.sess-toggle .car {
  color: var(--dim);
  flex: none;
  font-size: 11px;
  white-space: nowrap;
}
.sess-toggle:hover .car {
  color: var(--muted);
}
.sess-toggle .sess-info {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}
.sess-toggle b {
  font: 600 13.5px var(--font);
}
.sess-toggle small {
  color: var(--muted);
  font: 400 11.5px var(--font);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sess-laps {
  display: flex;
  flex-direction: column;
}
.sess.is-collapsed .lap:not(.sel) {
  display: none;
}
.lap {
  display: grid;
  grid-template-columns: 14px 1fr 50px 46px 54px;
  align-items: center;
  gap: 8px;
  width: 100%;
  height: 28px;
  padding: 0 14px;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: var(--text);
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
}
.lap:hover {
  background: var(--panel2);
}
.lap.sel {
  background: var(--panel2);
}
.lap .lb {
  color: var(--muted);
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.lap .tm {
  font-weight: 600;
  text-align: right;
}
.lap .dl {
  text-align: right;
  color: var(--muted);
  font-size: 11.5px;
}
.lap .dl.dim {
  color: var(--dim);
}
.lap .tg {
  text-align: right;
  color: var(--dim);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

/* ------------------------------------------------------------ compare bar */
.comparebar {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 8px 18px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  min-height: 40px;
}
.cb-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}
.cb-lab {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
}
.cb-hint {
  color: var(--dim);
  font-size: 12px;
}
.cb-empty {
  color: var(--muted);
  font-size: 13px;
}
.flash {
  flex: none;
  font-size: 12px;
  color: var(--warn);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s;
  padding: 3px 8px;
}
.flash.show {
  opacity: 1;
  background: color-mix(in srgb, var(--warn) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
}

/* ---------------------------------------------------------------- chips */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px 5px 10px;
  border: 1px solid var(--line2);
  background: var(--panel2);
  font-size: 12.5px;
  white-space: nowrap;
}
.chip b {
  font-weight: 600;
}
.chip .t {
  color: var(--muted);
}
.chip-x {
  background: transparent;
  border: 0;
  border-left: 1px solid var(--line2);
  color: var(--dim);
  font: 500 12px var(--font);
  padding: 0 6px;
  margin-left: 2px;
  cursor: pointer;
}
.chip-x:hover {
  color: var(--bad);
}

/* -------------------------------------------------------- swatch / best */
.sw {
  display: inline-block;
  width: 10px;
  height: 10px;
  flex: none;
}
/* In table cells the swatch sits inline before the lap label ("■ Session 4, Lap 7"). */
.t td .sw {
  margin-right: 6px;
  vertical-align: -1px;
}
.lap .sw {
  width: 12px;
  height: 12px;
}
.sw.off {
  background: transparent !important;
  outline: 1.5px solid var(--line2);
  outline-offset: -1.5px;
}
.is-best {
  color: var(--best);
  background: color-mix(in srgb, var(--best) 12%, transparent);
  font-weight: 600;
}
.is-sbest {
  font-weight: 600;
}

/* ----------------------------------------------------------- title / view */
#viewWrap {
  grid-column: 2;
  grid-row: 3;
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.title-row {
  flex: none;
  display: flex;
  align-items: baseline;
  gap: 14px;
  padding: 12px 18px 8px;
}
.title-row h1 {
  font: 600 20px var(--font);
  margin: 0;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.title-row .lead {
  color: var(--dim);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.title-row .meta {
  margin-left: auto;
  flex: none;
  color: var(--dim);
  font-size: 12px;
  white-space: nowrap;
}
.content {
  padding: 4px 18px 40px;
  overflow: auto;
  flex: 1;
  min-height: 0;
}

/* ================================================================ stats */
.stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
  margin-bottom: 16px;
}
.stat {
  background: var(--panel);
  padding: 8px 12px 9px;
}
.stat .v {
  font: 900 26px/1.05 var(--dot);
}
.stat .v small {
  font-size: 15px;
  color: var(--muted);
  font-weight: 500;
  margin-left: 4px;
  font-family: var(--font);
}
.stat .l {
  color: var(--muted);
  font-size: 12px;
  margin-top: 2px;
}
.stat.hi .v {
  color: var(--best);
}

/* ======================================================= sections/tables */
.sec {
  margin-bottom: 18px;
  min-width: 0;
  overflow-x: auto; /* wide split/metric tables scroll instead of clipping */
}
.sec-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 0 0 6px;
  border-bottom: 1px solid var(--line2);
  margin-bottom: 0;
}
.sec-head h2 {
  font: 600 15px var(--font);
  margin: 0;
  color: var(--text);
}
.sec-head .meta {
  color: var(--dim);
  font-size: 12px;
  margin-left: auto;
  white-space: nowrap;
}
.sec-head .meta b {
  color: var(--muted);
  font-weight: 500;
}
table.t {
  border-collapse: collapse;
  width: 100%;
  font-size: 13px;
}
.t th {
  font: 600 12px var(--font);
  letter-spacing: 0.02em;
  color: var(--muted);
  text-align: left;
  padding: 6px 8px 5px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
  background: var(--bg);
  position: sticky;
  top: 0;
}
.t td {
  padding: 0 8px;
  height: 27px;
  border-bottom: 1px solid var(--line);
  white-space: nowrap;
}
.t .num {
  text-align: right;
}
.t tbody tr:hover td {
  background: var(--panel);
}
.t tr.sess td {
  height: 24px;
  background: var(--panel);
  color: var(--muted);
  font: 600 12px var(--font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-bottom: 1px solid var(--line2);
}
.t tr.sel td {
  background: var(--panel2);
}
.t tr.sel td:first-child {
  box-shadow: inset 3px 0 0 var(--lapc, var(--line2));
}
.t td.time {
  font-weight: 600;
  font-size: 13.5px;
}
.t td.dim {
  color: var(--dim);
}
.t tr.theo td {
  background: var(--panel2);
  font-weight: 600;
  border-bottom: 1px solid var(--line2);
}
.t tr.theo td:first-child {
  color: var(--muted);
  font: 600 12px var(--font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.cols-2 {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: 18px;
  align-items: start;
}
.cols-map {
  display: grid;
  grid-template-columns: 360px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
.cols-map .sticky {
  position: sticky;
  top: 0;
}
@media (max-width: 1100px) {
  .cols-2 {
    grid-template-columns: 1fr;
  }
}
/* Track split's map (360px) + metrics table row stacks into one column once
   the VIEW'S OWN content width — window width minus the 280px picker (when
   shown) and 36px of view padding — drops below 900px. Two rules cover the
   picker shown/hidden cases since a plain media query only sees the window
   width. */
@media (max-width: 1216px) {
  .app:not(.picker-hidden) .cols-map {
    grid-template-columns: 1fr;
  }
  .app:not(.picker-hidden) .cols-map .sticky {
    position: static;
  }
}
@media (max-width: 936px) {
  .app.picker-hidden .cols-map {
    grid-template-columns: 1fr;
  }
  .app.picker-hidden .cols-map .sticky {
    position: static;
  }
}

/* ========================================== chart / map panel language */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
}
.panel-h {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 28px;
  padding: 5px 10px;
  border-bottom: 1px solid var(--line);
  flex-wrap: wrap;
}
.panel-h h3 {
  margin: 0;
  font: 600 12.5px var(--font);
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.panel-h .val {
  margin-left: auto;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  font-size: 12px;
  color: var(--muted);
}
.panel-h .val .ro {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.panel-h .val b {
  color: var(--text);
  font-weight: 600;
  /* live readouts: fixed-width digits so a changing value never re-wraps
     the header and shifts the chart under it */
  font-variant-numeric: tabular-nums;
  display: inline-block;
  min-width: 3ch;
  text-align: right;
}
.panel-h .val i {
  display: inline-block;
  width: 8px;
  height: 8px;
  flex: none;
}
.chart {
  position: relative;
  height: 150px;
}
.chart svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.chart .y {
  position: absolute;
  left: 6px;
  font: 11px var(--font);
  color: var(--dim);
}
.chart .cursor {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 0;
  border-left: 1px dashed var(--text);
}
.chart .cursor .rd {
  position: absolute;
  top: 4px;
  left: 6px;
  background: var(--panel);
  border: 1px solid var(--line2);
  padding: 2px 6px;
  font-size: 11px;
  white-space: nowrap;
}
.xaxis {
  display: flex;
  justify-content: space-between;
  padding: 3px 10px 4px 42px;
  color: var(--dim);
  font-size: 11px;
  border-top: 1px solid var(--line);
}
.stack .panel + .panel {
  border-top: 0;
}
.map {
  position: relative;
  background: var(--bg);
  overflow: hidden;
}
.map .ph {
  position: absolute;
  left: 10px;
  bottom: 8px;
  font: 11px var(--mono);
  color: var(--dim);
}
.map svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.map canvas {
  display: block;
  width: 100%;
  height: 100%;
  cursor: crosshair;
}
.readout {
  position: absolute;
  left: 10px;
  top: 10px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line2);
  padding: 7px 10px;
  min-width: 170px;
  font-size: 12px;
  color: var(--text);
  pointer-events: none;
}
.readout b {
  display: block;
  font: 600 15px var(--font);
}
.readout .r {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  color: var(--muted);
}
.readout .r em {
  font-style: normal;
  color: var(--text);
}
.legend {
  position: absolute;
  right: 10px;
  bottom: 10px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line2);
  padding: 6px 9px;
  font-size: 11px;
  color: var(--muted);
  pointer-events: none;
}
.legend .bar {
  height: 7px;
  width: 150px;
  margin: 4px 0 3px;
}
.legend .lab {
  display: flex;
  justify-content: space-between;
}
/* One plate naming every drawn lap (Track map): a row per lap when colour
   still means lap identity, or a single row ("Session 4, Lap 7 (best) ·
   coloured by speed") when a channel ramp is doing the colouring instead. */
.laplegend {
  position: absolute;
  left: 10px;
  bottom: 10px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line2);
  padding: 8px 10px;
  display: grid;
  gap: 3px;
  pointer-events: none;
}
.laplegend span {
  display: flex;
  align-items: center;
  font-size: 12px;
  color: var(--text);
  white-space: nowrap;
}
.laplegend i {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-right: 6px;
  flex: none;
}
/* Track map: zoom buttons float top-right inside the map itself, and a
   mono hint plate is centred along the top edge. Both sit over the canvas,
   never in a separate panel header (the map fills the whole panel). */
.map-zoom {
  position: absolute;
  right: 10px;
  top: 10px;
  display: flex;
  gap: 4px;
}
.map-hintplate {
  position: absolute;
  left: 50%;
  top: 10px;
  transform: translateX(-50%);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line2);
  padding: 4px 8px;
  font: 400 11px var(--mono);
  color: var(--muted);
  white-space: nowrap;
  pointer-events: none;
}
.toolbar {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  margin-bottom: 12px;
  flex-wrap: wrap;
}
.fld label {
  display: block;
  font: 600 11px var(--font);
  color: var(--hi);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin-bottom: 3px;
}
.fld select,
.fld input {
  background: var(--panel2);
  border: 1px solid var(--line2);
  color: var(--text);
  font: 500 12.5px var(--font);
  padding: 4px 8px;
  min-width: 130px;
}
.kbd-hint {
  color: var(--muted);
  font-size: 12px;
}
.btn-sm {
  height: 22px;
  font-size: 12px;
  line-height: 1;
  padding: 0 8px;
  display: inline-flex;
  align-items: center;
}
.map-hint {
  color: var(--muted);
  font-size: 12px;
}
.map-toolbar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  border-bottom: 1px solid var(--line);
}

/* ------------------------------------------------------ Time-distance view */
/* "Channels" toolbar control: a <details>/<summary> dressed as the screens'
   select (closed, one-line summary of what's on) that opens to the same
   checkboxes it always was — every control keeps a visible text label, this
   one just also collapses like the design's dropdown. */
.v-td .fld .dd { position: relative; }
.v-td .fld .dd summary {
  background: var(--panel2);
  border: 1px solid var(--line2);
  color: var(--text);
  font: 500 12.5px var(--font);
  padding: 4px 24px 4px 8px;
  min-width: 130px;
  cursor: pointer;
  list-style: none;
  white-space: nowrap;
  position: relative;
}
.v-td .fld .dd summary::-webkit-details-marker { display: none; }
.v-td .fld .dd summary::after {
  content: "▾";
  position: absolute;
  right: 8px;
  top: 4px;
  color: var(--muted);
}
.v-td .fld .dd[open] summary { border-color: var(--muted); }
.v-td .fld .dd-menu {
  position: absolute;
  z-index: 5;
  top: calc(100% + 2px);
  left: 0;
  background: var(--panel2);
  border: 1px solid var(--line2);
  padding: 8px 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  white-space: nowrap;
}
.v-td .dd-menu .chk {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 500 13px var(--font);
  color: var(--text);
  text-transform: none;
  letter-spacing: normal;
  margin: 0;
  cursor: pointer;
}
/* .fld input sets min-width:130px + full input chrome for text/number/select
   fields — reset all of that for the checkbox itself so it doesn't render as
   a 130px-wide box with the visible checkbox square stranded at one end. */
.v-td .dd-menu .chk input[type="checkbox"] {
  width: 13px;
  height: 13px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.v-td .toolbar .zoom-fld { margin-left: auto; }
.v-td .td-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 14px; align-items: start; }
.v-td .td-side { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 0; min-width: 0; }
.v-td.narrow .td-layout { display: flex; flex-direction: column-reverse; align-items: stretch; gap: 14px; }
.v-td.narrow .td-side { flex-direction: row; position: static; }
.v-td.narrow .td-side .panel { flex: none; width: 300px; }
.v-td.narrow .td-side .sec { flex: 1; min-width: 0; }

/* ------------------------------------------------------------ Laps & splits */
.v-laps details.rolling { margin-top: 18px; }
.v-laps details.rolling summary {
  cursor: pointer;
  font: 600 15px var(--font);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  padding: 6px 0;
}
.v-laps details.rolling summary:hover { color: var(--text); }
.v-laps details.rolling table.t { margin-top: 8px; }
.v-laps td.muted, .v-laps td.num.muted { color: var(--muted); }

/* ================================================================ Overview */
.v-overview { display: flex; flex-direction: column; height: 100%; min-height: 480px; }
.content:has(> .v-overview) { padding-bottom: 12px; }

/* ---- headline spec strip (study: .spec) --------------------------------- */
.ov-spec {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  border: 1px solid var(--line);
  margin-bottom: 10px;
  flex: none;
}
.ov-spec > div { padding: 8px 14px 9px; }
.ov-spec > div + div { border-left: 1px solid var(--line); }
.ov-spec .lbl {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin-bottom: 6px;
}
.ov-spec .lbl { margin-bottom: 2px; }
.ov-spec .v { font-size: 30px; line-height: 1; margin: 0 0 3px; }
.ov-spec .v small { font-size: 16px; }
.ov-spec .s { font-size: 12.5px; color: var(--muted); }

/* ---- top coaching tip under the spec strip ------------------------------ */
.ov-tip {
  border: 1px solid var(--line);
  border-left: 3px solid var(--hi);
  padding: 12px 14px 13px;
  margin: 0 0 12px;
}
.ov-tip .lbl {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  margin-bottom: 8px;
}
.ov-tip-what { display: flex; align-items: baseline; gap: 10px; }
.ov-tip-what h3 { margin: 0; font-size: 20px; line-height: 1.25; }
.ov-tip-meta { font-size: 13px; color: var(--muted); margin-top: 6px; }
.ov-tip-meta b { color: var(--text); }
.ov-tip-why { margin: 8px 0 0; font-size: 14px; max-width: 72ch; }
.ov-tip-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }

/* ---- lap replay (study: .main/.map/.plate/.readout/.legend/.transport) -- */
/* One screen: the replay (transport over the map) on the left, and on the
   right one tab at a time. Nothing in the page scrolls at laptop sizes; a
   long tab scrolls inside itself. */
.ov-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 14px;
}
.ov-replay { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.ov-replay-host { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ov-replay .ov-transport { margin-bottom: 0; border-bottom: 0; }
.ov-map { flex: 1; min-height: 300px; border: 1px solid var(--line); }
.ov-side { display: flex; flex-direction: column; min-height: 0; min-width: 0; border: 1px solid var(--line); }
.ov-tabs { display: flex; flex: none; border-bottom: 1px solid var(--line); overflow-x: auto; }
.ov-tab {
  flex: 1 1 auto;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  color: var(--muted);
  font: 600 12.5px var(--font);
  line-height: 1.2;
  padding: 8px 8px 6px;
  cursor: pointer;
}
.ov-tab:hover { color: var(--text); }
.ov-tab.on { color: var(--text); border-bottom-color: var(--hi); }
.ov-panel { flex: 1; min-height: 0; overflow: auto; }
.ov-panel[hidden] { display: none; }
.ov-panel-find { padding: 12px 14px; }
.ov-panel-find .ov-tip { margin-bottom: 12px; }
.ov-panel-find .ov-rows .hint { margin: 0 0 6px; }
.ov-panel-speed, .ov-panel-mom, .ov-panel-day { display: flex; flex-direction: column; overflow: hidden; }
.ov-panel-speed[hidden], .ov-panel-mom[hidden], .ov-panel-day[hidden] { display: none; }
/* Speed, throttle and brake stacked in one tab, sharing its height */
.ov-pedal { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ov-pedal-key { display: flex; flex-wrap: wrap; gap: 4px 14px; padding: 8px 12px 4px; font-size: 12px; color: var(--muted); }
.ov-pedal-key .ro { display: inline-flex; align-items: center; gap: 6px; }
.ov-pedal-key i { width: 9px; height: 9px; display: inline-block; }
.ov-pedal + .ov-pedal { border-top: 1px solid var(--line); }
.ov-colourby { position: absolute; right: 10px; top: 78px; display: flex; align-items: center; gap: 8px; padding: 4px 4px 4px 10px; margin: 0; }
.ov-colourby .lbl { margin: 0; }
.ov-colourby select { background: var(--panel2); border: 1px solid var(--line2); color: var(--text); font: 500 12.5px var(--font); padding: 3px 6px; }
.ov-linestyle { position: absolute; right: 10px; top: 44px; background: color-mix(in srgb, var(--bg) 88%, transparent); }
.ov-panel-speed .panel, .ov-panel-mom .panel, .ov-panel-day .panel { border: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.ov-panel .chart.mom { flex: 1; min-height: 0; }
.ov-panel-speed > .hint, .ov-panel-mom > .hint { padding: 14px; }
/* short laptop screens: the headline numbers drop their sentences so the
   replay keeps its height */
@media (max-height: 860px) and (min-width: 901px) {
  .ov-spec .s { display: none; }
}
.ov-plate {
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  border: 1px solid var(--line2);
  padding: 7px 10px;
}
.ov-readout { position: absolute; left: 10px; top: 10px; display: grid; gap: 3px; pointer-events: none; }
.ov-readout .lbl {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
}
.ov-readout .corner { font-size: 28px; line-height: 1; color: var(--tag); }
.ov-readout .desc { font-size: 12px; color: var(--text); max-width: 220px; }
.ov-readout .gap { font-size: 18px; line-height: 1; }
.ov-readout .gaps { display: grid; gap: 3px; }
.ov-readout .gaps .gap + .gap, .ov-readout .gaps .gap:first-child:not(:last-child) { font-size: 15px; }
.ov-mapctl { position: absolute; right: 10px; top: 10px; display: flex; gap: 0; }
.ov-mapctl > .mc { border-left: 0; }
/* Map view controls (mapview.js): + and − and reset as small squares, the
   usual map pattern; the replay adds follow car. */
.mapctl { display: inline-flex; }
.mc {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--line2);
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  color: var(--text);
  font: 600 17px/1 var(--font);
  cursor: pointer;
}
.mc + .mc { border-left: 0; }
.mc:hover { color: var(--hi); border-color: var(--muted); }
.mc.on { background: var(--text); color: var(--bg); border-color: var(--text); }
.mc:focus-visible { outline: 1px solid var(--accent); outline-offset: 1px; }
.mc svg { position: static; inset: auto; width: 14px; height: 14px; flex: none; }
.mapctl, .ov-mapctl { pointer-events: auto; z-index: 2; }
.ov-legend { position: absolute; left: 10px; bottom: 10px; display: grid; gap: 4px; font-size: 12px; pointer-events: none; }
.ov-legend span { display: flex; align-items: center; gap: 6px; }
.ov-transport {
  display: flex;
  align-items: center;
  gap: 8px 12px;
  padding: 8px 12px;
  border: 1px solid var(--line);
  flex-wrap: wrap;
  margin-bottom: 18px;
  flex: none;
}
.ov-transport .lbl {
  color: var(--hi);
  font: 600 11px var(--font);
  text-transform: lowercase;
  letter-spacing: 0.06em;
}
.ov-transport .hint { color: var(--dim); font-size: 12px; }
/* The replay scrubber, drawn here rather than by the browser so the orange
   fill always runs to the middle of the handle (--f, 0..1, set by the replay). */
.ov-transport input[type="range"] {
  --f: 0;
  --thumb: 14px;
  flex: 1;
  min-width: 140px;
  height: 18px;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}
.ov-transport input[type="range"]::-webkit-slider-runnable-track {
  height: 6px;
  background: linear-gradient(to right, var(--accent) 0 calc(var(--thumb) / 2 + (100% - var(--thumb)) * var(--f)), var(--line2) 0);
}
.ov-transport input[type="range"]::-moz-range-track {
  height: 6px;
  background: linear-gradient(to right, var(--accent) 0 calc(var(--thumb) / 2 + (100% - var(--thumb)) * var(--f)), var(--line2) 0);
}
.ov-transport input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: var(--thumb);
  height: var(--thumb);
  margin-top: -4px;
  border: 0;
  border-radius: 50%;
  background: var(--text);
}
.ov-transport input[type="range"]::-moz-range-thumb {
  width: var(--thumb);
  height: var(--thumb);
  border: 0;
  border-radius: 50%;
  background: var(--text);
}
.ov-transport input[type="range"]:focus-visible { outline: 1px solid var(--accent); outline-offset: 2px; }
.ov-transport .clock { font-size: 22px; line-height: 1; color: var(--hi); min-width: 96px; text-align: right; }
.ov-transport select {
  background: var(--panel2);
  border: 1px solid var(--line2);
  color: var(--text);
  font: 500 12.5px var(--font);
  padding: 4px 8px;
}
.chart.mom canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }

/* ---- "Where to find time" rows (study: .row) ---------------------------- */
.ov-rows-list .ov-row {
  display: grid;
  grid-template-columns: 40px minmax(0, 1fr) 70px;
  grid-template-areas: "t nm sec" "t bar bar" "t btns btns";
  align-items: center;
  gap: 6px 12px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.ov-rows-list .ov-row:last-child { border-bottom: 1px solid var(--line); }
.ov-row .t { grid-area: t; align-self: start; font-size: 24px; line-height: 1; color: var(--tag); }
.ov-row .nm { grid-area: nm; }
.ov-row .bar { grid-area: bar; }
.ov-row .sec { grid-area: sec; }
.ov-row .ov-row-btns { grid-area: btns; display: flex; gap: 8px; flex-wrap: wrap; }
.ov-row.on { box-shadow: inset 3px 0 0 var(--hi); padding-left: 8px; }
.ov-row .nm { font-weight: 600; }
.ov-row .nm small { display: block; font-weight: 400; color: var(--muted); font-size: 12px; }
.ov-row .bar {
  height: 12px;
  background: repeating-linear-gradient(90deg, var(--line) 0 6px, transparent 6px 8px);
  position: relative;
}
.ov-row .bar i { position: absolute; left: 0; top: 0; bottom: 0; background: var(--hi); }
.ov-row .sec { font-size: 20px; line-height: 1; text-align: right; }
.ov-row .sec small { font: 600 11px var(--font); margin-left: 3px; color: var(--muted); }

.ov-chartwrap {
  position: relative;
  flex: 1;
  min-height: 200px;
  margin: 0 2px 10px;
}
.ov-chartwrap canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.ov-tooltip {
  position: absolute;
  pointer-events: none;
  transform: translate(-50%, -115%);
  background: var(--panel);
  border: 1px solid var(--line2);
  color: var(--text);
  font-size: 12px;
  padding: 4px 8px;
  white-space: nowrap;
}
.ov-next {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 14px;
}
@media (max-width: 900px) {
  .ov-spec { grid-template-columns: 1fr; }
  .ov-spec > div + div { border-left: 0; border-top: 1px solid var(--line); }
  .v-overview { height: auto; min-height: 0; }
  .ov-body { grid-template-columns: 1fr; }
  .ov-map { min-height: 320px; }
  .ov-side { min-height: 420px; }
  .ov-rows-list .ov-row .bar { display: none; }
}

/* ============================================================ segments */
.segs {
  display: flex;
  gap: 4px;
  flex-wrap: wrap;
  align-items: center;
}
.segs .lab {
  font: 600 11px var(--font);
  color: var(--hi);
  text-transform: lowercase;
  letter-spacing: 0.06em;
  width: 60px;
}
.segs button {
  background: var(--panel2);
  border: 1px solid var(--line2);
  color: var(--text);
  font: 600 13px var(--mono);
  padding: 3px 0;
  width: 40px;
  cursor: pointer;
}
.segs.wide button { width: auto; padding: 3px 8px; }
.segs button:hover {
  border-color: var(--muted);
}
.segs button.sel {
  background: var(--text);
  border-color: var(--text);
  color: var(--bg);
}
.segname {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 12px 0 14px;
}
.segname-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
}
.segname .tag {
  font: 700 15px var(--mono);
  color: var(--tag);
}
.segname h2 {
  margin: 0;
  font: 600 24px var(--font);
}
.segname span.meta {
  color: var(--muted);
  font-size: 12.5px;
}

/* -------------------------------------------------------------- empty */
.empty {
  background: var(--panel);
  border: 1px dashed var(--line2);
  padding: 32px 24px;
  text-align: center;
  max-width: 480px;
  margin: 24px auto;
}
.empty h3 {
  margin: 0 0 6px;
  font: 600 18px var(--font);
}
.empty p {
  margin: 0 0 14px;
  color: var(--muted);
  font-size: 13px;
}

/* ==================================================== legacy classes ===
   Kept for views not yet restyled to the new class vocabulary above; mapped
   onto the same tokens so the whole app stays visually consistent. */
.notice {
  background: var(--panel);
  border: 1px dashed var(--line2);
  color: var(--muted);
  padding: 26px;
  text-align: center;
  font-size: 15px;
}
.notice code {
  background: var(--panel2);
  padding: 1px 6px;
  color: var(--text);
}
.hint {
  color: var(--dim);
  font-size: 12.5px;
}
kbd {
  font-family: var(--mono);
  font-size: 12px;
  background: var(--panel2);
  border: 1px solid var(--line2);
  padding: 0 5px;
}

/* ==================================================== scrollbars/uPlot */
::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}
::-webkit-scrollbar-thumb {
  background: var(--line2);
}
::-webkit-scrollbar-track {
  background: transparent;
}

.uplot {
  font-family: var(--font) !important;
}
.u-legend {
  display: none;
}
.u-select {
  background: color-mix(in srgb, var(--text) 15%, transparent);
}

/* scatter canvas box (same chrome as .map, flat panel2 ground) */
.scatter {
  position: relative;
  height: 520px;
  background: var(--panel2);
  overflow: hidden;
}
.scatter canvas {
  display: block;
  width: 100%;
}

/* Header fit: the logo lockup (wordmark, tagline, mark) is never hidden or
   shrunk. On a narrower window the control captions hide, then
   the gaps tighten; tabs that still don't fit move into the Advanced menu. */
@media (max-width: 1640px) {
  .ctrl-lab { display: none; }
  .hdr-controls { gap: 8px; }
  .hdr-controls .btn,
  .hdr-controls .seg button { padding: 0 9px; }
}
@media (max-width: 1500px) {
  header.top { gap: 12px; padding: 0 12px; }
  header.top .brand { padding-right: 8px; }
  .hdr-controls { padding-left: 12px; }
  .tabs { gap: 0; }
  .tabs .tab { padding: 0 8px; }
}

/* ======================================================== no data yet === */
/* Before any track day is imported: tabs stay visible but inert, and the
   lap list / compare bar (which have nothing to show) are hidden entirely so
   the welcome screen (views/welcome.js, mounted into #view) is the only
   thing in the content area. */
.app.days-view aside.picker,
.app.days-view .comparebar,
.app.days-view .title-row .meta {
  display: none;
}
.app.days-view {
  grid-template-columns: 0 minmax(0, 1fr);
}

/* --------------------------------------------------------- picker footer */
.picker-footer {
  flex: none;
  padding: 12px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.picker-footer .btn {
  width: 100%;
}
.picker-footer .storage-line {
  text-align: center;
  margin: 0;
}

/* -------------------------------------------------------------- welcome */
.welcome {
  max-width: 560px;
  margin: 48px auto;
  text-align: center;
}
.welcome h1 {
  font-size: 30px;
  margin-bottom: 6px;
}
.welcome .lead {
  color: var(--muted);
  font-size: 14.5px;
  margin: 0 0 28px;
}
.welcome .dropzone {
  border: 2px dashed var(--line2);
  padding: 40px 24px;
  background: var(--panel);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.welcome .dropzone.drag {
  border-color: var(--text);
  background: var(--panel2);
}
.welcome .dropzone .dz-label {
  font: 600 16px var(--font);
  margin: 0;
}
.welcome .dropzone .dz-or {
  color: var(--dim);
  font-size: 12px;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.welcome .privacy {
  color: var(--dim);
  font-size: 12px;
  margin: 20px 0 0;
}
.welcome.has-days h1 {
  display: none;
}
/* With days, Your days uses the width: totals, then the days as a table. */
.welcome.has-days {
  max-width: 1080px;
  margin: 20px auto;
  padding: 0 16px;
}
.welcome.has-days .lead:empty {
  display: none;
}
.welcome.has-days .dropzone {
  flex-direction: row;
  justify-content: center;
  padding: 14px 24px;
}
.dl-stats {
  margin-bottom: 14px;
}
.dl-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 4px;
}
.welcome-saved .dl-bar h2 {
  margin: 0 auto 0 0;
}
.dl-by {
  color: var(--muted);
  font-size: 12px;
}
.dl-bar .seg {
  border-radius: var(--radius-ctl);
}
.dl-group span {
  color: var(--muted);
  font-weight: 500;
  margin-left: 8px;
}
.dl-group {
  margin: 12px 0 0;
  font: 600 11px var(--mono, var(--font));
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--hi);
}
.welcome-saved .day-list li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 96px 110px 110px 76px;
  align-items: center;
  gap: 8px;
  padding: 0;
}
.welcome-saved .day-list li.dl-head {
  border-top: 0;
  padding: 4px 0 2px;
  color: var(--dim);
  font-size: 11.5px;
}
.dl-head span,
.dl-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.dl-num.is-best {
  padding: 2px 4px;
}
.dl-na {
  color: var(--dim);
  font-size: 12px;
}
.dl-rename {
  justify-self: end;
}
.dl-name {
  flex: 1;
  min-width: 0;
  margin: 6px 0;
  font: 600 14px var(--font);
  padding: 3px 6px;
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--muted);
  border-radius: var(--radius-ctl);
}
.welcome-saved li:has(.dl-name) .day-row {
  display: none;
}
.welcome-saved li:has(.dl-name) {
  grid-template-columns: minmax(0, 1fr) 96px 110px 110px 76px;
}
@media (max-width: 700px) {
  .welcome-saved .day-list li {
    grid-template-columns: minmax(0, 1fr) 80px 70px;
  }
  .welcome-saved .day-list li > :nth-child(2),
  .welcome-saved .day-list li > :nth-child(4) {
    display: none;
  }
  .dl-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.welcome-saved li.cur b {
  color: var(--hi);
}
.welcome-saved {
  text-align: left;
  margin: 0 0 20px;
  border: 1px solid var(--line2);
  background: var(--panel);
  padding: 12px 16px;
}
.welcome-saved h2 {
  font-size: 13px;
  margin: 0 0 6px;
}
.welcome-saved ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.welcome-saved li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-top: 1px solid var(--line);
}
.welcome-saved small {
  display: block;
  color: var(--dim);
}
.welcome-saved li:has(.day-row) {
  padding: 0;
}
/* A whole day row is the button that opens it (Your days, the account menu). */
.day-row {
  flex: 1;
  min-width: 0;
  display: block;
  text-align: left;
  background: none;
  border: 0;
  margin: 0;
  padding: 8px 6px;
  color: var(--text);
  font: inherit;
  cursor: pointer;
}
.day-row:hover,
.day-row:focus-visible {
  background: var(--panel2);
}
.day-row:focus-visible {
  outline: 1px solid var(--hi);
  outline-offset: -1px;
}
.day-row:disabled {
  cursor: progress;
}

/* --------------------------------------------------------- import panel */
.import-panel {
  position: fixed;
  top: 58px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  background: var(--panel);
  border: 1px solid var(--line2);
  box-shadow: none;
  padding: 12px 16px;
  min-width: 320px;
  max-width: 480px;
}
.import-panel .import-status {
  margin: 0;
  font-size: 13px;
}
.import-panel .import-status a {
  color: var(--text);
  font-weight: 600;
}
.import-panel .import-progress {
  margin-top: 8px;
  height: 5px;
  background: var(--panel2);
  overflow: hidden;
}
.import-panel .import-progress .bar {
  height: 100%;
  background: var(--text);
  width: 0%;
}
.import-panel .import-actions {
  margin-top: 10px;
  display: flex;
  gap: 8px;
}
.import-panel[hidden],
.import-panel .import-actions[hidden],
.import-panel .import-progress[hidden] {
  display: none;
}

/* ============================================================ coaching */
.co-spec { grid-template-columns: 1.3fr 1fr; }
.co-tips .co-tip {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) 130px 100px auto;
  align-items: center;
  gap: 14px;
  padding: 10px 0;
  border-top: 1px solid var(--line);
}
.co-tips .co-tip:last-child { border-bottom: 1px solid var(--line); }
.co-tip .t { font-size: 24px; line-height: 1; color: var(--tag); }
.co-tip .nm { font-weight: 600; }
.co-tip .nm small { display: block; font-weight: 400; color: var(--muted); font-size: 12px; margin-top: 2px; }
.co-tip .sec { font-size: 20px; line-height: 1; text-align: right; color: var(--hi); margin: 0; overflow: visible; }
.co-tip .sec small { font: 600 11px var(--font); margin-left: 3px; color: var(--muted); }
.co-tip .conf { font-size: 12px; color: var(--muted); }
.co-tip .conf-high { color: var(--text); font-weight: 600; }
.co-tip .conf-low { color: var(--dim); }
.co-limits, .co-caveats { margin: 8px 0 0; padding-left: 18px; color: var(--muted); }
.co-limits li, .co-caveats li { margin: 4px 0; }
.co-limits .tag, .v-coaching td .tag { font: 700 12px var(--mono); color: var(--tag); }
.co-back { margin-bottom: 4px; }
.co-lab { font: 600 11px var(--font); color: var(--hi); text-transform: lowercase; letter-spacing: 0.06em; margin-right: 8px; }
.segname .meta .co-find { color: var(--hi); font-weight: 600; }
.co-why { margin: 8px 0 0; padding-left: 20px; }
.co-why li { margin: 6px 0; line-height: 1.5; }
.co-check { margin: 8px 0 0; line-height: 1.5; }
.co-marks td:first-child { color: var(--muted); }
.co-marks th .sw { margin-right: 6px; }
.co-key { position: absolute; right: 10px; top: 10px; }
.co-phases { display: flex; border: 1px solid var(--line); margin-top: 10px; }
.co-phase { position: relative; padding: 8px 10px 12px; min-width: 72px; overflow: hidden; }
.co-phase + .co-phase { border-left: 1px solid var(--line); }
.co-phase i { position: absolute; left: 0; bottom: 0; height: 4px; background: var(--hi); pointer-events: none; }
.co-phase .lab, .co-phase .v, .co-phase .m { position: relative; display: block; white-space: nowrap; }
.co-phase .lab { font: 600 11px var(--font); color: var(--text); text-transform: lowercase; letter-spacing: 0.06em; }
.co-phase .v { font: 600 15px var(--font); }
.co-phase .m { font-size: 11px; color: var(--muted); }
.co-stack { margin: 18px 0; }
/* Track split on one screen (views/tracksplit.js): pickers and name on top,
   the map left, the lap table or traces right. */
.content:has(> .ts-view) { padding-bottom: 12px; }
.ts-view { display: flex; flex-direction: column; height: 100%; min-height: 480px; }
.ts-pick { flex: none; display: flex; flex-wrap: wrap; gap: 6px 22px; }
.ts-view .segname { flex: none; margin: 8px 0 10px; }
.ts-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 14px; }
.ts-mappanel { display: flex; flex-direction: column; min-height: 280px; }
.ts-mappanel .map { flex: 1; min-height: 0; }
.ts-nolap { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); padding: 12px 16px; text-align: center; }
.ts-nolap p { margin: 0 0 8px; }
.ts-panel { padding: 10px 12px; }
.ts-panel .sec { margin-top: 0; }
@media (max-width: 900px) {
  .ts-view { height: auto; }
  .ts-body { grid-template-columns: 1fr; }
  .ts-mappanel { min-height: 320px; }
  .ts-body .ov-side { min-height: 420px; }
}
/* A tip fits one screen: title and Previous/Next on top, the map on the
   left, one tab at a time on the right (the Overview's side tabs). */
.content:has(> .co-tipview),
.content:has(> .co-listview) { padding-bottom: 12px; }
.co-listview { display: flex; flex-direction: column; height: 100%; min-height: 420px; }
.co-listview .co-spec { flex: none; }
.co-listtabs { flex: 1; min-height: 0; }
.co-listtabs .ov-tab { flex: none; padding: 9px 14px 7px; }
@media (max-width: 900px) {
  .co-listview { height: auto; }
}
.co-tipview { display: flex; flex-direction: column; height: 100%; min-height: 480px; }
.co-top { flex: none; }
.co-nav { display: flex; align-items: center; gap: 8px; margin-top: 4px; }
.co-pos { color: var(--muted); font-size: 12.5px; padding: 0 4px; }
.co-nav .btn:disabled { opacity: 0.4; cursor: default; }
.co-tipview .segname { margin: 10px 0 12px; }
.co-body { flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 6fr); gap: 14px; }
.co-left { display: flex; flex-direction: column; gap: 10px; min-height: 0; min-width: 0; }
.co-against { flex: none; height: auto; }
.co-mappanel { flex: 1; min-height: 280px; display: flex; flex-direction: column; }
.co-mappanel .map { flex: 1; min-height: 0; }
.co-panel { padding: 12px 14px; }
.co-panel .co-stack { margin: 12px 0 0; }
.co-panel .sec-head { margin-top: 0; }
@media (max-width: 900px) {
  .co-tipview { height: auto; }
  .co-body { grid-template-columns: 1fr; }
  .co-mappanel { min-height: 320px; }
  .co-body .ov-side { min-height: 420px; }
}
@media (max-width: 900px) {
  .co-spec { grid-template-columns: 1fr; }
  .co-tips .co-tip { grid-template-columns: 44px 1fr 80px; }
  .co-tips .co-tip .conf,
  .co-tips .co-tip .btn { display: none; }
  .co-key { position: static; max-width: none; }
}
.co-tips .co-tip { cursor: pointer; }
.co-tips .co-tip:hover { background: var(--panel); }
/* Track map driving overlays (trackmap.js, lap-markers.js) */
/* The driving-marks key (marks-key.js): each mark drawn as on the map, with
   its label, two to a row. Glyphs use the text colour so they read on any
   lap colour; the thin line through each is the lap. */
.marks-key {
  display: grid;
  grid-template-columns: auto auto;
  gap: 2px 14px;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  border: 1px solid var(--line2);
  padding: 5px 10px;
  font-size: 12px;
  color: var(--text);
  pointer-events: auto;
  z-index: 2;
}
.marks-key[hidden] { display: none; }
/* Each item is the switch for its mark: dimmed and struck through when off. */
.marks-key .mk-item {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  background: none;
  border: 0;
  padding: 1px 2px;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.marks-key .mk-item:hover { color: var(--hi); }
.marks-key .mk-item.off { color: var(--dim); text-decoration: line-through; }
.marks-key .mk-item.off svg { opacity: 0.35; }
.marks-key .mk-hollow { fill: var(--bg); stroke: var(--text); stroke-width: 2.5; }
.marks-key svg { flex: none; position: static; width: 22px; height: 22px; inset: auto; }
.marks-key .mk-line { stroke: var(--muted); stroke-width: 2; fill: none; }
.marks-key .mk-fill { fill: var(--text); }
.marks-key .mk-solid { fill: var(--text); stroke: var(--bg); stroke-width: 1.5; }
.marks-key .mk-ring { fill: none; stroke: var(--text); stroke-width: 2.5; }
.marks-key .mk-bar { stroke: var(--text); stroke-width: 2.5; }
.tm-key {
  position: absolute;
  right: 10px;
  top: 46px;
}
.ov-key {
  position: absolute;
  right: 10px;
  bottom: 10px;
}
.ts-key {
  position: absolute;
  right: 10px;
  top: 10px;
}
.pg-key {
  display: inline-grid;
  margin-top: 6px;
  background: none;
}
.tm-overlays { flex-wrap: wrap; }
@media (max-width: 900px) {
  .tm-key { display: none; }
}
/* Math channels form (views/channels.js) */
.mc-form { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px; margin: 12px 0 6px; }
.mc-form input { padding: 6px 8px; background: var(--bg); color: var(--text); border: 1px solid var(--line2); border-radius: 0; font: 13px var(--font); }
.mc-expr { flex: 1; min-width: 260px; }
.mc-expr input { width: 100%; font-family: "IBM Plex Mono", monospace; }
.mc-error { margin: 4px 0; color: var(--warn); }
/* Phones: the logo alone on the first row, then every header control on a
   row of its own that wraps (so Sign in / the account menu is never scrolled
   out of sight beside the logo), then the view tabs. */
@media (max-width: 600px) {
  header.top.two-row {
    grid-template-rows: 56px auto 44px;
  }
  header.top .brand small,
  header.top .brand .mark {
    display: none;
  }
  header.top .brand b {
    font-size: 28px;
  }
  header.top.two-row .hdr-controls {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: stretch;
    flex-wrap: wrap;
    height: auto;
    gap: 8px;
    padding: 8px 0 10px;
    border-left: 0;
    border-top: 1px solid var(--line);
    overflow: visible;
  }
  header.top.two-row .hdr-controls .ctrl {
    height: var(--hdr-ctl);
  }
  header.top.two-row .hdr-controls .ctrl-lab {
    display: none;
  }
  header.top.two-row .tabs {
    grid-row: 3;
  }
  header.top.two-row .places {
    grid-column: 2;
    grid-row: 1;
    justify-self: start;
    height: 56px;
    margin: 0;
    padding: 0;
    border-top: 0;
  }
  header.top.two-row .places .place-btn .ico,
  header.top.two-row .place-switch .ico {
    display: none;
  }
  header.top.two-row .nav-div {
    display: none;
  }
}
/* Phones: the account and AI panels span the screen; anchored to their
   button's right edge they ran off the left side once the controls wrap. */
@media (max-width: 600px) {
  .acct-menu,
  .ai-menu {
    left: 16px !important;
    right: 16px !important;
    width: auto;
  }
}
/* Phones: Analyze is one column that scrolls as a page (header, compare bar,
   lap list when shown, then the view) instead of a 280px lap list beside a
   view squeezed to a sliver. */
@media (max-width: 600px) {
  .app,
  .app.picker-hidden {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto auto;
    height: auto;
    min-height: 100vh;
    overflow: visible;
  }
  header.top {
    grid-column: 1;
  }
  .comparebar {
    grid-column: 1;
    grid-row: 2;
    padding: 8px 16px;
  }
  aside.picker {
    grid-column: 1;
    grid-row: 3;
    max-height: 55vh;
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  #viewWrap {
    grid-column: 1;
    grid-row: 4;
  }
  .title-row {
    flex-wrap: wrap;
    padding: 12px 16px 8px;
  }
  .content {
    overflow: visible;
    padding: 4px 16px 40px;
  }
}
@media (max-width: 600px) {
  .ov-next {
    flex-wrap: wrap;
  }
}
/* Phones: Time-distance's map and "At the cursor" table stack, full width. */
@media (max-width: 600px) {
  .v-td.narrow .td-side {
    flex-direction: column;
  }
  .v-td.narrow .td-side .panel {
    width: auto;
  }
}
/* Phones: nothing in a view may be wider than the screen. Map-and-panel
   pairs shrink to it, section headings wrap, and wide tables scroll on
   their own instead of pushing the whole page sideways. */
@media (max-width: 600px) {
  .cols-map,
  .cols-2 {
    grid-template-columns: minmax(0, 1fr);
  }
  .cols-map > *,
  .cols-2 > * {
    min-width: 0;
  }
  .sec-head {
    flex-wrap: wrap;
  }
  .content table.t {
    display: block;
    max-width: 100%;
    overflow-x: auto;
  }
}
@media (max-width: 600px) {
  .sec-head .meta {
    white-space: normal;
  }
}
/* Phones: toolbar controls in a view keep their own height and wrap;
   the map's desktop hint plate gives way to the zoom buttons. */
@media (max-width: 600px) {
  .content .toolbar .ctrl {
    height: auto;
    flex-wrap: wrap;
  }
  .map-hintplate {
    display: none;
  }
  .map .readout {
    top: 52px;
    min-width: 0;
  }
}
/* Phones: iOS Safari zooms the whole page into any text field under 16px
   when it's tapped, and doesn't zoom back out. */
@media (max-width: 600px) {
  input:not([type="checkbox"]):not([type="radio"]),
  select,
  textarea {
    font-size: 16px !important;
  }
}
/* The Menu button only exists on phones (below). */
.hdr-more {
  display: none;
}
/* Phones: one short row for the logo and a Menu button; the controls open
   under it on demand, then the view tabs, so content starts near the top. */
@media (max-width: 600px) {
  header.top.two-row .hdr-more {
    display: inline-flex;
    align-items: center;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    align-self: center;
    height: 36px;
    padding: 0 14px;
    border-radius: var(--hdr-radius);
    font: 600 12px var(--mono);
    text-transform: uppercase;
    letter-spacing: 0.06em;
  }
  header.top.two-row:not(.more-open) .hdr-controls {
    display: none;
  }
}

/* ============================================================== notebook
   views/notebook.js: one stack of cells (config left, result right), an
   Agent panel on the right, App mode as a two-column dashboard. Buttons,
   chips and segmented controls are rounded like the header's controls. */
.content:has(> .nb-view) { padding-bottom: 12px; }
.nb-view { --nb-r: var(--radius-ctl); display: flex; flex-direction: column; height: 100%; min-height: 480px; }
.nb-bar { flex: none; display: flex; align-items: flex-end; gap: 12px; border-bottom: 1px solid var(--line); margin-bottom: 10px; flex-wrap: wrap; }
.nb-tabs { display: flex; gap: 4px; }
.nb-tab { display: inline-flex; align-items: center; gap: 6px; background: none; border: 0; border-bottom: 2px solid transparent; color: var(--muted); font: 600 12px var(--mono); text-transform: uppercase; letter-spacing: 0.05em; padding: 8px 8px 6px; cursor: pointer; }
.nb-tab:hover { color: var(--text); }
.nb-tab.on { color: var(--text); border-bottom-color: var(--accent); }
.nb-ico { width: 14px; height: 14px; flex: none; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.nb-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding-bottom: 6px; }
.nb-sep { width: 1px; height: 18px; background: var(--line2); margin: 0 4px; }
.nb-btn { display: inline-flex; align-items: center; gap: 5px; background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--nb-r); color: var(--text); font: 500 12.5px var(--font); padding: 4px 10px; cursor: pointer; white-space: nowrap; }
.nb-btn:hover:not(:disabled) { border-color: var(--muted); }
.nb-btn:disabled { opacity: 0.5; cursor: default; }
.nb-btn.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); font-weight: 600; }
.nb-btn.on { border-color: var(--accent); color: var(--accent); }
.nb-ibtn { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; background: none; border: 1px solid transparent; border-radius: var(--nb-r); color: var(--muted); cursor: pointer; }
.nb-ibtn:hover:not(:disabled) { color: var(--text); border-color: var(--line2); }
.nb-ibtn:disabled { opacity: 0.35; cursor: default; }
.nb-link { background: none; border: 0; padding: 2px 4px; color: var(--accent); font: 500 12px var(--font); cursor: pointer; }
.nb-main { flex: 1; min-height: 0; display: flex; gap: 12px; }
.nb-stack { flex: 1; min-width: 0; overflow: auto; display: flex; flex-direction: column; gap: 10px; padding-right: 2px; }
.nb-none { padding: 30px; text-align: center; color: var(--muted); border: 1px dashed var(--line2); }

.nb-cell { flex: none; background: var(--panel); border: 1px solid var(--line); display: flex; flex-direction: column; min-width: 0; transition: box-shadow 0.3s; }
.nb-cell.flash { box-shadow: 0 0 0 2px var(--accent); }
.nb-cell-h { display: flex; align-items: center; gap: 8px; min-height: 36px; padding: 5px 8px; border-bottom: 1px solid var(--line); min-width: 0; }
.nb-cell.collapsed .nb-cell-h { border-bottom: 0; }
.nb-cell.collapsed .nb-fold .nb-ico { transform: rotate(-90deg); }
.nb-kind { display: inline-flex; align-items: center; gap: 5px; color: var(--hi); font: 600 10.5px var(--mono); text-transform: uppercase; letter-spacing: 0.06em; white-space: nowrap; }
.nb-title { flex: 0 1 280px; min-width: 80px; background: transparent; border: 1px solid transparent; border-radius: var(--nb-r); color: var(--text); font: 600 13.5px var(--font); padding: 3px 6px; }
.nb-title:hover, .nb-title:focus { border-color: var(--line2); background: var(--bg); }
.nb-title::placeholder { color: var(--text); opacity: 1; }
.nb-sum { display: flex; gap: 5px; flex-wrap: nowrap; overflow: hidden; min-width: 0; flex: 1; color: var(--muted); font-size: 12px; white-space: nowrap; text-overflow: ellipsis; }
.nb-cell-acts { display: flex; gap: 2px; margin-left: auto; flex: none; }
.nb-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--nb-r); padding: 1px 8px; font: 500 11.5px var(--font); color: var(--text); white-space: nowrap; }
.nb-chip.tag { color: var(--tag); }
.nb-chip button { background: none; border: 0; padding: 0 0 0 2px; color: var(--muted); cursor: pointer; font-size: 13px; line-height: 1; }
button.nb-chip { cursor: pointer; }
button.nb-chip:hover { border-color: var(--muted); }

.nb-cell-b { display: flex; height: 280px; min-height: 0; }
.nb-cell.tall .nb-cell-b { height: 460px; }
.nb-cfg { flex: none; width: 250px; border-right: 1px solid var(--line); display: flex; flex-direction: column; min-height: 0; }
.nb-cfgtabs { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; margin: 8px 8px 0; padding: 2px; background: var(--bg); border-radius: var(--nb-r); }
.nb-cfgtabs button { background: none; border: 0; border-radius: var(--nb-r); padding: 4px; color: var(--muted); font: 600 12px var(--font); cursor: pointer; }
.nb-cfgtabs button.on { background: var(--panel2); color: var(--text); }
.nb-cfgpane { flex: 1; min-height: 0; overflow: auto; padding: 8px; display: flex; flex-direction: column; gap: 7px; }
.nb-f { display: grid; grid-template-columns: 62px minmax(0, 1fr); align-items: center; gap: 6px; }
.nb-f-col { grid-template-columns: 1fr; gap: 5px; }
.nb-l { color: var(--hi); font: 600 10.5px var(--mono); text-transform: uppercase; letter-spacing: 0.06em; }
.nb-cfg select, .nb-cfg input { width: 100%; min-width: 0; background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--nb-r); color: var(--text); font: 500 12.5px var(--font); padding: 3px 6px; }
.nb-fixed { color: var(--muted); font-size: 12.5px; padding: 3px 0; }
.nb-picks { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.nb-pick { background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--nb-r); color: var(--tag); font: 600 11px var(--mono); padding: 2px 6px; cursor: pointer; }
.nb-pick.on { background: var(--tag); border-color: var(--tag); color: var(--bg); }
.nb-seg { display: inline-flex; border: 1px solid var(--line2); border-radius: var(--nb-r); overflow: hidden; }
.nb-seg button { background: transparent; border: 0; color: var(--muted); font: 500 12px var(--font); padding: 3px 8px; cursor: pointer; }
.nb-seg button + button { border-left: 1px solid var(--line2); }
.nb-seg button.on { background: var(--text); color: var(--bg); }
.nb-cond { display: flex; flex-direction: column; gap: 4px; padding: 6px; border: 1px solid var(--line); border-radius: var(--nb-r); }
.nb-cond2 { display: flex; align-items: center; gap: 4px; }
.nb-cond2 input { width: 64px; flex: 1; }
.nb-u { color: var(--muted); font-size: 12px; }
.nb-note { margin: 0; color: var(--muted); font-size: 12px; line-height: 1.4; }
.nb-merr { margin: 0; color: var(--bad); font-size: 12px; }
.nb-merr:empty { display: none; }

.nb-body { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
.nb-body > .hint, .nb-body > .notice { margin: 12px; }
.nb-body .panel { border: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.nb-body .panel-h h3:empty { display: none; }
.nb-body .panel-h .val { flex-wrap: nowrap; overflow-x: auto; margin-left: 0; scrollbar-width: none; }
.nb-f-col > .nb-link { justify-self: start; }
.nb-lg { cursor: pointer; user-select: none; }
.nb-lg.off { opacity: 0.4; text-decoration: line-through; }
.nb-err { margin: 0; padding: 4px 10px; font-size: 12px; }
.nb-canvas { flex: 1; min-height: 0; position: relative; }
.nb-canvas canvas { position: absolute; inset: 0; cursor: crosshair; }
.nb-tip { position: absolute; pointer-events: none; background: var(--bg); border: 1px solid var(--line2); border-radius: var(--nb-r); padding: 3px 8px; font-size: 12px; color: var(--muted); white-space: nowrap; }
.nb-tip b { color: var(--text); font-variant-numeric: tabular-nums; }
.nb-tip i { display: inline-block; width: 8px; height: 8px; margin-right: 5px; }
.nb-table { overflow: auto; flex: 1; min-height: 0; padding: 6px 10px; }
.nb-table table { border-collapse: collapse; font: 12.5px var(--font); font-variant-numeric: tabular-nums; }
.nb-table th, .nb-table td { padding: 4px 12px; border-bottom: 1px solid var(--line); text-align: right; white-space: nowrap; }
.nb-table th[scope="row"] { text-align: left; font-weight: 500; color: var(--text); }
.nb-table th small { color: var(--muted); }
.nb-table thead th, .nb-table tr:first-child th { color: var(--muted); font-weight: 600; }
.nb-table th .nb-lg { display: inline-flex; align-items: center; gap: 5px; }
.nb-table th .nb-lg i { width: 8px; height: 8px; }
.nb-table th.off .nb-lg { opacity: 0.4; text-decoration: line-through; }
.nb-table .nb-span th, .nb-table .nb-span td { color: var(--muted); }
.nb-table .hint { margin: 6px 0 0; }
.nb-formula { margin: 8px 10px 0; font-size: 12.5px; color: var(--muted); }
.nb-formula b { color: var(--text); }
.nb-formula code { font: 12px var(--mono); color: var(--text); }
.nb-mathplot { flex: 1; min-height: 0; display: flex; flex-direction: column; }

/* Agent */
.nb-agent { flex: none; width: 300px; display: flex; flex-direction: column; min-height: 0; background: var(--panel); border: 1px solid var(--line); }
.nb-agent-h { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.nb-agent-h .nb-ico { color: var(--accent); }
.nb-agent-src { margin-left: auto; color: var(--muted); font-size: 12px; }
.nb-agent-log { flex: 1; min-height: 0; overflow: auto; padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.nb-msg { font-size: 13px; line-height: 1.4; display: flex; flex-direction: column; gap: 5px; }
.nb-msg p { margin: 0; }
.nb-msg.you { align-self: flex-end; max-width: 90%; background: var(--panel2); border: 1px solid var(--line2); border-radius: var(--nb-r); padding: 5px 9px; }
.nb-msg.busy { color: var(--muted); }
.nb-made { display: flex; align-items: center; gap: 6px; text-align: left; background: var(--bg); border: 1px solid var(--line2); border-radius: var(--nb-r); color: var(--text); font: 500 12.5px var(--font); padding: 6px 8px; cursor: pointer; }
.nb-made:hover { border-color: var(--muted); }
.nb-sugg { display: flex; flex-wrap: wrap; gap: 5px; }
.nb-ask { flex: none; display: flex; flex-direction: column; gap: 6px; padding: 8px; border-top: 1px solid var(--line); }
.nb-ask textarea { resize: none; background: var(--bg); border: 1px solid var(--line2); border-radius: var(--nb-r); color: var(--text); font: 13px var(--font); padding: 6px 8px; }
.nb-ask .nb-btn { align-self: flex-end; }

/* App mode: the charts and tables as a dashboard, two per row */
.nb-view.app .nb-stack { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: start; }
.nb-view.app .nb-cell-h { min-height: 34px; }
.nb-view.app .nb-cell-h h3 { margin: 0; font: 600 13.5px var(--font); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nb-view.app .nb-body { height: 300px; flex: none; }
.nb-view.app .nb-table-cell, .nb-view.app .nb-table { grid-column: auto; }

@media (max-width: 1100px) {
  .nb-agent { width: 260px; }
  .nb-cfg { width: 220px; }
}
@media (max-width: 800px) {
  .nb-main { flex-direction: column; }
  .nb-agent { width: auto; max-height: 320px; }
  .nb-cell-b { flex-direction: column; height: auto; }
  .nb-cfg { width: auto; border-right: 0; border-bottom: 1px solid var(--line); max-height: 240px; }
  .nb-body { height: 260px; flex: none; }
  .nb-view.app .nb-stack { grid-template-columns: 1fr; }
  .nb-sum { display: none; }
}
/* ---- Rounded controls (Giulio, 2026-09-30) ------------------------------
   Every button, chip, segmented control and dropdown takes the header's
   slight radius (--radius-ctl, tokens.json "radius-ctl"). Panels, tables,
   swatches and plates stay square. New controls get it by using .btn,
   .seg, .chip or .mapctl. */
:root { --radius-ctl: 4px; }
.btn,
.seg,
.chip,
.segs button,
.place-btn,
select {
  border-radius: var(--radius-ctl);
}
.seg { overflow: hidden; }
.chip-x { border-radius: 0 var(--radius-ctl) var(--radius-ctl) 0; }
.mapctl > .mc:first-child { border-radius: var(--radius-ctl) 0 0 var(--radius-ctl); }
.mapctl > .mc:last-child { border-radius: 0 var(--radius-ctl) var(--radius-ctl) 0; }
.ov-mapctl > .mapctl > .mc:last-child { border-radius: 0; }
.ov-mapctl > .mc:last-child { border-radius: 0 var(--radius-ctl) var(--radius-ctl) 0; }
.td-gapref { display: inline-block; padding: 5px 0; font: 600 12.5px var(--font); color: var(--text); }
.t th .th-u { display: block; font: 500 10.5px var(--font); color: var(--dim); text-transform: none; letter-spacing: 0; white-space: nowrap; }
.t-scroll { overflow-x: auto; }
.t-scroll .t td:first-child, .t-scroll .t th:first-child { position: sticky; left: 0; z-index: 1; background: var(--panel); }
/* chart x-zoom (chart.js): the stretch being picked, and the reset */
.zoom-sel { position: absolute; top: 0; bottom: 0; background: color-mix(in srgb, var(--accent) 18%, transparent); border-left: 1px solid var(--accent); border-right: 1px solid var(--accent); pointer-events: none; }
.panel-h .zoom-reset { margin-left: 8px; flex: none; }
.panel-h .zoom-reset[hidden] { display: none; }
.map svg.sw-shape, .sw-shape { position: static; inset: auto; width: 12px; height: 12px; flex: none; }
