/* NoVA Food Guide. Structure and typography only; brand tokens are injected
   per region by the generator, so this file stays region neutral.

   Built to docs/DESIGN-SPEC.md, which was measured off 13 live food
   publications. The load bearing decisions:
     Display is SANS, body is SERIF. Serif display over sans body is the
     signature of the two weakest sites in the reference set.
     Display leading is below 1.0. Eater 0.95, Infatuation 0.94, Time Out 0.89.
     ONE metadata style carries every small uppercase label on the site.
     No image is ever displayed larger than its source can honestly fill.
   No em dashes, ever. */

:root {
  /* fallbacks; the per region theme block overrides these */
  --paper: #f7f6f3;
  --paper-2: #efece5;
  --band: #e7e3d9;
  --ink: #12110f;
  --ink-2: #66635c;          /* metadata, captions */
  --ink-3: #918d85;          /* furthest back */
  --accent: #8e1d13;         /* lacquer red, hairlines and live state only */
  --serif: 'Literata', Georgia, serif;
  --sans: 'Archivo', 'Helvetica Neue', Arial, sans-serif;

  --line: color-mix(in srgb, var(--ink) 13%, transparent);
  --line-mid: color-mix(in srgb, var(--ink) 24%, transparent);

  /* grid: 1280 container, 40 gutter, 1200 content */
  --maxw: 1280px;
  --gutter: 40px;
  --gap: 24px;

  /* type scale. integers only, per spec 1.2 */
  --d1: 48px; --d1-lh: 44px;
  --d2: 34px; --d2-lh: 34px;
  --d3: 24px; --d3-lh: 24px;
  --d4: 20px; --d4-lh: 22px;
  --b1: 20px; --b1-lh: 30px;
  --b2: 18px; --b2-lh: 30px;
  --b3: 15px; --b3-lh: 24px;
  --b4: 14px; --b4-lh: 22px;
}

