/* ============================================================
   CityScape™ Vancouver — Local Spots, Spotted (/local-spots)
   Layout source: docs/mockups/local_spots_page_mockup.html
   DESIGN SYSTEM: press/press.css (Samuel's ruling 2026-09-02) —
   tokens, type scale, buttons, and the gold-hairline motif all
   mirror /press. Contrast-measured values (--muted, --blue-deep)
   come from press's header comment; do not re-derive them.
   The five --n-* neighbourhood colours are a FUNCTIONAL map
   palette (pins/legend/badges), owned by localSpots.js — they are
   not page chrome and deliberately do not track --blue/--gold.
   ============================================================ */

:root{
  --cream:#F4EFE4;
  --paper:#FFFCF5;
  --ink:#1c2836;
  --muted:#6F675A;
  --blue:#1B6FC8;
  --blue-deep:#155BA6;
  --gold:#C8A24D;
  --rule:var(--gold); /* legacy alias used throughout this file */
  --hairline:rgba(200,162,77,.55);
  --measure:68ch;
  --max:1080px;
}
*{box-sizing:border-box;margin:0;padding:0;}
html{scroll-behavior:smooth;}
body{
  background:var(--cream);color:var(--ink);
  font-family:'Barlow',system-ui,-apple-system,sans-serif;
  font-size:17px;line-height:1.65;
  -webkit-font-smoothing:antialiased;
}
.wrap{max-width:var(--max);margin:0 auto;padding:0 24px;}
h1,h2,h3,h4,.eyebrow,.btn{font-family:'Barlow Condensed','Barlow',sans-serif;}
p{max-width:var(--measure);text-wrap:pretty;}
a{color:var(--blue-deep);}
a:focus-visible,button:focus-visible{outline:2px solid var(--blue-deep);outline-offset:3px;border-radius:2px;}

/* ── Masthead / footer (press markup + press styles) ──────── */
.masthead{border-bottom:1px solid var(--hairline);}
.masthead .wrap{
  display:flex;align-items:center;justify-content:space-between;
  gap:20px;padding-block:20px;flex-wrap:wrap;
}
.masthead img{display:block;width:210px;max-width:52vw;height:auto;}
.eyebrow{font-weight:600;text-transform:uppercase;letter-spacing:.2em;font-size:13px;color:var(--muted);}
.masthead .eyebrow{text-align:right;}

.pagefoot{border-top:1px solid var(--hairline);padding-block:26px 44px;font-size:14.5px;color:var(--muted);}
.pagefoot .wrap{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;}

/* section divider, press's single defining motif */
.rule{height:1px;background:var(--hairline);border:0;margin:0;}

