/* ============================================================================
   Pingpillow — the house style, the one Bhav, Faultline, NPA Explorer and the
   Scorecard Playground are built in. Copied from apps/ml-demos/_demo.css;
   edit there, then copy here.

   Only the accent tokens below and the "own parts" section at the foot differ.
   Pingpillow's accent is jade. It deliberately does not appear in the verdict
   ramp: colour on this site means measured speed, and an accent that is also a
   verdict colour makes a link look like a judgement.

     Newsreader for display type, IBM Plex Sans for prose, IBM Plex Mono for
     every number and label. Hairlines rather than shadows, 3px corners rather
     than 18, one accent per demo, figures in tabular numerals.

   Dark first, with a full light re-spec rather than an inversion.
   ========================================================================= */

:root {
  color-scheme: dark;

  --bg:     #0B0E12;
  --panel:  #141921;
  --sunk:   #10151C;
  --line:   #232B35;
  --line2:  #1A2028;
  --ink:    #E8EDF3;
  --ink2:   #A6B2C0;
  --mute:   #6B7889;

  --accent:     #4FC3A1;
  --accent-ink: #0B0E12;
  --glow:       rgba(79, 195, 161, .15);

  /* The verdict ramp: one sequence, green through to red. "Workable" used to
     be the accent, which made it the only band whose colour meant two things
     and put a blue step in the middle of an otherwise ordered scale. */
  --ok:    #46A05F;
  --good:  #9CB84A;
  --amber: #D8A03C;
  --bad:   #D9534A;

  --mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --ui:      "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --display: "Newsreader", Georgia, "Times New Roman", serif;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --bg:     #ECEFF3;
    --panel:  #FFFFFF;
    --sunk:   #E3E7ED;
    --line:   #D2D8E0;
    --line2:  #E3E8ED;
    --ink:    #121821;
    --ink2:   #414C5A;
    --mute:   #6B7787;
    --accent:     #16775E;
    --accent-ink: #FFFFFF;
    --glow:       rgba(22, 119, 94, .10);
    --ok:    #2F7A43;
    --good:  #667F1E;
    --amber: #8A6414;
    --bad:   #B5384A;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--ink);
  font: 15.5px/1.62 var(--ui);
  -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }
strong, b { color: var(--ink); font-weight: 600; }
p { margin: 0; max-width: 68ch; color: var(--ink2); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--accent) 30%, transparent); }

h1, h2 { margin: 0; font-weight: 400; letter-spacing: -.016em; line-height: 1.12; }
h2 { font-family: var(--display); font-size: clamp(24px, 3.2vw, 34px); }

.muted { color: var(--mute); }
.small { font-size: 13px; line-height: 1.55; }
.fine  { font-size: 12.5px; line-height: 1.6; color: var(--mute); max-width: 74ch; }
.eyebrow {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--mute);
}

/* ---------------------------------------------------------------- chrome -- */
.topbar { border-bottom: 1px solid var(--line); }
.bar-in {
  max-width: 1000px; margin-inline: auto; height: 46px;
  padding-inline: clamp(16px, 4vw, 34px);
  display: flex; align-items: center; gap: 12px;
}
.back {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute); margin-right: auto;
}
.back:hover { color: var(--ink); text-decoration: none; }
.privacy {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ok);
  border: 1px solid currentColor; border-radius: 2px; padding: 3px 9px;
}

.hero {
  border-bottom: 1px solid var(--line);
  background:
    radial-gradient(120% 130% at 10% -12%, var(--glow) 0%, transparent 56%),
    var(--bg);
}
.hero-in {
  max-width: 1000px; margin-inline: auto;
  padding: clamp(36px, 6vw, 66px) clamp(16px, 4vw, 34px) clamp(22px, 4vw, 38px);
}
/* The map is the page on /map, and a full-height masthead above it meant the
   thing people came for started below the fold. */