@media (max-width: 720px) {
  :root {
    --gutter: 20px;
    --d1: 34px; --d1-lh: 32px;
    --d2: 26px; --d2-lh: 26px;
    --d3: 20px; --d3-lh: 20px;
    --d4: 18px; --d4-lh: 20px;
    --b1: 18px; --b1-lh: 28px;
    --b2: 17px; --b2-lh: 28px;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 96px; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--b2);
  line-height: var(--b2-lh);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img { max-width: 100%; display: block; }
a { color: inherit; }
::selection { background: var(--accent); color: var(--paper); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* ---------- THE metadata style. Spec 1.3, the highest leverage rule.
   Day, window, neighborhood, cuisine, credit, verified date, byline,
   breadcrumb, CTA label, filter label. All of them. Any other small
   uppercase tracked style in this file is a bug. ---------- */
.meta {
  font-family: var(--sans);
  font-size: 11px;
  line-height: 16px;
  font-weight: 600;
  font-stretch: 100%;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.meta--accent { color: var(--accent); }
.meta--invert { color: color-mix(in srgb, var(--paper) 72%, transparent); }

/* numbers that must align in a column */
.num {
  font-family: var(--sans);
  font-size: var(--b3);
  line-height: var(--b3-lh);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

/* ---------- display type: sans, sub 1.0 leading ---------- */
h1, h2, h3, h4 {
  font-family: var(--sans);
  font-weight: 700;
  margin: 0;
  text-wrap: balance;
  font-stretch: 100%;
}
h1 { font-size: var(--d1); line-height: var(--d1-lh); letter-spacing: 0.01em; }
h2 { font-size: var(--d2); line-height: var(--d2-lh); letter-spacing: 0.02em; font-stretch: 88%; }
h3 { font-size: var(--d3); line-height: var(--d3-lh); }
p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

.lede { font-size: var(--b1); line-height: var(--b1-lh); letter-spacing: -0.01em; max-width: 52ch; color: var(--ink); }
.dek  { font-size: var(--b3); line-height: var(--b3-lh); color: var(--ink-2); }

/* ---------- layout ---------- */
.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gutter); }
.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden;
      clip-path: inset(50%); white-space: nowrap; }
.skip { position: absolute; left: -9999px; background: var(--ink); color: var(--paper);
        padding: 10px 16px; z-index: 100; }
.skip:focus { left: 0; }

/* ---------- masthead ---------- */
.masthead { position: sticky; top: 0; z-index: 50; background: var(--paper);
            border-bottom: 1px solid var(--ink); }
.masthead-top { display: flex; justify-content: space-between; gap: 16px;
                padding-block: 9px; }
.masthead-main { display: flex; align-items: center; justify-content: space-between;
                 gap: 24px; padding-block: 16px; }
.logo { font-family: var(--sans); font-weight: 700; font-stretch: 88%;
        font-size: 26px; line-height: 26px; letter-spacing: 0.01em;
        text-decoration: none; white-space: nowrap; }
.logo span { color: var(--accent); }
.nav { display: flex; gap: 28px; align-items: center; }
.nav a { font-family: var(--sans); font-size: 13px; font-weight: 600; line-height: 16px;
         letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none;
         color: var(--ink-2); padding-block: 6px; position: relative; }
.nav a:hover { color: var(--ink); }
.nav a[aria-current] { color: var(--ink); }
.nav a[aria-current]::after { content: ""; position: absolute; left: 0; right: 0;
        bottom: 0; height: 2px; background: var(--accent); }
.nav-cta { border: 1px solid var(--ink); padding: 8px 14px; color: var(--ink) !important; }
.nav-cta:hover { background: var(--ink); color: var(--paper) !important; }
.nav-toggle { display: none; font-family: var(--sans); font-size: 11px; font-weight: 700;
        letter-spacing: 0.12em; text-transform: uppercase; background: none;
        border: 1px solid var(--ink); padding: 8px 12px; cursor: pointer; }

/* ---------- page opener ---------- */
/* The landing moment. A large heading with an empty half canvas beside it is a
   known failure (it reads unfinished), so the opener is centred and the live
   figures sit directly under it as the second focal point. */
/* The block sits under a sticky masthead, so a large top pad pushed the
   headline down the screen and read as a hole rather than as air. */
.opener { padding-block: clamp(34px, 4.2vw, 60px) clamp(22px, 2.6vw, 34px);
          text-align: center; }
/* 48px into a 571px cap forced a three line widening rag. Bigger type and a
   wider measure so the break lands where it was written. */
.opener h1 { max-width: 1040px; margin-inline: auto;
             font-size: clamp(38px, 4.7vw, 66px); line-height: 0.94;
             letter-spacing: -0.015em; }
.opener .lede { margin: 20px auto 0; text-align: center; }
.opener--left { text-align: left; }
.opener--left h1, .opener--left .lede { margin-inline: 0; text-align: left; }

.statline { display: flex; flex-wrap: wrap; justify-content: center;
            gap: 10px 40px; align-items: baseline; margin-top: 36px;
            padding-top: 22px; border-top: 1px solid var(--ink); }
.opener--left .statline { justify-content: flex-start; }
.statline > span { display: inline-flex; align-items: baseline; gap: 8px; }
.statline b { font-family: var(--sans); font-weight: 700; font-size: 30px;
              line-height: 30px; font-variant-numeric: tabular-nums;
              font-feature-settings: "tnum" 1; }
.statline .live b { color: var(--accent); }

/* ---------- earned motion ----------
   The headline sets itself line by line, and the live count counts up. The
   count is the one number on the page that changes with the clock, so the
   motion carries information rather than decorating. Nothing else moves. */
/* The mask clips to the line box, and at 0.94 leading that box is shorter than
   the glyphs, so descenders (the g in Virginia, the g in right) lost their
   tails. Pad the clip box and pull the same amount back off the layout. */
.line { display: block; overflow: hidden;
        padding-bottom: 0.16em; margin-bottom: -0.16em; }
.line > span { display: block; animation: lineup 0.62s cubic-bezier(0.16, 0.9, 0.24, 1) both; }
.line:nth-child(2) > span { animation-delay: 0.08s; }
@keyframes lineup { from { transform: translateY(105%); } to { transform: none; } }

/* ---------- the ledger: a typeset listing, tile at a fixed left edge ---------- */
.filters { display: flex; flex-wrap: wrap; gap: 10px 20px; align-items: center;
           padding-block: 18px 14px; position: sticky;
           top: var(--masthead-h, 92px); background: var(--paper); z-index: 20; }
.fgroup { display: inline-flex; align-items: center; gap: 10px; }
.chip { font-family: var(--sans); font-size: 13px; font-weight: 600; line-height: 18px;
        background: none; border: 0; padding: 2px 0; cursor: pointer; color: var(--ink-2);
        border-bottom: 2px solid transparent; }
.chip:hover { color: var(--ink); }
.chip[aria-pressed="true"] { color: var(--ink); border-bottom-color: var(--accent); }
.fsel { display: inline-flex; align-items: center; gap: 8px; }
.fsel select { font-family: var(--sans); font-size: 13px; font-weight: 600; color: var(--ink);
        background: none; border: 0; border-bottom: 1px solid var(--line-mid);
        padding: 2px 18px 2px 2px; cursor: pointer; appearance: none;
        background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='6'%3E%3Cpath d='M1 1l3.5 3.5L8 1' stroke='%2366635c' stroke-width='1.4' fill='none'/%3E%3C/svg%3E");
        background-repeat: no-repeat; background-position: right 2px center; }
.search input { font-family: var(--sans); font-size: 13px; color: var(--ink);
        background: none; border: 0; border-bottom: 1px solid var(--line-mid);
        padding: 3px 2px; min-width: 200px; }
.search input::placeholder { color: var(--ink-3); }

.ledger { width: 100%; border-collapse: collapse; }
.ledger thead th { box-shadow: 0 1px 0 var(--ink); position: sticky;
        top: calc(var(--masthead-h, 92px) + var(--filters-h, 52px));
        background: var(--paper); z-index: 10; text-align: left;
        font-family: var(--sans); font-size: 11px; line-height: 16px; font-weight: 600;
        letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-2);
        padding: 12px 16px 10px 0; border-bottom: 1px solid var(--ink); }