/* ── Hero: real map with the title overlaid ───────────────── */
.hero{padding:0;}
.hero-map{position:relative;isolation:isolate;background:var(--cream);} /* isolate: the title card's z-index stays inside this section, so the sticky site header scrolls OVER it (2026-09-21) */
#spotsMap{height:clamp(520px,46vw,640px);width:100%;background:#F2EEE7;z-index:0;} /* tall enough for the card ABOVE the zones (Samuel's mock is ~70vw, 2026-09-21) */
.hero-title{
  position:absolute;top:0;left:0;right:0;z-index:500; /* above leaflet panes */
  padding:34px 0 0;pointer-events:none;
}
.hero-title .in{
  max-width:var(--max);margin:0 auto;padding:0 24px;pointer-events:none;
}
.hero-title .scrim{
  display:inline-block;max-width:min(420px,29vw);
  background:rgba(244,239,228,.94);
  padding:22px 24px 24px;border:2px solid var(--gold);border-radius:10px;
  pointer-events:auto;
}
.hero-title h1{font-size:clamp(34px,4.2vw,52px);max-width:12ch;} /* 'Local Spots,' / 'Spotted' = two lines */
.hero-title h1 em{display:block;}
.hero-title .lede{font-size:17px;line-height:1.45;max-width:30ch;margin-top:12px;}
.hero-title .cta-row{margin-top:18px;}
h1{font-weight:700;font-size:clamp(30px,3.8vw,44px);line-height:1.03;letter-spacing:-.005em;max-width:20ch;text-wrap:balance;}
h1 em{font-style:normal;color:var(--blue);}
.lede{margin-top:12px;max-width:50ch;font-size:16.5px;line-height:1.5;}
.cta-row{display:flex;gap:14px;flex-wrap:wrap;margin-top:18px;}
.btn{
  display:inline-block;text-decoration:none;cursor:pointer;
  font-weight:600;text-transform:uppercase;letter-spacing:.06em;font-size:17px;
  padding:13px 26px;border-radius:3px;border:1.5px solid var(--blue);
  background:transparent;color:var(--blue-deep);
  transition:background-color .15s,color .15s,border-color .15s;
}
.btn{border-color:var(--hairline);}
.btn:hover,.btn:focus-visible{border-color:var(--blue);}
.btn.solid{background:var(--blue);border-color:var(--blue);color:#fff;}
.btn.solid:hover,.btn.solid:focus-visible{background:var(--blue-deep);border-color:var(--blue-deep);}
.btn.disabled{opacity:.45;pointer-events:none;border-color:var(--hairline);color:var(--muted);}

/* pins (Leaflet divIcons) */
.spot-pin-wrap{background:none;border:none;}
.spot-pin{
  display:block;width:18px;height:18px;border-radius:50%;
  border:2.5px solid #F4EFE4;box-shadow:0 1px 4px rgba(28,40,54,.35);
}
.spot-pin.diamond{border-radius:2px;transform:rotate(45deg);}
/* Neighbourhood selection. NOTHING is ever dimmed: scrimming the unselected
   zones and fading their pins washed the whole map out (Samuel 2026-10-13).
   Selection is marked by ADDING a wider cream ring to the chosen
   neighbourhood's pins; the zone itself takes a 3px outline, set in JS. */
.leaflet-marker-icon.pin-sel .spot-pin{box-shadow:0 0 0 3px #F4EFE4,0 1px 5px rgba(28,40,54,.4);transition:box-shadow .15s;}
/* The zone polygons never paint a fill -- the artwork underneath paints them,
   and an unselected zone is completely invisible -- so the affordance has to
   come from the cursor and the focus ring rather than from paint. */
.leaflet-overlay-pane path.leaflet-interactive{cursor:pointer;}
/* The focus ring is keyboard-only, gated by html.kbd (localSpots.js tracks
   the last input). :focus-visible is not enough: Safari drew the ring after
   an ordinary click (Samuel 2026-10-14), and nothing is ever drawn on a zone
   for a tap or a click. */
.leaflet-overlay-pane path.leaflet-interactive:focus{outline:none;}
html.kbd .leaflet-overlay-pane path.leaflet-interactive:focus{outline:3px solid var(--blue);outline-offset:2px;}
@media (prefers-reduced-motion:reduce){ .leaflet-marker-icon.pin-sel .spot-pin{transition:none;} }
.leaflet-container{font-family:'Barlow',sans-serif;}
/* Kept for screen readers, taken out of the visual flow. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;}
/* The "All neighbourhoods" chip rides on the map. Bottom-left on phones (the
   zoom control is hidden there) and top-right on desktop: the corners that
   clear the title card, pins, street signs, zoom and the Leaflet credit. */
.map-host{position:relative;}
.nh-reset{position:absolute;z-index:500;left:12px;bottom:34px;min-height:44px;padding:8px 14px;
  border:1px solid var(--hairline);border-radius:999px;background:var(--paper);
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:13px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--ink);cursor:pointer;
  box-shadow:0 2px 8px rgba(28,40,54,.18);}
.nh-reset[hidden]{display:none;}
/* Greyed while nothing is picked (phones show the chip at all times). */
.nh-reset:disabled{opacity:.5;cursor:default;box-shadow:none;}
@media (min-width:901px){ .nh-reset{left:auto;right:14px;top:14px;bottom:auto;} }
/* Pins do nothing on phones (localSpots.js), so they should not advertise a tap. */
@media (max-width:900px){ .leaflet-marker-icon{cursor:default;} }
/* Phones: the map runs straight down to the first neighbourhood card, with
   no page padding between them and no padding inside the map either -- the
   DRAWING reaches the card (Samuel 2026-10-14; a cream band there, inside
   the map or outside it, reads as a gap). The "Leaflet | Map (c)" bar is
   hidden here too: Leaflet is BSD, the vendored file carries its notice, and
   the CityScape line is our own. */
@media (max-width:900px){
  #spots{padding-top:0;}
  #spots .spots-head{margin-bottom:0;}   /* the id: the 6px rule later in this file otherwise wins */
  #spotsList > .nh-group:first-child{margin-top:0;}
  .leaflet-control-attribution{display:none;}
}

/* neighbourhood zone labels (Leaflet permanent tooltips) */
.nh-label{
  background:none;border:none;box-shadow:none;pointer-events:none;   /* signs re-enable below */
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;
  letter-spacing:.08em;font-size:15px;opacity:.75;
  color:inherit;
}
.nh-label::before{display:none;} /* no tooltip arrow */
/* Signs are tap targets that select their neighbourhood (2026-10-14). The
   two-class selector outranks .nh-label's pointer-events:none above. */
.nh-sign.leaflet-interactive{pointer-events:auto;cursor:pointer;}
@media (max-width:560px){.nh-label{font-size:11px;letter-spacing:.05em;}}
/* Street-sign labels (2026-09-21): the play mat's neighbourhood signs, inline SVG. */
.nh-sign{opacity:1;padding:0;}
/* sign + post: the post is a thin line in the zone colour from the sign to
   the zone edge (Samuel's layout, 2026-09-21). .above = sign over the zone,
   post hangs down; .below = sign under the zone, post reaches up. */
.nh-sign .post-wrap{display:flex;flex-direction:column;align-items:center;}
.nh-sign .street-sign{display:block;width:var(--sign-w,250px);height:auto;} /* --sign-w set by scaleSigns() */
.nh-sign .street-sign text{font-weight:400;}
/* Subtle lift so the sign reads as standing off the surface rather than
   painted on it (Samuel 2026-09-23). The WHOLE svg casts it, plate included,
   so the shadow falls outside the white rectangle and gives that rectangle a
   visible edge. It needs one: the plate is #fafafa on --paper #FFFCF5 in the
   spots list, a 1.03:1 contrast ratio, so on its own it is imperceptible and
   the blade looks like it is floating on the card.
   Do NOT move this to `.street-sign path`. That shadows the blade ONTO the
   plate and takes away the plate's only boundary — tried 2026-09-23, and the
   white border looked deleted. A CSS filter on the <svg> element is in CSS px
   (not SVG user units), so the lift stays 2px at every --sign-w. */
.street-sign{filter:drop-shadow(0 2px 4px rgba(28,40,54,.28));}

/* legend */
.map-legend{display:flex;gap:18px;flex-wrap:wrap;justify-content:center;padding:16px 0 0;font-size:13.5px;}
/* legend block is centre-aligned under the map (Samuel 2026-09-21) */
.legend-status{text-align:center;margin-inline:auto;} /* p has a max-width measure; centre the box too */
.map-legend .key{display:flex;align-items:center;gap:7px;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--muted);}
.map-legend .dot{width:11px;height:11px;border-radius:50%;flex:none;}
.map-legend .dot.diamond{border-radius:2px;transform:rotate(45deg);}
.legend-status{font-size:13.5px;color:var(--ink);margin-top:8px;font-weight:500;}
/* The tap cue now lives in the locations header, not under the map (Samuel
   2026-10-13: no copy between the map and that section). Its old
   padding-bottom plus #spots' padding-top was the 64px blank band. */
