/* The Slate — front end styles (design spec 05, §4–§11).
 *
 * Mobile first; ONE breakpoint at 768px. Archivo is self-hosted (no Google Fonts
 * request). Colour tokens are §11's, defined for light on :root and redefined for
 * dark in two places that must stay identical:
 *   - @media (prefers-color-scheme: dark)  — what visitors get
 *   - :root[data-theme="dark"]             — a TEST HOOK only (owner-approved). It
 *     lets screenshots and the verifier force dark without an OS setting. There is
 *     deliberately no visible theme toggle anywhere (spec §2).
 */

/* ------------------------------------------------------------------ fonts */
/* Archivo variable (wdth 62–125, wght 100–900 in the file; 400–800 is what the
   design uses). Two subsets, each fetched only if the page contains a glyph in its
   unicode-range. These are Google Fonts' latin-ext and latin subset ranges; they
   were cross-checked against the cmap of the two woff2 files in assets/fonts/. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('../fonts/archivo-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 62% 125%;
  font-display: swap;
  src: url('../fonts/archivo-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ------------------------------------------------------------------ tokens */
:root {
  color-scheme: light;
  --bg: #FFFFFF;
  --ink: #0B0B0C;
  --muted: #5C5C63;
  --accent: #B45309;
  --on-accent: #FFFFFF;
  --rule: #ECECEF;
  --rule-strong: #0B0B0C;
  --rule-strong-w: 2px;
  --pill-border: #D9D9DE;
  --placeholder: #F1F1F3;
}
@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;
    --bg: #0F0F0F;
    --ink: #F2F0EB;
    --muted: #A3A09A;
    --accent: #E8B04A;
    --on-accent: #0F0F0F;
    --rule: #222222;
    --rule-strong: #3A3A3A;
    --rule-strong-w: 1px;
    --pill-border: #333333;
    --placeholder: #1B1B1B;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #0F0F0F;
  --ink: #F2F0EB;
  --muted: #A3A09A;
  --accent: #E8B04A;
  --on-accent: #0F0F0F;
  --rule: #222222;
  --rule-strong: #3A3A3A;
  --rule-strong-w: 1px;
  --pill-border: #333333;
  --placeholder: #1B1B1B;
}

/* ------------------------------------------------------------------ base */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* The phone day band is sticky; keep keyboard focus from landing underneath it. */
  scroll-padding-top: 76px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Archivo', system-ui, sans-serif;
  font-size: 14px;
  line-height: 1.4;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
button, input, select { font: inherit; color: inherit; }
button { cursor: pointer; }
[hidden] { display: none !important; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* AC 14: every interactive element shows a 2px accent outline on :focus-visible. */
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* How far that ring reaches beyond the element: 2px outline + 3px offset. Anything that
   clips overflow around focusable children (the phone's sideways scrollers) must leave
   this much room on each side or the ring is cut off. Keep it equal to the two numbers
   above (the layout check in test/site/checks-client.js reads the rule and verifies). */
:root { --ring-reach: 5px; }

.page {
  --pad: 20px;
  max-width: 1160px;
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* ------------------------------------------------------------------ header */
.site-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 12px;
}
.wordmark {
  font-size: 19px;
  font-weight: 800;
  font-stretch: 75%;
  letter-spacing: 0.06em;
}
.tagline { display: none; margin: 0; font-size: 15px; color: var(--muted); }
.icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  border: 0;
  background: transparent;
}

/* ------------------------------------------------------------------ search field */
.field {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 16px;
  border: 1px solid var(--pill-border);
  border-radius: 999px;
  color: var(--muted);
}
.field input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 15px;
}
.field input::placeholder { color: var(--muted); opacity: 1; }
.field input:focus-visible { outline: none; }
.field:focus-within { outline: 2px solid var(--accent); outline-offset: 3px; }

.search-bar { padding-top: 8px; }
.field-desktop { display: none; }

/* ------------------------------------------------------------------ hero */
.hero { margin-top: 20px; }
.hero-title {
  margin: 0;
  font-size: 52px;
  line-height: 0.88;
  font-weight: 800;
  font-stretch: 62%;
  text-transform: uppercase;
}
.hero-line { display: block; }
.hero-range { margin: 12px 0 0; font-size: 14px; color: var(--muted); }
.hero-count { color: var(--accent); font-weight: 600; }

