/* chrome.css — the shell: nameplate (topbar), brand, mark, nav, theme control,
 * the header search, the collector banner, the footer colophon, and the route
 * transition.
 *
 * The topbar, banner and footer each get their own inner wrapper that
 * reproduces the canvas track maths — max content width plus the gutter — so
 * the brand lines up with the rail column without being a grid child of <main>.
 */

.topbar-inner,
.banner-slot,
.footer-inner {
  width: 100%;
  max-width: calc(var(--w-page) + 2 * var(--s-gutter));
  margin-inline: auto;
  padding-inline: var(--s-gutter);
}

/* ---------------------------------------------------------------- topbar
 *
 * A newspaper nameplate: opaque (it carries the same grain as the page, so it
 * reads as the same sheet), ruled off beneath, brand hard left, search, then
 * nav and the theme control hard right. It never wraps: a masthead that grows
 * a second line moves every page beneath it. */
.topbar {
  position: sticky; top: 0; z-index: 40;
  background-color: var(--bg);
  background-image: var(--grain);
  border-bottom: var(--edge);
  box-shadow: inset 0 -1px 0 var(--halo);
}

.topbar-inner {
  min-height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--s-4);
}

.brand {
  display: flex; align-items: center; gap: 10px;
  flex: none;
  min-height: 44px;
  color: var(--ink);
}
.brand:hover { color: var(--ink); }
.brand:hover .brand-sub { color: var(--accent); }
.brand-text {
  display: inline-flex; align-items: baseline; gap: 0.3em;
  white-space: nowrap;
  font-family: var(--font-display);
  font-size: var(--t-lg);
  line-height: 1;
  letter-spacing: -0.012em;
}
.brand-name { font-weight: 720; }
.brand-sub {
  font-style: italic;
  font-weight: 380;
  color: var(--ink-2);
  transition: color var(--dur-2) var(--ease-out);
}

/* The mark: four ticks on an axis — the product's core idea, and it reads as a
 * tally or a signature at 22px. The last tick is "now" and is the only
 * chromatic thing in the nameplate. */
.mark { flex: none; }
.mark-axis, .mark-tick { stroke: var(--ink); }
.mark-now { stroke: var(--accent); }

/* The strip scrolls rather than wraps, for the same reason the bar never does. */
.nav {
  display: flex; gap: 2px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.nav::-webkit-scrollbar { display: none; }

/* 44px hit area. Emphasis comes from a rule and a weight change, never from a
 * fill — so the active state survives greyscale. */
.nav-link {
  position: relative;
  flex: none; white-space: nowrap;
  display: inline-flex; align-items: center; min-height: 44px;
  padding: 0 12px;
  color: var(--ink-2);
  font-size: var(--t-sm); font-weight: 520;
  transition: color var(--dur-2) var(--ease-out);
}
.nav-link:hover { color: var(--ink); }
.nav-link[aria-current='page'] { color: var(--ink); font-weight: 680; }
.nav-link::after {
  content: '';
  position: absolute; left: 12px; right: 12px; bottom: 8px;
  height: var(--bw-2); background: var(--rule-strong);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-3) var(--ease-out);
}
.nav-link:hover::after { transform: scaleX(0.35); }
.nav-link[aria-current='page']::after { transform: scaleX(1); }

/* The theme control: a drawn disc (outline = light, filled = dark, half =
 * auto) plus the word. The disc is decoration; the word and the sr-only prefix
 * in index.html carry the state. */
.theme-control {
  flex: none;
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 36px; min-width: 44px; padding: 0 10px;
  background: transparent; color: var(--ink-2);
  border: var(--edge); border-radius: var(--r-full);
  font-family: var(--font-mono); font-size: var(--t-3xs); font-weight: 600;
  letter-spacing: var(--tr-label); text-transform: uppercase;
  transition: color var(--dur-1), border-color var(--dur-1), background-color var(--dur-1);
}
.theme-control:hover { color: var(--ink); border-color: var(--ink); background: var(--ink-wash); }
.theme-glyph {
  flex: none;
  width: 12px; height: 12px;
  border-radius: var(--r-full);
  border: 1.5px solid currentColor;
  background: linear-gradient(90deg, currentColor 50%, transparent 50%);
}
.theme-control[data-pref='light'] .theme-glyph { background: transparent; }
.theme-control[data-pref='dark'] .theme-glyph { background: currentColor; }