.map-hint{font-size:13px;color:var(--muted);font-style:italic;margin:4px 0 0;}

/* ── Modal ────────────────────────────────────────────────── */
.modal-scrim{
  position:fixed;inset:0;z-index:1000;background:rgba(28,40,54,.8);
  display:none;align-items:center;justify-content:center;padding:24px;
}
.modal-scrim.show{display:flex;}
.venue-modal{
  background:var(--cream);border:1px solid var(--hairline);border-radius:2px;
  box-shadow:0 18px 50px rgba(0,0,0,.35);
  max-width:980px;width:100%;display:flex;gap:0;position:relative;max-height:90vh;overflow:auto;
}
.venue-modal .close{
  position:absolute;top:10px;right:12px;background:none;border:none;
  font-size:26px;line-height:1;color:var(--muted);cursor:pointer;font-family:'Barlow',sans-serif;
  z-index:1;
}
/* The card is the hero of this panel, so its SIZE is what gets specified and
   the modal width falls out of it — not the other way round. Driving the art
   off `width:38%` of a 520px modal rendered a 650x900 mock-up at about
   176x243: a thumbnail of a card Samuel had just re-drawn (2026-10-05).
   An explicit height also beats flex's default `stretch`, which was silently
   overriding `aspect-ratio` and making the box as tall as the info column. */
.venue-modal .art{
  flex:none;height:min(620px,72vh);width:auto;aspect-ratio:5/7;background:#EAE4D4;
  display:flex;align-items:center;justify-content:center;border-right:1px solid var(--hairline);
  position:relative;overflow:hidden;
}
/* A card is NEVER cropped, whichever source it came from. `cover` used to be
   the default and only the mock-ups opted out, so any location falling back
   to a flat front had its edges sliced off — 7 of 41 when Samuel caught it
   on Gatley (2026-09-23). */
.venue-modal .art img{width:100%;height:100%;object-fit:contain;padding:18px;box-sizing:border-box;display:block;}
.venue-modal .art.mockup{background:var(--cream);}
.venue-modal .art.placeholder::after{
  content:"card art coming soon";font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;
  letter-spacing:.1em;font-size:11px;color:#A99F8B;text-align:center;padding:0 12px;
}
/* Beside a 620px-tall card the copy is short enough to pool at the top and
   leave a dead half-column, so it rides the card's centre line instead. */
.venue-modal .info{padding:34px 32px;flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;}
/* Sign-blade variant: the pill's own chrome gets out of the way and the SVG
   carries the neighbourhood, drop shadow and all. */
.venue-modal .neigh-badge.sign{background:none;padding:0;border-radius:0;margin-bottom:12px;}
.venue-modal .neigh-badge.sign .street-sign{display:block;width:200px;height:auto;}
.venue-modal .neigh-badge{
  display:inline-block;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;text-transform:uppercase;
  letter-spacing:.06em;font-size:12px;color:#fff;padding:3px 10px;margin-bottom:10px;border-radius:2px;
}
.venue-modal h3{font-weight:700;font-size:32px;line-height:1.05;margin-bottom:6px;}
.venue-modal .type{font-size:14px;color:var(--muted);margin-bottom:16px;}
.venue-modal .desc{font-size:15px;line-height:1.5;color:var(--ink);padding-top:14px;border-top:1px solid var(--hairline);}
.venue-modal .desc p{margin-bottom:8px;}
.venue-modal .desc .hours{margin:0 0 10px;}
.venue-modal .desc .hours b{
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;
  letter-spacing:.1em;font-size:12px;color:var(--muted);display:block;margin-bottom:2px;
}
.venue-modal .desc .hours ul{list-style:none;margin:0;padding:0;font-size:14px;line-height:1.5;}
.venue-modal .desc .hours-note{font-size:12.5px;color:var(--muted);font-style:italic;margin:4px 0 0;}
.venue-modal .desc .addr a{color:var(--blue-deep);}
.venue-modal .desc .addr{color:var(--muted);font-size:14px;}
.venue-modal .desc .roam em{font-style:italic;color:var(--muted);font-size:14px;}
/* There was a `@media (max-width:520px)` block here. Every rule in it was
   overridden by the LATER, equal-specificity `max-width:900px` bottom-sheet
   block below (`max-width:none` beat its `max-width:340px`; the sheet's art
   height beat its `200px`), so it read as live phone styling while doing
   nothing. Removed 2026-10-05 — the sheet block is the only phone path. */

