/* ============================================================
   gamescom 2026 guide — "Hall Signage"

   Trade-fair wayfinding crossed with print. Typography and hard
   edges do the work: no gradients, no blurred elevation, no
   rounded pill soup. Hall numbers are set on solid plates because
   that is the one thing you actually read while walking, and each
   exhibitor is a discrete panel rather than a cell of one table.

   Two earlier directions (a light "Fanzine" and a monospace
   "Console") were built on these same tokens and dropped once
   this one was chosen; recover them from css/themes.css in the
   history if you ever want to compare again.
   ============================================================ */

:root {
  /* ---- ground & ink (warm neutral, deliberately not navy) ---- */
  --ground:    #09090a;
  --ground-2:  #141416;
  --ground-3:  #1c1c1f;
  --rule:      #2b2c30;
  --rule-soft: #1f2023;
  --ink:       #f2efe9;
  --ink-mid:   #b3b1ab;
  --ink-dim:   #86847f;

  /* ---- one signal colour, used sparingly ---- */
  --signal:     #ff4d17;
  --signal-ink: #0b0b0c;
  --signal-wash: rgba(255, 77, 23, .12);
  --grain:       rgba(255, 255, 255, .025);

  /* ---- status ---- */
  --ok:      #2fbf85;
  --warn:    #e8a33a;
  --neutral: #86847f;
  --alert:   #f2564f;

  /* ---- type ---- */
  --font-ui:      "Archivo", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Archivo Narrow", "Archivo", system-ui, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  /* poster weight, used only for structural headings — exhibitor names stay on
     --font-display so 38 cards don't all shout at once */
  --font-poster:  "Anton", "Archivo Narrow", system-ui, sans-serif;

  /* ---- shape: near-square, signage-like ---- */
  --radius:   2px;
  --radius-sm: 2px;
  --border:   1px solid var(--rule);
  --wrap:     1200px;

  /* Hard offset, never blurred. On a near-black ground a black shadow is
     invisible, so the offset is LIGHTER than the ground — same printed
     second-layer effect as ink-on-paper, inverted. */
  --plate-shadow:       5px 5px 0 #212125;
  --plate-shadow-hover: 8px 8px 0 #2c2c31;

  font-size: 16px;
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { -webkit-text-size-adjust: 100%; }

body {
  background: var(--ground);
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: .95rem;
  line-height: 1.55;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  -webkit-font-smoothing: antialiased;
  /* barely-there halftone; gives the ground a printed grain instead of flat ink */
  background-image: radial-gradient(var(--grain) .5px, transparent .5px);
  background-size: 4px 4px;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; width: 100%; }
.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
  /* These are sentences, not labels — inheriting a `text-transform: uppercase`
     from the control they sit in makes some screen readers spell them out. */
  text-transform: none; letter-spacing: normal;
}

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 2px;
}

.skip-link {
  position: absolute; left: 24px; top: -60px; z-index: 200;
  background: var(--signal); color: var(--signal-ink);
  padding: 10px 16px; font-weight: 700; text-decoration: none;
  transition: top .15s;
}
.skip-link:focus { top: 12px; }

/* small letterspaced label used everywhere instead of icons/emoji */
.row-label,
.overline,
.field-label,
.block-head,
.section-num,
.tab-index,
.brand-kicker {
  font-family: var(--font-mono);
  font-size: .66rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}

/* ============================================================
   header
   ============================================================ */
.site-header {
  background: var(--ground);
  border-bottom: 1px solid var(--rule);
  position: sticky;
  top: 0;
  z-index: 50;
}

.header-inner {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 20px;
  flex-wrap: wrap;
  padding-top: 20px;
  padding-bottom: 16px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: inherit;
}
.brand-mark {
  display: grid;
  place-items: center;
  width: 46px; height: 46px;
  background: var(--signal);
  color: var(--signal-ink);
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -.03em;
  border-radius: var(--radius-sm);
}
.brand-text { display: flex; flex-direction: column; gap: 1px; }
.brand-title {
  font-family: var(--font-poster);
  font-size: 1.6rem;
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: .005em;
  text-transform: uppercase;
}
.brand-year { color: var(--ink-dim); font-weight: 600; }

.header-meta { text-align: right; display: flex; flex-direction: column; gap: 2px; }
.meta-line { color: var(--ink-mid); font-size: .84rem; }
.countdown {
  font-family: var(--font-mono);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--signal);
  font-variant-numeric: tabular-nums;
}

/* ---- tabs: signage strip, not browser chrome ---- */
.tabs-outer { border-top: 1px solid var(--rule-soft); }
.tabs { display: flex; overflow-x: auto; scrollbar-width: none; padding: 0 24px; }
.tabs::-webkit-scrollbar { display: none; }

.tab {
  background: none;
  border: none;
  border-bottom: 3px solid transparent;
  color: var(--ink-dim);
  font: inherit;
  font-weight: 600;
  font-size: .88rem;
  letter-spacing: .01em;
  padding: 13px 20px 11px;
  margin-right: -1px;
  cursor: pointer;
  white-space: nowrap;
  display: flex;
  align-items: baseline;
  gap: 8px;
  transition: color .12s, border-color .12s;
}
.tab:first-child { padding-left: 0; }
.tab .tab-index { transition: color .12s; }
.tab:hover { color: var(--ink); }
.tab.active { color: var(--ink); border-bottom-color: var(--signal); }
.tab.active .tab-index { color: var(--signal); }

/* ============================================================
   layout
   ============================================================ */
main { flex: 1; padding-top: 34px; padding-bottom: 72px; }
.view { display: none; }
.view.active { display: block; animation: rise .2s ease-out; }

@keyframes rise {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}

.lede {
  border-left: 3px solid var(--signal);
  padding: 2px 0 2px 18px;
  margin-bottom: 32px;
}
.lede h2 {
  font-family: var(--font-poster);
  font-size: 2rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: .005em; line-height: 1.05;
  margin-bottom: 8px;
}
.lede p { color: var(--ink-mid); }

