/* warmpaths.css — the Warm Paths landing page's own design (Commit 1 of DISPATCH-2026-09-20-warmpaths-landing).
   Built to wiki/audits/warmpaths-landing-mock.html; every value below is the mock's.

   ⛔⛔ EVERY RULE IS SCOPED UNDER `.wp`, AND THE MOCK'S WERE NOT. The mock is a standalone document, so it
   styles `body`, `nav`, `section`, `footer`, `h1`–`h4` and `a` bare. This page also loads `/styles.css`,
   which owns the SIGNUP MODAL — and the modal is what makes the Join button work. Pasting bare selectors
   in would restyle the modal's own nav/links/headings out from under it.
   ⭐ So the page content lives in `<div class="wp">` and the modal stays OUTSIDE it. Nothing here can reach
   the modal, and `styles.css` keeps it exactly as every other page has it.

   ⛔ AND THE TOKENS ARE RENAMED `--wp-*`. The mock declares `--bg`, `--ink`, `--line`, `--terra` … on
   `:root`, and `styles.css` declares its own palette there. A shared name would have this page silently
   repaint the modal, the footer and anything else loaded beside it — a collision with no error.

   ⚠ FONTS: the mock asks for Fraunces + JetBrains Mono, which the rest of the marketing site does not
   load. They are requested in the page head for THIS page only. Inter is already site-wide. */

.wp {
  --wp-bg:#f6f4ef; --wp-bg2:#efebe3; --wp-card:#fff; --wp-ink:#231e1a; --wp-ink2:#4a423b;
  --wp-muted:#7a716a; --wp-line:#e3ddd2; --wp-terra:#c4623a; --wp-terra-dk:#a44e2c; --wp-terra-lt:#f6e3da;
  --wp-sage:#dfe6d2; --wp-sage-ink:#48553a; --wp-gold:#f1e6cf; --wp-gold-ink:#6b4f1d;
  --wp-night:#1c1815; --wp-night2:#26211d;
  background:var(--wp-bg); color:var(--wp-ink);
  font:16px/1.55 Inter,system-ui,sans-serif; -webkit-font-smoothing:antialiased;
}
.wp *{box-sizing:border-box}
.wp a{color:inherit}
/* ⛔⛔ `color:inherit` IS LOAD-BEARING AND IT IS THE FIX FOR THE DARK SECTION'S BLACK HEADLINE.
   `/styles.css` declares `h1, h2, h3 { color: var(--text-primary) }` — and a DECLARED value beats an
   INHERITED one no matter the specificity, so `.wp .dark { color:#f2ede6 }` could never reach its own h2.
   ⭐ Fixed as a CLASS, not as the one instance: every heading now takes its section's colour, so a light
   section gets --wp-ink from `.wp` and a dark one gets its cream, with no per-section override to forget.
   ⚠ `h4` was never in that global rule, which is why the dark rule list looked right while the headline
   above it did not — the same bug, invisible on three of four elements. */