.hero.tight .hero-in { padding-block: clamp(20px, 3vw, 30px) clamp(14px, 2vw, 20px); }
.hero.tight .ttl { font-size: clamp(30px, 5vw, 46px); }
.hero.tight .lede { font-size: 14.5px; max-width: 620px; }
.ttl {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(40px, 8.4vw, 86px); line-height: .88;
  letter-spacing: -.038em; margin: 14px 0 0;
}
.ttl em { font-style: italic; color: var(--accent); }
.lede {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(17px, 2.1vw, 23px); line-height: 1.4;
  color: var(--ink2); max-width: 46ch; margin-top: 18px;
}

.shell {
  max-width: 1000px; margin-inline: auto;
  padding: 0 clamp(16px, 4vw, 34px) 8px;
}
.shell > section { padding-block: clamp(30px, 4.5vw, 54px); border-bottom: 1px solid var(--line2); }

.head { display: flex; align-items: baseline; gap: 13px; flex-wrap: wrap; }
.head .ix {
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .1em; color: var(--accent);
}
.stack { display: flex; flex-direction: column; gap: 14px; }

.card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 3px;
  padding: clamp(14px, 2.2vw, 24px);
  display: flex; flex-direction: column; gap: 18px;
  margin-top: 20px;
}

/* ------------------------------------------------------------- controls --- */
/* House style, kept verbatim. This sat inside the ML demos' rig block, but it
   is generic chrome rather than anything to do with that rig -- dropping it
   with the rest is what left the buttons here unstyled. */
.controls { display: flex; flex-wrap: wrap; gap: 9px; }
.btn, button {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  font: 500 11px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink2); background: transparent;
  border: 1px solid var(--line); border-radius: 2px;
  padding: 9px 14px; cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.btn:hover, button:hover { color: var(--ink); border-color: var(--mute); }
.btn:disabled, button:disabled { opacity: .45; cursor: default; }

/* ------------------------------------------------------------- own parts -- */
/* Everything below is Pingpillow's; the rest of this file is the house style. */

/* Nav sits beside the back link in the same mono register, because this is a
   multi-page site and the demos this style came from were single pages. */
.bar-nav { display: flex; gap: 16px; }
.bar-nav a {
  font-family: var(--mono); font-size: 11px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute);
}
.bar-nav a:hover, .bar-nav a[aria-current] { color: var(--ink); text-decoration: none; }

/* --------------------------------------------------------------- verdict -- */
/* Four bands drawn from the house palette rather than four new greens: the
   verdict is a judgement, and it should use the same ink as every other one.
   Each band owns its token; none of them is the accent. */
.v-excellent { --v: var(--ok); }
.v-good      { --v: var(--good); }
.v-fair      { --v: var(--amber); }
.v-poor      { --v: var(--bad); }

.badge {
  display: inline-block; font-family: var(--mono); font-size: 10px;
  letter-spacing: .16em; text-transform: uppercase; color: var(--v, var(--mute));
  border: 1px solid currentColor; border-radius: 2px; padding: 3px 9px;
  white-space: nowrap;
}

/* The verdict panel leads every hotel page; the band colour is a rule down the
   side rather than a fill, so the number stays the loudest thing on screen. */
.verdict { border-left: 2px solid var(--v, var(--line)); padding-left: 18px; }
.verdict .line { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }

/* ---------------------------------------------------------------- search -- */
.search { display: flex; gap: 8px; margin-top: 22px; max-width: 620px; }
.search input {
  flex: 1; min-width: 0; background: var(--sunk); color: var(--ink);
  border: 1px solid var(--line); border-radius: 2px; padding: 11px 13px;
  font: 400 14px/1.4 var(--ui);
}
.search input::placeholder { color: var(--mute); }
.search button {
  color: var(--accent-ink); background: var(--accent); border-color: var(--accent);
}
.search button:hover { color: var(--accent-ink); opacity: .88; }

/* Submitting a speedtest is the one place the site asks for something, so the
   fields are laid out as a row of small controls rather than a form wall. */
