/* ==========================================================================
   Fallcast site. One stylesheet for every page.

   Design notes
   - Photo-led hero, full-bleed maps, restrained type: a serif for the
     headlines and the story, the system sans for everything you tap.
   - The six class colors and the eight Normal colors are the app's own
     (PeeperKit/ColorClass.swift, TimingPalette.rendered). They are data and
     are set from JS (fc-map.js), never restyled here.
   - Light and dark follow the system. Every color is a token below.
   - 390 px first: nothing is wider than the viewport, no sideways scroll.
   ========================================================================== */

:root {
  --paper:   #FBF7F0;
  --card:    #FFFFFF;
  --ink:     #241C16;
  --muted:   #5C5049;
  --link:    #A8410F;
  --rule:    #E4D9C9;
  --accent:  #E0601E;
  --tint:    #F3EBDD;
  --shadow:  0 10px 30px rgba(36, 28, 22, .16), 0 2px 6px rgba(36, 28, 22, .10);

  --serif: "Iowan Old Style", "Charter", "Palatino Linotype", Georgia, "Times New Roman", serif;
  --sans:  -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --wrap: 72rem;
  --gutter: 1.25rem;
}

@media (prefers-color-scheme: dark) {
  :root {
    --paper:  #16120F;
    --card:   #211B16;
    --ink:    #F2EAE0;
    --muted:  #B9AA9C;
    --link:   #F5A06B;
    --rule:   #3A3029;
    --tint:   #1D1713;
    --shadow: 0 10px 30px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .4);
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } * { transition: none !important; animation: none !important; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;           /* belt and braces; nothing should need it */
}

img, svg { max-width: 100%; }
a { color: var(--link); text-underline-offset: 2px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 2px; border-radius: 4px; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 var(--gutter); }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; padding: 0; }

.skip { position: absolute; left: .75rem; top: -4rem; z-index: 100; background: var(--card); color: var(--ink); padding: .6rem .9rem; border-radius: 8px; }
.skip:focus { top: .75rem; }

/* ---------- Header (floats over the hero) ---------- */

.site-head { position: absolute; z-index: 20; top: 0; left: 0; right: 0; color: #fff; }
.site-head .wrap { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding-top: 1rem; padding-bottom: 1rem; }
.logo { display: inline-flex; align-items: center; gap: .6rem; color: inherit; text-decoration: none; font-weight: 700; font-size: 1.15rem; letter-spacing: -.01em; }
.logo img { width: 34px; height: 34px; border-radius: 8px; display: block; }
.head-nav { display: flex; align-items: center; gap: 1.1rem; font-size: .95rem; }
.head-nav a { color: inherit; text-decoration: none; opacity: .92; }
.head-nav a:hover { opacity: 1; text-decoration: underline; }
.pill { display: inline-block; border: 1.5px solid rgba(255,255,255,.85); border-radius: 999px; padding: .35rem .95rem; font-weight: 600; }
.pill:hover { background: rgba(255,255,255,.16); text-decoration: none !important; }
/* Every link in the header is a 44 px tall touch target (the glyphs stay small; the hit area is the ::after). */
.head-nav a, .head-nav .pill { position: relative; white-space: nowrap; }
.logo { position: relative; }
.logo::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 44px; transform: translateY(-50%); }
.head-nav a::after { content: ""; position: absolute; left: -.2rem; right: -.2rem; top: 50%; height: 44px; transform: translateY(-50%); }
.head-nav .nav-search { height: 44px; }

/* ---------- Hero ---------- */

.hero {
  position: relative;
  color: #fff;
  min-height: min(92svh, 860px);
  min-height: min(92vh, 860px);
  display: flex;
  align-items: flex-end;
  isolation: isolate;
  background: #3a2418;         /* shows while the photo loads */
}
@supports (height: 1svh) { .hero { min-height: min(92svh, 860px); } }
.hero-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(180deg, rgba(18,12,8,.55) 0%, rgba(18,12,8,.10) 26%, rgba(18,12,8,.28) 52%, rgba(18,12,8,.82) 100%);
}
.hero .wrap { width: 100%; padding-top: 7rem; padding-bottom: 3.4rem; }
.hero-copy { max-width: 42rem; }