/* ── Sections (press rhythm; dividers are <hr class="rule">) ── */
section.block{padding-block:clamp(40px,5.5vw,64px);}
h2{font-weight:700;font-size:clamp(24px,3vw,32px);line-height:1.1;letter-spacing:.01em;margin-bottom:6px;text-wrap:balance;}
.sub{color:var(--muted);font-size:15px;margin-bottom:30px;}

/* ── Prize band: paper, constrained to .wrap width ────────── */
.prize-band{background:var(--paper);border-bottom:1px solid var(--hairline);padding:34px 0 40px;}
.prize-image{
  position:relative;height:clamp(220px,32vw,340px);
  background:var(--paper);overflow:hidden;margin-bottom:24px;
}
.prize-image img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;}
/* Investor-tier render in place (2026-09-20): copy left, the whole render right,
   nothing cropped. The render already sits on cream, so it reads as one band. */
.prize-image.has-photo{height:auto;display:block;}
/* title + subtitle left, body copy right, render below */
.prize-image.has-photo .prize-copy-overlay .in{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);
  column-gap:40px;align-items:start;margin-bottom:22px;
}
.prize-image.has-photo .prize-copy-overlay h2,
.prize-image.has-photo .prize-copy-overlay p.sub{grid-column:1;}
.prize-image.has-photo .prize-copy-overlay p:not(.sub){grid-column:2;grid-row:1 / span 2;max-width:none;}
@media (max-width:640px){
  .prize-image.has-photo .prize-copy-overlay .in{grid-template-columns:1fr;}
  .prize-image.has-photo .prize-copy-overlay p:not(.sub){grid-column:1;grid-row:auto;}
}
.prize-image.has-photo::before{content:none;}
.prize-image.has-photo .prize-copy-overlay{position:static;display:block;}
.prize-image.has-photo img{position:static;width:100%;height:auto;object-fit:contain;display:block;border-radius:3px;border:1px solid var(--hairline);}
.prize-copy-overlay{
  position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;z-index:1;
}
.prize-copy-overlay h2{margin-bottom:4px;}
.prize-copy-overlay p{max-width:46ch;font-size:15.5px;}
/* entry tiers (2026-09-22) */
.tiers-head{margin-top:44px;}
.tiers-head h3{font-size:clamp(22px,2.4vw,28px);font-weight:700;margin:0 0 6px;text-wrap:balance;}
.tiers-facts{margin:0 0 18px;max-width:none;white-space:nowrap;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;font-size:14px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
.tiers-facts b{color:var(--ink);font-weight:700;}
/* The ladder, drawn once (2026-09-23). Replaced three tier cards that each
   redrew every slot. 15 slots, which is the contest's top threshold and NOT
   the venue count: see the comment on .ladder-track in local-spots/index.html. */
/* .entry-terms has margin-top only and .ladder-track margin-bottom only, so the
   copy and the card strip were touching (measured 0px). 22px matches the track's
   own margin-bottom, so the strip sits with even space above and below it. On
   .ladder, not .ladder-track, so it cannot collapse through the first child. */
.ladder{margin-top:22px;}
.ladder-track{display:flex;gap:6px;margin:0 0 22px;}
.ladder-track i{position:relative;display:block;width:30px;height:42px;border-radius:2px;background:url(photos/cards/local-spots-back-tiny.webp) center/cover no-repeat;box-shadow:0 1px 2px rgba(28,40,54,.25);}
/* notch under the 5th, 10th and 15th: the three rungs below */
.ladder-track i.mark::after{content:"";position:absolute;left:0;right:0;bottom:-8px;height:2px;background:var(--gold);}
.rungs{list-style:none;margin:0;padding:0;display:grid;gap:16px;grid-template-columns:repeat(3,1fr);}
.rungs li{position:relative;border:1px solid var(--hairline);border-radius:4px;background:var(--paper);transition:border-color .15s;}
.rungs li button{display:block;width:100%;padding:14px 16px;font:inherit;color:inherit;text-align:left;background:none;border:0;cursor:pointer;}
.rungs li.hero{border:2px solid var(--gold);}
.rungs li em{position:absolute;top:-11px;left:14px;font-style:normal;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--blue-deep);background:var(--paper);padding:2px 8px;}
.rungs b{font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:22px;display:block;}
.rungs span{font-size:15px;color:var(--muted);}
.rungs li.hero span{color:var(--ink);}
/* The entry terms in full: the one paragraph that states the ladder, the
   meetup cards and the Instagram step together, so the contest never has to
   be reassembled from three places. Reads a step up from the keepsake note
   under it. */