/* ------------------------------------------------------------------ filter bar */
/* Phone: one row that scrolls sideways, scrollbar hidden. The row bleeds to the
   screen edges so pills slide under the page padding instead of being clipped by it. */
/* overflow-x: auto makes overflow-y clip too, so the row pads by the focus ring's full
   reach (was 4px: 1px short, and the pills' rings lost their top and bottom edge). The
   margins give back what the padding adds, so the layout does not move. */
.filters { margin: calc(18px - (var(--ring-reach) - 4px)) calc(var(--pad) * -1) calc(4px - var(--ring-reach)); }
.filters-row {
  display: flex;
  gap: 8px;
  padding: var(--ring-reach) var(--pad);
  overflow-x: auto;
  scrollbar-width: none;
}
.filters-row::-webkit-scrollbar { display: none; }
.filters-divider { display: none; }
.filters-end { display: contents; }

.pill {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  padding: 0 16px;
  border: 1px solid var(--pill-border);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink);
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
}
@media (hover: hover) {
  .pill:hover { border-color: var(--ink); }
}
.pill[aria-pressed="true"],
.pill.is-selected {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
  font-weight: 600;
}

/* "Pick a date": a pill wrapping a native date input, stretched invisibly over it so
   the whole pill is the control and the browser's own picker does the work. */
.pill-date input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

/* "Days": a native <select> restyled as a pill; the chevron is drawn in CSS so it
   follows the theme colour. */
.pill-select select {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  padding: 0;
  background: transparent;
  color: inherit;
  font-weight: inherit;
  cursor: pointer;
}
.pill-select select option { color: var(--ink); background: var(--bg); }
.pill-select::after {
  content: "";
  width: 6px;
  height: 6px;
  margin: -3px 0 0 10px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  pointer-events: none;
}
.pill-date:focus-within,
.pill-select:focus-within { outline: 2px solid var(--accent); outline-offset: 3px; }
.pill-select select:focus-visible,
.pill-date input:focus-visible { outline: none; }

/* ------------------------------------------------------------------ content area */
#content:focus { outline: none; }
.status { margin: 40px 0; color: var(--muted); }

/* Day section — phone: a sticky full-width band above the day's list. */
.day { margin-top: 36px; }
#content > .day:first-child { margin-top: 16px; }

