/* The Love Faery — Listeners World Map + Love Wall. Self-contained page
   stylesheet, external file only (no inline <style>/style="" beyond the
   one hero-simple ambience block this page shares byte-for-byte with
   every other inner page — its hash is already in the site-wide CSP, see
   site/_headers). Loaded AFTER the shared assets/css/site.*.css so this
   file only adds what site.css does not already define (map, markers,
   love wall, geo directory, consent form) — no duplicated tokens except
   the two accent colors below, which intentionally use the brighter
   brand-refresh values (--wm-gold/--wm-teal) already live on /portal/,
   not yet promoted into the shared --gold/--teal tokens in site.css. */

:root{
  --wm-nightfall:#131E3C; --wm-nightdeep:#0B1329;
  --wm-gold:#c79a63; --wm-teal:#7fbcb6;
  --wm-rose:#E98DA8;
  --wm-line:rgba(248,245,238,.16);
  --wm-star:#F8F5EE;
  --wm-dur-mosaic:1.2s;
}

/* ── Sample-data disclosure — required, always visible, never hidden
   behind a hover or a tooltip. Every place real-looking numbers appear
   on this page sits inside a section carrying this banner above it. ── */
.wm-sample{
  display:inline-flex;align-items:center;gap:.4rem;
  background:rgba(199,154,99,.14);border:1px solid rgba(199,154,99,.55);
  color:var(--wm-gold);font-size:.72rem;font-weight:700;letter-spacing:.06em;
  text-transform:uppercase;border-radius:999px;padding:.3rem .75rem;margin:0 0 1rem;
}
.wm-sample-note{font-size:.85rem;color:var(--soft, #5A514C);margin:.3rem 0 1.2rem;max-width:38rem}
.wm-sample-note code{overflow-wrap:anywhere;display:block;margin:.25rem 0}

.wm-proto-banner{padding:0 1.1rem;margin-top:1.6rem}
.wm-sample-inline{margin:0 0 0 .4rem}
.fw-normal{font-weight:400}

/* ── Real headline stat -- distinct treatment from .wm-sample so a reader
   never confuses the one real number on this page (154 countries, from
   Tatiana's Spotify for Artists dashboard) with the sample-flagged
   per-country data right below it. ── */
.wm-stat-real{font-size:1.15rem;font-weight:700;margin:0 0 .5rem;color:var(--ink,#1B1512)}
.wm-stat-source{font-size:.8rem;font-weight:400;color:var(--faint,#6E655F);display:inline-block;margin-left:.3rem}

/* ── Map card — a dark night-garden panel inside the light page body,
   same "dark accent panel on a light page" pattern the hero/footer
   already use, chosen because glowing markers need real contrast to
   read at a glance. ───────────────────────────────────────────────── */
.map-section{padding:2.6rem 1.1rem 3rem}
.map-card{
  position:relative;max-width:64rem;margin:0 auto;border-radius:1.4rem;overflow:hidden;
  background:radial-gradient(130% 100% at 50% 0%, var(--wm-nightfall) 0%, var(--wm-nightdeep) 100%);
  border:1px solid var(--wm-line);
  box-shadow:0 30px 70px -40px rgba(0,0,0,.6);
  padding:1.4rem 1.1rem 1.6rem;
}
.map-card .stars i{position:absolute;width:2px;height:2px;border-radius:50%;background:var(--wm-star);
  opacity:.6;animation:wm-tw 5s ease-in-out infinite}
/* 8 fixed star positions — no inline style= per marker (CSP style-src-attr
   stays clean); matches the same nth-child convention site.css already uses
   for .hero-simple .stars. */
.map-card .stars i:nth-child(1){left:6%;top:12%}
.map-card .stars i:nth-child(2){left:18%;top:22%}
.map-card .stars i:nth-child(3){left:34%;top:8%}
.map-card .stars i:nth-child(4){left:52%;top:16%}
.map-card .stars i:nth-child(5){left:71%;top:10%}
.map-card .stars i:nth-child(6){left:86%;top:20%}
.map-card .stars i:nth-child(7){left:94%;top:34%}
.map-card .stars i:nth-child(8){left:12%;top:40%}
@keyframes wm-tw{0%,100%{opacity:.15}50%{opacity:.8}}
.map-frame{position:relative;width:100%;line-height:0}
/* The real painted atlas is the map now -- a normal responsive <picture>
   (real srcset/sizes, width/height set, LQIP shown as its own background
   until the WebP decodes) sits in-flow to establish the frame's aspect
   ratio; the SVG is an absolutely-positioned, same-size transparent overlay
   that carries only the interactive marker layer (no continent fills to
   maintain here any more -- see the calibration notes in
   platform/world-and-label-brand-plan.md for how markers are aligned to it). */
.map-art{display:block;width:100%}
.map-art-img{display:block;width:100%;height:auto;background-size:cover;background-position:center}
.worldmap{position:absolute;inset:0;display:block;width:100%;height:100%;overflow:visible}

/* Country markers — small "path" glyphs (not filled political borders,
   see the on-page note about why), positioned at each country's
   approximate centroid. Base marker = dim/no data; .has-data scales up
   (baked in at generation time from listener count) and glows gold;
   .is-top additionally gets the rose accent + a butterfly landing ring. */
/* Markers now sit on top of a busy, full-color painted atlas (not a flat
   dark background), so each one gets a soft dark halo (drop-shadow, GPU-
   cheap) purely for legibility -- reads the same over white ice, tan
   desert, or green forest without needing a per-region color override. */
.cmarker{cursor:pointer;filter:drop-shadow(0 0 2px rgba(10,14,28,.75)) drop-shadow(0 0 5px rgba(10,14,28,.45))}
/* Each marker is 3 <use> children in a fixed order (hit / glow / dot) --
   targeted by position, not a repeated class="" on all 194x3 elements
   (Gate B HTML-budget discipline; see world-map-calibration.md). The
   1st <use> is an invisible, larger-than-the-glyph tap target (Gate 17
   44x44px) that does not change the glow/dot's own visual size. */
.cmarker use:first-of-type{pointer-events:all}
.cmarker use:nth-of-type(2){fill:rgba(199,154,99,.22);transition:fill .2s ease}
.cmarker use:nth-of-type(3){fill:rgba(248,245,238,.55);transition:fill .2s ease, transform .2s ease}
.cmarker.has-data use:nth-of-type(2){fill:rgba(199,154,99,.32)}
.cmarker.has-data use:nth-of-type(3){fill:var(--wm-gold)}
.cmarker.is-top use:nth-of-type(2){fill:rgba(233,141,168,.4)}
.cmarker.is-top use:nth-of-type(3){fill:var(--wm-rose)}
.cmarker:hover use:nth-of-type(3),.cmarker:focus-visible use:nth-of-type(3){transform:scale(1.35)}
.cmarker:hover use:nth-of-type(2),.cmarker:focus-visible use:nth-of-type(2){fill:rgba(199,154,99,.55)}
.cmarker:focus-visible{outline:none}
.cmarker.is-active use:nth-of-type(3){transform:scale(1.5)}
.cmarker.is-active use:nth-of-type(2){fill:rgba(233,141,168,.6)}

/* JS-populated detail-panel CTA — classes instead of inline style="" so a
   runtime innerHTML write never needs a CSP style-src-attr hash. */
.wm-detail-cta{margin-top:.7rem}
.wm-detail-btn{border-color:rgba(248,245,238,.4);color:var(--wm-star,#F8F5EE)}

/* Landing rings pulse softly on the top-3 countries — pure CSS,
   transform/opacity only, paused under reduced-motion below. */
.cmarker.is-top use:nth-of-type(2){animation:wm-pulse 3.2s ease-in-out infinite}
@keyframes wm-pulse{0%,100%{opacity:.75}50%{opacity:1}}

/* A much fainter breathing glow on every OTHER listener country (not just
   the top 3) so the whole continent-set reads as quietly alive, not just
   the 3 loudest markers. Same transform/opacity-only pattern; nth-of-type
   buckets (position among all 194 sibling <g> marker elements) stand in
   for a per-marker delay without an inline style="" (CSP style-src-attr
   stays clean — see the .stars comment above for the same convention). */
.cmarker.has-data:not(.is-top) use:nth-of-type(2){animation:wm-pulse-soft 4.8s ease-in-out infinite}
.cmarker.has-data:not(.is-top):nth-of-type(3n){animation-delay:.6s}
.cmarker.has-data:not(.is-top):nth-of-type(3n+1){animation-delay:1.8s}
.cmarker.has-data:not(.is-top):nth-of-type(3n+2){animation-delay:3s}
@keyframes wm-pulse-soft{0%,100%{opacity:.6}50%{opacity:.85}}

/* ── Aurora — a soft drifting color band top (far north) and bottom
   (Antarctica), reinforcing what the artwork already paints there.
   screen blend + blur keeps it a glow, never a hard-edged bar. ────── */
.wm-aurora{position:absolute;left:0;right:0;pointer-events:none;
  mix-blend-mode:screen;filter:blur(3px);will-change:opacity,transform}
.wm-aurora-n{top:0;height:16%;
  background:linear-gradient(100deg,transparent 0%,rgba(127,188,182,.5) 30%,rgba(199,154,99,.35) 55%,transparent 85%);
  animation:wm-aurora-drift 24s ease-in-out infinite}
.wm-aurora-s{bottom:0;height:12%;
  background:linear-gradient(260deg,transparent 0%,rgba(127,188,182,.4) 35%,rgba(233,141,168,.25) 60%,transparent 90%);
  animation:wm-aurora-drift 30s ease-in-out infinite reverse}
@keyframes wm-aurora-drift{0%,100%{opacity:.35;transform:translateX(-2%)}50%{opacity:.65;transform:translateX(2%)}}

/* ── Lanterns — a handful of tiny warm firefly twinkles scattered on the
   landmasses (percent-positioned by hand, same nth-child convention as
   the card's ambient .stars). Barely-there: the painting should feel
   awake, not busy. ─────────────────────────────────────────────────── */
.wm-lanterns{position:absolute;inset:0;pointer-events:none}
.wm-lanterns i{position:absolute;width:3px;height:3px;border-radius:50%;background:var(--wm-gold);
  box-shadow:0 0 6px 2px rgba(199,154,99,.7);opacity:.2;animation:wm-lantern 4.4s ease-in-out infinite}
.wm-lanterns i:nth-child(1){left:20%;top:56%;animation-delay:.2s}
.wm-lanterns i:nth-child(2){left:34%;top:71%;animation-delay:1.6s}
.wm-lanterns i:nth-child(3){left:53%;top:38%;animation-delay:2.8s}
.wm-lanterns i:nth-child(4){left:62%;top:52%;animation-delay:.9s}
.wm-lanterns i:nth-child(5){left:73%;top:34%;animation-delay:3.4s}
.wm-lanterns i:nth-child(6){left:82%;top:60%;animation-delay:2.1s}
@keyframes wm-lantern{0%,100%{opacity:.12;transform:scale(.8)}50%{opacity:.7;transform:scale(1.3)}}

/* ── Motion canvas — one shared layer world.js draws BOTH the ocean-
   current star particles and the flying/landing butterflies into (one
   <canvas>, one requestAnimationFrame loop — see world.js). Sits above
   the SVG markers for the "butterfly lands on a glowing point" look but
   pointer-events:none keeps every marker/keyboard interaction working
   exactly as before. Empty (nothing drawn) with JS off or under
   reduced-motion — see world.js's guard clause. */
.wm-motion-canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}

/* Single class world.js toggles on .map-card to pause every CSS-driven
   loop below when the map scrolls off-screen or the tab is hidden — the
   canvas layer pauses itself (it stops calling requestAnimationFrame). */
.map-card.wm-paused .stars i,.map-card.wm-paused .wm-aurora,
.map-card.wm-paused .wm-lanterns i,.map-card.wm-paused .cmarker.is-top use:nth-of-type(2),
.map-card.wm-paused .cmarker.has-data use:nth-of-type(2){animation-play-state:paused}


/* ── Detail panel — always in-flow (not a floating hover tooltip), so
   touch devices get the exact same interaction as a mouse: tap a
   marker or a flag row, the panel below updates and receives focus. ── */
.map-detail{margin-top:1.1rem;padding:1rem 1.1rem;border-radius:.9rem;
  background:rgba(248,245,238,.06);border:1px solid var(--wm-line);color:var(--wm-star);min-height:4.5rem}
.map-detail[hidden]{display:none}
.map-detail h3{margin:0 0 .3rem;font-size:1.15rem;color:var(--wm-star)}
.map-detail .md-count{color:var(--wm-gold);font-weight:700}
.map-detail .md-cities{margin:.4rem 0 0;font-size:.88rem;color:rgba(248,245,238,.75)}
.map-detail .md-loves{margin:.6rem 0 0;display:grid;gap:.4rem}
.map-detail .md-love{font-size:.85rem;color:rgba(248,245,238,.88);padding:.4rem .6rem;
  border-left:2px solid var(--wm-teal);background:rgba(127,188,182,.08);border-radius:0 .5rem .5rem 0}
.map-detail .md-empty{font-size:.9rem;color:rgba(248,245,238,.65)}
.map-hint{margin:.7rem 0 0;font-size:.78rem;color:rgba(248,245,238,.55);text-align:center}

/* ── Love Wall — a mosaic of small cards, gentle stagger-fade-in,
   pointer-events kept on (fans can tap a card to jump the map to that
   country). One flexible grid, no library. ─────────────────────────── */
.wall-section{padding:0 1.1rem 3rem}
.wall-grid{max-width:64rem;margin:1.2rem auto 0;display:grid;gap:.85rem;
  grid-template-columns:repeat(auto-fill,minmax(15.5rem,1fr))}
.wall-card{background:var(--card,#fff);border:1px solid var(--line,rgba(27,21,18,.12));
  border-radius:.9rem;padding:.9rem 1rem;box-shadow:var(--shadow,0 1px 2px rgba(0,0,0,.05));
  opacity:0;transform:translateY(8px);animation:wm-in var(--wm-dur-mosaic) ease forwards}
/* Stagger via nth-child instead of a per-card inline animation-delay — same
   CSP reasoning as the stars above. 10 cards is the current sample count;
   a future real feed can grow past 10 without a broken stagger (any card
   past 10 just shares the last delay, a harmless degrade). */
.wall-card:nth-child(1){animation-delay:0s}
.wall-card:nth-child(2){animation-delay:.08s}
.wall-card:nth-child(3){animation-delay:.16s}
.wall-card:nth-child(4){animation-delay:.24s}
.wall-card:nth-child(5){animation-delay:.32s}
.wall-card:nth-child(6){animation-delay:.4s}
.wall-card:nth-child(7){animation-delay:.48s}
.wall-card:nth-child(8){animation-delay:.56s}
.wall-card:nth-child(9){animation-delay:.64s}
.wall-card:nth-child(n+10){animation-delay:.72s}
@keyframes wm-in{to{opacity:1;transform:none}}
.wall-card .wc-top{display:flex;align-items:center;gap:.4rem;font-weight:600}
.wall-card .wc-emoji{font-size:1.1rem}
.wall-card .wc-loc{font-size:.78rem;color:var(--faint,#6E655F);margin:.15rem 0 .4rem}
.wall-card .wc-msg{margin:0;font-size:.92rem;line-height:1.5}
.wall-card button{margin-top:.6rem;background:none;border:0;color:var(--wm-teal,#3C8C86);
  font-size:.78rem;font-weight:600;cursor:pointer;text-decoration:underline;
  display:inline-flex;align-items:center;min-height:44px;min-width:44px;padding:0}

/* ── Send-love form ────────────────────────────────────────────────── */
.love-form-section{padding:0 1.1rem 3rem}
.love-form-card{max-width:32rem;margin:1.2rem auto 0;background:var(--card,#fff);
  border:1px solid var(--line,rgba(27,21,18,.12));border-radius:1rem;padding:1.3rem 1.3rem 1.5rem;
  box-shadow:var(--shadow,0 1px 2px rgba(0,0,0,.05))}
.love-form-card h2{margin-top:0;font-size:1.25rem}
.love-form-card label{display:block;font-size:.85rem;font-weight:600;margin:.8rem 0 .3rem}
.love-form-card input[type="text"],.love-form-card input[type="email"],.love-form-card textarea{
  width:100%;box-sizing:border-box;font:inherit;padding:.6rem .7rem;border-radius:.5rem;
  border:1px solid var(--line,rgba(27,21,18,.2));background:var(--paper,#FCF8F4)}
/* Email only appears once "join the Circle" is ticked (progressive
   disclosure -- the common case never sees an email field at all). */
.love-email-wrap{margin-top:.6rem}
.love-email-wrap[hidden]{display:none}
.love-email-label{margin:0 0 .3rem}
.love-form-card textarea{resize:vertical;min-height:4rem}
.love-emoji-row{display:flex;gap:.4rem;margin-top:.3rem}
.love-emoji-row button{font-size:1.2rem;border-radius:.6rem;border:1px solid var(--line,rgba(27,21,18,.15));
  background:var(--paper,#FCF8F4);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;
  min-height:44px;min-width:44px;padding:0}
.love-emoji-row button[aria-pressed="true"]{border-color:var(--wm-gold);background:rgba(199,154,99,.14)}
.love-charcount{font-size:.75rem;color:var(--faint,#6E655F);text-align:right;margin-top:.2rem}
.love-consent{font-size:.78rem;color:var(--faint,#6E655F);margin-top:.9rem;line-height:1.5}
.love-consent label{display:flex;align-items:flex-start;gap:.5rem;font-weight:400;font-size:.82rem;margin-top:.5rem}
.love-consent input[type="checkbox"]{margin-top:.2rem}
/* Turnstile (invisible/managed appearance="interaction-only" -- most real
   visitors never see anything render here at all; the reserved height only
   matters on the rare challenge). Empty when unconfigured (no script loaded,
   see world.js), so this rule is inert until Caleb sets a real site key. */
.cf-turnstile{margin-top:1rem;min-height:0}
.love-form-card .btn-primary{margin-top:1rem;width:100%}
.love-form-subtext{font-size:.85rem;color:var(--faint,#6E655F)}
.love-form-status{margin-top:.7rem;font-size:.85rem}
.love-form-status[data-state="error"]{color:var(--throat,#B0154A)}
.love-form-status[data-state="ok"]{color:var(--leaf,#3C5E33)}
.love-form-status[data-state="wait"]{color:var(--faint,#6E655F)}

/* ── Geo directory — the top {has-data} countries ship server-rendered
   (real, crawlable, works with zero JS); "Show all 194 countries" lazily
   fetches + renders the rest, grouped by region, client-side (world.js's
   renderGeoAll) -- see platform/page-scorecard.md's HTML-budget note.
   .geo-count uses fixed, page-scoped colors (not the shared --faint
   token) tuned with real margin above the 4.5:1 floor in BOTH color
   schemes -- the shared token's dark-mode pairing measured a borderline
   ~4.3-4.7:1 here depending on sampling, this is a deliberately safer one. */
.geo-section{padding:0 1.1rem 3.5rem}
.geo-directory{max-width:52rem;margin:0 auto}
.geo-region{margin:0 0 .6rem;border:1px solid var(--line,rgba(27,21,18,.12));
  border-radius:.8rem;padding:.2rem .9rem;background:var(--card,#fff)}
.geo-region h3{font-size:.95rem;padding:.7rem 0;margin:0}
.geo-region-count{font-weight:400;color:var(--faint,#6E655F);margin-left:.4rem}
.geo-list{list-style:none;margin:0;padding:0 0 .6rem;display:grid;gap:.35rem}
.geo-list-top{padding:.2rem .9rem .6rem;border:1px solid var(--line,rgba(27,21,18,.12));
  border-radius:.8rem;background:var(--card,#fff);margin:0 0 1rem}
.geo-item{display:flex;flex-wrap:wrap;align-items:center;gap:.45rem;font-size:.88rem;
  padding:.35rem 0;border-top:1px solid var(--line,rgba(27,21,18,.08))}
.geo-item:first-child{border-top:0}
.geo-flag{font-size:1.05rem}
.geo-name{font-weight:600;min-width:9rem}
.geo-count{font-size:.78rem;color:#5A4F47}
.geo-count-empty{font-style:italic}
.geo-sample-tag{font-size:.62rem;font-weight:700;color:var(--wm-gold, #a07843);margin-left:.25rem}
.geo-send{margin-left:auto;font-size:.75rem;font-weight:600;color:var(--wm-teal,#3C8C86);
  background:none;border:1px solid var(--line,rgba(27,21,18,.2));border-radius:999px;
  padding:.28rem .7rem;cursor:pointer;display:inline-flex;align-items:center;min-height:44px}
.geo-send:hover{border-color:var(--wm-teal,#3C8C86)}
.geo-showall{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  margin:.4rem 0 1rem;padding:.5rem 1.1rem;font-size:.85rem;font-weight:600;cursor:pointer;
  color:var(--wm-teal,#3C8C86);background:none;border:1px solid var(--line,rgba(27,21,18,.2));
  border-radius:999px}
.geo-showall:hover{border-color:var(--wm-teal,#3C8C86)}
.geo-all[hidden]{display:none}
.geo-noscript-note{font-size:.85rem;color:var(--faint,#6E655F);max-width:38rem;margin:0 auto}
@media(prefers-color-scheme:dark){
  .geo-count{color:#ADA296}
}

/* ── Motion + contrast safety ─────────────────────────────────────── */
@media(prefers-reduced-motion:reduce){
  .map-card .stars i,.cmarker.is-top use:nth-of-type(2),.cmarker.has-data use:nth-of-type(2),
  .wall-card{animation:none !important;opacity:1 !important;transform:none !important}
  .wm-aurora{animation:none !important;opacity:.45 !important;transform:none !important}
  .wm-lanterns i{animation:none !important;opacity:.4 !important;transform:none !important}
  /* world.js itself already refuses to build the star/butterfly canvas
     under reduced-motion (its very first check) — this is belt-and-
     suspenders for the JS-disabled/race case: an empty canvas either way. */
  .wm-motion-canvas{display:none}
}

@media(max-width:640px){
  .geo-name{min-width:0}
  .geo-send{margin-left:0;flex-basis:100%}
  .wall-grid{grid-template-columns:1fr}
}