.status {
  display: inline-flex; align-items: center; gap: .55rem;
  background: rgba(255,255,255,.16); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  border: 1px solid rgba(255,255,255,.28);
  border-radius: 999px; padding: .3rem .85rem; font-size: .85rem; font-weight: 600; letter-spacing: .01em;
}
.status i { width: .5rem; height: .5rem; border-radius: 50%; background: #F5A06B; }

.brand { font-family: var(--serif); font-weight: 700; font-size: clamp(3.6rem, 13vw, 8.5rem); line-height: .95; letter-spacing: -.035em; margin: 1.1rem 0 .35rem; }
.hero h1 { font-family: var(--serif); font-weight: 500; font-size: clamp(1.35rem, 3.6vw, 2.1rem); line-height: 1.25; letter-spacing: -.01em; margin: 0 0 1.6rem; max-width: 30ch; text-wrap: balance; }
.hero h1 .kicker { display: block; font-family: var(--sans); font-size: .9rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; opacity: .85; margin-bottom: .5rem; }
.hero h1.state-title { font-weight: 700; font-size: clamp(3rem, 11vw, 7rem); line-height: .98; letter-spacing: -.035em; margin-bottom: 1.4rem; max-width: none; }

.hero-actions { display: flex; flex-wrap: wrap; gap: 1rem 1.25rem; align-items: center; }
.store { display: inline-block; line-height: 0; padding: 4px; }
.store img { width: 150px; height: 50px; display: block; }
.credit { position: absolute; right: var(--gutter); bottom: .75rem; z-index: 2; font-size: .72rem; line-height: 1.3; color: rgba(255,255,255,.82); text-align: right; max-width: 70%; text-shadow: 0 1px 3px rgba(0,0,0,.6); }
.credit a { color: inherit; }

/* State pages without a photo get a color treatment instead. */

/* ---------- State picker (a combobox) ---------- */

.picker { position: relative; width: min(100%, 26rem); }
.picker-box { position: relative; }
.picker input {
  width: 100%; height: 3.4rem; border: 0; border-radius: 14px;
  background: #fff; color: #241C16;
  font: 500 1rem/1 var(--sans); font-size: max(16px, 1rem);   /* >= 16px: no iOS zoom on focus */
  padding: 0 3rem 0 3rem; box-shadow: 0 6px 24px rgba(0,0,0,.28);
}
.picker input::placeholder { color: #6a5c52; }
.picker .ico { position: absolute; top: 50%; transform: translateY(-50%); pointer-events: none; color: #6a5c52; }
.picker .ico { left: 1rem; width: 20px; height: 20px; }

.picker ul {
  position: absolute; z-index: 50; left: 0; right: 0; top: calc(100% + 6px);
  margin: 0; padding: .35rem; list-style: none; max-height: min(22rem, 52vh); overflow-y: auto;
  background: var(--card); color: var(--ink); border: 1px solid var(--rule); border-radius: 14px; box-shadow: var(--shadow);
  overscroll-behavior: contain;
}
.picker li { padding: .6rem .75rem; border-radius: 9px; cursor: pointer; display: flex; justify-content: space-between; gap: 1rem; font-size: 1rem; line-height: 1.25; }
.picker li small { color: var(--muted); font-size: .8rem; letter-spacing: .04em; }
.picker li[aria-selected="true"], .picker li:hover { background: var(--tint); }
.picker li[aria-selected="true"] { outline: 2px solid var(--accent); outline-offset: -2px; }
.picker .empty { padding: .8rem .75rem; color: var(--muted); font-size: .95rem; }

/* ---------- Map sections ---------- */

.mapsec { padding: 3.2rem 0 0; }
.mapsec-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem 2rem; margin-bottom: 1.2rem; padding-top: .9rem; }
.eyebrow { font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 0 0 .35rem; }
.mapsec h2 { font-family: var(--serif); font-size: clamp(1.9rem, 5vw, 3rem); line-height: 1.08; letter-spacing: -.025em; margin: 0; font-weight: 700; }
.datelabel { margin: .45rem 0 0; color: var(--muted); font-size: 1rem; min-height: 1.6em; }
/* A heading and a date line are laid out in ONE grid cell with their longest possible text (the invisible .gh spans), so the
   block is as tall as its longest content in every mode, at every width, and the toggle and the map never move. */
[data-title], .datelabel { display: grid; }
.tx, .gh { grid-area: 1 / 1; min-width: 0; }
.gh { visibility: hidden; font-style: normal; pointer-events: none; }

.seg { display: inline-flex; background: var(--tint); border: 1px solid var(--rule); border-radius: 999px; padding: 3px; }
.seg button {
  font: 600 .95rem/1 var(--sans); color: var(--muted); background: transparent; border: 0; cursor: pointer;
  padding: .7rem 1.25rem; border-radius: 999px; min-width: 5.2rem;
}
.seg button[aria-pressed="true"] { background: var(--ink); color: var(--paper); }

.mapbox { position: relative; width: 100%; height: clamp(440px, 76svh, 820px); background: var(--tint); overflow: hidden; }
.mapbox.state { height: clamp(460px, 74svh, 780px); }
.mapbox .canvas { position: absolute; inset: 0; }
.mapbox .msg { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; padding: 2rem; color: var(--muted); font-size: .95rem; }

.mapbox noscript img { width: 100%; height: 100%; object-fit: contain; }

.legend { margin: 1.1rem auto 0; }
.legend ol { list-style: none; margin: 0; padding: 0; display: grid; gap: .7rem .5rem; grid-template-columns: repeat(var(--cols, 6), 1fr); }
.legend li { font-size: .82rem; line-height: 1.2; color: var(--muted); font-weight: 600; }
.legend li::before { content: ""; display: block; height: 10px; border-radius: 3px; background: var(--c); margin-bottom: .45rem; }
@media (max-width: 640px) { .legend ol { grid-template-columns: repeat(3, 1fr); } .legend.n8 ol { grid-template-columns: repeat(4, 1fr); } .legend li { font-size: .76rem; } }

.attrib { font-size: .76rem; color: var(--muted); margin: .9rem 0 0; }
.attrib a { color: inherit; }

/* MapLibre chrome, retuned */
.maplibregl-ctrl-group { border-radius: 10px !important; box-shadow: var(--shadow) !important; background: var(--card) !important; overflow: hidden; }
.maplibregl-ctrl-group button { width: 38px !important; height: 38px !important; }
@media (prefers-color-scheme: dark) { .maplibregl-ctrl-group button .maplibregl-ctrl-icon { filter: invert(1); } }
.maplibregl-ctrl-attrib { font-size: 11px; }
.maplibregl-popup-content { padding: 0 !important; border-radius: 12px !important; background: var(--card) !important; color: var(--ink) !important; box-shadow: var(--shadow) !important; font-family: var(--sans); }
.maplibregl-popup-tip { display: none; }
.maplibregl-popup-close-button { display: none; }
.pop { padding: .75rem .95rem .8rem; min-width: 10.5rem; max-width: 15rem; }
.pop .row { display: flex; align-items: center; gap: .55rem; font-size: 1.02rem; font-weight: 700; line-height: 1.2; }
.pop .dot { width: .8rem; height: .8rem; border-radius: 50%; background: var(--c); flex: none; box-shadow: 0 0 0 2px rgba(255,255,255,.7) inset; }

.pop .go { display: inline-block; margin-top: .55rem; font-size: .9rem; font-weight: 700; }
.pop .absent { color: var(--muted); font-weight: 600; }
.pop .st { font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: .3rem; }

/* ---------- Story (sticky map, stepping through this season) ---------- */

/* ---------- Nearby / all states ---------- */

.copy { padding: 3.5rem 0 0; }
.copy .lede { font-family: var(--serif); font-size: clamp(1.25rem, 2.6vw, 1.6rem); line-height: 1.5; max-width: 40rem; margin: 0; }
.nearby { padding: 2.5rem 0 0; }
.nearby h2 { font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 0 0 .8rem; }
.chips { display: flex; flex-wrap: wrap; gap: .6rem; list-style: none; margin: 0; padding: 0; }
.chips a { display: inline-block; border: 1px solid var(--rule); background: var(--card); color: var(--ink); text-decoration: none; border-radius: 999px; padding: .5rem 1rem; font-weight: 600; font-size: .95rem; }
.chips a:hover { border-color: var(--accent); }

.states-list { list-style: none; margin: 0; padding: .4rem 0 1.4rem; columns: 2; column-gap: 1.5rem; }
@media (min-width: 640px) { .states-list { columns: 3; } }
@media (min-width: 960px) { .states-list { columns: 5; } }
.states-list li { break-inside: avoid; margin: 0; }
.states-list a { display: block; padding: .38rem 0; color: var(--ink); text-decoration: none; }
.states-list a:hover { color: var(--link); text-decoration: underline; }

footer.site-foot { margin-top: 4.5rem; padding: 2.2rem 0 3rem; border-top: 1px solid var(--rule); font-size: .88rem; color: var(--muted); }
footer.site-foot .wrap { display: grid; gap: .8rem; }
footer.site-foot .links { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; }
footer.site-foot a { color: var(--ink); }
footer.site-foot p { margin: 0; }

/* ==========================================================================
   State story: the map is the page; cards scroll over it.
   ========================================================================== */

.site-head.solid { position: fixed; color: var(--ink); background: color-mix(in srgb, var(--paper) 88%, transparent); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-bottom: 1px solid var(--rule); }
.site-head.solid .wrap { padding-top: .6rem; padding-bottom: .6rem; }
.site-head.solid .pill { border-color: currentColor; }
.site-head.solid .pill:hover { background: var(--tint); }

/* The map's stage is as tall as the LARGE viewport (lvh): on a phone that is the screen with Safari's toolbars hidden, so
   the map covers the screen whether they are showing or not and nothing re-sizes when they come and go. (100vh is the
   fallback; story.js raises --stage-h if a browser ever shows more than that.) Cards and beats keep svh. */
.sp { position: relative; --stage-h: 100vh; }
@supports (height: 100lvh) { .sp { --stage-h: 100lvh; } }
/* The overlay layer (.sp-over) is a second sticky box exactly the size of the stage and pinned with it. It holds the legend and,
   on a phone, the one docked card. It sits between the map and the cards on a wide screen (as the legend always did) and
   ABOVE the cards on a phone, so the title scrolls up UNDER the legend instead of over it. */
.sp-over { position: sticky; top: 0; height: var(--stage-h); z-index: 1; pointer-events: none; }
.sp-dock { display: none; }
.sp-stage { position: sticky; top: 0; height: var(--stage-h); margin-top: calc(-1 * var(--stage-h)); z-index: 0; background: var(--tint); overflow: hidden; contain: layout paint; }
.sp-stage .canvas { position: absolute; inset: 0; }
.sp-stage .msg { position: absolute; inset: 0; display: grid; place-items: center; text-align: center; padding: 2rem; color: var(--muted); }
.sp-legend {
  position: absolute; z-index: 3; left: var(--gutter); right: var(--gutter); top: 3.9rem;
  padding: .55rem .75rem .6rem; border-radius: 12px; border: 1px solid var(--rule);
  background: color-mix(in srgb, var(--card) 90%, transparent); -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); box-shadow: var(--shadow);
}
.sp-legend .legend { margin: 0; }
.sp-legend .legend ol { gap: .35rem .5rem; }
.sp-legend .legend li { font-size: .7rem; }
.sp-legend .legend li::before { height: 7px; margin-bottom: .3rem; }
@media (min-width: 821px) {
  .sp-legend { top: auto; left: auto; bottom: 1.4rem; right: 1.2rem; width: min(37rem, 46vw); container-type: inline-size; }
  .sp-legend .legend li { font-size: .74rem; }
  /* Eight buckets in one row need about 31.5rem between the padding (the longest words, "September" and "November"); with some room to
     spare for other fonts that is 34.5rem. Narrower than that (a screen under about 1260 px wide) they wrap to two rows of four, so the
     legend never runs past its box and the right edge. The six-class Today legend needs 15rem and always fits. */
  @container (max-width: 34.5rem) { .sp-legend .legend.n8 ol { grid-template-columns: repeat(4, 1fr); } }
}

.sp-steps { position: relative; z-index: 2; margin-top: calc(-1 * var(--stage-h)); pointer-events: none; }
.sp-step { position: relative; }
.sp-step > .wrap { display: grid; }
.sp-card, .sp-tools { grid-area: 1 / 1; align-self: start; position: sticky; top: 17vh; top: 17svh; pointer-events: auto; width: min(26rem, 100%); }
.sp-card {
  background: color-mix(in srgb, var(--card) 95%, transparent); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid var(--rule); border-radius: 18px; box-shadow: var(--shadow); padding: 1.15rem 1.3rem 1.25rem;
  opacity: .55; transition: opacity .35s;
}
.sp-step.active .sp-card { opacity: 1; }
.sp-card p { margin: 0; font-family: var(--serif); font-size: clamp(1.15rem, 2vw, 1.34rem); line-height: 1.45; letter-spacing: -.005em; }
.sp-card mark { background: transparent; color: inherit; border-radius: 5px; padding: 0 .1em; margin: 0 -.1em; transition: background .35s, box-shadow .35s; }
.sp-card mark.on { background: rgba(224, 96, 30, .24); box-shadow: 0 0 0 2px rgba(224, 96, 30, .24); }

.sp-card.title { width: min(30rem, 100%); padding: 1.4rem 1.5rem 1.5rem; opacity: 1; }
.sp-card .status { font-family: var(--sans); font-size: .85rem; line-height: 1.3; }
.sp-card.title .status { background: var(--tint); border-color: var(--rule); color: var(--ink); -webkit-backdrop-filter: none; backdrop-filter: none; }
.sp-card.title h1 { font-family: var(--serif); margin: .9rem 0 1.1rem; font-size: clamp(2.8rem, 8vw, 4.6rem); line-height: .98; letter-spacing: -.035em; font-weight: 700; }
.sp-card.title h1 .kicker { display: block; font-family: var(--sans); font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin-bottom: .55rem; }
.sp-card.title .picker { width: 100%; }
.sp-card.title .picker input { box-shadow: none; border: 1px solid var(--rule); background: var(--paper); color: var(--ink); }
.sp-card.title .picker input::placeholder { color: var(--muted); }
.sp-card.title .picker .ico { color: var(--muted); }
.sp-card .cue { margin: 1rem 0 0; font: 600 .85rem/1.2 var(--sans); letter-spacing: 0; color: var(--muted); display: flex; align-items: center; gap: .5rem; }
.cue svg { width: 16px; height: 16px; }

.beats { grid-area: 1 / 1; pointer-events: none; }
.beat { height: 78vh; height: 78svh; }
.beat.tall { height: 100vh; height: 100svh; }

/* Photos: open with the stop they belong to, close without one. */
.ph { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .45s ease; }
.ph.on { grid-template-rows: 1fr; }
.ph-in { overflow: hidden; min-height: 0; }
.ph-item { display: none; margin: 0 0 .95rem; }
.ph-item.on { display: block; }
.ph-item img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; border-radius: 12px; background: var(--tint); }
.ph-item figcaption { font-family: var(--sans); font-size: .74rem; line-height: 1.4; color: var(--muted); margin-top: .45rem; }
.ph-item .pl { display: block; color: var(--ink); font-weight: 600; font-size: .8rem; }
.ph-item a { color: inherit; }