.section-title {
  font-family: var(--font-poster);
  font-size: 1.35rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: .01em;
  margin: 40px 0 4px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--rule);
  display: flex;
  align-items: baseline;
  gap: 12px;
}
.section-title .section-num { color: var(--signal); }
.section-sub { color: var(--ink-dim); font-size: .85rem; margin: 10px 0 16px; }
.section-title + .day-board,
.section-title + .priority-table,
.section-title + .tips { margin-top: 16px; }

/* ============================================================
   toolbar
   ============================================================ */
.toolbar {
  border: var(--border);
  border-radius: var(--radius);
  margin-bottom: 24px;
  background: var(--ground-2);
}
.toolbar-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--rule-soft);
  flex-wrap: wrap;
}
.toolbar-row:last-child { border-bottom: none; }
.toolbar-row .row-label { flex: 0 0 76px; padding-top: 1px; }

.toolbar-search { padding: 0; gap: 0; }
.field { display: flex; flex-direction: column; gap: 0; }
.field-search { flex: 1; min-width: 240px; }
.field-sort { border-left: 1px solid var(--rule-soft); }
.field-label { padding: 9px 16px 0; }

#search, #sort {
  background: none;
  border: none;
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
  padding: 2px 16px 11px;
  width: 100%;
}
#search::placeholder { color: var(--ink-dim); }
#search:focus-visible, #sort:focus-visible { outline-offset: -2px; }
#sort { cursor: pointer; font-size: .88rem; padding-right: 16px; }
#sort option { background: var(--ground-2); color: var(--ink); }

/* Collapsible filter drawer — open by default on desktop, closed on a phone
   where the full panel would otherwise fill the whole first screen. */
.toolbar-more { border-top: 1px solid var(--rule-soft); }
.toolbar-summary {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 16px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.toolbar-summary::-webkit-details-marker { display: none; }
.toolbar-summary .row-label { flex: 0 0 76px; }
.toolbar-summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 1.5px solid var(--ink-dim);
  border-bottom: 1.5px solid var(--ink-dim);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .15s;
  order: -1;
  margin-right: -6px;
}
.toolbar-more[open] > .toolbar-summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.toolbar-more[open] > .toolbar-summary { border-bottom: 1px solid var(--rule-soft); }
.toolbar-summary:hover .filter-summary { color: var(--ink); }

.filter-summary { font-size: .84rem; color: var(--ink-mid); }
.filter-summary[data-active="true"] { color: var(--signal); font-weight: 600; }

.filter-row { display: flex; gap: 6px; flex-wrap: wrap; flex: 1; }

.chip {
  background: none;
  border: 1px solid var(--rule);
  color: var(--ink-mid);
  border-radius: var(--radius-sm);
  padding: 4px 11px;
  font-family: var(--font-ui);
  font-size: .78rem;
  font-weight: 600;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.chip:hover { color: var(--ink); border-color: var(--ink-dim); }
.chip.active { background: var(--ink); border-color: var(--ink); color: var(--ground); }
.chip.hall-chip { font-family: var(--font-mono); font-weight: 500; font-size: .75rem; }
.chip.hall-chip.active,
.chip.age-chip.active { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); }

.toggle {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--ink-mid); font-size: .84rem; cursor: pointer; user-select: none;
}
.toggle:hover { color: var(--ink); }
.toggle input { accent-color: var(--signal); width: 15px; height: 15px; }

.reset {
  background: none; border: none; color: var(--signal);
  font: inherit; font-size: .8rem; font-weight: 600;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px;
  padding: 0;
}
.toolbar-foot { padding-top: 14px; padding-bottom: 14px; }
.result-count {
  margin-left: auto;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

/* ============================================================
   exhibitor cards
   ============================================================ */
/* Cards are discrete printed plates, not cells of one table: real gaps plus a
   hard un-blurred offset shadow. Blurred shadows read as generic material
   elevation; a hard offset reads as something laid on top of the page. */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
  gap: 20px;
}

.card {
  min-width: 0;
  background: var(--ground-2);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--plate-shadow);
  padding: 0;
  display: flex;
  flex-direction: column;
  transition: background .12s, box-shadow .12s, transform .12s;
}
/* Arriving from the hall map's "open in guide": say which of the 53 cards
   you were sent to, then get out of the way. The global reduced-motion
   rule collapses this to an instant, which is the right amount of it. */
@keyframes card-landed {
  from { box-shadow: 0 0 0 2px var(--signal), var(--plate-shadow); }
  to   { box-shadow: 0 0 0 2px transparent, var(--plate-shadow); }
}
.card-landed { animation: card-landed 1.8s ease-out; }

.card:hover {
  background: var(--ground-3);
  transform: translate(-2px, -2px);
  box-shadow: var(--plate-shadow-hover);
}

/* --- head: the hall number as a signage plate --- */
.exh-head { display: flex; gap: 0; border-bottom: 1px solid var(--rule-soft); }

.hall-marker {
  flex: 0 0 108px;
  padding: 14px 12px;
  background: var(--signal);
  color: var(--signal-ink);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
}
.hall-marker[data-state="unconfirmed"] { background: var(--warn); }
.hall-marker[data-state="tba"],
.hall-marker[data-state="absent"] { background: var(--ground-3); color: var(--ink-dim); }

/* The plate doubles as the link to that booth on the hall map when the
   map covers its hall (see hallMarker) — an anchor wearing the same
   plate, not a new control. */
a.hall-marker { text-decoration: none; position: relative; }
.hall-map-cue {
  font-family: var(--font-mono);
  font-size: .56rem; letter-spacing: .1em; text-transform: uppercase;
  opacity: .62;
  margin-top: 2px;
}
a.hall-marker:hover .hall-map-cue,
a.hall-marker:focus-visible .hall-map-cue { opacity: 1; }

/* The same link, in running text: every hall named in the planner rows opens
   that hall on the map (see hallLink). These sit inside dense lists, so the
   affordance is a quiet underline rather than another plate — it keeps the
   row's own colour until you reach for it, then takes the accent. */
.hall-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
.hall-link:hover,
.hall-link:focus-visible { color: var(--signal); text-decoration-color: currentColor; }