/* ---------------------------------------------------- header search
 *
 * Search is a capability, not a page. The field is a rule you write on: no
 * fill, no radius, no box. It carries the auto margin, so the brand sits hard
 * left and nav + theme sit hard right with the field between. */

.hdr-search {
  position: relative;
  flex: 1 1 180px; min-width: 0; max-width: 360px;
  margin-right: auto;
}

.hdr-field {
  display: flex; align-items: center; gap: 8px;
  min-height: 40px; padding: 0 0 2px;
  background: transparent;
  border: none; border-bottom: var(--bw-1) solid var(--rule);
  border-radius: 0;
  transition-property: border-color, box-shadow;
  transition-duration: var(--dur-2);
  transition-timing-function: var(--ease-snap);
}
/* The focused rule is 1px of border plus 1px of INSET SHADOW rather than a
 * border-width change: animating border-width reflows the bar. */
.hdr-field:hover { border-bottom-color: var(--ink-3); }
.hdr-field:focus-within {
  border-bottom-color: var(--accent);
  box-shadow: inset 0 -2px 0 -1px var(--accent);
}

.hdr-icon { color: var(--ink-3); font-size: 16px; line-height: 1; flex: none; }

.hdr-input {
  flex: 1; min-width: 0;
  background: none; border: none; outline: none;
  color: var(--ink); font: inherit; font-size: var(--t-sm);
}
.hdr-input::placeholder { color: var(--ink-3); }
.hdr-input::-webkit-search-cancel-button { appearance: none; }

.hdr-key {
  flex: none;
  padding: 1px 6px;
  border: var(--edge-soft); border-radius: var(--r-1);
  color: var(--ink-3); font-family: var(--font-mono); font-size: var(--t-3xs);
  line-height: 1.4;
}

/* The narrow-viewport trigger. Hidden above 720px, where the field itself fits. */
.hdr-toggle {
  display: none;
  place-items: center;
  width: 44px; height: 44px;
  background: transparent; border: 1px solid transparent; border-radius: var(--r-full);
  color: var(--ink-2); font-size: 19px; line-height: 1;
  transition-property: color, border-color; transition-duration: var(--dur-1);
}
.hdr-toggle:hover { color: var(--ink); border-color: var(--rule); }