/* The last step: the toggle, and the map is yours. */
.sp-step.explore .beat { height: 100vh; height: 100svh; }
.sp-tools { align-self: end; top: auto; bottom: 1.2rem; width: min(24rem, 100%); opacity: 0; transition: opacity .35s; display: block; }
.sp.exploring .sp-tools { opacity: 1; }
.sp-tools .row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem 1rem; }
.sp-tools .datelabel { margin: .7rem 0 0; font-size: .92rem; min-height: 1.3em; }

.sp-tools .seg button { padding: .65rem 1.15rem; }

@media (max-width: 820px) {
  .sp-card, .sp-tools { align-self: end; top: auto; bottom: .75rem; width: 100%; }
  .sp-card:not(.title) { max-height: calc(100svh - 8rem); overflow-y: auto; }
  .sp-card p { font-size: 1.12rem; }
  .ph-item img { aspect-ratio: 16 / 9; }
  .sp-card.title { padding: 1.1rem 1.2rem 1.2rem; }
  .sp-card.title h1 { font-size: clamp(2.6rem, 14vw, 3.6rem); margin: .7rem 0 .9rem; }
  .sp-tools { bottom: .75rem; }
  .sp.exploring .sp-legend { top: 3.9rem; }

  /* ONE docked card (story.js builds it). The step cards in the page become invisible spacers: they keep their size, so the
     timing of the steps and of the camera is unchanged, but nothing sticky is left to rise, pin and snap at a step boundary.
     The dock is pinned to the bottom of the SMALL viewport (toolbars shown) and never moves: the stage is as tall as the large
     one, so the offset is the difference. Content swaps with a short crossfade; between beats of one step only the marks and
     the photo change. */
  .sp-over { z-index: 3; }
  .sp.docked .sp-step:not(.explore) .sp-card { opacity: 0; pointer-events: none; transition: none; }
  .sp-dock { display: block; position: absolute; left: var(--gutter); right: var(--gutter); height: 0; bottom: max(.75rem, calc(var(--stage-h) - 100svh + .75rem)); }       /* a line: the panes hang up from it, so the dock itself has no height to change */
  .sp-pane { position: absolute; left: 0; right: 0; bottom: 0; min-width: 0; opacity: 0; visibility: hidden; pointer-events: none; transition: opacity .22s ease, visibility 0s linear .22s; }
  .sp-pane.on { opacity: 1; visibility: visible; pointer-events: auto; transition: opacity .22s ease; }
  .sp-pane-tools { visibility: visible; transition: opacity .22s ease; }                 /* the toggle is a real control: it stays in the accessibility tree and the tab order, and shows when it takes focus */
  .sp-pane-tools:focus-within { opacity: 1; pointer-events: auto; }
  .sp-pane .sp-card, .sp-pane .sp-tools { pointer-events: inherit; }                 /* a hidden pane must not catch taps (its toggle sat over the title's links, unseen) */
  .sp-pane.still .ph { transition: none; }
  /* In the dock a photo never pops: all of a step's photos stay laid out in one stack, the one that is on is opaque, and the row
     eases open and shut (the page's own cards switch photos with display, which closes a card in one frame). */
  .sp-dock .ph-in { display: grid; }
  .sp-dock .ph-item { display: block; grid-area: 1 / 1; opacity: 0; transition: opacity .3s ease; }
  .sp-dock .ph-item.on { opacity: 1; }
  .sp-dock .ph-item:not(.on) { pointer-events: none; }
  .sp-pane.still .ph-item { transition: none; }
  .sp-dock .sp-card, .sp-dock .sp-tools { position: relative; top: auto; bottom: auto; width: 100%; margin: 0; opacity: 1; transition: none; }
  .nomap .sp-dock { display: none; }
}
@media (max-width: 820px) and (prefers-reduced-motion: reduce) { .sp-pane, .sp-pane.on, .sp-dock .ph, .sp-dock .ph-item { transition: none; } }