.hall-kicker {
  font-family: var(--font-mono);
  font-size: .58rem; letter-spacing: .16em; text-transform: uppercase;
  color: inherit; opacity: .7;
}
.hall-num {
  font-family: var(--font-mono);
  font-size: 1.75rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: -.04em;
  font-variant-numeric: tabular-nums;
}
.hall-marker[data-state="tba"] .hall-num,
.hall-marker[data-state="absent"] .hall-num { font-size: 1rem; letter-spacing: 0; }
/* A plate can now carry several stands — Nintendo holds four — and the
   comma is where the line is allowed to turn. break-all broke wherever
   the 108 px ran out, which split "A020/B019" after its first character
   and left a booth number nobody could read; break-word keeps each stand
   whole and only breaks inside one that could not fit a line on its own. */
.hall-booth {
  font-family: var(--font-mono);
  font-size: .68rem;
  color: inherit; opacity: .78;
  overflow-wrap: break-word;
}

.exh-id { padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; justify-content: center; min-width: 0; }
.exh-id h3 {
  font-family: var(--font-display);
  font-size: 1.18rem;
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -.005em;
}

.card-body { padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; flex: 1; }
.desc { color: var(--ink-mid); font-size: .87rem; }

/* --- lineup block --- */
.block-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 10px;
  padding-bottom: 6px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--rule-soft);
}

.games { list-style: none; display: flex; flex-direction: column; }
.game {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  gap: 2px 10px;
  padding: 7px 0 7px 14px;
  border-top: 1px solid var(--rule-soft);
  position: relative;
  font-size: .87rem;
}
.game:first-child { border-top: none; }
.game::before {
  content: "";
  position: absolute; left: 0; top: 13px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--neutral);
}
.game[data-status="confirmed"]::before { background: var(--ok); }
.game[data-status="expected"]::before  { background: var(--warn); }
.game[data-status="rumored"]::before   { background: var(--neutral); }

.game-title { font-weight: 600; }
.game-main { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; min-width: 0; }
.game-plat {
  font-family: var(--font-mono);
  font-size: .64rem;
  letter-spacing: .06em;
  color: var(--ink-dim);
  white-space: nowrap;
  align-self: center;
}
.game-note { grid-column: 1 / -1; color: var(--ink-dim); font-size: .78rem; line-height: 1.45; }

.badge {
  font-family: var(--font-mono);
  font-size: .6rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: .1em;
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  border: 1px solid transparent;
}
.badge-playable { color: var(--signal); border-color: var(--signal-wash); background: var(--signal-wash); }
.badge-age { background: transparent; }
.badge-age[data-age-status="confirmed"] { color: var(--alert); border-color: var(--alert); }
.badge-age[data-age-status="expected"] { color: var(--warn); border-color: var(--warn); }
.block-head .badge-age { margin-left: 9px; }
.exh-id h3 .badge-age { margin-left: 6px; vertical-align: .2em; }

/* The one hand-applied element in the layout, and deliberately the only one:
   once per card it reads as a stamp, but repeated down every game row the
   tilts land at different x positions and read as jitter. */
.stamp {
  display: inline-block;
  margin-left: 9px;
  background: var(--signal);
  color: var(--signal-ink);
  font-family: var(--font-mono);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  transform: rotate(-2.5deg);
  box-shadow: 2px 2px 0 rgba(0, 0, 0, .45);
}
.badge-status[data-status="expected"] { color: var(--warn); border-color: rgba(232,163,58,.25); }
.badge-status[data-status="rumored"]  { color: var(--neutral); border-color: var(--rule); }

.more-games {
  align-self: flex-start;
  margin-top: 8px;
  background: none; border: none; padding: 0;
  color: var(--signal);
  font-family: var(--font-mono);
  font-size: .7rem; letter-spacing: .08em; text-transform: uppercase;
  cursor: pointer;
}
.more-games:hover { text-decoration: underline; text-underline-offset: 3px; }

/* ============================================================
   full official directory
   ------------------------------------------------------------
   Deliberately not a second grid: cards are the edited guide, this is the raw
   list underneath it. It reads as a register — mono booth numbers, ruled rows,
   no plate shadow — so nothing about it competes with the cards above.
   ============================================================ */