.wp h1,.wp h2,.wp h3,.wp h4{font-family:Fraunces,Georgia,serif;font-weight:600;letter-spacing:-.012em;margin:0;color:inherit}
.wp .wrap{max-width:1140px;margin:0 auto;padding:0 24px}
.wp .mono{font:500 11px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.18em;text-transform:uppercase;color:var(--wp-terra)}
.wp .btn{display:inline-flex;align-items:center;gap:8px;background:var(--wp-ink);color:#fff;font-weight:600;padding:14px 22px;border-radius:12px;text-decoration:none;transition:transform .15s,background .15s;white-space:nowrap}
.wp .btn:hover{background:#000;transform:translateY(-1px)}
.wp .btn.terra{background:var(--wp-terra)}.wp .btn.terra:hover{background:var(--wp-terra-dk)}
.wp nav{display:flex;align-items:center;justify-content:space-between;padding:22px 0}
/* ⚠ `nowrap` ON THE GROUP: at phone width "· Community" dropped under the wordmark, which made the room
   label read as a second line of the brand rather than a qualifier on it. */
.wp .logo{display:flex;align-items:center;gap:10px;font:600 22px Fraunces,Georgia,serif;text-decoration:none;white-space:nowrap}
.wp .logo img{width:28px;height:28px;border-radius:6px}
/* ⚖️ "AdPerch · Community" — Community MUTED, SAME SIZE. Ruled 2026-09-20 as the nav pattern for every
   Community room page, so it is a reusable class rather than a one-off on this page. */
.wp .logo .logo-room{color:var(--wp-muted);font-weight:500}

/* ⚖️ THE HERO IS THE WHOLE FIRST SCREEN (2026-09-20). ⚠ `svh`, NOT `vh`: on a phone `100vh` is the
   viewport with the URL bar HIDDEN, so a vh-sized hero is taller than what you can actually see and the
   nudge sits below the fold — the opposite of its job. `svh` is the small viewport and always fits.
   ⚠ The `vh` line before it is the fallback for browsers without `svh`, not a duplicate. */
.wp .hero{padding:40px 0 28px;text-align:center;display:flex;flex-direction:column;justify-content:center;
  min-height:calc(100vh - 92px);min-height:calc(100svh - 92px)}
/* ⭐ The nudge sits at the BOTTOM of the hero, not after the copy — it is a hint about the page, not a
   line of the argument. `margin-top:auto` puts it there whatever the copy's height. */
.wp .hero .nudge{margin-top:auto;padding-top:28px}
.wp .hero .nudge a{display:inline-flex;align-items:center;gap:7px;font:500 13px Inter;color:var(--wp-muted);text-decoration:none}
.wp .hero .nudge a:hover{color:var(--wp-terra)}
.wp .hero .nudge span{display:inline-block;animation:wp-bob 2.4s ease-in-out infinite}
@keyframes wp-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(4px)}}
.wp .hero h1{font-size:clamp(46px,7vw,76px);line-height:1;max-width:980px;margin:16px auto 0}
.wp .hero h1 .cycle{display:inline-grid;justify-items:start;color:var(--wp-terra);vertical-align:top;position:relative;white-space:nowrap;text-align:left}
/* ⛔⛔ `position:relative` IS THE WHOLE FIX FOR THE OVERRUNNING UNDERLINE. The `::after` is
   `position:absolute; left:0; right:0`, and an absolute box resolves against its nearest POSITIONED
   ancestor — which was `.cycle`, not the span. `.cycle` is one grid cell sized to the WIDEST of the three
   words, so the rule was drawn to "how to raise." under every word including "a fund."
   ⭐ Positioning the span makes `left:0/right:0` mean the span's own box, which is content-width
   (`justify-self:start`). The underline now ends where the word does, at every width. */
.wp .hero h1 .cycle span{grid-area:1/1;justify-self:start;position:relative;opacity:0;transform:translateY(14px);animation:wp-cyc 9s infinite}
.wp .hero h1 .cycle span:nth-child(2){animation-delay:3s}
.wp .hero h1 .cycle span:nth-child(3){animation-delay:6s}
.wp .hero h1 .cycle span::after{content:"";position:absolute;left:0;right:0;bottom:2px;height:5px;background:var(--wp-terra);border-radius:3px}
@keyframes wp-cyc{0%{opacity:0;transform:translateY(14px)}6%{opacity:1;transform:none}30%{opacity:1;transform:none}36%{opacity:0;transform:translateY(-14px)}100%{opacity:0}}
.wp .hero p.lead{font-size:20px;color:var(--wp-ink2);max-width:760px;margin:26px auto 30px}
.wp .hero .cta{display:flex;gap:14px;align-items:center;justify-content:center;flex-wrap:wrap}
.wp .hero .cta small{color:var(--wp-muted)}