.sp-stage .maplibregl-ctrl-top-right { top: 3.6rem; }
@media (max-width: 820px) { .sp-stage .maplibregl-ctrl-top-right { top: 8.6rem; } .sp-stage .maplibregl-ctrl-top-left { top: 8.6rem; left: .4rem; max-width: calc(100% - 4.5rem); } .sp-stage .maplibregl-ctrl-attrib { background: color-mix(in srgb, var(--paper) 80%, transparent) !important; color: var(--ink); } }

.picker[data-flip="up"] ul { top: auto; bottom: calc(100% + 6px); }
.seg button:disabled { opacity: .4; cursor: default; }

@media (max-width: 640px) { .mapbox:not(.state) { height: clamp(330px, 56svh, 480px); } }

/* ==========================================================================
   Round 2
   ========================================================================== */

/* ---- Compact home hero ---- */
.hero.compact { min-height: min(54svh, 500px); min-height: min(54vh, 500px); }
@supports (height: 1svh) { .hero.compact { min-height: min(54svh, 500px); } }
.hero.compact::after { background: linear-gradient(180deg, rgba(18,12,8,.50) 0%, rgba(18,12,8,.06) 30%, rgba(18,12,8,.18) 55%, rgba(18,12,8,.72) 100%); }
.hero.compact .wrap { padding-top: 5.2rem; padding-bottom: 2.4rem; }
.hero.compact .status { background: none; border: 0; padding: 0; backdrop-filter: none; -webkit-backdrop-filter: none; font-size: .78rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; opacity: .92; text-shadow: 0 1px 8px rgba(0,0,0,.5); }
.hero.compact .brand { font-size: clamp(2.6rem, 6.2vw, 4.4rem); margin: .35rem 0 .3rem; text-shadow: 0 2px 22px rgba(0,0,0,.35); }
.hero.compact h1 { font-size: clamp(1.02rem, 2vw, 1.4rem); margin: 0 0 1.1rem; max-width: 34ch; text-shadow: 0 1px 12px rgba(0,0,0,.45); }
.hero.compact .hero-copy { max-width: 36rem; }
@media (max-width: 520px) {
  .hero.compact { min-height: 0; }
  .hero.compact .wrap { padding-top: 4.6rem; padding-bottom: 1.5rem; }
  .hero.compact .brand { font-size: 2.5rem; }
  .hero.compact .credit { position: static; text-align: left; max-width: none; padding: .55rem var(--gutter) 0; font-size: .7rem; }
  .hero.compact .hero-actions { gap: .6rem 1rem; }
}
.hero .picker input { height: 3.1rem; }
.mapsec { padding-top: 1.3rem; }                   /* 1.3 + the head's .9 = the 2.2rem it always was; the pinned (Progression) block no longer adds its own */