.directory {
  margin-top: 34px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--ground-2);
}
.directory-summary {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.directory-summary::-webkit-details-marker { display: none; }
.directory-summary::after {
  content: "";
  width: 7px; height: 7px;
  border-right: 1.5px solid var(--ink-dim);
  border-bottom: 1.5px solid var(--ink-dim);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .15s;
  order: -1;
  margin-right: -6px;
}
.directory[open] > .directory-summary::after { transform: rotate(-135deg) translate(-3px, -3px); }
.directory[open] > .directory-summary { border-bottom: 1px solid var(--rule-soft); }
.directory-lede { font-size: .84rem; color: var(--ink-mid); min-width: 0; }
.directory-summary:hover .directory-lede { color: var(--ink); }

.directory-note {
  margin: 0;
  padding: 12px 16px 0;
  font-size: .8rem;
  color: var(--ink-dim);
  line-height: 1.5;
}
.directory-note:empty { display: none; }

.dir-list {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
}
.dir-row {
  display: grid;
  /* name takes the slack; country and stands stay in their own columns so the
     booth numbers line up into a readable rail down the right */
  grid-template-columns: minmax(0, 1fr) minmax(0, 130px) minmax(0, 250px);
  gap: 6px 14px;
  align-items: baseline;
  padding: 8px 16px;
  border-top: 1px solid var(--rule-soft);
  font-size: .85rem;
}
.dir-row:first-child { border-top: none; }
.dir-row:hover { background: var(--ground-3); }

.dir-name { min-width: 0; color: var(--ink); }
.dir-name a { color: inherit; text-decoration: none; }
.dir-name a:hover { color: var(--signal); text-decoration: underline; text-underline-offset: 3px; }
.dir-country { color: var(--ink-dim); font-size: .78rem; }

.dir-stands { display: flex; flex-wrap: wrap; gap: 4px 10px; min-width: 0; }
.dir-stand {
  font-family: var(--font-mono);
  font-size: .72rem;
  letter-spacing: .04em;
  color: var(--ink-mid);
  white-space: nowrap;
}
.dir-stand b { color: var(--ink); font-weight: 700; }
/* A stand in a hall the map draws is a link on the whole chip — the
   underline rides on the hall/booth alone, so the "at <host>" tail stays
   a note rather than looking like part of the destination. */
a.dir-stand { text-decoration: none; }
a.dir-stand .dir-stand-where {
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a.dir-stand:hover .dir-stand-where,
a.dir-stand:focus-visible .dir-stand-where { text-decoration-color: currentColor; }
a.dir-stand:hover,
a.dir-stand:focus-visible { color: var(--signal); }
a.dir-stand:hover b,
a.dir-stand:focus-visible b { color: var(--signal); }
/* which curated booth this stand actually sits on — the 172 Indie Arena Booth
   studios are meaningless without it */
.dir-stand i {
  font-style: normal;
  font-family: var(--font-ui);
  color: var(--ink-dim);
  white-space: normal;
}
.dir-stand-trade { color: var(--ink-dim); }
.dir-stand-trade b { color: var(--warn); }
.dir-stand-tba { color: var(--ink-dim); }

.dir-more {
  display: block;
  margin: 14px 16px;
  font-family: var(--font-mono);
  font-size: .74rem;
  letter-spacing: .08em;
  text-transform: uppercase;
}

@media (max-width: 640px) {
  .dir-row { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  .dir-country { font-size: .74rem; }
}

/* ============================================================
   saved & played marks
   ------------------------------------------------------------
   Saved is the visitor's own emphasis, so it takes the signal colour when set —
   that is what the one accent is for. Its "+" and "−" use the same language as
   "+ 4 more" above. Played deliberately does not take the signal colour: done
   is the opposite of emphasis, so its set plate and related content stay muted.
   ============================================================ */
.bm {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  padding: 0;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s, opacity .12s;
}
.bm:hover { color: var(--ink); border-color: var(--ink-dim); }
.bm[aria-pressed="true"] {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--signal-ink);
}
.bm[aria-pressed="true"]:hover { background: #ff6b3b; border-color: #ff6b3b; color: var(--signal-ink); }
.bm[data-mark="played"][aria-pressed="true"],
.bm[data-mark="played"][aria-pressed="true"]:hover {
  background: var(--ink-dim);
  border-color: var(--ink-dim);
  color: var(--ground);
}
.bm-mark { font-size: .9rem; line-height: 1; }

/* card head: a plate on the right edge, bracketing the hall plate on the left */
.bm-wide { width: auto; height: auto; padding: 0 15px; }
.exh-head .bm {
  align-self: stretch;
  height: auto;
  margin-left: auto;
  border: none;
  border-left: 1px solid var(--rule-soft);
  border-radius: 0;
}
.exh-head .bm:not(.bm-wide) { width: 28px; }
.exh-head .bm + .bm { margin-left: 0; }
.card[data-saved="true"] { border-color: var(--signal); }
.card[data-played="true"] { border-color: var(--rule); }
.card[data-played="true"] .card-body { opacity: .62; }

/* Repeated down a 23-game lineup the buttons would out-shout the titles, so
   they sit back until you reach for one — or until they're set. */
.game .bm { width: 18px; height: 18px; align-self: center; opacity: .45; }
.game:hover .bm,
.game .bm:focus-visible,
.game .bm[aria-pressed="true"] { opacity: 1; }
.game[data-saved="true"] .game-title { color: var(--signal); }
.game[data-played="true"] .game-title,
.game[data-played="true"] .game-plat { color: var(--ink-dim); }
.game[data-played="true"]::before { background: var(--neutral); }

.saved-count {
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}
.toggle input:checked ~ .saved-count { color: var(--signal); }

.tag-row { display: flex; gap: 5px; flex-wrap: wrap; }
.tag {
  font-family: var(--font-mono);
  font-size: .66rem;
  color: var(--ink-dim);
  border: 1px solid var(--rule);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
}

/* --- foot: queue index gauge --- */
.card-foot {
  margin-top: auto;
  padding: 12px 16px;
  border-top: 1px solid var(--rule-soft);
  background: rgba(0, 0, 0, .18);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.queue { display: flex; align-items: center; gap: 12px; }
.queue-val {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  margin-left: auto;
}
.meter { display: flex; gap: 2px; }
.meter i { width: 22px; height: 6px; background: var(--rule); border-radius: 1px; }
.meter[data-level="1"] i:nth-child(-n+1),
.meter[data-level="2"] i:nth-child(-n+2) { background: var(--ok); }
.meter[data-level="3"] i:nth-child(-n+3) { background: var(--warn); }
.meter[data-level="4"] i:nth-child(-n+4),
.meter[data-level="5"] i:nth-child(-n+5) { background: var(--alert); }

.queue[data-level="1"] .queue-val, .queue[data-level="2"] .queue-val { color: var(--ok); }
.queue[data-level="3"] .queue-val { color: var(--warn); }
.queue[data-level="4"] .queue-val, .queue[data-level="5"] .queue-val { color: var(--alert); }

.advice { font-size: .82rem; color: var(--ink-mid); line-height: 1.5; }
.advice-label {
  font-family: var(--font-mono);
  font-size: .62rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--signal); margin-right: 7px;
}

/* Leaving the guide is a deliberate act, so the link sits quiet under the
   plan and only lights up on hover — it must not compete with the queue gauge. */
.foot-links { display: flex; align-items: center; gap: 14px; }
.official-link {
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-dim);
  text-decoration: none;
  border-bottom: 1px solid var(--rule);
  padding-bottom: 1px;
}
.official-link:hover { color: var(--signal); border-bottom-color: var(--signal); }

/* The attribution marker. It has to be there on every card without becoming
   the thing you read, so it sits at the far end of the foot in the quietest
   ink on the page — the count is the whole label, and the accessible name
   spells out what it opens. margin-left:auto rather than an order rule so it
   still lands on the right when a card has no official page to sit beside. */
.src-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  flex: 0 0 auto;
  /* Quiet, but still a comfortable thumb target — the padding grows the box
     without adding any ink. */
  min-height: 24px;
  padding: 2px 7px 2px 5px;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: .64rem;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: color .12s, border-color .12s;
}
.src-btn:hover { color: var(--ink); border-color: var(--ink-dim); }
.src-glyph {
  display: inline-grid;
  place-items: center;
  width: 13px; height: 13px;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: .56rem;
  font-weight: 700;
  line-height: 1;
}

/* ============================================================
   planner — day board
   ============================================================ */
.day-board { border: var(--border); border-radius: var(--radius); overflow: hidden; }
.day-row {
  display: grid;
  grid-template-columns: 92px 130px 1fr;
  gap: 0 18px;
  align-items: baseline;
  padding: 14px 18px;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--ground-2);
}
.day-row:last-child { border-bottom: none; }
.day-row:hover { background: var(--ground-3); }