.fields { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.fields input, .fields select {
  background: var(--sunk); color: var(--ink); border: 1px solid var(--line);
  border-radius: 2px; padding: 8px 10px; font: 400 13px/1.4 var(--ui);
}
.fields input::placeholder { color: var(--mute); }
.fields .grow { flex: 1; min-width: 190px; }

/* ------------------------------------------------------------------ map --- */
#map { border: 1px solid var(--line); border-radius: 3px; background: var(--sunk); }
#mapwrap { position: relative; height: clamp(420px, 68vh, 720px); margin-top: 20px; }
#mapwrap #map { height: 100%; }

/* Map furniture is laid out, not nudged.
   Every panel used to be its own absolutely-positioned box with a hand-tuned
   offset, and each one was tuned against the others' height at the moment it
   was written. Then a panel grew: the speed-cell count ended up painted on top
   of the first search result, the centre readout sat through the zoom buttons,
   and on a phone the layer toggles and the readout shared eight pixels. Every
   fix moved the collision somewhere else, because offsets do not know about
   each other.
   A grid does. The four corners are grid areas with a gap between them, so no
   panel can reach another whatever its content does — and the one panel that
   is meant to cover things, the search dropdown, is given its own stacking
   layer to do it cleanly. */
.mapui {
  position: absolute; inset: 12px; z-index: 500;
  display: grid; gap: 10px;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
  grid-template-rows: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
  grid-template-areas: "tl  .  tr"
                       ".   .  . "
                       "bl  .  br";
  pointer-events: none;                 /* the map keeps every gap */
}
.mapui > * { display: flex; flex-direction: column; gap: 10px; min-width: 0; }
/* flex-start so the count under the search box is the width of its own text
   rather than stretched to the search box's. */
.ui-tl { grid-area: tl; align-items: flex-start; }
.ui-tr { grid-area: tr; align-items: flex-end; }
.ui-bl { grid-area: bl; justify-content: flex-end; }
.ui-br { grid-area: br; align-items: flex-end; justify-content: flex-end; }
/* Leaflet owns two bottom corners of its own: the zoom buttons bottom right
   and the attribution along the bottom edge. Neither is in this grid, so the
   bottom row stops short of them rather than being tuned around them. */
.ui-bl, .ui-br { padding-bottom: 18px; }
.ui-br { padding-right: 46px; }
/* The search panel is the only one allowed to cover another: its results list
   is a dropdown, and a dropdown that gets punched through by the panel below
   it is the bug this whole layout exists to end. */
.ui-tl { z-index: 2; }

.panel {
  pointer-events: auto; background: var(--panel);
  border: 1px solid var(--line); border-radius: 3px; padding: 11px 13px;
  font-family: var(--mono); font-size: 11px; line-height: 1.75; color: var(--ink2);
}
#status { color: var(--mute); }
/* While results are open the count underneath them is noise, and hiding it
   gives the list the whole corner. */
.ui-tl.searching #status { display: none; }

/* -------------------------------------------------------- map search --- */
/* Finding a place had no answer on the map: you could pan the planet, but not
   say where you were going. This is the offline gazetteer as a search box —
   cities, landmarks, stations, airports and named streets, because a traveller
   knows "Brandenburg Gate" and not the address of anything near it. */
/* A definite width, not min(340px, 100%): inside an auto grid track the
   percentage resolves against a column that is sizing itself to this box,
   and the search shrank to its min-content width. */
#geo { position: relative; width: 340px; max-width: 100%; padding: 0; }
#geo form { display: flex; margin: 0; }
#geo input {
  flex: 1; min-width: 0; background: transparent; color: var(--ink);
  border: 0; border-radius: 3px; padding: 10px 12px;
  font: 400 13px/1.3 var(--ui);
}
#geo input:focus { outline: none; }
#geo input::placeholder { color: var(--mute); }
#geo button {
  border: 0; border-left: 1px solid var(--line); background: transparent;
  color: var(--mute); padding: 0 12px; cursor: pointer;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase;
}
#geo button:hover { color: var(--accent); }