.ledger td { padding: 16px 16px 16px 0; border-bottom: 1px solid var(--line);
             vertical-align: top; }
.ledger tbody tr:hover { background: color-mix(in srgb, var(--band) 45%, transparent); }
.ledger .c-tile { width: 56px; padding-right: 16px; }
.ledger .c-venue { width: 27%; }
.ledger .c-when { width: 16%; }
.ledger .c-deal { font-size: var(--b3); line-height: var(--b3-lh); }
.v-name { font-family: var(--sans); font-size: var(--d4); line-height: var(--d4-lh);
          font-weight: 700; font-stretch: 88%; letter-spacing: 0; display: block; }
.v-name a { text-decoration: none; }
.v-name a:hover { color: var(--accent); }

/* the tile: one shape, one size, down all 507 rows. A straight left edge is
   worth more than 507 mediocre photographs. */
/* One shape at one size down all 507 rows. A photograph fills it; a venue
   without one gets quiet initials on paper, so the pictures are the only thing
   carrying colour and the column still reads as a straight edge. Loud coloured
   initial blocks were tried at 120px and read as a placeholder wall. */
.tile { width: 56px; height: 56px; border-radius: 2px; overflow: hidden;
        display: grid; place-items: center; }
.tile img { width: 100%; height: 100%; object-fit: cover; }
.tile-type { font-family: var(--sans); font-weight: 700; font-stretch: 75%;
             font-size: 15px; line-height: 1; letter-spacing: 0.06em;
             color: var(--ink-3); }
.tile-a, .tile-b, .tile-c { background: none; border: 1px solid var(--line); }

.daystrip { font-family: var(--sans); font-size: 12px; font-weight: 700;
            letter-spacing: 0.16em; color: var(--ink-3); white-space: nowrap; }
.daystrip .on { color: var(--ink); }
.count { margin-top: 16px; }
.ledger-empty { padding: 48px 0; text-align: center; color: var(--ink-2); }

/* ---------- the lead: three rooms, not one floating plate ----------
   A single feature under a centred headline left a hole between them and said
   nothing about the size of the guide. Three cards fill the fold, prove the
   breadth, and each is 384 CSS px so a 2400px source is retina sharp twice
   over. Card anatomy follows the reference set: picture, place, name, the deal,
   the window. */
.lead-grid { display: grid; grid-template-columns: repeat(3, 1fr);
             gap: 28px; padding-block: 8px 8px; }
.lead-card { display: flex; flex-direction: column; }
.lead-card a.pic { display: block; overflow: hidden; background: var(--band); }
.lead-card img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
                 transition: transform 0.6s cubic-bezier(0.2, 0.8, 0.3, 1); }