.day-when { display: flex; flex-direction: column; }
.day-dow {
  font-family: var(--font-poster);
  font-size: 1.45rem; font-weight: 400; line-height: 1;
  text-transform: uppercase; letter-spacing: .01em;
}
.day-date {
  font-family: var(--font-mono);
  font-size: .7rem; color: var(--ink-dim); font-variant-numeric: tabular-nums;
}
.day-access {
  font-family: var(--font-mono);
  font-size: .64rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--radius-sm); justify-self: start;
  border: 1px solid;
}
.day-access.public { color: var(--ok); border-color: rgba(47,191,133,.3); background: rgba(47,191,133,.08); }
.day-access.trade  { color: var(--alert); border-color: rgba(242,86,79,.3); background: rgba(242,86,79,.08); }

.day-detail { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.day-hours { font-family: var(--font-mono); font-size: .74rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.day-note { color: var(--ink-mid); font-size: .85rem; }

/* ============================================================
   planner — your plan, shared shell (see the lens blocks below)
   ============================================================ */
#plan-section { scroll-margin-top: 140px; }
.plan-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin: -4px 0 12px;
}
.plan-controls .result-count { margin-left: auto; }
.plan-lens { display: flex; gap: 6px; }
.plan-days {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  margin: -2px 0 12px;
}

/* ============================================================
   planner — your plan, day lens (itinerary)
   ============================================================ */
.it-board { border: var(--border); border-radius: var(--radius); overflow: hidden; }
.it-group + .it-group { border-top: 1px solid var(--rule); }
.it-group-head {
  display: grid;
  grid-template-columns: 92px 130px 1fr;
  gap: 0 18px;
  align-items: baseline;
  padding: 11px 18px;
  background: var(--ground-3);
  border-bottom: 1px solid var(--rule);
}
.it-group-head.unassigned { display: block; }
.it-group-title {
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-mid);
}

.it-item {
  display: grid;
  grid-template-columns: minmax(150px, 1.1fr) minmax(180px, 1.35fr) auto 20px;
  gap: 0 16px;
  align-items: center;
  padding: 12px 18px;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--ground-2);
}
.it-item:last-child { border-bottom: none; }
.it-item:hover { background: var(--ground-3); }
.it-item[data-played="true"] {
  opacity: .62;
  box-shadow: inset 3px 0 0 var(--ink-dim);
}
.it-main { display: flex; flex-direction: column; min-width: 0; }
.it-kind {
  font-family: var(--font-mono);
  font-size: .62rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.it-name { font-weight: 700; font-size: .95rem; }
.it-loc {
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--ink-mid);
  font-variant-numeric: tabular-nums;
}
.it-days { display: flex; gap: 5px; flex-wrap: wrap; justify-content: flex-end; }
.day-chip {
  background: none;
  border: 1px solid var(--rule);
  color: var(--ink-mid);
  border-radius: var(--radius-sm);
  padding: 3px 8px;
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color .12s, border-color .12s, background .12s;
}
.day-chip:hover { color: var(--ink); border-color: var(--ink-dim); }
.day-chip.active { background: var(--signal); border-color: var(--signal); color: var(--signal-ink); }
.day-chip[data-trade="true"]:not(.active) { border-style: dashed; color: var(--ink-dim); }
.it-item .bm { grid-column: -2 / -1; grid-row: 1; align-self: center; }

/* ============================================================
   planner — priority table
   ============================================================ */
.priority-controls {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.priority-controls .result-count { margin-left: auto; }

.priority-table { border: var(--border); border-radius: var(--radius); overflow: hidden; }
.priority-item {
  display: grid;
  grid-template-columns: 40px minmax(150px, 1.1fr) 96px 2fr auto;
  gap: 0 16px;
  align-items: baseline;
  padding: 12px 18px;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--ground-2);
}
/* the last column in either layout, so no override is needed on a phone */
.row-actions {
  display: flex;
  align-items: center;
  gap: 6px;
}
.priority-item .row-actions { grid-column: -2 / -1; grid-row: 1; align-self: center; }
.priority-item[data-saved="true"] { box-shadow: inset 3px 0 0 var(--signal); }
.priority-item[data-played="true"] {
  opacity: .62;
  box-shadow: inset 3px 0 0 var(--ink-dim);
}

/* Which of your saved games this booth is actually running — the reason a
   publisher row is on your list at all. */
.priority-saved {
  grid-column: 2 / -1;
  display: flex;
  align-items: baseline;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 5px;
}
.priority-saved .row-label { color: var(--signal); flex: 0 0 auto; }
.priority-game {
  font-family: var(--font-mono);
  font-size: .72rem;
  color: var(--ink);
  border: 1px solid var(--signal-wash);
  background: var(--signal-wash);
  padding: 1px 7px;
  border-radius: var(--radius-sm);
}
.priority-item:last-child { border-bottom: none; }
.priority-item:hover { background: var(--ground-3); }
.priority-rank {
  font-family: var(--font-mono);
  font-weight: 700; font-size: .95rem;
  color: var(--signal);
  font-variant-numeric: tabular-nums;
}
.priority-name,
.wristband-name { font-weight: 700; font-size: .95rem; }
.priority-name .badge-age { margin-left: 6px; vertical-align: .1em; }
.priority-loc,
.wristband-loc {
  font-family: var(--font-mono);
  font-size: .76rem; color: var(--ink-mid);
  font-variant-numeric: tabular-nums;
}
.priority-advice,
.wristband-games { color: var(--ink-mid); font-size: .84rem; }

