/* =======================================================================
   front-door.css — the FRONT DOOR wears the Frost Milano skin

   index.html only, and every rule in here is scoped to
   body[data-info-home] so that nothing it does can reach tonight.html,
   venues.html or venue.html. The register (css/info.css) still lays this
   page OUT — the column, the sticker gutter, the dock in the corner. This
   file only paints it, in css/style.css's 1999 ice, so the front door and
   the artist page at frost.html read as one hand.

   THE OWNER'S ASK, 2026-08-23: "make the tap in home page look like frosts
   music page ... when you tap in but also yes the whole normal home page
   too." The taps are the three .door cards; the "whole normal home page"
   is everything around them. Both are below.

   WHY A THIRD STYLESHEET AND NOT A RESKIN OF info.css
   css/info.css's token block recolours the WHOLE register in one place,
   which is the point of it — swapping it to the ICE set (it is already
   recorded there, commented) would have dragged the listings pages into
   the Y2K look with this page, and they are meant to be a plain reading
   surface on one bar of signal. So the divergence lives here, on the one
   page that asked for it, and scripts/info-shell-check.mjs still finds
   hud.css then info.css on this page in that order, still finds no
   page-local <style> token block, and still owns the register's shape.

   THE VALUES ARE COPIES, NOT IMPORTS. css/style.css is not linked here:
   it styles a whole other page's shell, hero, panels and televisions, and
   pulling all 888 lines in to borrow six gradients would put frost.html's
   layout on the front door by accident. The ice tokens below are the same
   numbers as its :root, deliberately duplicated and named as such.

   ONE BAR OF SIGNAL. The register's rule is no webfont, and this page now
   links two (Anton and VT323 — the wordmark and the pixel type ARE the
   look being asked for). They are asked for with display=swap and every
   stack below falls back to Impact and Courier New, which ship on the
   machines this page is read on: with the fonts blocked the page is the
   same page in the wrong typeface, not a broken one.
   ======================================================================= */

