/* waitmap.css — the interactive wait map, /whennext/. see docs/CODE_NOTES.md CN-1840 */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('../fonts/spacegrotesk-400.woff2') format('woff2');
}
@font-face { font-family: 'Space Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/spacemono-400.woff2') format('woff2'); }
@font-face { font-family: 'Space Mono'; font-style: normal; font-weight: 700; font-display: swap; src: url('../fonts/spacemono-700.woff2') format('woff2'); }

:root {
  --grot: 'Space Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'Space Mono', ui-monospace, 'SFMono-Regular', Consolas, monospace;
  /* KIT.T — the plate's own paper and ink ladder, so a reader arriving from the image lands
     on the same sheet. */
  /* the paper is held as components as well as a colour, because three rules below need it at a. see docs/CODE_NOTES.md CN-1841 */
  --paper-rgb: 221, 219, 216;
  --paper: rgb(var(--paper-rgb));
  --ink: rgb(58, 47, 36);
  --ink-soft: rgb(106, 92, 74);
  --ink-faint: rgb(138, 124, 104);
  /* The knock: paper, at the plate's own 0.92, thrown eight ways round a glyph. */
  --knock: rgba(var(--paper-rgb), 0.92);
  /* Two washes, and the difference between them is the whole of this page's affordance budget. see docs/CODE_NOTES.md CN-1842 */
  --wash: rgba(var(--paper-rgb), 0.90);
  --field: rgba(92, 74, 52, 0.10);
  --field-hi: rgba(92, 74, 52, 0.16);
  /* Set by waitmap.js from the measured chrome, so the map fits the clear band between the
     head and the legend instead of being guessed at. */
  --head-h: 132px;
  --legend-h: 118px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--grot);
  -webkit-text-size-adjust: 100%;
}

/* The map fills the window; the chrome floats over it. Touch gestures belong to the canvas,
   never to the page — without this a pinch scrolls Safari instead of zooming the map. */
.stage { position: fixed; inset: 0; touch-action: none; }
.stage canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
#cOver { cursor: grab; }
#cOver.dragging { cursor: grabbing; }
#cOver.over-dot { cursor: pointer; }

/* ---- the head ------------------------------------------------------------------------- */
/* Type on the sheet, no plate under it. At rest the map is fitted BELOW this band, so nothing
   is covered; once a reader zooms in the map runs under it and the knock does the work. */
.head {
  position: fixed; top: 0; left: 0; right: 0;
  padding: 18px 24px 12px;
  /* THE HEAD DOES NOT EAT THE DRAG. Once a reader has zoomed in, the map runs underneath this
     band, and a title block that swallowed pointer events would make the top of the map
     un-draggable for no reason a reader could see. Only the link back to the piece is clickable. */
  pointer-events: none;
  z-index: 3;
}
.eyebrow {
  pointer-events: auto;
  display: inline-block;
  font-size: 12px; font-weight: 600; letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--ink-soft); text-decoration: none;
  margin: 0 0 10px;
  text-shadow: 0 0 3px var(--knock), 0 0 3px var(--knock), 0 0 6px var(--knock);
}
.eyebrow:hover { color: var(--ink); }

.title {
  margin: 0;
  font-size: clamp(21px, 3.4vw, 40px);
  font-weight: 500; line-height: 1.06; letter-spacing: -0.01em;
  color: var(--ink);
  text-shadow: 0 0 4px var(--knock), 0 0 4px var(--knock), 0 0 9px var(--knock);
}
.sub {
  margin: 8px 0 0;
  max-width: 62ch;
  font-size: clamp(13px, 1.35vw, 19px);
  font-weight: 500; line-height: 1.32;
  color: var(--ink-soft);
  text-shadow: 0 0 4px var(--knock), 0 0 4px var(--knock), 0 0 8px var(--knock);
}
/* The one word the plate had to be asked for twice: TOTAL, not a deep partial. */
.sub strong { color: var(--ink); font-weight: 700; }