/* Same row language as queue priority, without the rank column. Four tracks, and
   every row fills all four — the "18+ expected" marker rides inside the titles
   cell, because each row is its own grid and a column only some rows fill would
   size their fr tracks differently. */
.wristband-item {
  grid-template-columns: minmax(150px, 1.1fr) minmax(130px, .8fr) minmax(200px, 2fr) auto;
}
.wristband-status { margin-left: 4px; vertical-align: baseline; }

/* ============================================================
   planner — your plan, hall lens (route)
   ============================================================ */
.route-board { border: var(--border); border-radius: var(--radius); overflow: hidden; }
.route-hall {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 18px;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--ground-3);
}
.route-hall-kicker {
  font-family: var(--font-mono);
  font-size: .64rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-dim);
}
.route-hall-num {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.route-hall-map {
  font-family: var(--font-mono);
  font-size: .64rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-dim); text-decoration: none;
  border: 1px solid var(--rule); border-radius: var(--radius-sm);
  padding: 2px 7px;
}
.route-hall-map:hover, .route-hall-map:focus-visible { color: var(--ink); border-color: var(--ink-dim); }
.route-hall-count {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: .68rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
}

.route-item {
  display: grid;
  grid-template-columns: minmax(150px, 1.2fr) minmax(110px, 1fr) auto auto;
  gap: 0 16px;
  align-items: baseline;
  padding: 12px 18px;
  border-bottom: 1px solid var(--rule-soft);
  background: var(--ground-2);
}
.route-item:last-child { border-bottom: none; }
.route-item:hover { background: var(--ground-3); }
.route-item[data-saved="true"] { box-shadow: inset 3px 0 0 var(--signal); }
.route-item[data-played="true"] {
  opacity: .62;
  box-shadow: inset 3px 0 0 var(--ink-dim);
}
.route-item .row-actions { grid-column: -2 / -1; grid-row: 1; align-self: center; }
.route-item .priority-saved { grid-column: 1 / -1; }
.route-name { font-weight: 700; font-size: .95rem; }
/* the day a stop is planned for, read straight off the itinerary */
.route-day {
  font-family: var(--font-mono);
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--signal);
  background: var(--signal-wash);
  border-radius: var(--radius-sm);
  padding: 2px 6px;
  margin-left: 8px;
  vertical-align: .14em;
  white-space: nowrap;
}
.route-booth {
  font-family: var(--font-mono);
  font-size: .76rem;
  color: var(--ink-mid);
  font-variant-numeric: tabular-nums;
}
.route-crowd {
  font-family: var(--font-mono);
  font-size: .72rem;
  font-weight: 700;
  color: var(--ink-mid);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.route-crowd[data-level="4"] { color: var(--warn); }
.route-crowd[data-level="5"] { color: var(--alert); }
.route-absent {
  margin-top: 12px;
  color: var(--ink-dim);
  font-size: .82rem;
}

/* ============================================================
   planner — tips
   ============================================================ */
.tips { list-style: none; counter-reset: tip; border-top: 1px solid var(--rule); }
.tips li {
  counter-increment: tip;
  position: relative;
  padding: 13px 0 13px 46px;
  border-bottom: 1px solid var(--rule-soft);
  color: var(--ink-mid);
  font-size: .9rem;
}
.tips li::before {
  content: counter(tip, decimal-leading-zero);
  position: absolute; left: 0; top: 13px;
  font-family: var(--font-mono);
  font-size: .74rem; font-weight: 700;
  color: var(--signal);
}

/* ============================================================
   event info
   ============================================================ */
.info-block { margin-bottom: 34px; }
.info-block > h2 {
  font-family: var(--font-poster);
  font-size: 1.35rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: .01em;
  padding-bottom: 8px; margin-bottom: 14px;
  border-bottom: 1px solid var(--rule);
  display: flex; align-items: baseline; gap: 12px;
}
.info-block > h2 .section-num { color: var(--signal); }
.info-block p {
  color: var(--ink-mid);
  font-size: .9rem;
}
.info-block p + p { margin-top: 10px; }
.info-block b, .info-block strong { color: var(--ink); font-weight: 600; }
.info-block a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--signal); text-underline-offset: 3px; }
.info-block a:hover { color: var(--signal); }

.info-block .headline-fact {
  font-family: var(--font-poster);
  font-size: 2.1rem; font-weight: 400; line-height: 1.1;
  text-transform: uppercase; letter-spacing: .005em;
  color: var(--ink);
  margin-bottom: 6px;
}
.info-block .fact-sub {
  font-family: var(--font-mono);
  font-size: .78rem; color: var(--ink-dim); letter-spacing: .04em;
}

.area-list { list-style: none; border-top: 1px solid var(--rule-soft); }
.area-list li {
  display: grid;
  grid-template-columns: 76px 1fr;
  gap: 0 16px;
  padding: 11px 0;
  border-bottom: 1px solid var(--rule-soft);
  align-items: baseline;
}
.area-hall {
  font-family: var(--font-mono);
  font-size: .8rem; font-weight: 700; color: var(--signal);
  font-variant-numeric: tabular-nums;
}
.area-hall.none { color: var(--ink-dim); font-weight: 400; }
.area-name { font-weight: 600; font-size: .92rem; }
.area-desc { color: var(--ink-mid); font-size: .85rem; }

.link-list { list-style: none; border-top: 1px solid var(--rule-soft); }
.link-list li { border-bottom: 1px solid var(--rule-soft); }
.link-list a { display: flex; gap: 12px; align-items: baseline; padding: 11px 0; text-decoration: none; color: var(--ink); }
.link-list a:hover .link-name { color: var(--signal); }
.link-name { font-weight: 600; font-size: .92rem; }
.link-desc { color: var(--ink-dim); font-size: .82rem; margin-left: auto; }

/* ============================================================
   updates timeline
   ============================================================ */