/* ---- Search: the nav icon, the overlay, grouped results ---- */
.nav-search { display: inline-grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; opacity: .95; }
.nav-search:hover { background: rgba(255,255,255,.18); }
.site-head.solid .nav-search:hover { background: var(--tint); }
.nav-search svg { width: 20px; height: 20px; }
.picker .ico { z-index: 1; }
.picker input { padding-right: 1rem; }
.picker ul .grp { padding: .55rem .75rem .25rem; font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); cursor: default; display: block; }
.picker li[role=option] small { text-align: right; }

.picker li mark { background: transparent; color: inherit; font-weight: 700; }
.picker .empty { color: var(--muted); }

.search-overlay { position: fixed; inset: 0; z-index: 200; display: grid; align-items: start; justify-items: center; padding: 8vh var(--gutter) 0; }
.search-overlay[hidden] { display: none; }
.search-backdrop { position: absolute; inset: 0; background: color-mix(in srgb, var(--paper) 62%, rgba(20,14,10,.55)); -webkit-backdrop-filter: blur(5px); backdrop-filter: blur(5px); }
.search-dialog { position: relative; width: min(34rem, 100%); }
.search-dialog .picker { width: 100%; }
.search-dialog .picker ul { position: static; margin-top: .5rem; max-height: min(26rem, 62vh); }
.search-dialog .picker input { border: 1px solid var(--rule); background: var(--card); color: var(--ink); box-shadow: var(--shadow); }
.search-dialog .picker input::placeholder { color: var(--muted); }
.search-dialog .picker .ico { color: var(--muted); top: 1.7rem; }   /* the list is in flow here, so .picker-box is input + list tall: pin the icon to the input's own middle (half of its 3.4rem) */