/* The results hang off the search box rather than growing it. Growing it made
   the panel's height everyone else's problem: on a short phone the stack below
   it — readout, toggles, legend — was pushed off the bottom of the map. A
   dropdown is an overlay, so it is positioned like one, and the corner's
   stacking layer puts it cleanly over the furniture it covers. */
#geo-out {
  position: absolute; top: 100%; left: -1px; right: -1px;
  list-style: none; margin: 0; padding: 0; overflow-y: auto;
  /* Capped against the shortest map (420px) rather than the viewport, so the
     list ends inside the map instead of hanging off the bottom. */
  max-height: min(40vh, 260px);
  background: var(--panel); border: 1px solid var(--line); border-top: 0;
  border-radius: 0 0 3px 3px;
}
#geo-out:empty { display: none; }
/* The intro card runs the same search through the same renderer, so it gets
   the same rows. It was left out of these selectors and drew them as a bulleted
   list with the name and the kind run together — "Darjeelingcity". */
#geo-out li, #intro-out li {
  padding: 8px 12px; cursor: pointer; border-bottom: 1px solid var(--line2);
  font-family: var(--ui); font-size: 13px; color: var(--ink);
}
#geo-out li:last-child, #intro-out li:last-child { border-bottom: 0; }
#geo-out li:hover, #geo-out li[aria-selected="true"],
#intro-out li:hover, #intro-out li[aria-selected="true"] { background: var(--sunk); }
#geo-out .where, #intro-out .where {
  display: block; font-family: var(--mono); font-size: 10px; color: var(--mute);
  letter-spacing: .06em; text-transform: uppercase; margin-top: 2px;
}
/* The pin dropped on a chosen result. Drawn in the accent, which is the one
   thing on the map that is not a speed colour. */
.geo-pin {
  border: 2px solid var(--accent); border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* ------------------------------------------------- map first run --------- */
/* Opening on a map of somewhere you did not ask for, with a small box in the
   corner, asks the visitor to work out what the page is for. It opens on a
   question instead: where are you going? Everything else waits behind it. */
#intro {
  position: absolute; inset: 0; z-index: 900; display: grid; place-items: center;
  padding: 20px; background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
  border-radius: 3px; transition: opacity .45s ease, visibility .45s;
}
#intro[hidden] { display: none; }
#intro.gone { opacity: 0; visibility: hidden; pointer-events: none; }
/* The card holds a question, a search box, five chips and a results list, and
   the map it floats in is 420px tall at its shortest. Bounded to the map and
   allowed to scroll, rather than growing out through the bottom of it. */
.intro-card {
  width: min(460px, 100%); max-height: 100%; overflow-y: auto;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 3px; padding: 26px 24px; text-align: center;
}
.intro-card h2 {
  font: 300 clamp(24px, 4.4vw, 32px)/1.15 var(--display);
  margin: 12px 0 6px; letter-spacing: -.01em;
}
.intro-card h2 em { font-style: italic; color: var(--accent); }
.intro-card p { color: var(--ink2); font-size: 13.5px; margin: 0 0 18px; }
.intro-card .search { margin-top: 0; max-width: none; }
#intro-out { margin-top: 10px; text-align: left; list-style: none;
             max-height: min(38vh, 230px); overflow-y: auto; }
.intro-or {
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--mute); margin: 16px 0 12px;
}
.intro-loc {
  background: transparent; color: var(--ink); border: 1px solid var(--line);
  border-radius: 2px; padding: 9px 16px; cursor: pointer;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase;
}
.intro-loc:hover { border-color: var(--accent); color: var(--accent); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 18px; }
.chips button {
  background: var(--sunk); border: 1px solid var(--line2); color: var(--ink2);
  border-radius: 2px; padding: 5px 10px; font-size: 12px; cursor: pointer;
}
.chips button:hover { color: var(--accent); border-color: var(--accent); }
.intro-note { font-size: 12px; color: var(--mute); margin-top: 14px; min-height: 1.2em; }