.entry-terms{margin:18px 0 0;font-size:16px;line-height:1.55;color:var(--ink);max-width:none;}
.entry-terms strong{font-weight:600;white-space:nowrap;}
/* .entry-note shares the keepsake caption style rather than duplicating it.
   It needs its OWN class because querySelector('.keepsake') is how the smoke
   test reads the keepsake sentence, and two sentences on one class made that
   lookup ambiguous (caught by localSpotsSmoke, 2026-10-08). */
.keepsake,
.entry-note{margin:10px 0 0;font-size:14.5px;line-height:1.5;color:var(--muted);max-width:none;}
/* Phones: tap the Developer tier render for a bigger look (Samuel 2026-09-23).
   z 1400 sits above the phone venue sheet (1300); the two never open together
   but the ladder should stay unambiguous. The image is sized to the viewport
   HEIGHT and the body scrolls sideways — fitting the width would give ~344px,
   no better than the inline render, whereas fitting height is ~975px across on
   a 380x760 screen. The button wrapper is added by localSpots.js on phones
   only, so desktop markup is untouched. */
.prize-zoom{display:block;width:100%;padding:0;border:0;background:none;position:relative;cursor:zoom-in;}
.prize-zoom .chip{position:absolute;right:10px;bottom:10px;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:#fff;background:var(--blue);padding:8px 12px;border-radius:999px;box-shadow:0 2px 6px rgba(28,40,54,.25);}
.prize-lb{display:none;position:fixed;inset:0;z-index:1400;background:var(--cream);flex-direction:column;}
.prize-lb.open{display:flex;}
.prize-lb-bar{display:flex;align-items:center;justify-content:space-between;padding:0 8px 0 18px;height:52px;border-bottom:1px solid var(--hairline);background:var(--paper);}
.prize-lb-bar b{font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:18px;letter-spacing:.04em;}
.prize-lb-close{width:44px;height:44px;border:0;background:none;font-size:30px;line-height:1;color:var(--ink);cursor:pointer;}
.prize-lb-body{flex:1;min-height:0;overflow:auto;-webkit-overflow-scrolling:touch;display:flex;align-items:center;}
.prize-lb-body img{height:100%;width:auto;max-width:none;display:block;}
.prize-lb-hint{margin:0;padding:8px 18px;font-size:12.5px;color:var(--muted);font-style:italic;border-top:1px solid var(--hairline);background:var(--paper);}
/* Linking the track to the rungs (Samuel 2026-09-23). An intensity ramp down
   the ladder — muted, blue, then gold, which the hero rung already wears.
   The notches carry their rung's colour ALWAYS, so the connection reads
   before anyone touches anything; hovering, focusing or tapping a rung then
   lights the cards it takes. Cumulative: the 10 rung lights 1-10.
   opacity + box-shadow rather than this file's usual border-colour-only
   hover, because "dim the others" cannot be a border colour — but both are
   layout-neutral, so the track cannot wrap and the ladder cannot grow.
   .15s matches the file's other transitions and the prefers-reduced-motion
   blanket at the end of this file kills it for free. */
.ladder{--lit-1:var(--muted);--lit-2:var(--blue);--lit-top:var(--gold);}
/* Keyed by class, not position: the marked slots are the contest thresholds
   (3, 6, 9), so a class survives any change to the number of slots. */
.ladder-track i.m-3::after{background:var(--lit-1);}
.ladder-track i.m-6::after{background:var(--lit-2);}
.ladder-track i.m-top::after{background:var(--lit-top);}
.ladder-track i{transition:opacity .15s,box-shadow .15s;}
.ladder[data-lit] .ladder-track i{opacity:.3;}
.ladder[data-tier="1"]{--lit:var(--lit-1);}
.ladder[data-tier="2"]{--lit:var(--lit-2);}
.ladder[data-tier="top"]{--lit:var(--lit-top);}
.ladder[data-lit] .ladder-track i.lit{opacity:1;box-shadow:0 1px 2px rgba(28,40,54,.25),0 0 0 2px var(--lit);}
.ladder[data-tier="1"] .rungs li:nth-child(1),
.ladder[data-tier="2"] .rungs li:nth-child(2),
.ladder[data-tier="top"] .rungs li:last-child{border-color:var(--lit);}
.deadline{margin:22px 0 0;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:16px;letter-spacing:.02em;color:var(--ink);}
.condition{margin:4px 0 0;font-size:13.5px;line-height:1.45;color:var(--muted);max-width:none;}
/* fine print: the way promo sites do it. Tiny, muted, full width, one paragraph. */
.rules-note{margin:14px 0 0;font-size:11px;line-height:1.45;color:#8b8272;max-width:none;font-style:normal;}
.rules-note a{color:var(--blue-deep);font-weight:500;}
@media (max-width:640px){
  .tiers-facts{white-space:normal;line-height:1.5;}
  /* stacked: the count on the left, the reward on the right, one line a rung */
  .rungs{grid-template-columns:1fr;gap:8px;}
  .rungs li button{display:flex;align-items:baseline;justify-content:space-between;gap:12px;padding:12px 14px;}
  .rungs b{font-size:19px;}
  .rungs li em{top:-10px;}
}

/* ── Spotlights ───────────────────────────────────────────── */
.spotlight-grid{display:grid;gap:22px;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));margin-top:22px;}
.spotlight{border:1px solid var(--hairline);border-radius:2px;overflow:hidden;}
/* card-art tile: portrait 5:7, same crop treatment as the modal art */
.spotlight .card-art{aspect-ratio:5/7;background:#EAE4D4;position:relative;overflow:hidden;}
.spotlight .card-art.placeholder::after{
  content:"card art coming soon";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;letter-spacing:.1em;
  font-size:11px;color:#A99F8B;text-align:center;padding:0 14px;
}
/* same rule on the spotlight tiles: the whole card, never cropped */
.spotlight .card-art img{width:100%;height:100%;object-fit:contain;padding:4%;box-sizing:border-box;display:block;}
.card-art.mockup{background:transparent;}
.spotlight .body{padding:14px 16px 18px;}
.spotlight .badge{display:inline-block;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:11px;color:#fff;padding:2px 8px;margin-bottom:8px;border-radius:2px;}
.spotlight h4{font-weight:700;font-size:18px;margin-bottom:4px;}
.spotlight p{font-size:14px;color:var(--muted);line-height:1.4;}

/* ── How it works ─────────────────────────────────────────── */
.steps{list-style:none;counter-reset:step;display:grid;gap:0 32px;grid-template-columns:1fr 1fr;}
.steps li{
  position:relative;counter-increment:step;
  display:grid;grid-template-columns:160px 1fr;gap:16px;
  padding:16px 0;border-top:1px solid var(--hairline);
}
.steps li:nth-child(1),.steps li:nth-child(2){border-top:none;}
/* The numeral moved onto the photo (2026-09-23) — it used to own a 40px
   column, which the photo now needs. Keeping it large matters: in a 2x2 the
   numbers are the only thing saying whether to read across or down. */
.steps li::before{content:none;}
/* Photo slot, one per step. Empty until Samuel shoots them; the placeholder
   prints the shot brief from data-shot so the page states what belongs here.
   Same treatment as .spotlight .card-art.placeholder. */
/* align-self:start is belt-and-braces, not a fix for a live bug: .shot is a
   grid item of .steps li with no explicit alignment, and current browsers
   already let aspect-ratio win over the default `stretch`, so the slots
   measure 4/3 either way (verified 2026-10-04). It is here to state the
   intent, because the day someone sets align-items on .steps li the slots
   would otherwise grow to their own text column and photos would be cropped
   by how long the copy happens to be. localSpotsSmoke asserts the 4/3. */
.shot{
  position:relative;align-self:start;aspect-ratio:4/3;background:#EAE4D4;
  border:1px solid var(--hairline);border-radius:2px;overflow:hidden;
}
.shot img{width:100%;height:100%;object-fit:cover;display:block;}
/* the step number, sitting on the photo — the game's .turn-circle idiom
   (css/styles.css) in this page's palette. counter(step) is inherited from
   .steps, so it still reads the li's counter from in here. */
.shot::before{
  content:counter(step);position:absolute;top:8px;left:8px;z-index:1;
  width:30px;height:30px;border-radius:50%;
  background:var(--paper);border:2px solid var(--gold);color:var(--ink);
  display:flex;align-items:center;justify-content:center;
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:17px;
}
/* The brief clears the numeral: the badge is 30px at top:8px, and both this
   and ::before are absolutely positioned on the same box, so neither
   reserves space for the other. Without the top padding the badge sat on
   the brief's first line. */
.shot.placeholder::after{
  content:attr(data-shot);position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;text-align:center;
  padding:46px 12px 12px;
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;
  letter-spacing:.1em;font-size:11px;color:#A99F8B;line-height:1.35;
}
.steps h3{font-weight:700;font-size:18px;margin-bottom:2px;letter-spacing:.01em;}
.steps p{max-width:40ch;color:var(--ink);font-size:15px;line-height:1.45;}
@media (max-width:640px){
  .steps{grid-template-columns:1fr;}
  .steps li:nth-child(2){border-top:1px solid var(--hairline);}
  /* photo full width, but 16:9 not 4:3 — 4:3 full-bleed would add ~260px a
     step, and this section is already four screenfuls down. */
  .steps li{grid-template-columns:1fr;}
  .shot{aspect-ratio:16/9;}
}
.steps .fine{color:var(--muted);font-size:14px;margin-top:6px;}

/* press's .assets-note idiom: gold left rule, no tint fill */
.nudge{
  margin-top:8px;padding:2px 0 2px 18px;border-left:2px solid var(--gold);
  font-size:15px;max-width:62ch;
}
.nudge b{font-weight:600;}

/* ── Host a stand (venue-facing) ──────────────────────────── */
/* Two columns on desktop so four short paragraphs read in one glance;
   one column on narrow, same as .steps. */
.host-points{display:grid;gap:18px 32px;grid-template-columns:1fr 1fr;margin-bottom:26px;}
.host-points p{font-size:15px;line-height:1.5;max-width:46ch;}
.host-points b{font-weight:700;}
.host-points a,.nudge a{color:var(--blue-deep);text-decoration:underline;text-underline-offset:2px;}

/* ── Subscribe ────────────────────────────────────────────── */
.subscribe{display:flex;gap:24px;flex-wrap:wrap;align-items:flex-start;justify-content:space-between;}
.subscribe-copy{max-width:48ch;}
.subscribe-form{display:flex;gap:0;flex-wrap:wrap;min-width:280px;flex:1;max-width:380px;}
.subscribe-form input[type=email]{
  flex:1;min-width:180px;padding:12px 14px;border:1.5px solid var(--blue);border-right:none;
  border-radius:3px 0 0 3px;
  font-family:'Barlow',sans-serif;font-size:15px;background:var(--cream);color:var(--ink);
}
.subscribe-form input[type=email]:focus-visible{outline:none;background:var(--paper);}
.subscribe-form button{
  border:1.5px solid var(--blue);background:var(--blue);color:#fff;
  border-radius:0 3px 3px 0;
  font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;text-transform:uppercase;
  letter-spacing:.06em;font-size:15px;padding:0 20px;cursor:pointer;
  transition:background-color .15s;
}
.subscribe-form button:hover{background:var(--blue-deep);border-color:var(--blue-deep);}
.subscribe-done{
  border-left:2px solid var(--gold);
  padding:2px 0 2px 18px;font-size:15px;max-width:380px;flex:1;min-width:280px;
}

/* ── Checklist download ───────────────────────────────────── */
.checklist-box{
  display:flex;gap:18px;align-items:center;flex-wrap:wrap;justify-content:space-between;
  border:1px solid var(--hairline);border-radius:2px;padding:20px 24px;background:var(--paper);
}
.checklist-box .txt b{font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:18px;display:block;}
.checklist-box .txt span{font-size:14px;color:var(--muted);}

/* ── Mobile ───────────────────────────────────────────────── */
/* ── Phone layout (2026-09-22) ──────────────────────────────
   Under 900px the hero is the SAME composition as desktop: the live
   illustrated map with the title card floating over it, inset 18px so the
   drawing shows down both edges and below. compose(COMPOSE.phone) in
   localSpots.js frames the zones and derives the box height.
   Below that: a "See the spots" CTA, the spots as a list grouped by
   neighbourhood, pin details as a bottom sheet. (This replaced the flat
   map still, the full-screen map sheet and the List|Map toggle.) */
.phone-only{display:none;}
@media (max-width:900px){
  .phone-only{display:block;}
  .desk-only{display:none !important;}
  /* The card stays position:absolute (the base rule) and floats over the
     map, as on desktop — only the framing constants differ. Opaque, not
     the desktop 94%: ~280px of body copy over a line drawing needs it. */
  .hero-title{padding:18px 0 0;}
  .hero-title .in{max-width:none;padding:0 18px;}
  .hero-title .scrim{display:block;max-width:none;padding:18px 18px 20px;background:var(--cream);}
  .hero-title h1{max-width:none;}
  .hero-title h1 em{display:inline;}
  .hero-title .live-count{margin:12px 0 0;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:600;font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);}
  .hero-title .cta-row{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px;}
  .hero-title .cta-row .btn{display:inline-block;}
  .hero-title .btn.ghost{background:transparent;color:var(--blue-deep);border:1.5px solid var(--hairline);}
  #spotsMap{height:78vh;}                       /* pre-compose box; compose() writes an inline height */
  .hero .map-legend,.hero .legend-status{display:none;}
  /* Finger-sized pins. !important is required: Leaflet writes width, height
     and margin inline from iconSize/iconAnchor. A 44px hit area around a
     small dot, so the Downtown cluster still reads as separate pins. */
  .spot-pin-wrap{width:44px !important;height:44px !important;margin-left:-22px !important;margin-top:-22px !important;display:flex;align-items:center;justify-content:center;}
  .spot-pin{width:20px;height:20px;}
  /* A composed picture, not a pannable map: dragging is already off on
     touch, so a zoom-in would strand the view. compose() disables pinch
     and double-tap zoom to match. */
  .leaflet-control-zoom{display:none;}

  /* spots list */
  .spots-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:6px;}
  .spots-head h2{margin:0;}
  .spots-head .sub{margin:2px 0 0;font-size:14px;}
  .nh-group{margin-top:10px;border:1px solid var(--hairline);border-radius:8px;background:var(--paper);}
  /* The group header was a <summary>; it is now a <button> that selects the
     neighbourhood (2026-10-12). Same box, same sign, same count: only the
     chevron is gone, because there is nothing left to expand. */
  .nh-group .nh-head{list-style:none;display:flex;align-items:center;gap:10px;min-height:60px;width:100%;padding:8px 12px 8px 10px;cursor:pointer;background:none;border:0;border-bottom:1px solid var(--hairline);font:inherit;color:inherit;text-align:left;}
  .nh-group .nh-head .street-sign{width:160px;height:auto;flex:none;}
  .nh-group .nh-head .count{margin-left:auto;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);white-space:nowrap;}
  .nh-group .spot-row{margin:8px 8px 0;width:calc(100% - 16px);}
  .nh-group .spot-row:last-child{margin-bottom:8px;}
  .spot-row{display:grid;grid-template-columns:44px 1fr;gap:12px;align-items:center;width:100%;min-height:68px;padding:8px 10px 8px 8px;margin:0 0 6px;border:1px solid var(--hairline);border-radius:6px;background:var(--paper);text-align:left;cursor:pointer;font:inherit;color:inherit;}
  .spot-row .thumb{width:44px;height:62px;border-radius:3px;background:#EAE4D4 center/cover no-repeat;}
  .spot-row .thumb.mockup{background-size:contain;background-color:transparent;}
  .spot-row b{display:block;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:18px;line-height:1.1;}
  .spot-row small{display:block;font-size:13px;color:var(--muted);margin-top:3px;}
  /* The row a pin just pointed at. */
  .spot-row.hit{border-color:var(--blue);box-shadow:0 0 0 2px rgba(27,111,200,.25);}
  .nh-group.sel{border-color:var(--blue);}

  /* fine print collapses; host section collapses */
  .fine summary{list-style:none;cursor:pointer;font-family:'Barlow Condensed','Barlow',sans-serif;font-weight:700;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--blue-deep);margin-top:14px;}
  .fine summary::-webkit-details-marker{display:none;}
  .fine summary::after{content:" +";}
  .fine[open] summary::after{content:" \2013";}
  .host-body.collapsed{max-height:210px;overflow:hidden;position:relative;}
  .host-body.collapsed::after{content:"";position:absolute;left:0;right:0;bottom:0;height:80px;background:linear-gradient(rgba(244,239,228,0),var(--cream));}
  .host-more{margin-top:8px;background:none;border:0;padding:0;color:var(--blue-deep);font:600 15px 'Barlow',sans-serif;border-bottom:1px solid var(--hairline);cursor:pointer;}

  /* spotlight row: peek-scroll */
  .spotlight-grid{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;padding:4px 18px 8px;margin:0 -18px;-webkit-overflow-scrolling:touch;}
  .spotlight-grid .spotlight{flex:0 0 72vw;scroll-snap-align:start;}

  /* venue modal = bottom sheet */
  .modal-scrim{align-items:flex-end;padding:0;z-index:1300;}
  .venue-modal{max-width:none;max-height:82vh;border-radius:14px 14px 0 0;flex-direction:column;animation:sheetUp .22s ease-out;}
  /* Height-capped at 210px, a 5:7 card came out ~150px wide in a 390px sheet.
     The element stays full-width so the hairline still spans the sheet — the
     gutters either side of the card are cream on cream, so they read as air. */
  .venue-modal .art{width:100%;aspect-ratio:auto;height:min(42vh,320px);border-right:none;border-bottom:1px solid var(--hairline);}
  .venue-modal .art img{object-fit:contain;}
  /* The sheet scrolls, so the copy starts at the top here — centring it is a
     desktop move, where the card fixes the panel's height. */
  .venue-modal .info{justify-content:flex-start;}
  @keyframes sheetUp{from{transform:translateY(24px);opacity:.6}to{transform:none;opacity:1}}
}
@media (min-width:901px){ .fine summary{display:none;} .fine{display:block;} }
.fine{margin:0;} .fine .rules-note{margin-top:8px;}