.timeline { border-left: 1px solid var(--rule); padding-left: 26px; margin-left: 6px; }
.timeline-entry { position: relative; padding-bottom: 30px; }
.timeline-entry::before {
  content: "";
  position: absolute; left: -31px; top: 7px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--signal); border: 2px solid var(--ground);
}
.timeline-entry:not(:first-child)::before { background: var(--rule); }
.timeline-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 8px; }
.timeline-date { font-family: var(--font-mono); font-size: .88rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.rev-tag {
  font-family: var(--font-mono);
  font-size: .62rem; font-weight: 500; letter-spacing: .12em; text-transform: uppercase;
  color: var(--signal); border: 1px solid var(--signal-wash); background: var(--signal-wash);
  padding: 1px 7px; border-radius: var(--radius-sm);
}
.timeline-entry ul { list-style: none; }
.timeline-entry li {
  color: var(--ink-mid); font-size: .88rem;
  padding: 4px 0 4px 16px; position: relative;
}
.timeline-entry li::before {
  content: "—"; position: absolute; left: 0; color: var(--ink-dim);
}

/* ============================================================
   footer
   ============================================================ */
.site-footer { border-top: 1px solid var(--rule); padding: 32px 0 48px; }
.footer-inner {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 48px;
  align-items: start;
}
.footer-col { display: flex; flex-direction: column; gap: 6px; font-size: .82rem; color: var(--ink-dim); }
.footer-strong { color: var(--ink); font-weight: 600; }
.mono-note { font-family: var(--font-mono); font-size: .7rem; line-height: 1.6; margin-top: 4px; }

.legend { list-style: none; display: flex; flex-direction: column; gap: 5px; margin-top: 4px; }
.legend li { display: flex; align-items: baseline; gap: 8px; font-size: .78rem; }
.legend b { color: var(--ink); font-weight: 600; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--neutral); flex: 0 0 auto; }
.dot[data-status="confirmed"] { background: var(--ok); }
.dot[data-status="expected"]  { background: var(--warn); }
.dot[data-status="rumored"]   { background: var(--neutral); }

.empty { text-align: center; color: var(--ink-dim); padding: 70px 0; font-size: .9rem; }
.empty code { font-family: var(--font-mono); color: var(--ink); }

.subtle-link {
  color: var(--ink-dim);
  text-decoration: underline;
  text-decoration-color: var(--rule);
  text-underline-offset: 3px;
}

/* ============================================================
   sheets — the panel chrome shared by every dialog
   ============================================================ */
.sheet {
  width: min(540px, calc(100vw - 32px));
  max-height: min(760px, calc(100vh - 32px));
  margin: auto;
  padding: 0;
  overflow: auto;
  background: var(--ground-2);
  color: var(--ink);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  box-shadow: var(--plate-shadow-hover);
}
.sheet::backdrop { background: rgba(0, 0, 0, .78); }

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--rule);
}
.sheet-head h2 {
  margin-top: 2px;
  font-family: var(--font-poster);
  font-size: 1.65rem;
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: .005em;
  text-transform: uppercase;
}
.sheet-close {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink-dim);
  font: inherit;
  font-size: 1.35rem;
  line-height: 1;
  cursor: pointer;
}
.sheet-close:hover { border-color: var(--ink-dim); color: var(--ink); }

.sheet-body { padding: 20px; }

/* ============================================================
   share saved list
   ============================================================ */
.share-count { margin-bottom: 14px; color: var(--ink-mid); font-size: .88rem; }

.share-link-field {
  display: block;
  background: var(--ground);
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
}
.share-link-field .field-label { display: block; padding: 8px 12px 0; }
#share-link {
  display: block;
  width: 100%;
  padding: 4px 12px 10px;
  background: none;
  border: none;
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: .74rem;
  line-height: 1.5;
}
#share-link:focus-visible { outline-offset: -2px; }
#share-link::selection { background: var(--signal); color: var(--signal-ink); }

.share-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.share-action {
  padding: 7px 13px;
  background: none;
  border: 1px solid var(--rule);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .12s, border-color .12s, color .12s;
}
.share-action:hover { border-color: var(--ink-dim); }
.share-action-primary {
  background: var(--signal);
  border-color: var(--signal);
  color: var(--signal-ink);
}
.share-action-primary:hover { background: #ff6b3b; border-color: #ff6b3b; }
.share-action[hidden] { display: none; }
.share-status {
  margin-top: 10px;
  min-height: 1.2em;
  color: var(--ink-mid);
  font-size: .8rem;
}

.share-qr {
  display: grid;
  grid-template-columns: minmax(180px, 250px) 1fr;
  align-items: center;
  gap: 18px;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid var(--rule-soft);
}
.share-qr[hidden], .share-qr-fallback[hidden] { display: none; }
.share-qr-image {
  width: 100%;
  padding: 8px;
  background: #fff;
  color: #000;
  line-height: 0;
}
.share-qr-image svg { display: block; width: 100%; height: auto; }
.share-qr p, .share-qr-fallback { color: var(--ink-dim); font-size: .8rem; }
.share-qr-fallback {
  margin-top: 20px;
  padding: 12px 14px;
  border-left: 3px solid var(--warn);
  background: rgba(232, 163, 58, .08);
}

/* ============================================================
   sources dialog
   ============================================================ */
.src-dialog { width: min(500px, calc(100vw - 32px)); }
.src-subject {
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.25;
}
.src-note { margin-top: 4px; color: var(--ink-mid); font-size: .84rem; }

.src-list { list-style: none; margin-top: 16px; border-top: 1px solid var(--rule-soft); }
.src-list li {
  display: flex;
  align-items: baseline;
  gap: 12px;
  border-bottom: 1px solid var(--rule-soft);
}
.src-num {
  font-family: var(--font-mono);
  font-size: .66rem;
  color: var(--ink-dim);
  font-variant-numeric: tabular-nums;
  padding: 11px 0;
}
/* The host is the part that tells you who is making the claim, so it is set as
   the link; the path trails behind it in dimmer ink and is allowed to wrap
   rather than pushing the panel sideways. */
.src-list a {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 8px;
  padding: 10px 0;
  text-decoration: none;
  color: var(--ink);
}
.src-host {
  font-family: var(--font-mono);
  font-size: .78rem;
  border-bottom: 1px solid var(--rule);
}
.src-list a:hover .src-host { color: var(--signal); border-bottom-color: var(--signal); }
.src-path {
  min-width: 0;
  color: var(--ink-dim);
  font-family: var(--font-mono);
  font-size: .68rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
}
.src-caveat {
  margin-top: 18px;
  padding: 12px 14px;
  border-left: 3px solid var(--warn);
  background: rgba(232, 163, 58, .08);
  color: var(--ink-mid);
  font-size: .8rem;
  line-height: 1.5;
}

/* Event info carries the same marker for the whole page's data. */
.info-foot {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 26px;
  padding-top: 16px;
  border-top: 1px solid var(--rule-soft);
  color: var(--ink-dim);
  font-size: .8rem;
}
.info-foot .src-btn { margin-left: 0; }

/* ============================================================
   installed-app chrome — install button, offline flag, toast
   ============================================================ */

/* Reads as a stamped label rather than a call-to-action button: it sits in
   the masthead next to the countdown and must not out-shout the hall plates. */
.install-btn {
  align-self: flex-end;
  margin-top: 6px;
  background: none;
  border: 1px solid var(--signal);
  color: var(--signal);
  border-radius: var(--radius-sm);
  padding: 3px 10px;
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .12s, color .12s;
}
.install-btn:hover { background: var(--signal); color: var(--signal-ink); }

/* Only meaningful while the network is gone, so it is absent — not merely
   dimmed — the rest of the time. */
.offline-flag {
  display: none;
  font-family: var(--font-mono);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--warn);
}
html[data-offline="true"] .offline-flag { display: block; }