/* ---- State pages: a light title over the map, not a box ---- */
.sp-title { grid-area: 1 / 1; align-self: start; position: sticky; top: 17vh; top: 17svh; pointer-events: auto; width: min(24rem, 100%); position: sticky; isolation: isolate; padding: .2rem 0; }
.sp-title::before { content: ""; position: absolute; z-index: -1; inset: -2.4rem -3.2rem -2rem -2.2rem; background: radial-gradient(closest-side, color-mix(in srgb, var(--paper) 86%, transparent) 55%, transparent); }
.sp-title .kicker, .state-title .kicker { margin: 0 0 .1rem; font: 700 .78rem/1.2 var(--sans); letter-spacing: .14em; text-transform: uppercase; color: var(--muted); }
.sp-title h1 { font-family: var(--serif); font-weight: 700; font-size: clamp(3rem, 7vw, 5rem); line-height: .96; letter-spacing: -.035em; margin: 0 0 .5rem; color: var(--ink); text-shadow: 0 0 22px var(--paper), 0 0 6px var(--paper); }
.sp-title .status-small { margin: 0; font: 600 .8rem/1.3 var(--sans); color: var(--muted); }
.sp-title .cue { display: flex; align-items: center; gap: .4rem; margin: .9rem 0 0; font: 600 .8rem/1.2 var(--sans); color: var(--muted); }
.sp-title .cue svg { width: 14px; height: 14px; }
/* "Skip to the map": a quiet link after the Scroll cue, the same size and color, with a hit area taller than the line. */
.sp-skip { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: .22em; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); padding: .7rem .4rem; margin: -.7rem -.4rem; }
.sp-skip:hover { color: var(--ink); text-decoration-color: currentColor; }
.sp-step.explore:focus { outline: none; }               /* the jump moves focus here; it is a place, not a control */
@media (max-width: 820px) {
  .sp-title { align-self: end; position: relative; top: auto; bottom: auto; margin-bottom: 1.4rem; width: 100%; }      /* not sticky: it scrolls away with the page, nothing to snap */
  .sp-title::before { inset: -3rem -1.1rem -1rem -1.1rem; background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--paper) 88%, transparent) 55%); }
  .sp-title h1 { font-size: clamp(2.6rem, 14vw, 3.6rem); }
}
.state-title h1 { font-family: var(--serif); font-weight: 700; font-size: clamp(2.2rem, 6vw, 3.6rem); line-height: 1; letter-spacing: -.03em; margin: 0; }
.state-top { padding-top: 5.4rem; }
.state-top .datelabel { margin-top: .5rem; }

/* ---- Story beats: more scroll between camera moves ---- */
.beat { height: 100vh; height: 100svh; }
.beat.tall { height: 100vh; height: 100svh; }

/* ---- All-states index ---- */
.index-page { padding: 6rem 0 1rem; }
.index-page h1 { font-family: var(--serif); font-size: clamp(2rem, 6vw, 3.4rem); letter-spacing: -.03em; line-height: 1.05; margin: 0 0 .6rem; }

.index-page .region { padding-top: 1.8rem; border-top: 1px solid var(--rule); margin-top: 1.8rem; }
.index-page .region h2 { font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 0 0 .5rem; }
.index-page .states-list { padding-bottom: 0; }
.site-foot { margin-top: 4.5rem; padding: 2rem 0 2.6rem; border-top: 1px solid var(--rule); font-size: .85rem; color: var(--muted); }
.site-foot .wrap { display: grid; gap: .7rem; }
.site-foot .links { display: flex; flex-wrap: wrap; gap: .4rem 1.3rem; }
.site-foot a { color: var(--ink); }
.site-foot p { margin: 0; }
.plain-state .copy { padding-top: 2.5rem; }

/* Story: the legend and the date label show only while the map is pinned */

/* Home: one map. The +/- buttons and the Today | Normal toggle belong to the last step. */