.day-head {
  position: sticky;
  top: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "num label" "num count";
  column-gap: 12px;
  align-items: center;
  margin: 0 calc(var(--pad) * -1);
  padding: 12px var(--pad) 10px;
  background: var(--bg);
  border-bottom: var(--rule-strong-w) solid var(--rule-strong);
}
.day-num {
  grid-area: num;
  margin: 0;
  font-size: 40px;
  font-weight: 800;
  font-stretch: 62%;
  line-height: 0.9;
  text-transform: uppercase;
}
.day-label {
  grid-area: label;
  align-self: end;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--accent);
}
.day-count {
  grid-area: count;
  align-self: start;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.day--today .day-num { color: var(--accent); }
.day--today .day-count { grid-area: 1 / 2 / 3 / 3; align-self: center; }

.day-list { margin: 0; padding: 0; list-style: none; }
.day-item { border-bottom: 1px solid var(--rule); }

/* Event row — phone: time column 52px (hour over AM/PM), then title over meta. */
.ev { display: flex; gap: 14px; padding: 12px 0; }
.ev-time {
  flex: none;
  width: 52px;
  padding-top: 2px;
  display: flex;
  flex-direction: column;
  font-variant-numeric: tabular-nums;
}
.ev-hour { font-size: 16px; font-weight: 700; }
.ev-ampm { font-size: 11px; font-weight: 600; letter-spacing: 0.08em; color: var(--muted); }
.ev-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ev-title {
  font-size: 17px;
  font-weight: 600;
  font-stretch: 90%;
  line-height: 1.25;
  overflow-wrap: anywhere;
}
.ev-meta { font-size: 14px; color: var(--muted); overflow-wrap: anywhere; }
.ev-cat { display: none; }

a.ev:focus-visible .ev-title { text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
@media (hover: hover) {
  a.ev:hover .ev-title { color: var(--accent); text-decoration: underline; text-underline-offset: 5px; text-decoration-thickness: 1px; }
  a.bn-card:hover .bn-title { color: var(--accent); }
}

/* ------------------------------------------------------------------ Big Nights */
.bn { margin-top: 36px; }
.bn-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px 16px;
}
.bn-heading {
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  font-size: 30px;
  font-weight: 800;
  font-stretch: 62%;
  text-transform: uppercase;
  line-height: 1;
}
.bn-hint { flex: none; font-size: 13px; color: var(--muted); white-space: nowrap; }
.bn-count { display: none; }

/* Phone: horizontal scroll row, 290px cards, the next card peeking, snapping.
   overflow-x: auto clips overflow-y as well, so a focused card (a.bn-card) lost the top
   and bottom of its ring. The row pads by the ring's full reach top and bottom, and the
   margins give back exactly what that padding adds so the layout does not move. */
.bn-row {
  display: flex;
  gap: 12px;
  margin: calc(14px - var(--ring-reach)) calc(var(--pad) * -1) calc(0px - var(--ring-reach));
  padding: var(--ring-reach) var(--pad);
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--pad);
  scrollbar-width: none;
}
.bn-row::-webkit-scrollbar { display: none; }
.bn-item { flex: none; width: 290px; scroll-snap-align: start; }
.bn-card { display: flex; flex-direction: column; gap: 8px; }
.bn-poster {
  display: block;
  width: 100%;
  /* 4:3, not the 4:5 the spec first proposed. §8 flagged this as a risk to verify and
     said to change the ratio if the crops were bad. They were: on live posters a 4:5
     crop discards about half the width of a 3_2 source, cutting "COMPOSITIONS" to
     "MPOSITIO", its subtitle and venue mid-word, and slicing a face in half on the
     Foster The People poster. 4:3 was tested against six real posters and holds all of
     them, including the full Compositions text; 1:1 still cut that title. */
  aspect-ratio: 4 / 3;
  overflow: hidden;
  border: 1px solid var(--rule);
  border-radius: 8px;
  background: var(--placeholder);
}
.bn-img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* Image credit (spec §8): smallest type in the system, muted, never truncated. */
/* Every card reserves the same slot whether or not its image carries a credit —
   otherwise the credited card's title and venue sit lower than its neighbours' and the
   row's baselines stop aligning (spec §8). The slot is TWO lines tall (min-height:
   2 x 1.3em = 28.6px at 11px) and the text WRAPS: no overflow clip, no ellipsis, no
   nowrap, because the credit is a condition of the image's display right and must never
   be cut off. A credit that needs a third line grows the slot (spec §8: correctness of
   the credit beats alignment); overflow-wrap lets an unbroken string wrap too. */