.hdr-panel {
  position: absolute; z-index: 45;
  top: calc(100% + 6px); left: 0;
  width: min(420px, calc(100vw - 2 * var(--s-gutter)));
  max-height: min(66vh, 480px); overflow-y: auto;
  background: var(--surface);
  border: var(--edge);
  border-radius: var(--r-2);
  box-shadow: var(--shadow-lift), inset 0 1px 0 var(--halo);
  animation: hdr-drop var(--dur-2) var(--ease-snap) both;
}
@keyframes hdr-drop {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

.hdr-group + .hdr-group { border-top: var(--edge-soft); }
.hdr-group-label { padding: 10px var(--s-4) 4px; }

.hdr-opt {
  display: flex; align-items: center; gap: var(--s-2);
  min-height: 44px;
  padding: 8px var(--s-4);
  border-bottom: var(--edge-hair);
  color: var(--ink); font-size: var(--t-sm);
  cursor: pointer;
}
.hdr-opt:last-child { border-bottom: none; }
/* Hover and keyboard produce the SAME highlight. */
.hdr-opt:hover, .hdr-opt.is-active { background: var(--ink-wash); color: var(--ink); }
.hdr-opt.is-active { box-shadow: inset 2px 0 0 var(--accent); }

.hdr-opt-name {
  min-width: 0; flex: 1;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hdr-opt-id {
  flex: none; color: var(--ink-3);
  font-family: var(--font-mono); font-size: var(--t-3xs);
}
.hdr-opt-side {
  flex: none; color: var(--ink-3);
  font-size: var(--t-2xs); font-variant-numeric: tabular-nums;
}
.hdr-opt-all { color: var(--accent); font-weight: 600; }

.hdr-empty { padding: var(--s-4); color: var(--ink-3); font-size: var(--t-sm); }

/* Below 720px the field collapses to a button in the bar and expands as an
 * overlay row directly under it. --topbar-h never changes, so nothing shifts. */
@media (max-width: 44.9375rem) {
  .topbar-inner { gap: var(--s-2); }
  .hdr-search { flex: none; max-width: none; margin-left: auto; margin-right: 0; order: 2; }
  .nav { order: 3; }
  .theme-control { order: 4; }
  .hdr-key { display: none; }
  .hdr-toggle { display: inline-grid; }
  .hdr-dock { display: none; }
  .hdr-search.is-open .hdr-dock {
    display: block;
    position: fixed; z-index: 45;
    top: var(--topbar-h); left: 0; right: 0;
    padding: var(--s-2) var(--s-gutter) var(--s-4);
    background: var(--bg);
    border-bottom: var(--edge);
  }
  .hdr-search.is-open .hdr-panel {
    position: static;
    width: auto; margin-top: var(--s-2);
    max-height: min(58vh, 420px);
  }
  .nav-link { padding: 0 8px; }
  .nav-link::after { left: 8px; right: 8px; }
  .theme-label { display: none; }
  .theme-control { min-width: 44px; justify-content: center; padding: 0; width: 44px; height: 44px; }
}

/* Phone width: the nameplate keeps its name and drops the italic "Tracker",
 * and the "Groups" link steps out of the bar — the nameplate itself goes home,
 * and the footer carries the link on every page. Measured at 375px: with both
 * it needed ~420px and the strip scrolled "Feedback" out of sight. */
@media (max-width: 29.9375rem) {
  .brand-sub { display: none; }
  .brand { gap: 7px; }
  .brand-text { font-size: var(--t-base); }
  .nav-link[data-match='home'] { display: none; }
}

/* ---------------------------------------------------------------- banner
 *
 * Reserved for the COLLECTOR being down, or the server being unreachable. Not
 * for an old figure: a figure that is old is not wrong, and the site's whole
 * argument is that it says how old. */
.banner-slot:empty { display: none; }
.banner-slot { padding-top: var(--s-3); }

.alert {
  display: flex; flex-wrap: wrap; gap: var(--s-1);
  padding: var(--s-3) var(--s-4);
  border: var(--edge);
  border-left: var(--bw-4) solid var(--ink-3);
  border-radius: var(--r-2);
  background: var(--surface);
  font-size: var(--t-sm);
  line-height: var(--lh-normal);
}
.alert strong { font-weight: 650; }
.alert-warn { border-left-color: var(--warn); }
.alert-warn strong { color: var(--warn); }
.alert-danger { border-left-color: var(--danger); }
.alert-danger strong { color: var(--danger); }

/* ---------------------------------------------------------------- footer
 *
 * The colophon: a double rule, the mark, where to go next, the method note,
 * and the tracking line in mono caps. */

.footer {
  margin-top: var(--s-8);
  border-top: var(--edge-double);
  padding-block: var(--s-6) var(--s-8);
}

.footer-inner {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--s-4);
  row-gap: var(--s-3);
  align-items: start;
}

.footer-mark { display: block; padding-top: 2px; }
.footer-mark .mark { opacity: 0.9; }

.footer-nav {
  grid-column: 2;
  display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-5);
  font-family: var(--font-display);
  font-size: var(--t-lg);
}
.footer-nav a {
  display: inline-flex; align-items: center; min-height: 44px;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 4px;
}
.footer-nav a:hover { text-decoration-color: currentColor; }

.footer-note {
  grid-column: 2;
  max-width: var(--w-text);
  color: var(--ink-2);
  font-size: var(--t-sm);
  line-height: var(--lh-normal);
  text-wrap: pretty;
}
.footer-link { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }

.footer-dim {
  grid-column: 2;
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: var(--t-3xs);
  letter-spacing: var(--tr-label);
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}
.footer-dim:empty { display: none; }

/* ------------------------------------------------------ route transition
 *
 * Same-document View Transitions, started by app.js around the view swap when
 * the browser supports them and the reader has not asked for reduced motion.
 * The nameplate is its own layer and does not move; the page lifts out and the
 * next one settles in. Everything else (the root) snaps, so nothing flickers. */
.topbar { view-transition-name: nameplate; }
.canvas { view-transition-name: page; }

::view-transition-old(root),
::view-transition-new(root) { animation: none; }
::view-transition-group(nameplate) { animation: none; }
::view-transition-old(page) { animation: page-out var(--dur-2) var(--ease-snap) both; }
::view-transition-new(page) { animation: page-in var(--dur-3) var(--ease-out) both; }

@keyframes page-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes page-in { from { opacity: 0; transform: translateY(12px); } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