/* Home map: Progression's vertical timeline (circles joined by a line; the selected date is filled) */
.timeline { position: absolute; z-index: 3; left: .9rem; bottom: 1rem; display: flex; flex-direction: column; padding: .55rem .8rem .55rem .65rem; border-radius: 14px;
  background: color-mix(in srgb, var(--paper) 78%, transparent); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.timeline[hidden] { display: none; }
.timeline button { position: relative; display: flex; align-items: center; gap: .7rem; height: 2.15rem; padding: 0; border: 0; background: none; cursor: pointer; font: 600 .86rem/1 var(--sans); color: var(--muted); text-align: left; }
.timeline button:not(:last-child)::after { content: ""; position: absolute; left: 6px; top: calc(50% + 7px); width: 2px; height: calc(100% - 14px); background: color-mix(in srgb, var(--muted) 38%, transparent); border-radius: 1px; }
.timeline .dot { position: relative; z-index: 1; flex: none; width: 14px; height: 14px; border-radius: 50%; box-sizing: border-box; border: 2px solid color-mix(in srgb, var(--muted) 65%, transparent); background: var(--paper); }
.timeline button:hover { color: var(--ink); }
.timeline button:hover .dot { border-color: var(--accent); }
.timeline button[aria-checked="true"] { color: var(--ink); font-weight: 700; }
.timeline button[aria-checked="true"] .dot { background: var(--accent); border-color: var(--accent); }
.timeline .l-short { display: none; }
@media (max-width: 520px) {
  .timeline { left: .45rem; bottom: .6rem; padding: .4rem .55rem .4rem .45rem; }
  .timeline button { height: 1.85rem; font-size: .76rem; gap: .5rem; }
  .timeline button:not(:last-child)::after { top: calc(50% + 6px); height: calc(100% - 12px); }
  .timeline .l-long { display: none; }
  .timeline .l-short { display: inline; }
}
@media (max-width: 520px) { .seg button { min-width: 0; padding: .65rem 1rem; } }

/* Vermont story: the timeline sits on the right on a wide screen, and under the legend on a phone */
.sp-stage .timeline { left: auto; right: 1.2rem; bottom: auto; top: 50%; transform: translateY(-50%); }
@media (max-width: 820px) {
  .sp-stage .timeline { right: auto; left: .45rem; top: 9.4rem; bottom: auto; transform: none; }
}
.sp-stage .timeline[hidden] { display: none; }
.sp-tools .seg button { padding: .65rem .9rem; min-width: 4.4rem; }
.sp-step > .wrap > * { min-width: 0; }
@media (max-width: 520px) {
  .sp-tools { padding: .9rem 1rem 1rem; }
  .sp-tools .seg { max-width: 100%; }
  .sp-tools .seg button { padding: .6rem .62rem; font-size: .86rem; min-width: 0; }
  .seg button { padding: .6rem .8rem; }
}
@media (max-width: 460px) {
  .site-head .wrap { gap: .4rem; padding-left: .9rem; padding-right: .9rem; }
  .logo { font-size: 1.05rem; gap: .45rem; }
  .head-nav { gap: .2rem; font-size: .9rem; }
  .head-nav a:not(.pill) { padding: 0 .3rem; }
  .pill { padding: .32rem .75rem; font-size: .9rem; }
}
@media (max-width: 380px) {
  .site-head .wrap { gap: .3rem; padding-left: .75rem; padding-right: .75rem; }
  .logo { font-size: .98rem; gap: .35rem; }
  .logo img { width: 30px; height: 30px; }
  .head-nav { gap: .1rem; font-size: .84rem; }
  .head-nav a:not(.pill) { padding: 0 .2rem; }
  .pill { padding: .3rem .6rem; font-size: .84rem; }
  .nav-search { width: 36px; }
}
@media (max-width: 340px) {
  .site-head .wrap { gap: .2rem; padding-left: .55rem; padding-right: .55rem; }
  .logo { font-size: .92rem; gap: .3rem; }
  .logo img { width: 28px; height: 28px; }
  .head-nav { gap: 0; font-size: .78rem; }
  .head-nav a:not(.pill) { padding: 0 .15rem; }
  .pill { padding: .28rem .5rem; font-size: .78rem; }
  .nav-search { width: 32px; }
  .nav-search svg { width: 18px; height: 18px; }
}

.sp, .sp-steps { overflow-x: clip; }

/* Story: after the last stop the map stays pinned (nothing changes) before the page moves on */
.dwell { height: 250vh; height: 250svh; }

/* On a phone the timeline sits above the map's own attribution line, never over it. */
@media (max-width: 520px) { .mapbox .timeline { bottom: 2.3rem; } }
/* Vermont story on a narrow screen: everything that hangs from the top sits just under the legend, whatever height it has. */
@media (max-width: 820px) {
  .sp-stage .maplibregl-ctrl-top-right, .sp-stage .maplibregl-ctrl-top-left { top: calc(var(--lg-bottom, 9rem) + 6px); }
  .sp-stage .timeline { top: calc(var(--lg-bottom, 9rem) + 34px); }
}

/* ==========================================================================
   Launch additions: states by region, the app, the explainer, credits, no map
   ========================================================================== */

/* ---- Home: the app, mostly pictures ---- */
.app-sec { padding: 4.5rem 0 0; }
.app-line { font-family: var(--serif); font-size: clamp(1.2rem, 2.4vw, 1.5rem); line-height: 1.45; margin: 0 0 1.6rem; text-wrap: balance; }       /* one line where it fits (about 1024 px up); balanced lines, no lone last word, below that */
.shots { display: flex; gap: .9rem; overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; -webkit-overflow-scrolling: touch;
         margin: 0 calc(-1 * var(--gutter)); padding: 0 var(--gutter) .4rem; scroll-padding: 0 var(--gutter); }
.shots { scrollbar-width: none; }
.shots::-webkit-scrollbar { display: none; }
.shots img { flex: 0 0 62%; width: 62%; height: auto; scroll-snap-align: start; border-radius: 14px; background: var(--tint); }
@media (min-width: 40rem) { .shots img { flex-basis: 15rem; width: 15rem; } }          /* still one row you swipe, the next picture peeking, until all five fit */
@media (min-width: 70rem) {                                                           /* five across, each about 200 px or wider */
  .shots { overflow: visible; scroll-snap-type: none; margin: 0; padding: 0; }
  .shots img { flex: 1 1 0; width: 0; min-width: 0; }
}
.app-sec .store { margin-top: 1.1rem; }
.more { margin-top: 2.6rem; margin-bottom: 0; font-size: 1rem; }
.more a { font-weight: 600; }

/* ---- Photo credits: small, quiet, under every picture ---- */
.credit a, .ph-item figcaption a, .ex-photo figcaption a { color: inherit; text-decoration-thickness: 1px; }
.ex-photo figcaption { font-family: var(--sans); font-size: .74rem; line-height: 1.4; color: var(--muted); margin-top: .45rem; }

/* ---- The explainer: editorial type, no map ---- */
.explainer { padding: 6rem 0 1rem; }
.explainer .wrap { max-width: 46rem; }
.explainer h1 { font-family: var(--serif); font-size: clamp(2rem, 6vw, 3.4rem); letter-spacing: -.03em; line-height: 1.05; margin: 0 0 2rem; }
.explainer h2 { font-family: var(--serif); font-size: clamp(1.5rem, 3.4vw, 2rem); line-height: 1.15; letter-spacing: -.02em; margin: 3rem 0 .4rem; padding-top: 1.8rem; border-top: 1px solid var(--rule); }
.explainer h1 + h2 { margin-top: 0; padding-top: 0; border-top: 0; }
.explainer h3 { font: 700 .78rem/1.3 var(--sans); letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 1.9rem 0 .4rem; }
.explainer p { font-family: var(--serif); font-size: 1.2rem; line-height: 1.6; margin: 0 0 1rem; max-width: 38rem; }
.ex-photo { margin: .6rem 0 1.2rem; }
.ex-photo img { display: block; width: 100%; height: auto; border-radius: 12px; background: var(--tint); }
@media (min-width: 900px) {
  .explainer .wrap { max-width: 62rem; }
  .ex-sec.has-photo { display: grid; grid-template-columns: minmax(0, 1fr) 19rem; column-gap: 2.4rem; align-items: start; }
  .ex-sec.has-photo > h2, .ex-sec.has-photo > h3, .ex-sec.has-photo > p { grid-column: 1; }
  .ex-sec.has-photo > .ex-photo { grid-column: 2; grid-row: 1 / span 4; margin-top: 1.9rem; }
}

/* ---- Footer map credit ---- */
.site-foot .mapcredit { font-size: .8rem; }
.site-foot .mapcredit a { color: inherit; }

/* ---- No WebGL (or the library or style did not load): the same tiles as plain images under one SVG, see fc-map.js, "the fallback" ---- */
.fc-grid { position: absolute; inset: 0; overflow: hidden; background: var(--paper); }
.fc-layer { position: absolute; inset: 0; }
.fc-layer img { position: absolute; display: block; max-width: none; -webkit-user-drag: none; user-select: none; }
.fc-grid.pix img { image-rendering: pixelated; }
.fc-over { position: absolute; left: 0; top: 0; pointer-events: none; }
.fc-over path { fill-rule: evenodd; }
.fc-over .mask { fill: var(--paper); }
.fc-over .dim { fill: #F2F3F0; }
.fc-over .ln, .fc-over .focus { fill: none; stroke-linejoin: round; }
.fc-over .ln { stroke: rgba(255, 247, 236, .36); stroke-width: .6; }
.fc-over.st .ln { stroke-width: 1; }
.fc-over .focus { stroke: #241C16; stroke-opacity: .8; stroke-width: 1.6; }
@media (prefers-color-scheme: dark) { .fc-over .dim { fill: #0C0C0C; } .fc-over .ln { stroke: rgba(242, 234, 224, .2); } .fc-over .focus { stroke: #fff; } }

/* ---- No map at all (the tiles host or the manifest cannot be reached): the static Normal picture in the same box ---- */
.nomap .seg, .nomap [data-chips], .nomap .timeline, .nomap .sp-legend, .nomap .sp-tools { display: none; }
.nomap:not(.has-static) .legend, .nomap:not(.has-static) .datelabel { display: none; }
.nomap .mapbox { background: var(--paper); }
.nomap .mapbox > img { inset: 1rem; width: calc(100% - 2rem); height: calc(100% - 2rem); }
.mapbox > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.nomap .mapbox .msg { inset: auto 0 0 0; padding: .9rem 1rem; background: color-mix(in srgb, var(--paper) 88%, transparent); }

/* ---- Home: "Only in the app" ---- */
.app-sec h2 { font-family: var(--serif); font-size: clamp(1.5rem, 3.4vw, 2rem); line-height: 1.15; letter-spacing: -.02em; margin: 2.2rem 0 1rem; font-weight: 700; }
.app-features { list-style: none; margin: 0 0 2rem; padding: 0; display: grid; gap: .9rem 1.6rem; grid-template-columns: 1fr; }
.app-features li { margin: 0; padding: .95rem 1.1rem; background: var(--card); border: 1px solid var(--rule); border-radius: 14px; font-size: 1rem; line-height: 1.45; color: var(--muted); }
.app-features strong { display: block; color: var(--ink); font-size: 1.05rem; margin-bottom: .15rem; }
@media (min-width: 40rem) { .app-features { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .app-features { grid-template-columns: repeat(4, 1fr); } }

@media (max-width: 520px) { .hero .picker { width: 100%; } }

/* Phone hero: the credit sits under the copy, on its own line (the hero is a flex row, so it must wrap). */
@media (max-width: 520px) { .hero.compact { flex-wrap: wrap; align-content: flex-end; } .hero.compact .credit { flex: 0 0 100%; } }

/* Footer links: comfortable to tap */
.site-foot .links a { display: inline-block; padding: .4rem 0; }
.site-foot .links { gap: 0 1.3rem; }

/* The map's own attribution: the page's colors, both schemes (MapLibre's default is white on a translucent white). */
.maplibregl-ctrl-attrib.maplibregl-compact, .maplibregl-ctrl-attrib { background: color-mix(in srgb, var(--paper) 86%, transparent) !important; color: var(--ink) !important; }
.maplibregl-ctrl-attrib a { color: var(--ink) !important; }
.maplibregl-ctrl-attrib-button { background-color: transparent !important; }
@media (prefers-color-scheme: dark) { .maplibregl-ctrl-attrib-button { filter: invert(1); } }

/* Phones: no backdrop blur over the map. The map redraws every frame while it eases and while tiles arrive, and a blur
   behind the cards, the legend, the header and the timeline has to be recomputed with it (and again each time a card's
   opacity animates). The same panels are drawn nearly opaque instead, which looks the same and costs almost nothing. */
@media (max-width: 820px) {
  .sp-card, .sp-legend, .site-head.solid, .timeline { -webkit-backdrop-filter: none; backdrop-filter: none; }
  .sp-card { background: color-mix(in srgb, var(--card) 97%, transparent); }
  .sp-legend { background: color-mix(in srgb, var(--card) 96%, transparent); }
  .site-head.solid { background: color-mix(in srgb, var(--paper) 96%, transparent); }
  .timeline { background: color-mix(in srgb, var(--paper) 92%, transparent); }
}

/* ---- Touch screens: the map is awake only after a tap (fc-map.js, "touch: one finger scrolls the page") ----
   Active: the whole map area takes the touch. touch-action none on the container and the canvas (MapLibre's own rule
   would leave pan-x pan-y); the legend and the timeline's frame let touches through to the map, so there is no dead
   zone under them (their buttons, the zoom buttons and the attribution keep their own touch). The only sign is a thin
   outline. */
.fc-active, .fc-active .maplibregl-canvas-container, .fc-active .maplibregl-canvas { touch-action: none !important; }
.fc-active .sp-legend, .fc-active .timeline, .fc-active .legend { pointer-events: none; }
.fc-active .timeline button { pointer-events: auto; }
.fc-active .maplibregl-ctrl-attrib { pointer-events: none; }
.fc-active .maplibregl-ctrl-attrib a, .fc-active .maplibregl-ctrl-attrib-button { pointer-events: auto; }
.fc-active .maplibregl-popup-content { pointer-events: none; }
.fc-active .maplibregl-popup-content a { pointer-events: auto; }
.fc-active::after { content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none; box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--accent) 80%, transparent); }