.bn-credit {
  display: block;
  /* ONE line of the smallest type, tight. A two-line reservation left a visible blank
     band between the poster and the date line on every uncredited card — which is most
     of them (5 credits in 285 live events). The slot still WRAPS rather than clipping,
     so §8's "never truncated away" holds; a credit needing a second line grows its own
     slot and misaligns that row, which §8 explicitly permits. Live maximum is 41
     characters, which fits one line in a 290px card. */
  min-height: 1.3em;
  margin-top: 4px;
  font-size: 11px;
  line-height: 1.3;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.bn-credit--empty { visibility: hidden; }
.bn-when {
  margin-top: 4px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
}
.bn-title {
  font-size: 24px;
  font-weight: 800;
  font-stretch: 70%;
  text-transform: uppercase;
  line-height: 1;
  overflow-wrap: anywhere;
}
.bn-where { font-size: 14px; color: var(--muted); overflow-wrap: anywhere; }

/* ------------------------------------------------------------------ empty states */
.empty { margin-top: 40px; padding: 28px 0; border-top: 1px solid var(--rule); }
.empty-msg {
  margin: 0 0 16px;
  font-size: 19px;
  font-weight: 600;
  font-stretch: 90%;
  line-height: 1.25;
}
.btn {
  min-height: 44px;
  padding: 10px 20px;
  border: 1px solid var(--ink);
  border-radius: 999px;
  background: var(--bg);
  color: var(--ink);
  font-size: 15px;
  font-weight: 600;
}
@media (hover: hover) {
  .btn:hover { background: var(--ink); color: var(--bg); }
}

/* ------------------------------------------------------------------ footer */
.site-footer {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 40px;
  padding: 20px 0 40px;
  border-top: 1px solid var(--rule);
  /* Smallest type in the system, muted, never coloured or boxed (spec §10). */
  font-size: 11px;
  color: var(--muted);
}
.site-footer p { margin: 0; }
.footer-links:empty { display: none; }

/* ------------------------------------------------------------------ ≥ 768px */
@media (min-width: 768px) {
  html { scroll-padding-top: 24px; }
  .page { --pad: 32px; padding-bottom: 96px; }

  .site-header { align-items: baseline; padding-top: 36px; gap: 12px; }
  .wordmark { font-size: 22px; }
  .tagline { display: block; }
  .icon-btn { display: none; }
  .search-bar { display: none; }
  .field-desktop { display: flex; flex: 0 1 280px; min-width: 200px; }
  .field-desktop input { font-size: 15px; }

  .hero { margin-top: 72px; }
  .hero-title { font-size: 112px; }
  .hero-range { margin-top: 20px; font-size: 17px; }

  .filters { margin: 40px 0 0; }
  .filters-row { flex-wrap: wrap; align-items: center; gap: 10px; padding: 0; overflow: visible; }
  .filters-divider { display: block; flex: none; width: 1px; height: 24px; margin: 0 8px; background: var(--pill-border); }
  .filters-end {
    display: flex;
    flex: 1 1 260px;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 10px;
  }
  .pill { height: 44px; padding: 0 20px; font-size: 15px; }

  /* Day section — desktop: sticky left column beside the list.
     The column is `minmax(150px, max-content)`, not a flat 150px: 150 is the floor, and
     the column grows for content that will not fit it. Two things need that — TONIGHT
     set at 72px, and the label "TOMORROW · TUE", which wraps to two lines at 150px with
     the 0.16em tracking these labels carry. Spec §5 records the width and the reason. */
  .day {
    display: grid;
    grid-template-columns: minmax(150px, max-content) minmax(0, 1fr);
    column-gap: 48px;
    margin-top: 64px;
    padding-top: 32px;
    border-top: var(--rule-strong-w) solid var(--rule-strong);
  }
  #content > .day:first-child { margin-top: 56px; }
  .day--today { grid-template-columns: minmax(150px, max-content) minmax(0, 1fr); }
  .day-head {
    position: sticky;
    top: 24px;
    z-index: auto;
    display: block;
    align-self: start;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
  }
  /* One line. "TOMORROW · TUE" is the longest label and wraps at a flat 150px; the
     column above grows to fit it instead of letting it break mid-label. */
  .day-label { font-size: 14px; white-space: nowrap; }
  .day-num { margin-top: 6px; font-size: 96px; line-height: 0.85; }
  .day--today .day-num { margin-top: 0; font-size: 72px; }
  .day-count { margin-top: 12px; font-size: 13px; letter-spacing: 0.14em; }

  .ev {
    display: grid;
    grid-template-columns: 72px minmax(0, 1fr) auto;
    column-gap: 20px;
    align-items: baseline;
    padding: 16px 0;
  }
  .ev-time { display: block; width: auto; padding: 0; }
  .ev-hour { font-size: 17px; }
  .ev-body { gap: 4px; }
  .ev-title { font-size: 19px; }
  .ev-meta { font-size: 15px; }
  .ev-cat-inline { display: none; }
  .ev-cat {
    display: block;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted);
  }

  /* Big Nights — desktop: equal-width cards in a grid that wraps below ~960px. */
  .bn { margin-top: 72px; }
  .bn-heading { font-size: 44px; }
  .bn-hint { display: none; }
  .bn-count { display: inline; flex: none; font-size: 15px; color: var(--muted); }
  .bn-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 32px 24px;
    margin: 24px 0 0;
    padding: 0;
    overflow: visible;
    scroll-snap-type: none;
  }
  .bn-item { width: auto; }
  .bn-card { gap: 12px; }
  .bn-when { font-size: 13px; }
  .bn-title { font-size: 30px; }
  .bn-where { font-size: 15px; }

  .empty { margin-top: 56px; }

  .site-footer {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 12px 32px;
    margin-top: 96px;
    padding: 24px 0 0;
  }
  .page { padding-bottom: 96px; }
}