/* A wireframe globe, spun with a scrolling background rather than a library.
   It shows while a place is being resolved and the tiles are on their way. */
.globe {
  width: 66px; height: 66px; border-radius: 50%; margin: 0 auto; position: relative;
  overflow: hidden; border: 1px solid var(--line);
  background: radial-gradient(circle at 32% 28%,
              color-mix(in srgb, var(--accent) 45%, #fff),
              var(--accent) 52%, color-mix(in srgb, var(--accent) 45%, #000));
}
.globe::after {
  content: ''; position: absolute; inset: 0;
  background-image:
    repeating-linear-gradient(90deg, rgba(255,255,255,.34) 0 1px, transparent 1px 13px),
    repeating-linear-gradient(0deg,  rgba(255,255,255,.20) 0 1px, transparent 1px 11px);
  animation: pp-spin 2.6s linear infinite;
}
@keyframes pp-spin { to { background-position: -26px 0, 0 0; } }
@media (prefers-reduced-motion: reduce) { .globe::after { animation: none; } }

/* The readout under the search box: the speed wherever the map is centred,
   updating as it is dragged, so the map reads as an instrument. */
/* Bottom right, beside the zoom buttons rather than over them — the grid's
   br area already reserves their column. */
#here { white-space: nowrap; }
#here .hv { font-family: var(--mono); font-size: 15px; color: var(--ink); }
#here .hl { color: var(--mute); }
#here .dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 7px; vertical-align: 1px;
}

/* On a phone the map furniture cannot all live in the corners: at 390px the
   layer toggles sat on top of the search box and covered its button. Give the
   search the full top edge and put the readout and the toggles on the row
   underneath it. */
@media (max-width: 620px) {
  /* A phone has no four corners to speak of. The search takes the full top
     edge, the readout and the toggles share the row under it — as two grid
     columns, so the wider one pushes the other rather than sitting on it —
     and the legend keeps the bottom. */
  .mapui {
    grid-template-columns: minmax(0, 1fr) minmax(0, auto);
    grid-template-rows: auto auto minmax(0, 1fr) auto;
    grid-template-areas: "tl  tl"
                         "br  tr"
                         ".   . "
                         "bl  bl";
    gap: 8px;
  }
  .ui-br { align-items: flex-start; justify-content: flex-start;
           padding-right: 0; padding-bottom: 0; }
  #geo { width: 100%; }
  #here { white-space: normal; }
  #ctl  { line-height: 1.5; }
  /* The legend is the one panel a phone can do without at a glance — it drops
     its heading rather than fighting for the corner. */
  #legend div:first-child { display: none; }
  #here .hv { font-size: 13.5px; }
  #geo-out { max-height: min(34vh, 220px); }
  /* The legend keeps the whole bottom edge but stops short of Leaflet's
     zoom buttons; squeezed into one column instead, it wrapped its own
     first line. */
  .ui-bl { padding-right: 46px; padding-bottom: 22px; }
}
.panel b { color: var(--ink); font-weight: 600; letter-spacing: .1em;
           text-transform: uppercase; font-size: 9.5px; }
.sw { display: inline-block; width: 9px; height: 9px; margin-right: 8px; vertical-align: 0; }
.panel label { cursor: pointer; user-select: none; color: var(--ink2); }
/* Native checkboxes paint themselves the browser's blue, which was the one
   piece of blue left on the map after the palette change. */
.panel input[type="checkbox"] { accent-color: var(--accent); }

/* Leaflet ships its own light chrome; these pull it back onto the palette. */
.leaflet-container { background: var(--sunk); font: inherit; }
.leaflet-popup-content-wrapper, .leaflet-tooltip {
  background: var(--panel); color: var(--ink); border: 1px solid var(--line);
  border-radius: 3px; box-shadow: none; font-size: 12.5px;
}
.leaflet-popup-tip { background: var(--panel); border: 1px solid var(--line); }
.leaflet-tooltip::before { display: none; }
.leaflet-bar a { background: var(--panel); color: var(--ink2); border-color: var(--line); }
.leaflet-bar a:hover { background: var(--sunk); color: var(--ink); }
.leaflet-control-attribution {
  background: var(--panel); color: var(--mute); font-size: 10px;
}
.leaflet-control-attribution a { color: var(--mute); }
/* No invert filter here any more: the basemap ships a real dark style, which
   map.js picks per theme. Inverting a light raster turned water pink and made
   the carpet colours lie about themselves. */

/* --------------------------------------------------------------- tables --- */
/* Hotel names are the one left-aligned prose column; the house rule already
   handles that, but names must be allowed to wrap or the table never fits. */
td:first-child { white-space: normal; text-transform: none; }
td:first-child a { color: var(--ink); }
td:first-child a:hover { color: var(--accent); }
.rank { font-family: var(--mono); color: var(--mute); font-size: 11.5px; }

/* A measured-in-room result outranks every estimate on the page, so it is the
   only thing here allowed to carry the accent as a fill. */
.measured {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ok);
}

.pair { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line);
        grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); margin-top: 18px; }