/* ---- search --------------------------------------------------------------------------- */
.find { position: fixed; top: 18px; right: 24px; z-index: 5; width: 264px; }
#q {
  width: 100%;
  /* 16px is not a style choice on iOS: anything smaller makes Safari zoom the whole page the
     moment the field is focused, which on a map is a bug the reader has to undo by hand. */
  font: 500 16px/1.2 var(--grot);
  color: var(--ink);
  background: var(--field);
  border: 0; border-radius: 0; outline: 0;
  padding: 11px 12px;
  -webkit-appearance: none; appearance: none;
}
#q::placeholder { color: var(--ink-faint); }
#q:focus { background: var(--field-hi); }
.results { list-style: none; margin: 0; padding: 0; background: rgba(226, 224, 220, 0.97); max-height: 46vh; overflow-y: auto; }
.results:empty { display: none; }
.results li {
  padding: 9px 12px;
  font-size: 14px; line-height: 1.25;
  color: var(--ink); cursor: pointer;
  display: flex; align-items: baseline; gap: 8px;
}
.results li[aria-selected="true"], .results li:hover { background: rgba(150, 116, 50, 0.14); }
.results .r-cc { color: var(--ink-faint); font-size: 12px; }
.results .r-wait { margin-left: auto; font-family: var(--mono); font-size: 12px; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.results .r-none { color: var(--ink-faint); cursor: default; }
.results .r-none:hover { background: none; }

/* ---- the card that says what a dot is --------------------------------------------------- */
.card {
  position: fixed; z-index: 6;
  display: none;
  padding: 11px 14px 12px;
  background: var(--wash);
  max-width: 300px;
  pointer-events: none;
}
.card.on { display: block; }
.card .c-name { font-size: 17px; font-weight: 600; line-height: 1.15; color: var(--ink); }
.card .c-cc { font-size: 13px; color: var(--ink-soft); margin-top: 2px; }
.card .c-wait { font-size: 15px; font-weight: 600; margin-top: 8px; color: var(--ink); }
.card .c-wait .n { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.card .c-date { font-size: 13px; color: var(--ink-soft); margin-top: 3px; }
.card .c-date .n { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.card .c-note { font-size: 12px; color: var(--ink-faint); margin-top: 5px; }

/* ---- zoom ------------------------------------------------------------------------------ */
.zoomers { position: fixed; right: 24px; z-index: 5; bottom: calc(var(--legend-h) + 18px); display: flex; flex-direction: column; align-items: stretch; gap: 2px; }
.zoomers button {
  font: 500 19px/1 var(--grot);
  color: var(--ink);
  background: var(--field);
  border: 0; outline: 0;
  /* both of these, and neither is belongs-and-braces. iOS Safari draws a <button> with its own. see docs/CODE_NOTES.md CN-1843 */
  -webkit-appearance: none; appearance: none;
  border-radius: 0;
  padding: 0; width: 40px; height: 40px;
  cursor: pointer; text-align: center;
  display: flex; align-items: center; justify-content: center;
}
.zoomers button:hover { background: var(--field-hi); }
.zoomers button:disabled { color: var(--ink-faint); cursor: default; }

/* The globe glyph: strokes, no fill, butt caps — a mark in the piece's own hand, not a UI icon.
   The weight is the piece's own hairline rather than an icon-set 2px: this page draws its graticule
   at 1px and its country borders at 0.6, and a control that shouted over both would be the loudest
   line on a screen whose subject is a field of small marks. */
.zoomers button.reset svg { width: 22px; height: 22px; display: block; overflow: visible; }
.zoomers button.reset svg * {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.15;
  stroke-linecap: butt;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}
/* The SAME ink as the + and the −. A lighter grey read as disabled, which is the one thing a
   control that only ever appears when it is usable must not look like; the hairline weight already
   makes it quieter than two solid glyphs without borrowing the colour of a dead button. */
.zoomers button.reset { color: var(--ink); }

/* hidden until there is somewhere to come back from, and separated from the pair when it is there. see docs/CODE_NOTES.md CN-1844 */
.zoomers button.reset { display: none; margin-bottom: 10px; }
.zoomers.has-return button.reset { display: flex; }

/* ---- the legend ------------------------------------------------------------------------ */
.legend {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 4;
  padding: 12px 24px 12px;
  background: linear-gradient(to bottom, rgba(var(--paper-rgb), 0) 0%, rgba(var(--paper-rgb), 0.86) 22%, rgba(var(--paper-rgb), 0.97) 60%);
  /* Same rule as the head: the legend is a thing to read, not a thing to catch a drag on. */
  pointer-events: none;
}
.legend a { pointer-events: auto; }
.legend-head {
  margin: 0 0 9px;
  font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-faint);
  line-height: 1.4;
}
.legend-row { display: flex; align-items: flex-start; gap: 26px; }
.legend-bar { flex: 1 1 auto; min-width: 0; }
.legend-ramp { height: 16px; width: 100%; }
.legend-ticks { position: relative; height: 20px; margin-top: 5px; }
.legend-ticks span {
  position: absolute; top: 0;
  font-family: var(--mono); font-size: 12px; color: var(--ink-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.legend-ticks span.now { font-family: var(--grot); font-weight: 500; }
.legend-off { flex: 0 0 auto; display: flex; flex-direction: column; gap: 5px; }
.legend-swatch { width: 96px; height: 16px; }
.legend-off-label { font-size: 12px; color: var(--ink-soft); }

.credit { margin: 10px 0 0; font-size: 12px; color: var(--ink-faint); display: flex; flex-wrap: wrap; gap: 0 8px; align-items: baseline; }
.credit a { color: var(--ink-soft); text-decoration: none; }
.credit a:hover { color: var(--ink); text-decoration: underline; }
.credit .dot { color: var(--ink-faint); }

/* ---- the loading plate ------------------------------------------------------------------ */
.loading {
  position: fixed; inset: 0; z-index: 20;
  background: var(--paper);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px;
  transition: opacity 420ms ease;
}
.loading.gone { opacity: 0; pointer-events: none; }
.loading-word { margin: 0; font-size: 17px; font-weight: 500; color: var(--ink); }
.loading-sub { margin: 0; font-size: 13px; color: var(--ink-faint); }

.noscript { position: fixed; inset: 0; z-index: 30; margin: 0; padding: 28vh 24px; background: var(--paper); font-size: 16px; line-height: 1.5; color: var(--ink); }
.noscript a { color: var(--ink-soft); }

/* ---- the phone -------------------------------------------------------------------------- */
/* Most of the traffic this page was built for arrives here. The search field goes full width
   under the title, the card is parked above the legend rather than following a finger that is
   covering the dot it describes, and the legend loses the off-scale swatch's shoulder so the
   ramp keeps its width. */
@media (max-width: 720px) {
  .head { padding: 12px 14px 8px; }
  .eyebrow { font-size: 12px; letter-spacing: 0.2em; margin-bottom: 7px; }
  .sub { font-size: 13px; max-width: none; }
  /* Under the head rather than beside it — there is no beside on a phone. --head-h is written by
     waitmap.js off the head's measured height, so a title that wraps to three lines pushes the
     field down with it instead of landing on top of it. */
  .find { position: fixed; top: var(--head-h); right: 14px; left: 14px; width: auto; }
  .results { max-height: 40vh; }
  .card {
    left: 14px; right: 14px; max-width: none;
    bottom: calc(var(--legend-h) + 14px);
  }
  .zoomers { right: 14px; bottom: calc(var(--legend-h) + 14px); }
  .zoomers.hidden-by-card { display: none; }
  /* A THUMB IS NOT A CURSOR. The 12px floor in this piece is a rule about TYPE; a control has its
     own minimum and it is bigger — 44px is the size a thumb hits without aiming, and it is the
     figure both platform guidelines land on. The drawing inside does not grow with it: the target
     gets larger, the marks stay hairline. */
  .zoomers button { width: 44px; height: 44px; font-size: 20px; }
  .zoomers button.reset svg { width: 23px; height: 23px; }
  .legend { padding: 8px 14px 10px; }
  .legend-head { letter-spacing: 0.06em; margin-bottom: 7px; line-height: 1.32; }
  /* align-items: stretch is the whole fix, and the bug it repairs is worth the line. The base rule. see docs/CODE_NOTES.md CN-1845 */
  .legend-row { gap: 12px; flex-direction: column; align-items: stretch; }
  .legend-off { flex-direction: row; align-items: center; gap: 10px; }
  .legend-swatch { width: 54px; height: 12px; }
  .credit { font-size: 12px; gap: 0 6px; margin-top: 7px; line-height: 1.45; }
}

/* ---- the embed ---------------------------------------------------------------------------- */
/* `?embed=1` — the same map, set into another page. about.html carries this in an iframe under the. see docs/CODE_NOTES.md CN-1846 */
html.is-embed,
html.is-embed body { background: transparent; }
html.is-embed .head,
html.is-embed .credit { display: none; }
/* With the head gone there is nothing above the field, and on a phone `.find` is positioned from
   --head-h, which is now nought. */
html.is-embed .find { top: 14px; }
html.is-embed .legend { padding-bottom: 10px; }
/* The plate is opaque on purpose even here: it is the thing that hides half a megabyte of solving,
   and a transparent one would show the map assembling itself. It fades to the host's paper. */
html.is-embed .loading { background: rgb(var(--paper-rgb)); }
html.is-embed .results { background: rgba(var(--paper-rgb), 0.97); }

/* the embed's chrome, once the frame went full-bleed but the controls should not have (10 Aug. see docs/CODE_NOTES.md CN-1847 */
html.is-embed.has-col .legend-head,
html.is-embed.has-col .legend-row {
  max-width: var(--col);
  margin-left: auto;
  margin-right: auto;
}
/* Scoped past the phone breakpoint on purpose. Under 721px the existing phone rules already run. see docs/CODE_NOTES.md CN-1848 */
@media (min-width: 721px) {
  html.is-embed.has-col .find { right: max(0px, calc(50vw - var(--col) / 2)); }
  html.is-embed.has-col .zoomers { right: max(0px, calc(50vw - var(--col) / 2)); }
}