.wp .gives{padding:40px 0 80px}
.wp .gives .wrap{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.wp .give{background:var(--wp-card);border:1px solid var(--wp-line);border-radius:22px;padding:26px 24px 22px;display:flex;flex-direction:column;min-height:460px;position:relative;overflow:hidden;transition:transform .2s,box-shadow .2s}
.wp .give:hover{transform:translateY(-3px);box-shadow:0 24px 60px rgba(35,30,26,.10)}
.wp .give .k{display:inline-flex;align-items:center;gap:8px;font:500 12px "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;padding:6px 11px;border-radius:999px;width:max-content}
.wp .give.paths .k{background:var(--wp-gold);color:var(--wp-gold-ink)}
.wp .give.skills .k{background:var(--wp-sage);color:var(--wp-sage-ink)}
.wp .give.services .k{background:var(--wp-terra-lt);color:var(--wp-terra)}
.wp .give h2{font-size:30px;line-height:1.1;margin:16px 0 8px}
.wp .give p{color:var(--wp-ink2);margin:0 0 18px;font-size:15.5px}
.wp .stage{margin-top:auto;background:var(--wp-bg);border:1px solid var(--wp-line);border-radius:14px;padding:16px;position:relative;min-height:190px}
/* ⛔ WAS `position:absolute; top:10px; right:12px` AND IT COLLIDED WITH EVERY STAGE'S CONTENT. An
   absolutely-positioned caption is out of flow, so the pills, the swap cards and the SVG all ran under it.
   ⭐ It is a NORMAL FIRST ROW now — the stage is a flex column, so the caption takes its own line and the
   demo below it starts where it should. ⚠ `.stage` keeps `position:relative` because the swap demo's
   absolutely-positioned cards anchor to it. */
.wp .stage{display:flex;flex-direction:column}
.wp .stage .cap{display:block;margin:0 0 10px;font:500 10.5px "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;color:var(--wp-muted)}

.wp .pstage svg{width:100%;height:185px;overflow:visible}
.wp .node{fill:#fff;stroke:var(--wp-line);stroke-width:1.5}
.wp .node.fund{fill:var(--wp-gold);stroke:#e2d0a6}.wp .node.you{fill:var(--wp-terra-lt);stroke:var(--wp-terra)}
.wp .nl{font:600 12.5px Fraunces,Georgia,serif;fill:var(--wp-ink)}.wp .ns{font:400 9.5px Inter;fill:var(--wp-muted)}
.wp .trail{fill:none;stroke:var(--wp-terra);stroke-width:3;stroke-linecap:round;stroke-dasharray:600;stroke-dashoffset:600;animation:wp-draw 6s infinite}
.wp .trail.cold{stroke:#d9d2c6;stroke-dasharray:5 7;animation:none;stroke-dashoffset:0;stroke-width:1.5}
@keyframes wp-draw{0%{stroke-dashoffset:600}25%{stroke-dashoffset:0}85%{stroke-dashoffset:0}100%{stroke-dashoffset:600}}
.wp .tagp{opacity:0;animation:wp-tag 6s infinite}
@keyframes wp-tag{0%,25%{opacity:0}35%,85%{opacity:1}95%,100%{opacity:0}}

.wp .pills{display:flex;flex-wrap:wrap;gap:6px}
.wp .pill{font:500 12.5px Inter;padding:6px 11px;border-radius:999px;background:#fff;border:1px solid var(--wp-line);color:var(--wp-ink2)}
.wp .pill.lit{animation:wp-lit 8s infinite}
.wp .pill.lit:nth-child(2){animation-delay:2.6s}.wp .pill.lit:nth-child(5){animation-delay:5.3s}
@keyframes wp-lit{0%,8%{background:#fff;color:var(--wp-ink2);border-color:var(--wp-line)}12%,30%{background:var(--wp-sage-ink);color:#fff;border-color:var(--wp-sage-ink)}34%,100%{background:#fff;color:var(--wp-ink2);border-color:var(--wp-line)}}
.wp .count{margin-top:14px;font:600 14px Inter;color:var(--wp-sage-ink);display:grid}
.wp .count span{grid-area:1/1;opacity:0;animation:wp-cnt 8s infinite}
.wp .count span:nth-child(2){animation-delay:2.667s}.wp .count span:nth-child(3){animation-delay:5.333s}
/* ⛔⛔ RETIMED 2026-09-20 — THE LINE WAS INVISIBLE ALMOST HALF THE TIME, WHICH IS WHY IT READ AS MISSING.
   The old keyframe showed each span from 14% to 30% of an 8s cycle with delays 0 / 2.6 / 5.3 — so the three
   visible windows were 1.12–2.4s, 3.72–5.0s and 6.42–7.7s, leaving FOUR DEAD GAPS totalling ~3.6s of every
   8. Anyone glancing at the card during one of those saw an empty row and concluded the demo was broken.
   ⭐ The markup was never wrong: `.count` sits between `.pills` and `.ask-line`, and the grid reserves its
   height even at opacity 0 — so nothing moved, it just said nothing.
   ⚠ Now each span holds ~2.4s of its 2.667s slot and the gap is only the crossfade, so the row always has
   a sentence in it. The count is the POINT of this demo; a demo that is blank half the time is a bug that
   looks like a design. */
@keyframes wp-cnt{0%{opacity:0;transform:translateY(6px)}3%{opacity:1;transform:none}30%{opacity:1;transform:none}33%,100%{opacity:0}}
.wp .count b{font:600 20px Fraunces,Georgia,serif;color:var(--wp-ink)}
.wp .ask-line{margin-top:12px;background:#fff;border:1px solid var(--wp-line);border-radius:10px;padding:9px 12px;font-size:13px;color:var(--wp-muted);display:flex;justify-content:space-between;align-items:center;gap:10px}
.wp .ask-line i{font-style:normal;color:var(--wp-ink);font-weight:500}
.wp .ask-line em{font-style:normal;font:600 12px Inter;background:var(--wp-ink);color:#fff;padding:6px 10px;border-radius:7px}

.wp .swap{position:relative;height:168px}
.wp .sc{position:absolute;left:0;right:0;background:#fff;border:1px solid var(--wp-line);border-radius:12px;padding:10px 12px;display:flex;gap:10px;align-items:center}
.wp .sc .av{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font:600 12px Inter;flex:none}
.wp .sc b{display:block;font-size:14px}.wp .sc small{color:var(--wp-muted);font-size:11.5px;line-height:1.3;display:block}
.wp .sc.a{top:0;animation:wp-swa 7s infinite}.wp .sc.b{top:88px;animation:wp-swb 7s infinite}
.wp .sc.a .av{background:var(--wp-terra-lt);color:var(--wp-terra)}.wp .sc.b .av{background:#e3e8ee;color:#33475b}
@keyframes wp-swa{0%,35%{top:0}50%,85%{top:88px}100%{top:0}}
@keyframes wp-swb{0%,35%{top:88px}50%,85%{top:0}100%{top:88px}}
.wp .arrows{position:absolute;left:50%;top:66px;transform:translateX(-50%);font:600 18px Inter;color:var(--wp-terra);background:var(--wp-bg);padding:0 8px;z-index:2}
.wp .soon{display:block;margin-top:10px;font:500 10.5px "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;color:var(--wp-muted)}

.wp .strip{background:var(--wp-night);color:#efe9e0;padding:26px 0}
.wp .strip .wrap{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;text-align:center}
.wp .strip b{display:block;font:600 34px Fraunces,Georgia,serif;color:#fff}
.wp .strip span{font-size:14px;color:#bdb3a8}
/* ⚠ THE THIRD CELL IS A SENTENCE, NOT A CAPTION, and it must not wrap mid-clause. The cell is given room
   and the text is kept at 14px so it reads as one line on a desktop width. ⛔ `nowrap` is deliberately NOT
   used: at phone width one line is impossible, and forcing it would push the strip into a horizontal
   scroll — the one thing the mobile rule exists to prevent. */
.wp .strip .wide{grid-column:span 1}
.wp .strip .wide span{max-width:none;display:block}
.wp .strip b.t{color:#e08a66}

.wp section{padding:88px 0}
.wp .sec-head{max-width:680px;margin-bottom:44px}
.wp .sec-head h2{font-size:clamp(34px,4.4vw,50px);line-height:1.06;margin-top:12px}
.wp .sec-head p{font-size:18px;color:var(--wp-ink2);margin:14px 0 0}
.wp .rule{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
.wp .rule h2{font-size:clamp(38px,5vw,62px);line-height:1.02}
.wp .rule h2 em{font-style:normal;color:var(--wp-terra)}
.wp .rule p{font-size:18px;color:var(--wp-ink2);margin-top:16px}
.wp .ledger{background:#fff;border:1px solid var(--wp-line);border-radius:20px;padding:22px;box-shadow:0 30px 70px rgba(35,30,26,.08)}
.wp .ledger .hd{display:flex;justify-content:space-between;font:500 11px "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;color:var(--wp-muted);margin-bottom:12px}
.wp .lrow{display:grid;grid-template-columns:32px 1fr auto;gap:12px;align-items:center;padding:11px 0;border-top:1px solid var(--wp-line)}
.wp .lrow .av{width:32px;height:32px;border-radius:8px;background:#ebe4d7;display:grid;place-items:center;font:600 12px Inter;color:var(--wp-muted)}
.wp .lrow b{font-size:15px}.wp .lrow small{display:block;color:var(--wp-muted);font-size:12.5px}
.wp .tog{width:36px;height:20px;border-radius:999px;background:var(--wp-terra);position:relative}
.wp .tog::after{content:"";position:absolute;top:2px;right:2px;width:16px;height:16px;border-radius:50%;background:#fff}
.wp .tog.off{background:#d8d1c5}.wp .tog.off::after{right:auto;left:2px}
.wp .unlock{margin-top:14px;padding:12px 14px;border-radius:12px;background:var(--wp-sage);color:var(--wp-sage-ink);font-weight:500;font-size:14px;display:flex;gap:10px;align-items:center}

.wp .steps{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.wp .step{border:1px solid var(--wp-line);border-radius:18px;padding:24px;background:linear-gradient(180deg,#fff,var(--wp-bg))}
.wp .step .n{font:600 13px "JetBrains Mono",ui-monospace,monospace;color:var(--wp-terra);margin-bottom:12px}
.wp .step h3{font-size:24px;margin-bottom:8px}.wp .step p{color:var(--wp-ink2);margin:0;font-size:15px}

.wp .dark{background:var(--wp-night);color:#f2ede6}
.wp .dark .mono{color:#e08a66}.wp .dark .sec-head p{color:#b9b0a6}
.wp .cardstage{display:grid;grid-template-columns:1fr 1fr;gap:44px;align-items:center}
.wp .fitcard{background:#fff;color:var(--wp-ink);border-radius:18px;padding:22px 22px 18px;box-shadow:0 30px 80px rgba(0,0,0,.45);max-width:470px;transform:rotate(-1.5deg)}
.wp .fitcard .top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
/* 2026-10-18 — the fit card is labelled Example (the counts ruling); the shared chip, seated on its own line */
.wp .fitcard .wp-ex{display:inline-block;margin:0 0 10px}
.wp .fitcard h3{font-size:26px}.wp .fitcard .sub{color:var(--wp-muted);font-size:14px;margin-top:2px}
/* ⚖️ A TIER WORD, NEVER A NUMBER (ruled 2026-09-20). The slot keeps the mock's chip styling; only what it
   can contain is constrained — see the page's comment where it is used. */
.wp .score{font:600 13px "JetBrains Mono",ui-monospace,monospace;color:var(--wp-sage-ink);background:var(--wp-sage);padding:5px 9px;border-radius:8px;white-space:nowrap}
.wp .fitcard .why{margin:16px 0;font-size:14.5px;color:var(--wp-ink2);border-left:3px solid var(--wp-line);padding-left:12px}
.wp .fitcard .ticks{display:flex;gap:10px;margin-top:14px}
.wp .fitcard .ticks span{font:600 12.5px Inter;color:var(--wp-sage-ink);background:var(--wp-sage);padding:5px 9px;border-radius:8px}
.wp .warm{display:flex;align-items:center;gap:10px;background:var(--wp-terra-lt);border:1px solid #efc9b6;border-radius:12px;padding:12px 14px;margin-top:14px}
.wp .warm .dot{width:10px;height:10px;border-radius:50%;background:var(--wp-terra);flex:none;animation:wp-ring 1.8s infinite}
@keyframes wp-ring{0%{box-shadow:0 0 0 0 rgba(196,98,58,.5)}100%{box-shadow:0 0 0 12px rgba(196,98,58,0)}}
.wp .warm b{color:var(--wp-terra)}
.wp .warm .ask{margin-left:auto;font:600 13px Inter;background:var(--wp-terra);color:#fff;padding:8px 12px;border-radius:8px;white-space:nowrap}
.wp .fitcard .foot{display:flex;gap:8px;margin-top:14px;font-size:13px;color:var(--wp-muted)}
.wp .rules{list-style:none;padding:0;margin:0;display:grid;gap:18px}
.wp .rules li{display:grid;grid-template-columns:34px 1fr;gap:14px;align-items:start}
.wp .rules .ic{width:34px;height:34px;border-radius:10px;background:var(--wp-night2);display:grid;place-items:center;color:#e08a66;font-weight:600}
.wp .rules h4{margin:0 0 4px;font-size:19px}.wp .rules p{margin:0;color:#b9b0a6;font-size:15px}

.wp .close{background:var(--wp-bg2);border-top:1px solid var(--wp-line)}
.wp .close .wrap{text-align:center;max-width:780px}
.wp .close h2{font-size:clamp(36px,5vw,60px);line-height:1.04}
.wp .close p{font-size:18px;color:var(--wp-ink2);margin:18px auto 30px;max-width:720px}
.wp .close .fine{font-size:14px;color:var(--wp-muted);margin-top:14px}
/* ⚖️ THE FOOTER, REBUILT 2026-09-20 — three columns, stacked on mobile, cream with a top border.
   ⚠ Every link in the middle column is a page that EXISTS. A footer is the one place a dead link is most
   likely to be found and least likely to be forgiven, so the list is the live set, not the intended one. */
.wp footer{background:var(--wp-bg2);border-top:1px solid var(--wp-line);padding:40px 0 28px;color:var(--wp-muted);font-size:13px;margin-top:0}
.wp footer .wrap{display:grid;grid-template-columns:1.6fr 1fr 1fr;gap:32px;align-items:start}
.wp .f-brand{display:flex;align-items:center;gap:10px;font:600 18px Fraunces,Georgia,serif;color:var(--wp-ink);white-space:nowrap}
.wp .f-brand img{width:24px;height:24px;border-radius:6px}
.wp .f-brand .logo-room{color:var(--wp-muted);font-weight:500}
.wp .f-blurb{margin:10px 0 0;max-width:34ch;line-height:1.5}
.wp footer h4{font:600 12px "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;color:var(--wp-ink2);margin:0 0 10px}
.wp .f-col ul{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.wp .f-col a{text-decoration:none}
.wp .f-col a:hover{color:var(--wp-terra);text-decoration:underline}
.wp .f-bottom{border-top:1px solid var(--wp-line);margin-top:28px;padding-top:16px;display:flex;gap:14px;flex-wrap:wrap}
.wp .f-bottom a{text-decoration:none}
.wp .f-bottom a:hover{color:var(--wp-terra);text-decoration:underline}

@media (max-width:900px){
  /* ⚖️ §5: the cycling word STAYS INLINE after "You know" — never on its own line, which was the bug at
     narrow width. The mock's own mobile rule made it a block grid; keeping `inline-grid` is the fix. */
  .wp .hero h1{font-size:clamp(38px,9vw,64px)}
  .wp .gives .wrap,.wp .steps,.wp .strip .wrap,.wp .rule,.wp .cardstage{grid-template-columns:1fr}
  .wp .fitcard{transform:none;max-width:none}
  .wp section{padding:64px 0}
  .wp footer .wrap{grid-template-columns:1fr;gap:26px}
}

/* ⚠ 480px IS THE NAV'S OWN BREAKPOINT, not the layout's. The columns collapse at 900 because the CONTENT
   needs it; the nav only runs out of room much later, and collapsing it early would shrink the brand on
   tablets for no reason. */
@media (max-width:480px){
  .wp nav{padding:16px 0}
  .wp .logo{font-size:19px;gap:8px}
  .wp .logo img{width:24px;height:24px}
  /* ⚖️ Kept rather than hidden: the room label is the point of this nav pattern, and a Community page whose
     nav does not say Community on a phone is the one place it matters most. Muted and smaller, same line. */
  .wp .logo .logo-room{font-size:16px}
  .wp nav .btn{padding:10px 14px;font-size:14px}
}

/* ⚖️ §5: "respect prefers-reduced-motion by showing the END STATE" — not by freezing at frame zero, which
   for the drawn line is an INVISIBLE path and for the cycling word is an empty heading. Each animation is
   pinned to the state it would finish in. */
@media (prefers-reduced-motion: reduce){
  /* ⛔ NO REVEAL AND NO PAUSE — the end state, immediately. Fading blocks in on scroll for the person who
     asked for no motion is honouring half the request, which reads as deliberate rather than broken. */
  .wp-js .wp [data-reveal]{opacity:1;transform:none;transition:none}
  .wp-js .wp [data-reveal]:not(.is-in),
  .wp-js .wp [data-reveal]:not(.is-in) *{animation-play-state:running}
  .wp .hero .nudge span{animation:none}
  .wp .hero h1 .cycle span{animation:none;opacity:0}
  .wp .hero h1 .cycle span:first-child{opacity:1;transform:none}
  .wp .trail{animation:none;stroke-dashoffset:0}
  .wp .tagp{animation:none;opacity:1}
  .wp .pill.lit{animation:none;background:var(--wp-sage-ink);color:#fff;border-color:var(--wp-sage-ink)}
  .wp .count span{animation:none;opacity:0}
  .wp .count span:first-child{opacity:1;transform:none}
  .wp .sc.a,.wp .sc.b{animation:none}
  .wp .warm .dot{animation:none}
}


/* ══ SCROLL REVEAL (2026-09-20) ═══════════════════════════════════════════════════════════════════════
   ⛔⛔ EVERY RULE IS GATED ON `.wp-js`, WHICH AN INLINE HEAD SCRIPT SETS — AND THAT IS THE FAIL-OPEN.
   Without it the blocks are visible and the demos run, so a blocked or failed script leaves a working
   page rather than a blank one. A page whose CONTENT depends on script to appear is one bad request from
   nothing at all.
   ⭐ IT IS SET BEFORE FIRST PAINT, not by warmpaths.js at the end of the body — otherwise the demos would
   start on load and then freeze the moment the class arrived, which is a visible stutter on every view.
   ⚠ The head script skips it entirely under `prefers-reduced-motion`, so that reader never enters the
   hidden state at all and needs no rule to get out of it.

   ⭐⭐ THE SECOND HALF IS THE ONE THAT MATTERS: `animation-play-state: paused` holds every demo at frame 0
   until its block is in view. Without it you scroll down to a loop already mid-cycle — the line
   half-drawn, the pills lit for a reason you did not see. A demo that has already played is not a demo. */
.wp-js .wp [data-reveal]{opacity:0;transform:translateY(24px);transition:opacity .55s ease,transform .55s ease}
.wp-js .wp [data-reveal].is-in{opacity:1;transform:none}
.wp-js .wp [data-reveal]:not(.is-in),
.wp-js .wp [data-reveal]:not(.is-in) *{animation-play-state:paused}

/* ══ THE PICK PAD (ruled Bret 2026-09-25, "C") — the doing before the signup, mounted by pad.js in the hero ══════
   ⚠ Sage for picked, matching the app's "Lend a hand." card: a pick here is the same act as a pill there. */
.wp .wpad{max-width:640px;margin:26px auto 0;text-align:left;background:var(--wp-card);border:1px solid var(--wp-line);
  border-radius:16px;padding:22px 22px 16px;box-shadow:0 10px 30px rgba(35,30,26,.08)}
.wp .wpad-h{font-size:22px;line-height:1.2;margin:0 0 4px}
.wp .wpad-grp{font:500 10.5px/1 "JetBrains Mono",ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;
  color:var(--wp-muted);margin:16px 0 9px}
.wp .wpad-pills{display:flex;flex-wrap:wrap;gap:7px}
.wp .wpad-funds{margin-bottom:9px}
.wp .wpad-pill{font:500 14px/1.2 Inter,system-ui,sans-serif;padding:8px 13px;border-radius:999px;background:var(--wp-bg2);
  border:1px solid var(--wp-line);color:var(--wp-ink2);cursor:pointer}
.wp .wpad-pill:hover{border-color:var(--wp-muted)}
.wp .wpad-pill.on{background:var(--wp-sage);border-color:#7d9b6a;color:var(--wp-sage-ink);font-weight:600}
.wp .wpad-pill.more{background:none;border-style:dashed;color:var(--wp-muted)}
.wp .wpad-search{width:100%;font:15px Inter,system-ui,sans-serif;padding:11px 13px;border:1px solid var(--wp-line);
  border-radius:10px;background:#fff;color:var(--wp-ink)}
.wp .wpad-search:focus{outline:2px solid var(--wp-terra-lt);border-color:var(--wp-terra)}
.wp .wpad-hits{display:flex;flex-direction:column;margin-top:6px}
.wp .wpad-hit{text-align:left;font:500 14.5px Inter,system-ui,sans-serif;padding:10px 12px;border:0;border-radius:8px;
  background:none;color:var(--wp-ink);cursor:pointer}
.wp .wpad-hit:hover,.wp .wpad-hit:focus{background:var(--wp-bg2)}
.wp .wpad-say{font-size:13px;color:var(--wp-muted);margin:6px 0 0;min-height:0}
.wp .wpad-say:empty{display:none}
.wp .wpad-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:18px;flex-wrap:wrap}
.wp .wpad-count{font-size:13.5px;color:var(--wp-ink2)}
.wp .wpad-fine{font-size:12.5px;color:var(--wp-muted);margin:10px 0 0}
@media (max-width:640px){
  .wp .wpad{margin-top:20px;padding:18px 15px 14px}
  .wp .wpad-h{font-size:20px}
  /* ⭐ ON A PHONE THE SAVE ROW STICKS to the bottom of the pad while it scrolls past, so the button is never below
     the fold of a long pill list. */
  .wp .wpad-foot{position:sticky;bottom:0;background:var(--wp-card);padding:10px 0 4px;margin-top:12px}
  .wp .wpad-save{width:100%;justify-content:center}
}
/* ⚠ `hidden` must win over the hero row's own display rule, or the fallback button shows beside the pad. */
.wp [data-wpad-fallback][hidden]{display:none}