.pair > div { background: var(--bg); padding: 14px 16px; }
.pair .k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em;
           text-transform: uppercase; color: var(--mute); }
.pair .v { font-family: var(--mono); font-size: 19px; font-variant-numeric: tabular-nums;
           color: var(--ink); margin-top: 5px; }

.chips { display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 16px; }
.chips a { font-size: 13.5px; }
.chips .n { font-family: var(--mono); font-size: 11px; color: var(--mute); }

/* --------------------------------------------------------------- figures -- */
/* The 1px gaps are the line colour showing through, so rules never double. */
.stats {
  display: grid; gap: 1px; margin-top: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr));
  background: var(--line); border: 1px solid var(--line);
}
.stat { background: var(--bg); padding: 16px clamp(12px, 2vw, 20px) 14px; }
.stat .n {
  display: block; font-family: var(--mono); font-weight: 600;
  font-size: clamp(20px, 3vw, 30px); letter-spacing: -.035em; line-height: 1.05;
  font-variant-numeric: tabular-nums; color: var(--ink);
}
.stat .l {
  display: block; margin-top: 7px; font-family: var(--mono); font-size: 9.5px;
  letter-spacing: .14em; text-transform: uppercase; color: var(--mute); line-height: 1.6;
}

/* ---------------------------------------------------------------- tables -- */
.table-wrap {
  overflow-x: auto; -webkit-overflow-scrolling: touch; margin-top: 18px;
  border: 1px solid var(--line); border-radius: 3px; background: var(--panel);
}
table { border-collapse: collapse; width: 100%; font-size: 13px; }
th, td {
  padding: 9px 12px; text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--line2);
  font-family: var(--mono); font-variant-numeric: tabular-nums;
}
th:first-child, td:first-child {
  text-align: left; text-transform: capitalize;
  font-family: var(--ui); color: var(--ink2);
}
thead th {
  font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--mute); font-weight: 500; border-bottom: 1px solid var(--line);
}
tbody tr:last-child td { border-bottom: 0; }

.note { border-left: 2px solid var(--amber); padding-left: 18px; margin-top: 20px; }
.note p { margin: 0; }

.credit {
  border-top: 1px solid var(--line); margin-top: 8px;
  padding-block: 26px 52px;
  font-family: var(--mono); font-size: 11.5px; line-height: 1.85; color: var(--mute);
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* A class that sets `display` beats the user-agent rule for [hidden], so every
   element toggled with el.hidden stayed visible -- the "Stop camera" button was
   on screen before the camera had ever been started. This has to come last. */
[hidden] { display: none !important; }