.toast {
  position: fixed;
  left: 24px;
  right: 24px;
  bottom: calc(24px + env(safe-area-inset-bottom));
  z-index: 100;
  margin: 0 auto;
  max-width: 460px;
  display: flex;
  align-items: center;
  gap: 14px;
  background: var(--ground-2);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--signal);
  border-radius: var(--radius);
  box-shadow: var(--plate-shadow);
  padding: 12px 14px;
  font-size: .84rem;
  color: var(--ink);
}
.toast[hidden] { display: none; }
.toast-text { flex: 1; }
.toast-action {
  flex: 0 0 auto;
  background: var(--signal);
  border: none;
  color: var(--signal-ink);
  border-radius: var(--radius-sm);
  padding: 5px 12px;
  font-family: var(--font-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
}
.toast-dismiss {
  flex: 0 0 auto;
  background: none;
  border: none;
  color: var(--ink-dim);
  font-size: 1.2rem;
  line-height: 1;
  padding: 0 2px;
  cursor: pointer;
}
.toast-dismiss:hover { color: var(--ink); }

/* Standalone has no browser chrome to sit under, so the app has to keep
   itself clear of the notch and the home indicator on its own. */
html[data-standalone="true"] body { padding-top: env(safe-area-inset-top); }
html[data-standalone="true"] .site-footer { padding-bottom: calc(48px + env(safe-area-inset-bottom)); }
.wrap { padding-left: max(24px, env(safe-area-inset-left)); padding-right: max(24px, env(safe-area-inset-right)); }

/* ============================================================
   responsive
   ============================================================ */
@media (max-width: 860px) {
  .footer-inner { grid-template-columns: 1fr 1fr; }
  .priority-item { grid-template-columns: 34px 1fr auto; row-gap: 4px; }
  .priority-loc, .priority-advice { grid-column: 2 / -1; }
  .route-item { grid-template-columns: 1fr auto auto; row-gap: 4px; }
  .route-booth { grid-column: 1 / -1; grid-row: 2; }
  .route-crowd { grid-column: 2; grid-row: 1; }
  .wristband-item { grid-template-columns: 1fr auto; }
  .wristband-loc,
  .wristband-games { grid-column: 1 / -1; justify-self: start; }
}

@media (max-width: 620px) {
  .wrap { padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
  .tabs { padding: 0 16px; }
  .toast { left: 16px; right: 16px; bottom: calc(16px + env(safe-area-inset-bottom)); }
  .install-btn { align-self: flex-start; }
  /* the full masthead is ~290px on a phone — far too much to pin above a
     long scrolling list, so it scrolls away here instead */
  .site-header { position: static; }
  /* …and with nothing pinned on top, the sticky-header scroll offset would
     just strand the route heading 140px down the screen */
  #route-section { scroll-margin-top: 16px; }
  .header-inner { flex-direction: column; align-items: flex-start; gap: 12px; padding-bottom: 14px; }
  .header-meta { text-align: left; }
  .grid { grid-template-columns: 1fr; }
  .footer-inner { grid-template-columns: 1fr; gap: 26px; }
  .day-row { grid-template-columns: 76px 1fr; row-gap: 8px; }
  .day-access { grid-column: 2; }
  .day-detail { grid-column: 1 / -1; }
  .it-group-head { grid-template-columns: 76px 1fr; row-gap: 8px; }
  .it-item { grid-template-columns: minmax(110px, 1fr) minmax(0, 1.2fr) 20px; row-gap: 9px; }
  .it-days { grid-column: 1 / -1; justify-content: flex-start; }
  .toolbar-row .row-label { flex-basis: 100%; }
  /* let the summary text take a full line instead of squeezing into a column */
  .toolbar-summary { flex-wrap: wrap; row-gap: 4px; }
  .toolbar-summary .row-label { flex: 0 0 auto; }
  .filter-summary { flex: 1 1 100%; order: 3; }
  .directory-summary { flex-wrap: wrap; row-gap: 4px; }
  .directory-lede { flex: 1 1 100%; order: 3; }
  .field-sort { border-left: none; border-top: 1px solid var(--rule-soft); }
  .toolbar-search { flex-direction: column; align-items: stretch; }
  .result-count { margin-left: 0; flex-basis: 100%; }
  .area-list li { grid-template-columns: 1fr; row-gap: 2px; }
  .sheet { width: calc(100vw - 24px); max-height: calc(100vh - 24px); }
  .sheet-head, .sheet-body { padding: 16px; }
  .share-qr { grid-template-columns: 1fr; }
  .share-qr-image { max-width: 280px; margin: 0 auto; }
  .share-qr p { text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