.lead-card a.pic:hover img { transform: scale(1.035); }
.lead-card .place { margin-top: 14px; }
.lead-card h3 { margin-top: 4px; font-size: var(--d3); line-height: var(--d3-lh); }
.lead-card h3 a { text-decoration: none; }
.lead-card h3 a:hover { color: var(--accent); }
.lead-card .deal { margin-top: 8px; font-size: var(--b3); line-height: var(--b3-lh); }
.lead-card .when { margin-top: 10px; }
@media (max-width: 900px) { .lead-grid { grid-template-columns: 1fr 1fr; gap: 24px; } }
@media (max-width: 620px) { .lead-grid { grid-template-columns: 1fr; gap: 32px; } }

/* ---------- feature: image never wider than 690, per the honest crop math --- */
.feature { display: grid; grid-template-columns: 690px 1fr; gap: 40px;
           align-items: start; padding-block: 56px; }

.feature figure { margin: 0; }
.feature img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--band); }
.feature cite { display: block; margin-top: 8px; font-style: normal; }
.feature h2 { margin-bottom: 10px; }
.feature .deal { font-size: var(--b2); line-height: var(--b2-lh); margin-top: 12px; }

/* ---------- dispatch list (openings) ---------- */
.dispatch { list-style: none; margin: 0; padding: 0; }
.dispatch li { border-bottom: 1px solid var(--line); }
.dispatch a { display: grid; grid-template-columns: 130px 1fr 90px; gap: 20px;
              align-items: baseline; padding: 16px 0; text-decoration: none; }
.dispatch a:hover h3 { color: var(--accent); }
.dispatch h3 { font-size: var(--d4); line-height: var(--d4-lh); font-stretch: 88%; }
.dispatch .d-detail { font-size: var(--b3); line-height: var(--b3-lh); color: var(--ink-2);
                      margin: 4px 0 0; }

/* ---------- section head ---------- */
.shead { display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
         padding-bottom: 12px; margin-bottom: 4px;
         border-bottom: 1px solid var(--line-mid); }
.section { padding-block: 48px; }

/* ---------- held tier + faq ---------- */
.held-tier, .faq { padding-top: 44px; margin-top: 56px;
                   border-top: 1px solid var(--line-mid); }
.held-grid { list-style: none; margin: 0; padding: 0; columns: 3; column-gap: 40px; }
.held-grid li { break-inside: avoid; padding: 7px 0; border-bottom: 1px solid var(--line);
                font-size: var(--b3); line-height: var(--b3-lh); }
/* Equal panels on a fixed grid. Auto-fit columns with content-sized rows left
   every answer starting at a different height, so nothing lined up down the
   page. Squared panels on a tinted ground, stretched to the tallest item in
   each row, read as a reference table rather than a card template. */
.faq dl { display: grid; grid-template-columns: repeat(3, 1fr);
          gap: 20px; margin: 24px 0 0; align-items: stretch; }
.faq dl > div { background: var(--paper-2); padding: 22px 24px;
                display: flex; flex-direction: column; }
.faq dt { font-family: var(--sans); font-weight: 700; font-size: var(--b3);
          line-height: var(--b3-lh); margin-bottom: 8px; }
.faq dd { margin: 0; font-size: var(--b3); line-height: var(--b3-lh);
          color: var(--ink-2); }
@media (max-width: 980px) { .faq dl { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .faq dl { grid-template-columns: 1fr; } }

/* ---------- footer ---------- */
.footer { margin-top: 72px; background: var(--ink); color: var(--paper); padding-block: 48px 32px; }
.footer a { text-decoration: none; }
.footer a:hover { color: color-mix(in srgb, var(--paper) 70%, var(--accent)); }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 40px; }
.footer h4 { font-family: var(--sans); font-size: 11px; line-height: 16px; font-weight: 600;
             letter-spacing: 0.12em; text-transform: uppercase;
             color: color-mix(in srgb, var(--paper) 60%, transparent); margin-bottom: 12px; }
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { padding: 5px 0; font-size: var(--b3); line-height: var(--b3-lh); }
.footer .logo span { color: color-mix(in srgb, var(--paper) 75%, var(--accent)); }
.colophon { grid-column: 1 / -1; display: flex; justify-content: space-between; gap: 20px;
            padding-top: 24px; margin-top: 16px;
            border-top: 1px solid color-mix(in srgb, var(--paper) 18%, transparent); }