@media (max-width:560px){
  /* The track is 15 slots now (the contest's top threshold), not the venue
     count: 16x15 + 3x14 = 282px, inside the 324px of content a 360px
     viewport gives. Resize these two together if the threshold ever moves. */
  .ladder-track{gap:3px;}
  .ladder-track i{width:16px;height:23px;}
  .ladder-track i.mark::after{bottom:-6px;}
  .ladder[data-lit] .ladder-track i{box-shadow:0 1px 2px rgba(28,40,54,.25);}
  .ladder[data-lit] .ladder-track i.lit{box-shadow:0 1px 2px rgba(28,40,54,.25),0 0 0 1.5px var(--lit);}
  body{font-size:16px;}
  .wrap{padding:0 18px;}
  .hero-title{padding-top:16px;}
  .hero-title .in{padding:0 16px;}
  .hero-title .scrim{padding:16px 16px 18px;max-width:100%;}
  h1{font-size:29px;}
  .lede{font-size:14.5px;}
  .btn{font-size:15px;padding:11px 20px;}
  .prize-copy-overlay p{font-size:14px;}
  /* portrait card tiles go two-up on phones, not a 4-tall stack */
  .spotlight-grid{grid-template-columns:1fr 1fr;gap:14px;}
  .host-points{grid-template-columns:1fr;gap:14px;}
}

@media (prefers-reduced-motion:reduce){*{transition:none!important;}html{scroll-behavior:auto;}}