body[data-info-home] {
  /* the ice set, copied from css/style.css :root — see the header */
  --ice-deep:   #0a0a0a;
  --ice-deep2:  #1e1e1e;
  --ice-bright: #ffd800;
  --ice-light:  #ffe873;
  --ice-white:  #fff8dc;
  --frost-3:    #d6b000;
  --frost-4:    #8a7200;
  --chk-light:  #f5edc8;
  --chk-dark:   #141414;

  --emoji:   "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";
  --display: "Anton", "Impact", "Haettenschweiler", var(--emoji), sans-serif;
  --pixel:   "VT323", "Courier New", var(--emoji), monospace;
  --body:    "Space Grotesk", Verdana, Geneva, var(--emoji), sans-serif;

  font-family: var(--body);
  color: var(--ice-white);
  /* the starfield + glacier, same recipe as css/style.css's body */
  background-color: var(--ice-deep);
  background-image:
    radial-gradient(1.5px 1.5px at 20px 30px, #ffffff 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 120px 80px, #fff0a8 50%, transparent 51%),
    radial-gradient(1px 1px at 70px 160px, #ffffff 50%, transparent 51%),
    radial-gradient(1px 1px at 180px 200px, #e8c84a 50%, transparent 51%),
    radial-gradient(circle at 50% -10%, #3d3200 0%, transparent 55%),
    linear-gradient(180deg, #121212 0%, #0a0a0a 60%, #000000 100%);
  background-size: 220px 240px, 220px 240px, 220px 240px, 220px 240px,
                   100% 100%, 100% 100%;
  background-attachment: fixed;
}

/* ---------- THE TICKER ----------
   frost.html's marquee, in CSS only. The track holds the sentence TWICE
   and travels -50%, so the loop is seamless; that is why the markup looks
   repetitive. Sticky like the original, and under the two HUD stickers'
   z-index rather than over them. */
body[data-info-home] .fd-ticker {
  position: sticky; top: 0; z-index: 500;
  background: linear-gradient(180deg, #2a2a2a, #161616);
  border-bottom: 3px ridge var(--frost-3);
  overflow: hidden; white-space: nowrap;
  font-family: var(--pixel); font-size: 1.2rem; letter-spacing: 1px;
  color: #ffe873; text-shadow: 0 0 8px rgba(255,216,0, .6);
}
body[data-info-home] .fd-ticker__track {
  display: inline-block; padding: 5px 0;
  animation: fd-ticker 28s linear infinite;
}
@keyframes fd-ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- THE SHELL ----------
   the register's 680px column, given frost.html's ridged glass frame. */
body[data-info-home] .wrap {
  margin: 18px auto; padding: 14px 16px 20px;
  background: linear-gradient(180deg, rgba(26,22,0, .92), rgba(20,20,20, .94));
  border: 5px ridge var(--frost-3); border-radius: 10px;
  box-shadow: 0 0 0 2px #050505, 0 0 40px rgba(255,216,0, .25),
              inset 0 0 60px rgba(255,216,0, .06);
}
/* ⚠ THE PHONE GETS THE WHOLE WIDTH, AND THE COLUMN IS CENTRED. Owner,
   2026-09-15: "the phone home page ... should use the full width and
   everything needs to be centered". Until then this page kept info.css's
   74px LEFT padding under 760px — the gutter the paper and the map stickers
   sit in — and photographed at 390px that is the whole defect: every
   centred thing on the page (the wordmark, the tagline, TONIGHT IN AUSTIN,
   the buttons) was centred in a column that started 74px right of where
   the eye expects it, and the cards ran ~270px wide on a 390px screen.
   So here, and only here, the gutter goes: the frame keeps a 4px margin so
   its ridge still reads as a frame, the padding is the same both sides, and
   the two stickers sit ON the column the way they sit on every walked room
   in town (they are position:fixed and z 5; the body's 104px bottom padding
   keeps the map off the footer at the end of the scroll). Nothing is hidden. */
@media (max-width: 760px) {
  body[data-info-home] .wrap {
    margin: 8px 4px; padding: 10px 8px 16px;
    border-radius: 8px;
  }
  /* "everything centered": the three doors were the one thing left reading
     from the left edge once the column was straight — a full-width card on
     a phone with its title and line hugging the left rim, under a centred
     wordmark, a centred board and centred "… or" lines. Centred like the
     rest; the desktop keeps the register's left-set door text. */
  body[data-info-home] .door { text-align: center; }
}

/* ---------- THE MASTHEAD ----------
   js/info-nav.js builds .ibar and this page never writes it; it gets
   frost.html's nav buttons rather than the register's quiet caps row. */
body[data-info-home] .ibar {
  gap: 8px; justify-content: center; padding: 8px;
  margin: 4px 0 14px; letter-spacing: 1px;
  background: linear-gradient(180deg, #2a2a2a, #181818);
  border: 4px ridge var(--frost-3); border-radius: 8px;
  box-shadow: 0 4px 0 #000000, 0 8px 18px rgba(0, 0, 0, .5);
}
body[data-info-home] .ibar a {
  font-family: var(--display); font-size: 1rem; color: var(--ice-white);
  padding: 5px 12px; border-radius: 6px;
  background: linear-gradient(180deg, #5a4a00, #2a2300);
  border: 2px outset #e6c200; text-shadow: 0 1px 0 #050505;
}
body[data-info-home] .ibar a:hover { filter: brightness(1.25); color: #fff; }
body[data-info-home] .ibar .ibar__brand,
body[data-info-home] .ibar .ibar__cur {
  font-family: var(--display); color: var(--ice-white); border-bottom: 0;
  letter-spacing: 1px;
}
/* ⚠ THIS ONE WAS BACKWARDS, and it is the clearest case in the register of
   the defect the owner named on 2026-09-08 ("nothing really makes it obvious
   … make important things eye catching"). The nav links beside it are a LIT
   button — `linear-gradient(180deg, #5a4a00, #2a2300)` with an outset border
   — and the current page was `#3d3200 → #1a1a1a`, which is DARKER than they
   are. On a phone that reads as the one item you cannot press. A dark fill
   plus a glow is what a disabled control looks like; it is not emphasis.

   It is now the same solid accent the whole register uses, in this page's
   own idiom (the ridge border and Anton face stay, so the arcade masthead
   still looks like itself). See css/info.css's .ibar__cur for the contract
   and scripts/register-highlight-check.mjs for the gate on it. */
body[data-info-home] .ibar .ibar__cur {
  background: var(--ice-bright); color: #161616;
  border: 3px ridge var(--frost-3); border-radius: 6px; padding: 4px 12px;
  text-shadow: none;
}

/* ---------- THE HERO ----------
   ⚠ THE <h1> STAYS ONE PLAIN STRING. scripts/front-door-check.mjs reads
   <h1>…</h1> whole and compares it to the masthead's brand, so a
   .wordmark__line span inside it would fail the gate with the page looking
   perfect. The chrome-ice gradient is therefore painted on the h1 itself. */
body[data-info-home] header.top { text-align: center; padding: 8px 0 4px; }
body[data-info-home] .fd-blink {
  font-family: var(--pixel); font-size: 1.05rem; color: #ffe9a8;
  letter-spacing: 2px; margin-bottom: 8px;
  animation: fd-blink 1.1s steps(2, start) infinite;
}
@keyframes fd-blink { 50% { opacity: .15; } }
/* the mark above the title. It was min(38vw, 210px) — "small here, because
   this page is the listings board" — until the owner, 2026-09-15: "the home
   page logo is too small". So it fills the reading column: 560px is the
   680px column less the frame's padding, and on a phone 82vw is the column
   too (measured at 390px: 320px wide, three times the 110px it was). The
   name under it (the h1, front-door-check reads it) stays. */
body[data-info-home] .fd-logo {
  display: block; margin: 0 auto 6px; width: min(82vw, 560px, 70vh); height: auto;
  filter: drop-shadow(0 0 22px rgba(255,216,0,.28)) drop-shadow(0 4px 10px rgba(0,0,0,.7));
}
body[data-info-home] h1 {
  font-family: var(--display); text-transform: uppercase;
  font-size: clamp(2.6rem, 12vw, 5rem); line-height: .9; letter-spacing: 2px;
  background: linear-gradient(180deg, #ffffff 0%, #fff6cc 22%, #ffe27a 40%,
                              #d6b000 55%, #ffffff 70%, #8a7200 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 2px 0 #1e1e1e) drop-shadow(0 4px 10px rgba(0, 0, 0, .6));
}
body[data-info-home] .when {
  font-family: var(--pixel); font-size: 1.2rem; text-transform: none;
  letter-spacing: 1px; color: var(--ice-light);
  text-shadow: 0 0 10px rgba(255,216,0, .4); margin-top: 8px;
}
/* the two checker bands bookend the page and are used TWICE and only
   twice, which is css/style.css's own rule for them */
body[data-info-home] .fd-checker {
  height: 14px; margin: 14px 0 4px;
  background: conic-gradient(var(--chk-dark) 0 25%, var(--chk-light) 0 50%,
                             var(--chk-dark) 0 75%, var(--chk-light) 0) 0 0 / 16px 16px;
  border-top: 2px solid var(--frost-4); border-bottom: 2px solid var(--frost-4);
}

/* ---------- THE LIVE STRIP ---------- */
body[data-info-home] .live {
  background: linear-gradient(180deg, rgba(30,26,0, .55), rgba(10,10,10, .6));
  border: 3px groove var(--frost-4); border-radius: 8px;
}
body[data-info-home] .live h2 {
  font-family: var(--display); font-size: 1.25rem; letter-spacing: 2px;
  color: var(--ice-white); text-align: center;
  text-shadow: 0 0 14px rgba(255,216,0, .6), 0 2px 0 #050505;
}
body[data-info-home] .live .row { border-top-color: rgba(214,176,0, .3); }
body[data-info-home] .live .rm { color: var(--ice-white); }
body[data-info-home] .live .ac,
body[data-info-home] .live .none {
  color: var(--ice-light); font-family: var(--pixel); font-size: 1.1rem;
}
body[data-info-home] .go {
  font-family: var(--display); letter-spacing: 1.5px; text-transform: uppercase;
  font-size: 1rem; padding: 9px 18px; border-radius: 999px;
  color: #241606; border: 2px solid #ffeec4;
  background: linear-gradient(180deg, #ffffff 0%, #f3cf7a 45%, #8a5a12 100%);
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, .9),
              inset 0 -3px 6px rgba(20,16,0, .4),
              0 3px 0 #1e1e1e, 0 5px 14px rgba(0, 0, 0, .5);
}

/* ---------- THE TAPS ----------
   THE THING THE OWNER ASKED FOR. The three doors were flat register cards;
   they are now frost.html's glossy Y2K bevel — a white top highlight, a
   colour ramp, a hard 3px drop that the :active state travels down into,
   so a tap has somewhere to go. They stay STACKED and full width (four
   pills side by side at 390px is four pills nobody can read), and each
   keeps its own colour from css/style.css's hero row, for its reasons:
   gold for the listings that load nothing, CAB YELLOW for the download,
   ice for the music. The filled doors keep reading loudest because they
   are the ones that cost a download.
   ⚠ THAT USED TO SAY "the world door ... the only one", AND IT STOPPED
   BEING TRUE ON 2026-08-31 when the hub landed as a second .door--world.
   A comment that names a count goes stale the moment the count moves, and
   this one had been the reason a reader believed the page had exactly one
   heavy card. Say the RULE (filled = costs a download), not the tally. */
body[data-info-home] .door {
  --b1: #ffe14d; --b2: #a68a00;
  margin: 12px 0; padding: 14px 18px; border-radius: 14px;
  color: #1a1600; border: 2px solid #fff8dc;
  background: linear-gradient(180deg, #ffffff 0%, var(--b1) 45%, var(--b2) 100%);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, .9),
              inset 0 -3px 6px rgba(20,16,0, .4),
              0 3px 0 #1e1e1e, 0 5px 14px rgba(0, 0, 0, .5);
  transition: transform .08s ease, filter .12s ease;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .5);
}
body[data-info-home] .door:hover { filter: brightness(1.1) saturate(1.1); transform: translateY(-1px); }
body[data-info-home] .door:active {
  filter: none; transform: translateY(2px);
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, .7),
              inset 0 -2px 5px rgba(20,16,0, .5), 0 1px 0 #1e1e1e;
}
body[data-info-home] .door b {
  font-family: var(--display); font-size: 1.35rem; letter-spacing: 1.5px;
  text-transform: uppercase;
}
body[data-info-home] .door > span {
  font-family: var(--pixel); font-size: 1.1rem; line-height: 1.25;
  color: #1a1600; margin-top: 4px;
}
body[data-info-home] .door--world {
  --b1: #ffd84d; --b2: #a86a06;
  color: #000; border-color: #fff0bf;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
}
body[data-info-home] .door--world b { color: #2a1608; }
body[data-info-home] .door--world > span { color: #3a2208; }
/* THE OTHER WORLD, added 2026-08-30 on the owner's ask ("add an easy way to
   get to the 2d world"). It sits directly under .door--world and has to read
   as its SIBLING rather than as a third listings card, so it takes a colour
   of its own out of css/style.css's hero row - .btn--lounge's purple, the
   same way .door--world takes .btn--city's cab yellow. That row is the
   palette; this file only spends it.

   ⚠ BUT IT TAKES THE RAMP LIGHT AND THE INK DARK, WHICH .btn--lounge DOES
   NOT, AND THE REASON IS THE HEIGHT OF A CARD. Every door's background is
   `#ffffff 0% -> var(--b1) 45% -> var(--b2) 100%`; on a 44px button the white
   stop is a highlight you never put text on, and on a door five times that it
   is the whole top third - which is where the <b> sits. Drawn with
   .btn--lounge's own white ink, measured off those stops, the heading came
   out white on #d3beee: about 1.7:1, unreadable, and it renders perfectly.
   So this follows .door--world's pattern instead (dark ink, white highlight,
   light ramp) with .btn--lounge's hue. Both stops are computed, not chosen:
   #2a1240 on the darkest one it ever touches (#9d63ec) is 4.3:1, against the
   gold door's own 3.35:1 (#3a2208 on #a86a06) - so the card that carries the
   most body text is also the more legible of the pair. Restyling here means
   re-running that arithmetic, not re-picking the purple. */
body[data-info-home] .door--flat {
  --b1: #d9b3ff; --b2: #9d63ec;
  color: #000; border-color: #f3e9ff;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
}
body[data-info-home] .door--flat b { color: #2a1240; }
body[data-info-home] .door--flat > span { color: #33184d; }

/* THE HUB, added 2026-08-31. It wears .door--world for the download warning -
   that class is the mark for "this costs a download", not a name - so without
   a hue of its own the front page would carry TWO IDENTICAL GOLD SLABS and the
   reader would have to read them to tell the 3D city from the room that opens
   onto it. This block only moves the colour; it sits AFTER .door--world on
   purpose, since both selectors have the same specificity and source order is
   what decides.

   THE HUE IS MEASURED, NOT PICKED, ON BOTH AXES - and the first attempt
   FAILED THE FIRST AXIS while looking fine. It took the cyan of the room's
   own `world2d` pad (#c8a800), which is honest provenance and still wrong
   here: the PLAIN .door above is a cyan-to-blue ramp (#ffe14d -> #a68a00),
   so the hub landed 11 DEGREES OF HUE from the four cards it has to be told
   apart from, and on the render it read as a fifth ice card rather than as a
   world. Gold is 37 deg, the 2D world's lavender 265, the plain ice 202; of
   the candidates tried, forest green sits 70 deg from the NEAREST of those
   three, which is the largest gap available once those are spent. Green also
   says the thing the copy says - START HERE.
   THEN THE SECOND AXIS, because the distinct hue is worthless unreadable.
   A first green (#2f7d3a) measured 2.91:1 - second worst on the page. This
   one is #08240f on the darkest stop it ever touches (#4aa85c) at 5.55:1,
   with body copy at 4.80, against the purple door's 4.31, the gold door's
   3.35 and the plain door's 2.92 - the most legible card here, not merely an
   acceptable one. Restyling means re-running BOTH numbers, not re-picking a
   green: hue distance from the other three ramps, then contrast. */
body[data-info-home] .door--hub {
  --b1: #b6efc0; --b2: #4aa85c;
  color: #08240f; border-color: #e6fbea;
  text-shadow: 0 1px 0 rgba(255, 255, 255, .45);
}
body[data-info-home] .door--hub b { color: #08240f; }
body[data-info-home] .door--hub > span { color: #0d3116; }
body[data-info-home] .door__net { color: #1a1600; }
/* the two "… or" lines: still a line and not a fourth door, per index.html */
body[data-info-home] .doors__more {
  font-family: var(--pixel); font-size: 1.15rem; color: var(--ice-light);
  text-align: center; margin: -4px 0 16px;
}
body[data-info-home] .doors__more a { color: var(--ice-bright); }

/* ---------- THE FOOTER ---------- */
body[data-info-home] footer.src {
  border-top: 0; text-align: center; color: var(--ice-light);
  font-family: var(--pixel); font-size: 1.05rem; line-height: 1.4;
}
body[data-info-home] footer.src a { color: var(--ice-bright); }

/* ---------- PHONE ----------
   Landscape on a phone is the case the repo cares about: ~740x360 (the
   stickers' 74px gutter is gone since 2026-09-15 — see THE SHELL above,
   and read the gutter arithmetic in the comments below as the history it
   is). The wordmark comes down so
   the hero, the strip and the first tap all fit above the fold. */
@media (max-width: 420px) {
  body[data-info-home] h1 { font-size: 2.3rem; }
  body[data-info-home] .door { padding: 12px 14px; }
  body[data-info-home] .door b { font-size: 1.15rem; }
}
/* LANDSCAPE PHONE, and it is the case that binds. At 740x360 the ticker,
   the masthead row and the hero alone filled the whole viewport on the
   first render - the strip and the first tap were both below the fold, on
   a page whose entire job is to be tapped. Everything vertical comes in:
   the wordmark, the two pixel lines, the nav's padding, the frame's own
   margin. Nothing is HIDDEN - a shorter page, not a poorer one. */
@media (max-height: 460px) and (orientation: landscape) {
  body[data-info-home] .fd-ticker { font-size: .95rem; }
  body[data-info-home] .fd-ticker__track { padding: 2px 0; }
  body[data-info-home] .wrap { margin: 6px 4px; padding-top: 8px; }
  body[data-info-home] .ibar { padding: 5px; margin: 0 0 8px; gap: 6px; }
  body[data-info-home] .ibar a { font-size: .8rem; padding: 3px 9px; }
  body[data-info-home] header.top { padding: 2px 0 0; }
  body[data-info-home] .fd-blink { font-size: .85rem; margin-bottom: 2px; }
  body[data-info-home] h1 { font-size: 2.1rem; }
  body[data-info-home] .fd-logo { width: min(82vw, 70vh); margin-bottom: 2px; }
  body[data-info-home] .when { font-size: .95rem; margin-top: 2px; }
  body[data-info-home] .fd-checker { margin: 8px 0 2px; height: 10px; }
  body[data-info-home] .live { padding: 8px 12px; }
  body[data-info-home] .live h2 { font-size: 1rem; }
  body[data-info-home] .door { margin: 8px 0; padding: 9px 14px; text-align: center; }
  body[data-info-home] .door b { font-size: 1.05rem; }
  body[data-info-home] .door > span { font-size: .95rem; }
}

/* the whole look is animation — the ticker, the blink. Both off when the
   visitor has asked for less motion; the page loses nothing it says. */
@media (prefers-reduced-motion: reduce) {
  body[data-info-home] .fd-ticker__track,
  body[data-info-home] .fd-blink { animation: none; }
}

/* =======================================================================
   THE LISTINGS BOARD — added 2026-09-08 on the owner's ask: "make the home
   page read better like a do512 — the first thing we should be doing is
   replacing them with our website."

   THE MEASUREMENT THAT DEMANDED IT. On a 1280px frame the front door
   rendered ONE narrow 680px column in which the listings — the thing this
   site is for — were a single sentence, followed by three full-width game
   doors each taller than the listings section entire. do512 answers "what
   is on tonight" with thirty scannable rows before you scroll.

   SO THE COLUMN WIDENS, AND ONLY HERE. css/info.css's 680px is a READING
   column and it is right for a page of prose; a board of sixty rooms is
   not prose, and a grid squeezed into 680px is a list wearing a grid's
   markup. Everything that IS prose on this page — the hero, the doors, the
   footer — keeps the reading measure through .fd-col, so widening the frame
   does not turn the three taps into billboards.
   ======================================================================= */
body[data-info-home] .wrap { max-width: 1180px; }
/* the reading measure, kept for everything that is not the board */
body[data-info-home] .fd-col { max-width: 680px; margin-left: auto; margin-right: auto; }

body[data-info-home] .fb { margin: 4px 0 6px; }
body[data-info-home] .fb__head {
  display: flex; align-items: baseline; justify-content: center;
  flex-wrap: wrap; gap: 6px 14px; margin-bottom: 4px;
}
body[data-info-home] .fb__head h2 {
  font-family: var(--display); font-size: 1.5rem; letter-spacing: 2px;
  color: var(--ice-white); margin: 0;
  text-shadow: 0 0 14px rgba(255,216,0, .6), 0 2px 0 #050505;
}
body[data-info-home] .fb__note {
  font-family: var(--pixel); font-size: 1.15rem; color: var(--ice-light);
  text-align: center; margin: 0 0 10px;
}

/* THE GRID. auto-fill, not auto-fit: with one card on the board auto-fit
   stretches it across the whole 1180px frame, which reads as a hero image
   for whichever room happens to be first. auto-fill keeps the track. */
body[data-info-home] .fb__grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
}

body[data-info-home] .fb-card {
  display: flex; flex-direction: column; overflow: hidden;
  background: linear-gradient(180deg, rgba(30,26,0, .62), rgba(10,10,10, .72));
  border: 2px groove var(--frost-4); border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 2px 8px rgba(0, 0, 0, .4);
}
/* the drawn plate. 5:3 is venue-signs.js's own design space and the box is
   held to it, so a card whose art is a nameplate is the same size as one
   whose art is the Continental's — a ragged grid reads as a broken one. */
body[data-info-home] .fb-card__art {
  display: block; width: 100%; height: auto; aspect-ratio: 5 / 3;
  border-bottom: 1px solid rgba(255,216,0, .22); background: #101010;
}
/* ⚠ min-width:0 IS LOAD-BEARING AND ITS ABSENCE OVERFLOWED EVERY PHONE CARD.
   A flex item defaults to min-width:auto, which is "never shrink below your
   own content" — so with the card laid down as a row (the phone block at the
   foot of this file) the body refused to go under its longest unbreakable
   line and pushed its text straight out through the card's right edge:
   "10:30PM - 11:30" and "THE RO" were photographed clipped at 390px. The
   card still had a border, a background and a plate, so it read as a styling
   choice rather than as a broken box. */
body[data-info-home] .fb-card__body { padding: 8px 10px 10px; display: flex;
  flex-direction: column; gap: 3px; flex: 1; min-width: 0; }

/* A COLUMN, NOT A WRAPPING ROW. As a row the badge and the time sat on one
   line for a short time string ("9:30PM 3 11:30PM") and two for a long
   one, so eight cards side by side stepped up and down against each other
   for no reason a reader could see. Stacked, every live card is the same
   height as every other live card. */
body[data-info-home] .fb-card__tag {
  display: flex; flex-direction: column; align-items: flex-start; gap: 0;
  font-family: var(--pixel); font-size: 1rem; letter-spacing: .5px;
}
/* THE TIME MAY NOT BREAK AND MAY NOT ESCAPE. nowrap alone did the first and
   not the second: held on one line in a column narrower than the string, it
   simply drew through the card's right border. Photographed at 390px as
   "10:30PM 3 11:30" with the PM sheared off, which is a listings site
   printing the wrong time rather than an ugly one.
   ⚠ AND IT IS THE FALLBACK FONT THAT BINDS, NOT VT323. This machine's
   headless chrome cannot reach fonts.googleapis.com (the trap
   draw-from-photo/LESSONS.md records), so every frame here is Courier New
   standing in — WIDER than the pixel face that ships. Sizing to what the
   screenshot shows is therefore sizing to the worst case, which is the
   right way round, and the ellipsis below is the guarantee for the case
   neither font survives. */
body[data-info-home] .fb-time {
  color: #ffe9a8; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis;
}
body[data-info-home] .fb-card__tag { min-width: 0; }
body[data-info-home] .fb-time--none { color: var(--frost-3); font-size: .85rem; }
body[data-info-home] .fb-live { color: #ff5f6d; font-family: var(--display);
  letter-spacing: 1px; font-size: .95rem; }

body[data-info-home] .fb-card__act {
  font-family: var(--display); font-size: 1.12rem; line-height: 1.15;
  letter-spacing: .5px; color: var(--ice-white); margin: 1px 0 0;
  text-transform: uppercase; overflow-wrap: anywhere;
}
/* a friend's name is a link to the band's own page (data/acts.json page);
   it keeps the heading's ink so the card reads the same as a stranger's,
   and shows it is a link on hover the way the room does */
body[data-info-home] .fb-card__act-link { color: inherit; text-decoration: none; border-bottom: 0; }
body[data-info-home] .fb-card__act-link:hover { color: #fff; text-decoration: underline; }
body[data-info-home] .fb-card__room {
  font-family: var(--pixel); font-size: 1.15rem; color: var(--ice-bright);
  text-decoration: none; border-bottom: 0; overflow-wrap: anywhere;
}
body[data-info-home] .fb-card__room:hover { color: #fff; text-decoration: underline; }
body[data-info-home] .fb-card__where,
body[data-info-home] .fb-card__when {
  font-family: var(--pixel); font-size: .95rem; color: var(--frost-3);
}

/* the two errands off a card, and DIRECTIONS is the one the owner asked
   for: a bill you cannot get to is a bill you did not really read. */
body[data-info-home] .fb-card__go {
  margin-top: auto; padding-top: 7px; display: flex; gap: 6px; flex-wrap: wrap;
}
body[data-info-home] .fb-go {
  font-family: var(--display); font-size: .82rem; letter-spacing: 1px;
  padding: 4px 9px; border-radius: 999px; text-decoration: none;
  border: 1px solid rgba(255,216,0, .45); color: var(--ice-light);
  background: rgba(255,216,0, .09);
}
body[data-info-home] .fb-go:hover { background: rgba(255,216,0, .22); color: #fff; }
body[data-info-home] .fb-go--room { border-color: rgba(214,176,0, .3);
  background: transparent; color: var(--frost-3); }

/* ON NOW. The one card state that is a fact rather than a decoration, so it
   is the only one given a colour that is not the page's ice. */
body[data-info-home] .fb-card--live { border-color: #a8324a;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .12), 0 0 14px rgba(255, 95, 109, .28); }

body[data-info-home] .fb__more { text-align: center; margin: 12px 0 2px; }

/* ---------- FROST & FRIENDS ----------
   The owner's own circle, above the town's board. The same section, the
   same cards, ONE difference and it is the frame: gold, the site's colour
   for a thing that is the house's (the stamp row, the tip line), against
   the ice everything read off a board is drawn in. The cards inside keep
   the board's own rules - ON NOW is still red and still a set. The day
   badge (.fb-date) is the one field the board's cards never carry, because
   their headline says TONIGHT; here a card may be Thursday's. */
body[data-info-home] .fb--friends {
  border-color: #b8923a;
  background: linear-gradient(180deg, rgba(58, 44, 10, .5), rgba(30, 22, 5, .6));
  box-shadow: 0 0 18px rgba(255, 214, 102, .14);
  margin-bottom: 14px;
}
body[data-info-home] .fb--friends .fb__head h2 {
  color: #ffe9a8;
  text-shadow: 0 0 14px rgba(255, 214, 102, .55), 0 2px 0 #1a1204;
}
body[data-info-home] .fb--friends .fb__note { color: #e8d39a; }
body[data-info-home] .fb--friends .fb-card { border-color: #8a6b26; }
body[data-info-home] .fb--friends .fb-card--live { border-color: #a8324a; }
body[data-info-home] .fb-date {
  color: #ffe9a8; font-family: var(--display); letter-spacing: 1px; font-size: .95rem;
}

/* ---------- PHONE: THE CARD LIES DOWN ----------
   ⚠ MEASURED AT 390px BEFORE THIS BLOCK EXISTED, AND IT WAS A WRECK. The
   first cut kept two tile columns on a phone. It does not fit and the
   arithmetic says why: info.css holds .wrap's left padding at 74px under
   760px, because the paper and the map are position:fixed in that gutter on
   every page in town — so a 390px screen has ~300px of column, and two
   tracks with a gap is ~145px a card. Every field wrapped to two and three
   lines, one card ran 600px tall, and the whole board was ONE AND A HALF
   cards per screen. A listings page you have to scroll for two minutes to
   read eight rooms is not a listings page.

   So under 560px a card is a ROW, which is the shape every listings site
   converges on for a phone and the shape this one should have started at:
   the drawn plate at 96px on the left, the words beside it, the two errands
   under the words. Eight rooms a screen instead of one and a half. Nothing
   is HIDDEN — the same fields, laid down. */
@media (max-width: 560px) {
  body[data-info-home] .fb__grid { grid-template-columns: 1fr; gap: 8px; }
  body[data-info-home] .fb-card { flex-direction: row; align-items: stretch; }
  /* STRETCH + contain, not a fixed 5:3 box pinned to the top. Held to its
     aspect the plate was 58px tall against a 240px card and left a dead
     column down the left of every row. A canvas is a replaced element, so
     object-fit works on it: the plate now fills the row's full height and
     `contain` scales the drawing inside it whole — a sign cropped to fill
     would be this file editing somebody's storefront. */
  /* 76, not 96. The arithmetic at 390px: 74px of that screen is the fixed
     sticker gutter info.css reserves, and after the frame's padding and two
     borders the card is ~270px. A 96px plate left 156px of text column, and
     Courier New at .92rem needs ~150px for "10:30PM 3 11:30PM" alone.
     (2026-09-15: the gutter is gone and the card is ~350px at 390, so the
     text column is ~260px now; 76 stays because eight rooms a screen was
     the point and a wider plate buys nothing the text needs.) */
  body[data-info-home] .fb-card__art {
    flex: 0 0 76px; width: 76px; height: auto; align-self: stretch;
    aspect-ratio: auto; object-fit: contain;
    border-bottom: 0; border-right: 1px solid rgba(255,216,0, .22);
    /* the letterbox is DELIBERATE and needs to look it. `contain` centres a
       5:3 drawing in a 76x164 column, so 59px above and below it are bare;
       against the card's own gradient that read as a hole where an image
       had failed. Sunk a shade darker, the column reads as the thumbnail
       frame it is. `cover` was the other way to fill it and it is not
       available here: it would crop the name off a nameplate. */
    background: rgba(4,4,4, .55);
  }
  body[data-info-home] .fb-card__body { padding: 6px 9px 7px; gap: 1px; }
  /* the badge and the time go back to being a ROW here: a 96px plate is
     three text lines tall and the column shape wasted the third of them */
  body[data-info-home] .fb-card__tag {
    flex-direction: row; align-items: baseline; gap: 7px; flex-wrap: wrap;
    font-size: .82rem;
  }
  /* the time is ONE token and must never break inside itself:
     "10:30PM 3 11:30PM" split across two lines read as two times */
  body[data-info-home] .fb-time { white-space: nowrap; }
  body[data-info-home] .fb-card__act { font-size: .98rem; letter-spacing: .3px; }
  body[data-info-home] .fb-card__room { font-size: 1rem; }
  body[data-info-home] .fb-card__where { font-size: .85rem; }
  /* the two errands sit side by side or they cost a line each */
  body[data-info-home] .fb-card__go { padding-top: 5px; gap: 5px; }
  body[data-info-home] .fb-go { font-size: .72rem; padding: 3px 7px; white-space: nowrap; }
  body[data-info-home] .fb__head h2 { font-size: 1.25rem; }
  body[data-info-home] .fb__note { font-size: 1rem; margin-bottom: 8px; }

  /* ONE ERRAND ON A PHONE, AND IT IS THE ONE THAT WAS ASKED FOR. Measured
     at 375px: the body column is 159px and the two pills are 89 + 74 + 5 =
     168, so they wrapped and the go row cost 59px on EVERY card. THE ROOM
     is the pill that goes, because it is the only thing on the card that
     was already reachable another way - .fb-card__room, the venue's name
     right above it, is the same link to the same page. DIRECTIONS is not
     duplicated anywhere and is the half the owner asked for. (2026-09-15:
     the gutter's removal would let both pills fit again; the room pill
     stays hidden on the duplication argument alone.) */
  body[data-info-home] .fb-go--room { display: none; }
}

/* ---------- PHONE: THE FOLD ----------
   Measured at 375x812 before this block: the first listing began at y=620,
   so a phone showed ONE card, half of it below the fold, after scrolling
   past a nav, a blink, a wordmark and a tagline that between them ate 356
   vertical pixels. That is the same defect this whole change is about -
   the listings below the branding - reappearing on the screen most people
   will actually read it on.

   NOTHING IS HIDDEN, including the blink: it is aria-hidden decoration and
   would have been the easy cut, but it is the 1999 ice the owner asked for
   by name. Everything just comes in, the way the landscape block already
   does it. */
@media (max-width: 560px) {
  body[data-info-home] .ibar { padding: 8px 6px; gap: 5px; margin-bottom: 6px; }
  body[data-info-home] .ibar a { font-size: .82rem; padding: 3px 8px; }
  body[data-info-home] .fd-blink { font-size: .82rem; margin-bottom: 0; }
  body[data-info-home] h1 { font-size: 2.05rem; }
  body[data-info-home] .when { font-size: 1rem; line-height: 1.25; margin-top: 2px; }
  body[data-info-home] .fd-checker { margin: 8px 0 4px; }
  body[data-info-home] header.top { padding: 4px 0 0; }
}

/* ---------- LANDSCAPE PHONE ----------
   THE CASE THAT BINDS, and the first cut of this block missed the whole
   point of it. It set two tracks and a narrower plate but left the card in
   its TALL TILE shape — art on top, words under — because the row layout
   above is keyed on `max-width: 560px` and a landscape phone is 740 wide.
   Measured at 740x360: the first card began at y=280 and stood 268px tall,
   so the entire listing visible on a landscape phone was the top 80px of
   ONE card. Height is the scarce axis here, not width, so the card lies
   down the same way it does in portrait — and it keeps two tracks, because
   the width IS there and the board is the one thing on this page that
   gains from it. */
@media (max-height: 460px) and (orientation: landscape) {
  body[data-info-home] .fb__grid { grid-template-columns: 1fr 1fr; gap: 7px; }
  body[data-info-home] .fb-card { flex-direction: row; align-items: stretch; }
  body[data-info-home] .fb-card__art {
    flex: 0 0 74px; width: 74px; height: auto; align-self: stretch;
    aspect-ratio: auto; object-fit: contain; background: rgba(4,4,4, .55);
    border-bottom: 0; border-right: 1px solid rgba(255,216,0, .22);
  }
  body[data-info-home] .fb-card__body { padding: 5px 8px 6px; gap: 0; }
  body[data-info-home] .fb-card__tag {
    flex-direction: row; align-items: baseline; gap: 7px; flex-wrap: wrap;
    font-size: .8rem;
  }
  body[data-info-home] .fb-card__act { font-size: .95rem; }
  body[data-info-home] .fb-card__room { font-size: .98rem; }
  body[data-info-home] .fb-card__where { font-size: .82rem; }
  body[data-info-home] .fb-card__go { padding-top: 4px; }
  body[data-info-home] .fb-go { font-size: .7rem; padding: 2px 7px; }
  /* same reasoning as portrait: the venue's name above is already this link */
  body[data-info-home] .fb-go--room { display: none; }
  body[data-info-home] .fb__head h2 { font-size: 1.05rem; }
  body[data-info-home] .fb__note { font-size: .9rem; margin-bottom: 5px; }
}