/* ---------- one earned moment: the opener sets itself on load ---------- */
@keyframes rise { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.enter-1, .enter-2, .enter-3 { animation: rise 0.5s cubic-bezier(0.2, 0.8, 0.3, 1) both; }
.enter-2 { animation-delay: 0.07s; }
.enter-3 { animation-delay: 0.13s; }

/* ---------- mobile: a stacked record, not a squeezed table ---------- */
@media (max-width: 900px) {
  .feature { grid-template-columns: 1fr; gap: 20px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .held-grid { columns: 2; }
}
@media (max-width: 720px) {
  .nav-toggle { display: block; }
  .nav { display: none; position: absolute; left: 0; right: 0; top: 100%;
         flex-direction: column; align-items: flex-start; gap: 0; background: var(--paper);
         border-bottom: 1px solid var(--ink); padding: 8px var(--gutter) 16px; }
  .nav.open { display: flex; }
  .nav a { padding-block: 10px; font-size: 15px; }
  .masthead-main { position: relative; }
  .masthead-top span:nth-child(2) { display: none; }
  .ledger, .ledger tbody, .ledger tr, .ledger td { display: block; width: auto; }
  .ledger thead { display: none; }
  .ledger tbody tr { display: grid; grid-template-columns: 56px 1fr; gap: 4px 14px;
                     padding: 16px 0; border-bottom: 1px solid var(--line); }
  .ledger td { border: 0; padding: 0; }
  .ledger .c-tile { grid-row: 1 / 5; width: 56px; }
  /* The desktop column percentages outrank `.ledger td { width: auto }` on
     specificity, so they survived the stack and squeezed every venue name into
     27% of a 390px screen and every window into 16%. In a stacked record the
     cell owns the row. */
  .ledger .c-venue, .ledger .c-when, .ledger .c-deal { width: auto; }
  .ledger .c-when { font-variant-numeric: tabular-nums; }
  .held-grid { columns: 1; }
  .footer-grid { grid-template-columns: 1fr; }
  .dispatch a { grid-template-columns: 1fr; gap: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .enter-1, .enter-2, .enter-3, .line > span {
    animation: none !important; opacity: 1; transform: none; }
  * { transition: none !important; scroll-behavior: auto !important; }
}


/* ---------- interactive states. Every hover, focus and active state moves.
   The site previously had zero CSS transitions on any page, which is why it
   felt inert to the touch. ---------- */
a, .chip, .nav a, .fsel select, .search input, .ledger tbody tr, .tile,
.dispatch a, .nav-cta, .v-name a {
  transition: color 0.18s ease, background-color 0.18s ease,
              border-color 0.18s ease, opacity 0.18s ease, transform 0.18s ease;
}
.dispatch a:hover { background: color-mix(in srgb, var(--band) 40%, transparent); }
.dispatch a { padding-inline: 8px; margin-inline: -8px; }
.tile { transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.3, 1); }
.ledger tbody tr:hover .tile { transform: scale(1.06); }
.v-name a { text-decoration: underline; text-decoration-color: transparent;
            text-underline-offset: 3px; }
.ledger tbody tr:hover .v-name a { text-decoration-color: var(--accent); }
.meta a { border-bottom: 1px solid var(--line-mid); }
.meta a:hover { border-bottom-color: var(--accent); color: var(--accent); }

/* the openings table: a name is not an address */
.venue .cuisine, .v-name + .meta { display: block; }
#radar td.venue .cuisine { display: block; margin-top: 3px; }

@media (max-width: 720px) {
  /* the radar table gets the same stacked-record treatment as the ledger,
     instead of crushing five columns into 390px and printing one word a line */
  #radar, #radar tbody, #radar tr, #radar td { display: block; width: auto; }
  #radar thead { display: none; }
  #radar tbody tr { padding: 14px 0; border-bottom: 1px solid var(--line); }
  #radar td { border: 0; padding: 2px 0; }
  #radar td.venue { font-size: var(--d4); line-height: var(--d4-lh);
                    font-family: var(--sans); font-weight: 700; }
  /* centred on phones as well, matching desktop. The numbers stack as centred
     rows rather than a ragged staircase. */
  .statline { justify-content: center; gap: 10px 22px; }
  .statline > span { justify-content: center; }
  .opener { text-align: center; }
  .opener h1, .opener .lede { margin-inline: auto; text-align: center; }
  .opener .lede { max-width: 34ch; }
  /* the explicit line breaks are set for a wide measure; on a phone let the
     headline find its own break so it does not read as four ragged lines */
  .opener h1 .line { display: inline; overflow: visible;
                     padding-bottom: 0; margin-bottom: 0; }
  .opener h1 .line > span { display: inline; animation: none; }
  .opener h1 .line + .line::before { content: " "; }
  /* the nav panel needs a ground of its own */
  .nav.open { box-shadow: 0 18px 40px -12px rgba(0,0,0,0.28); }
}

/* the methodology thesis: one statement, set across the measure so it does not
   leave half the page empty beside it */
.rule-statement { margin: 26px 0 0; max-width: 34ch; font-family: var(--sans);
                  font-weight: 700; font-size: var(--d3); line-height: 1.22;
                  letter-spacing: -0.005em; }
@media (min-width: 900px) { .rule-statement { max-width: 62ch; font-size: var(--d2);
                  line-height: 1.16; font-stretch: 88%; } }

/* ---------- browse index: every collection reachable from the ledger ----------
   Collection pages that nothing links to are orphans, so the index is both the
   reader's way in and the crawl path. */
.browse { padding-top: 44px; margin-top: 56px; border-top: 1px solid var(--line-mid); }
.browse-grid { display: grid; grid-template-columns: repeat(4, 1fr);
               gap: 28px; margin-top: 24px; }
.browse-grid ul { list-style: none; margin: 10px 0 0; padding: 0; }
.browse-grid li { padding: 5px 0; border-bottom: 1px solid var(--line);
                  font-size: var(--b3); line-height: var(--b3-lh); }
.browse-grid a { display: flex; justify-content: space-between; gap: 12px;
                 text-decoration: none; }
.browse-grid a:hover { color: var(--accent); }
@media (max-width: 900px) { .browse-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .browse-grid { grid-template-columns: 1fr; } }

/* --- the changelog ---------------------------------------------------
   Only renders when a sweep actually moved rows, so an empty week prints
   nothing rather than an empty promise. */
.changelog { border-top: 1px solid var(--rule); padding-top: 34px; margin-top: 46px; }
.changelog .dek { max-width: 56ch; margin: 10px 0 26px; color: var(--ink-3); }
.changelog-grid { display: grid; gap: 26px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.changelog-grid > div { background: var(--paper-2); padding: 20px 22px; }
.changelog-grid ul { list-style: none; margin: 12px 0 0; padding: 0; }
.changelog-grid li { padding: 7px 0; border-bottom: 1px solid var(--rule); font-size: 15px; }
.changelog-grid li:last-child { border-bottom: 0; }
.changelog-grid li b { font-weight: 500; }

/* Prose computed from the rows on the page. Sits between the headline and the
   table, so a short list page still says something before the data starts. */
.pattern {
  max-width: 62ch; margin: 0 0 30px; font-size: 17.5px; line-height: 1.6;
  color: var(--ink-2); border-left: 2px solid var(--rule); padding-left: 18px;
}

@media (max-width: 640px) {
  /* The stat line wrapped into ragged pairs, so four facts landed on four
     different left edges. One grid, numbers on one axis, labels on another. */
  .statline {
    display: grid; grid-template-columns: max-content 1fr;
    gap: 6px 12px; justify-content: start; text-align: left;
  }
  .statline > span {
    display: contents;
  }
  .statline > span > b { text-align: right; }
  .statline > span.meta {
    display: block; grid-column: 1 / -1; padding-top: 4px;
  }
}

/* Area and collection pages carry one photograph, large, above the pattern
   paragraph. The picture was already being chosen for og:image and then thrown
   away, so these pages published nothing but type. */
.area-hero { margin: 0 0 34px; }
.area-hero img {
  width: 100%; aspect-ratio: 1180 / 620; object-fit: cover;
  background: var(--band); display: block;
}
.area-hero figcaption { margin-top: 8px; }
@media (max-width: 720px) { .area-hero { margin-bottom: 24px; } }
