/* Rebuild the Block: the interactive street hero.
   Every selector is scoped to #rebuild-story: the bundle shipped with its
   own :root, html and body rules, which would otherwise repaint the whole
   page navy and lower --ca-focus to gold-500 (2.61 on white). Scoped, the
   scene keeps its dark palette and the rest of the site keeps its own. */
#rebuild-story{color-scheme:dark;
      --ca-red-50:#FCECEC;--ca-red-300:#E4666C;--ca-red-500:#B3030D;--ca-red-700:#8C0209;--ca-red-900:#5C0105;
      --ca-navy-50:#EEF2F8;--ca-navy-100:#D8E0EE;--ca-navy-300:#8A9CC4;--ca-navy-500:#1E4278;--ca-navy-700:#02204F;--ca-navy-900:#01132F;
      --ca-gold-50:#FDF6E3;--ca-gold-300:#E8C267;--ca-gold-500:#D1952B;--ca-gold-700:#8F5E00;--ca-gold-900:#5E3D00;
      --ca-ink:#121826;--ca-charcoal:#2E3547;--ca-slate:#5A6377;--ca-steel:#8B93A6;--ca-limestone:#C9CFDB;--ca-fog:#E6E9F0;--ca-cream:#F6F4EC;--ca-paper:#F8F8F8;--ca-white:#FFFFFF;
      --ca-forest:#2A541E;--ca-plum:#362454;--ca-focus:#D1952B;
      --display:'Alfa Slab One',Rockwell,'Roboto Slab',serif;--text:'Barlow','Helvetica Neue',Arial,sans-serif;--accent:'Barlow Condensed','Arial Narrow',sans-serif;
      --p:0;--travel:0;--top-ui:320px;
    }#rebuild-story *, #rebuild-story *::before, #rebuild-story *::after{box-sizing:border-box}#rebuild-story{background:var(--ca-navy-900);color:var(--ca-paper);font-family:var(--text);font-size:17px;line-height:1.5}#rebuild-story button, #rebuild-story a{font:inherit}#rebuild-story button{cursor:pointer}#rebuild-story img{max-width:100%}#rebuild-story .sr-only{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}#rebuild-story .skip-link{position:fixed;z-index:9999;left:16px;top:12px;transform:translateY(-160%);background:var(--ca-gold-500);color:var(--ca-navy-900);padding:10px 14px;border-radius:3px;font:600 16px/1 var(--accent);letter-spacing:.08em;text-transform:uppercase}#rebuild-story .skip-link:focus{transform:none}#rebuild-story :focus-visible{outline:3px solid var(--ca-focus);outline-offset:3px}#rebuild-story{height:300vh;min-height:1500px;background:var(--ca-navy-900)}#rebuild-story .hero{position:sticky;top:0;height:100vh;height:100svh;min-height:620px;overflow:hidden;isolation:isolate;background:linear-gradient(180deg,#69798c 0%,#9ea4aa 54%,#6b675f 100%);touch-action:pan-y}#rebuild-story .sky-clear, #rebuild-story .sky-overcast, #rebuild-story .sky-glow{position:absolute;inset:0;pointer-events:none}#rebuild-story .sky-clear{z-index:-8;background:linear-gradient(180deg,#6fa8ec 0%,#b9daf5 58%,#f5d2a8 100%)}#rebuild-story .sky-overcast{z-index:18;background:linear-gradient(180deg,rgba(39,50,65,.82),rgba(91,93,96,.64) 56%,rgba(44,43,44,.32));opacity:calc(1 - var(--p));mix-blend-mode:multiply}#rebuild-story .sky-glow{z-index:17;background:radial-gradient(circle at 16% 10%,rgba(255,240,192,.7),transparent 25%),linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,188,105,.12));opacity:var(--p);mix-blend-mode:screen}#rebuild-story .sun{position:absolute;z-index:-6;width:clamp(70px,8vw,120px);aspect-ratio:1;border-radius:50%;background:radial-gradient(circle at 40% 38%,#fff9cf 0 12%,#ffd466 38%,rgba(255,184,55,.35) 66%,transparent 72%);filter:blur(.2px);opacity:calc(.08 + var(--p) * .92);pointer-events:none;transform:translate3d(8vw,52vh,0)}#rebuild-story .cloud{position:absolute;z-index:-5;width:170px;height:46px;border-radius:50%;background:rgba(248,248,248,.72);filter:blur(2px);box-shadow:38px -18px 0 4px rgba(248,248,248,.65),78px 2px 0 -4px rgba(248,248,248,.7);animation:cloud-drift 38s linear infinite;pointer-events:none}#rebuild-story .cloud.one{left:13vw;top:12vh}#rebuild-story .cloud.two{left:74vw;top:18vh;transform:scale(.72);animation-duration:51s;animation-delay:-22s}
    @keyframes cloud-drift{0%{translate:-12vw 0}50%{translate:7vw 8px}100%{translate:-12vw 0}}#rebuild-story .horizon{position:absolute;z-index:-4;left:-10vw;right:-90vw;bottom:24vh;height:27vh;opacity:.42;filter:blur(8px);background:linear-gradient(90deg,rgba(29,45,76,.76) 0 9%,transparent 9% 11%,rgba(33,49,78,.72) 11% 17%,transparent 17% 19%,rgba(24,42,71,.68) 19% 25%,transparent 25% 43%,rgba(70,112,60,.64) 55%,rgba(101,143,73,.76) 70%,rgba(80,126,61,.72));clip-path:polygon(0 100%,0 48%,4% 48%,4% 17%,7% 17%,7% 55%,10% 55%,10% 3%,14% 3%,14% 48%,17% 48%,17% 30%,22% 30%,22% 63%,27% 63%,27% 34%,31% 34%,31% 62%,40% 62%,46% 80%,51% 66%,57% 83%,63% 55%,70% 82%,78% 60%,86% 77%,93% 50%,100% 69%,100% 100%);transform:translate3d(0,0,0);will-change:transform}#rebuild-story .top-scrim{position:absolute;z-index:20;inset:0 0 auto;height:min(54vh,430px);background:linear-gradient(180deg,rgba(1,19,47,.97),rgba(1,19,47,.82) 57%,rgba(1,19,47,.18) 88%,transparent);pointer-events:none}#rebuild-story .topbar{position:absolute;z-index:35;left:clamp(16px,3vw,46px);right:clamp(16px,3vw,46px);top:max(12px,env(safe-area-inset-top));display:grid;grid-template-columns:minmax(180px,1fr) auto;gap:18px;align-items:center}#rebuild-story .meter-wrap{max-width:520px}#rebuild-story .meter-label{display:flex;justify-content:space-between;gap:18px;margin-bottom:7px;color:var(--ca-navy-100);font:600 13px/1 var(--accent);letter-spacing:.12em;text-transform:uppercase}#rebuild-story .meter{height:10px;border:1px solid rgba(248,248,248,.48);background:rgba(1,19,47,.74);overflow:hidden}#rebuild-story .meter-fill{width:100%;height:100%;transform:scaleX(var(--p));transform-origin:left center;background:linear-gradient(90deg,var(--ca-gold-500),#f3c758);will-change:transform}#rebuild-story .utility{display:flex;align-items:center;justify-content:flex-end;gap:8px;flex-wrap:wrap}#rebuild-story .btn{display:inline-flex;min-height:44px;align-items:center;justify-content:center;gap:8px;border-radius:3px;padding:0 1.35rem;border:0;font:600 17px/1 var(--accent);letter-spacing:.08em;text-transform:uppercase;text-decoration:none;white-space:nowrap}#rebuild-story .btn-small{min-height:36px;padding:0 1rem;font-size:15px}#rebuild-story .btn-primary{background:var(--ca-gold-500);color:var(--ca-navy-900)}#rebuild-story .btn-primary:hover{background:var(--ca-gold-300)}#rebuild-story .btn-secondary{background:rgba(1,19,47,.56);color:var(--ca-paper);border:2px solid var(--ca-paper)}#rebuild-story .btn-secondary:hover{background:rgba(248,248,248,.12)}#rebuild-story .btn-tertiary{min-height:36px;background:rgba(1,19,47,.78);color:var(--ca-paper);border:1px solid rgba(248,248,248,.42);padding:0 .8rem}#rebuild-story .intro{position:absolute;z-index:32;left:clamp(18px,4vw,64px);top:76px;width:min(620px,calc(100% - 36px));pointer-events:none}#rebuild-story .eyebrow{color:var(--ca-gold-300);font:600 14px/1.2 var(--accent);letter-spacing:.14em;text-transform:uppercase}#rebuild-story .intro h1{max-width:12ch;margin:.16em 0 .12em;color:var(--ca-paper);font:400 clamp(2.65rem,5.8vw,4.75rem)/1.02 var(--display);letter-spacing:-.005em;text-wrap:balance}#rebuild-story .intro p{max-width:54ch;margin:0;color:var(--ca-navy-100);font-size:clamp(17px,1.55vw,20px);line-height:1.45;text-shadow:0 1px 14px rgba(1,19,47,.8)}#rebuild-story .tabs{position:absolute;z-index:34;top:min(49vh,430px);left:50%;display:flex;max-width:calc(100vw - 32px);transform:translateX(-50%);gap:4px;padding:5px;background:rgba(1,19,47,.88);border:1px solid rgba(248,248,248,.3);box-shadow:0 8px 30px rgba(1,19,47,.32);overflow-x:auto;scrollbar-width:none}#rebuild-story .tabs::-webkit-scrollbar{display:none}#rebuild-story .tab{flex:none;min-height:40px;border:0;border-radius:3px;padding:0 14px;background:transparent;color:var(--ca-navy-100);font:600 15px/1 var(--accent);letter-spacing:.07em;text-transform:uppercase}#rebuild-story .tab:hover{background:rgba(248,248,248,.1);color:var(--ca-paper)}#rebuild-story .tab[aria-selected="true"]{background:var(--ca-gold-500);color:var(--ca-navy-900)}#rebuild-story .scroll-hint{position:absolute;z-index:33;top:min(56vh,490px);left:50%;transform:translate(-50%,-6px);margin:0;padding:6px 11px;color:var(--ca-paper);background:rgba(1,19,47,.78);font:600 14px/1.2 var(--accent);letter-spacing:.08em;text-transform:uppercase;opacity:0;transition:opacity .25s,transform .25s;pointer-events:none}#rebuild-story .scroll-hint.show{opacity:1;transform:translate(-50%,0)}#rebuild-story .viewport{position:absolute;z-index:2;inset:0;overflow:hidden;touch-action:pan-y;cursor:grab}#rebuild-story .viewport.dragging{cursor:grabbing}#rebuild-story .viewport.painting{cursor:crosshair;touch-action:none}#rebuild-story .street-track{position:absolute;inset:0 auto 0 0;width:300vw;height:100%;display:flex;transform:translate3d(0,0,0);will-change:transform}#rebuild-story .block{position:relative;flex:0 0 100vw;height:100%;overflow:hidden}#rebuild-story .plate-layer{position:absolute;left:0;right:0;bottom:0;aspect-ratio:2880/1607;overflow:hidden}#rebuild-story .plate-image, #rebuild-story .decline-image{position:absolute;inset:0;width:100%;height:100%;object-fit:fill;pointer-events:none;user-select:none}#rebuild-story .plate-image{z-index:1}#rebuild-story .decline-image{z-index:2;will-change:opacity,filter}#rebuild-story .simulated-decline{filter:grayscale(.82) sepia(.1) brightness(.58) contrast(1.04) saturate(.55)}#rebuild-story .damage-film{position:absolute;z-index:3;inset:0;opacity:.75;pointer-events:none;background:linear-gradient(168deg,transparent 0 45%,rgba(27,25,29,.38) 46% 47%,transparent 48% 72%,rgba(60,50,40,.34) 73% 74%,transparent 75%),repeating-linear-gradient(92deg,transparent 0 8%,rgba(14,26,34,.09) 8.2% 8.6%,transparent 8.8% 15%);mix-blend-mode:multiply}#rebuild-story .patch{position:absolute;z-index:4;overflow:hidden;opacity:0;pointer-events:none;will-change:clip-path,opacity,filter,transform}#rebuild-story .patch img{position:absolute;max-width:none;pointer-events:none;user-select:none}#rebuild-story .patch.settled[data-reveal="light-on"]{animation:neon-breathe 2.8s ease-in-out infinite}#rebuild-story .patch.flicker{animation:neon-flicker .78s steps(1) 1}
    @keyframes neon-flicker{0%,12%,32%,50%,70%,100%{opacity:1}7%,24%,42%,61%,79%{opacity:.16}}
    /* The settled neon breathes with brightness alone. The drop-shadow it used
   to carry was drawn from the patch's rectangular alpha, so it glowed as a
   yellow box outline rather than around the sign inside it. */
@keyframes neon-breathe{
  0%,100%{filter:brightness(1);transform:scale(1)}
  50%{filter:brightness(1.06);transform:scale(1.003)}
}#rebuild-story .brush-canvas{position:absolute;z-index:5;inset:0;width:100%;height:100%;pointer-events:none}#rebuild-story .hotspot{position:absolute;z-index:8;display:block;min-width:24px;min-height:24px;margin:0;padding:0;border:0;border-radius:3px;background:transparent;color:transparent;box-shadow:none}#rebuild-story .hotspot::after{content:"";position:absolute;width:13px;height:13px;right:4px;top:4px;border-radius:50%;background:var(--ca-gold-500);border:2px solid var(--ca-navy-900);box-shadow:0 0 0 2px var(--ca-paper),0 3px 9px rgba(1,19,47,.55);opacity:0;transform:scale(.4);transition:opacity .2s,transform .2s}#rebuild-story .debug .hotspot.user-fixed::after{opacity:1}#rebuild-story .hotspot:focus-visible{outline:4px solid var(--ca-gold-500);outline-offset:2px;background:rgba(209,149,43,.14)}
    #rebuild-story .chevron{position:absolute;z-index:34;top:64%;width:52px;height:68px;border:2px solid var(--ca-paper);background:rgba(1,19,47,.84);color:var(--ca-paper);font-size:31px;line-height:1;border-radius:3px;box-shadow:0 6px 18px rgba(1,19,47,.3)}#rebuild-story .chevron:hover{background:var(--ca-gold-500);color:var(--ca-navy-900)}#rebuild-story .chevron.left{left:12px}#rebuild-story .chevron.right{right:12px}#rebuild-story .chevron:disabled{opacity:.26;cursor:not-allowed}#rebuild-story .tooltip{position:fixed;z-index:80;max-width:min(340px,calc(100vw - 24px));padding:11px 14px 12px;background:var(--ca-navy-700);color:var(--ca-paper);border-top:4px solid var(--ca-gold-500);border-radius:3px;box-shadow:0 12px 32px rgba(1,19,47,.4);font:600 16px/1.25 var(--text);opacity:0;transform:translateY(6px);pointer-events:none;transition:opacity .12s,transform .12s}#rebuild-story .tooltip.show{opacity:1;transform:none}#rebuild-story .lens{position:fixed;z-index:75;width:120px;height:120px;border-radius:50%;border:4px solid var(--ca-gold-500);box-shadow:0 0 0 2px var(--ca-paper),0 12px 30px rgba(1,19,47,.48);background-repeat:no-repeat;opacity:0;pointer-events:none;transform:scale(.92);transition:opacity .12s,transform .12s}#rebuild-story .lens.show{opacity:1;transform:scale(1)}#rebuild-story dialog.card-dialog{width:min(660px,calc(100vw - 24px));max-height:min(88vh,780px);margin:auto;padding:0;border:0;border-radius:3px;background:var(--ca-navy-700);color:var(--ca-paper);box-shadow:0 24px 80px rgba(1,19,47,.65);overflow:auto}#rebuild-story dialog.card-dialog::backdrop{background:rgba(1,19,47,.76);backdrop-filter:blur(5px)}#rebuild-story .card-inner{padding:clamp(22px,4vw,40px)}#rebuild-story .close-card{float:right;width:44px;height:44px;margin:-8px -8px 8px 12px;border:2px solid var(--ca-paper);border-radius:3px;background:transparent;color:var(--ca-paper);font-size:28px;line-height:1}#rebuild-story .card-office{margin:0 52px 9px 0;color:var(--ca-gold-300);font:600 14px/1.2 var(--accent);letter-spacing:.14em;text-transform:uppercase}#rebuild-story .card-dialog h2{clear:both;margin:0 0 14px;font:400 clamp(1.75rem,4vw,2.25rem)/1.1 var(--display);letter-spacing:-.005em;text-wrap:balance}#rebuild-story .card-does{margin:0 0 18px;color:var(--ca-navy-100);font-size:17px;line-height:1.6}#rebuild-story .chips{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 24px}#rebuild-story .chip{display:inline-flex;min-height:30px;align-items:center;padding:0 10px;border-radius:3px;font:600 13px/1 var(--accent);letter-spacing:.06em;text-transform:uppercase}#rebuild-story .chip.level-open{background:var(--ca-forest);color:white}#rebuild-story .chip.level-statutory{background:var(--ca-gold-500);color:var(--ca-navy-900)}#rebuild-story .chip.level-license{background:var(--ca-red-500);color:white;border:1px solid white}#rebuild-story .chip.level-experience{background:var(--ca-navy-500);color:white;border:1px solid var(--ca-paper)}#rebuild-story .chip.level-appointed{background:var(--ca-plum);color:white}#rebuild-story .chip.level-varies{background:var(--ca-charcoal);color:white}#rebuild-story .chip.fact{background:var(--ca-gold-500);color:var(--ca-navy-900)}#rebuild-story .card-actions{display:flex;gap:12px;align-items:center;flex-wrap:wrap}#rebuild-story .card-note{margin:18px 0 0;color:var(--ca-navy-100);font-size:13px}#rebuild-story .payoff-wrap{position:absolute;z-index:36;right:clamp(16px,3vw,44px);bottom:clamp(18px,3vw,38px);width:min(520px,calc(100vw - 32px));pointer-events:none}
#rebuild-story .payoff{position:relative;z-index:1;width:100%;padding:23px;background:var(--ca-red-500);color:white;border:1px solid white;border-radius:3px;box-shadow:0 18px 55px rgba(1,19,47,.48);opacity:0;transform:translateY(120%);pointer-events:none;will-change:transform,opacity}#rebuild-story .payoff.show{opacity:1;transform:translateY(0);pointer-events:auto}#rebuild-story .payoff::before{content:"";display:block;width:64px;height:5px;margin-bottom:16px;background:var(--ca-gold-500)}#rebuild-story .payoff h2{margin:0 0 10px;font:400 clamp(1.65rem,3vw,2rem)/1.12 var(--display)}#rebuild-story .payoff p{margin:0 0 18px;font-size:17px}#rebuild-story .payoff .btn-primary{background:white;color:var(--ca-red-500)}#rebuild-story .payoff .btn-secondary{background:transparent}#rebuild-story .after{background:var(--ca-cream);color:var(--ca-ink);padding:clamp(58px,8vw,110px) max(24px,calc((100vw - 1180px)/2));border-top:8px solid var(--ca-gold-500)}#rebuild-story .after-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,6vw,78px)}#rebuild-story .after .eyebrow{color:var(--ca-gold-700)}#rebuild-story .after h2{margin:.25em 0 .3em;color:var(--ca-navy-700);font:400 clamp(2.1rem,5vw,3.5rem)/1.05 var(--display);letter-spacing:-.005em}#rebuild-story .after p{font-size:18px;line-height:1.65}#rebuild-story .after .btn-primary{background:var(--ca-red-500);color:white}#rebuild-story .after .btn-primary:hover{background:var(--ca-red-700)}#rebuild-story .after .btn-secondary{border-color:var(--ca-navy-700);color:var(--ca-navy-700);background:transparent}#rebuild-story .sources{margin-top:70px;padding-top:26px;border-top:1px solid var(--ca-limestone)}#rebuild-story .sources h3{margin:0 0 12px;color:var(--ca-navy-700);font-size:22px}#rebuild-story .source-links{display:flex;gap:8px 18px;flex-wrap:wrap}#rebuild-story .source-links a{color:var(--ca-red-700);font-weight:600;text-underline-offset:4px}#rebuild-story .source-note{max-width:90ch;color:var(--ca-slate);font-size:14px}
    @media (max-width:800px){#rebuild-story{--top-ui:310px}#rebuild-story .hero{min-height:620px}#rebuild-story .topbar{grid-template-columns:1fr;gap:7px;right:14px;left:14px}#rebuild-story .meter-wrap{max-width:none}#rebuild-story .utility{position:absolute;right:0;top:35px;gap:5px}#rebuild-story .utility .btn{font-size:13px;min-height:34px;padding:0 .7rem}#rebuild-story .intro{top:86px;left:18px;width:calc(100% - 36px)}#rebuild-story .intro h1{font-size:clamp(2.55rem,12vw,3.55rem);max-width:10ch}#rebuild-story .intro p{max-width:38ch;font-size:17px;line-height:1.38}#rebuild-story .tabs{top:332px;left:12px;right:12px;max-width:none;transform:none;justify-content:flex-start}#rebuild-story .tab{padding:0 12px}#rebuild-story .scroll-hint{top:384px;white-space:nowrap}#rebuild-story .chevron{top:auto;bottom:16px;width:46px;height:52px}#rebuild-story .chevron.left{left:10px}#rebuild-story .chevron.right{right:10px}#rebuild-story .payoff-wrap{bottom:78px}#rebuild-story .payoff .card-actions{display:grid}#rebuild-story .payoff .btn{width:100%}#rebuild-story .after-grid{grid-template-columns:1fr}#rebuild-story .lens{display:none}
    }
    @media (max-width:480px){#rebuild-story .intro h1{margin-top:.12em}#rebuild-story .intro p{font-size:16px}#rebuild-story .tabs{top:330px}#rebuild-story .tab{padding:0 8px;font-size:12px}#rebuild-story .scroll-hint{top:382px;font-size:12px}#rebuild-story .utility{top:34px}#rebuild-story .utility .debug-label{display:none}#rebuild-story .plate-layer{bottom:68px}#rebuild-story .card-actions{display:grid}#rebuild-story .card-actions .btn{width:100%}#rebuild-story .chips{gap:6px}#rebuild-story .card-inner{padding:22px 18px 24px}#rebuild-story .card-dialog h2{font-size:1.7rem}
    }
    @media (prefers-reduced-motion:reduce){#rebuild-story{scroll-behavior:auto}#rebuild-story{height:auto;min-height:0}#rebuild-story .hero{position:relative;height:100svh}#rebuild-story *, #rebuild-story *::before, #rebuild-story *::after{scroll-behavior:auto!important;animation:none!important;transition:none!important}#rebuild-story .sky-overcast{display:none}#rebuild-story .sun{opacity:1}#rebuild-story .cloud{display:none}#rebuild-story .payoff.show{transform:none}#rebuild-story .street-track{transition:none}
    }

/* ==========================================================================
   Hero layout revisions
   The walk controls, the block names and the restoration meter now sit
   together at the foot of the scene, so the sky above the street stays clear.
   ========================================================================== */

/* The top bar keeps only the utility buttons now the meter has moved out. */
#rebuild-story .topbar{grid-template-columns:minmax(0,1fr)}
#rebuild-story .meter-wrap{max-width:none}

/* 5. Hero copy ranges left, rather than centring inside its column. */
#rebuild-story .intro{text-align:left}
#rebuild-story .intro h1,
#rebuild-story .intro p{margin-left:0;margin-right:auto;text-align:left}

/* 7. Walk controls and block names, one row, centred at the foot. */
#rebuild-story .street-controls{position:absolute;z-index:34;left:50%;
  bottom:clamp(74px,11vh,104px);transform:translateX(-50%);
  display:flex;align-items:center;gap:var(--s-2);max-width:calc(100vw - 24px)}
#rebuild-story .street-controls .tabs{position:static;transform:none;left:auto;top:auto;
  max-width:min(60vw,540px);overflow-x:auto;scrollbar-width:none}

/* 6. The arrows are SVG now, not the ‹ › characters. Those carry heavy and
      uneven side bearing, so no amount of flex centring put them in the middle
      of the box; a path centres exactly. */
#rebuild-story .chevron{position:static;display:flex;align-items:center;
  justify-content:center;flex:none;top:auto;bottom:auto;left:auto;right:auto;
  width:var(--ctrl-h);height:var(--ctrl-h);padding:0;line-height:1}
#rebuild-story .chevron svg{width:22px;height:22px;display:block}
#rebuild-story .chevron.left,
#rebuild-story .chevron.right{position:static;left:auto;right:auto}

/* 2. The meter, centred beneath the controls. */
#rebuild-story .street-meter{position:absolute;z-index:34;left:50%;
  bottom:clamp(20px,4.5vh,40px);transform:translateX(-50%);
  width:min(520px,calc(100vw - 32px))}
#rebuild-story .street-meter .meter-label{justify-content:center;gap:var(--s-2)}

/* 4. A pulsing arrow under the scroll note. */
#rebuild-story .scroll-hint{display:flex;align-items:center;gap:var(--s-2)}
#rebuild-story .hint-arrow{width:15px;height:15px;flex:none;
  animation:hint-bob 1.6s ease-in-out infinite}
@keyframes hint-bob{
  0%,100%{transform:translateY(-2px);opacity:.55}
  50%{transform:translateY(3px);opacity:1}
}

@media (max-width:760px){
  #rebuild-story .street-controls{bottom:auto;top:min(52vh,404px);gap:var(--s-1)}
  
  #rebuild-story .street-meter{bottom:14px;width:calc(100vw - 24px)}
}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .hint-arrow{animation:none}
}

/* ==========================================================================
   Hero behaviour revisions
   ========================================================================== */

/* The pinned height buys two things: the scroll distance that drives the
   rebuild, and a tail afterwards so the payoff card is read before the page
   moves on. PIN_TAIL in rebuild.js splits the two. */
#rebuild-story{height:380vh;min-height:1900px}

/* Everything the reader needs has to be on screen at once: the intro at the
   top, the walk controls and the meter at the foot. Short viewports get a
   tighter stack rather than a scrollbar. */
/* The hero pins *below* the sticky site header and is exactly the height of
   what is left of the viewport, so the walk controls and the meter are on
   screen the moment the page loads rather than 66px under the fold. */
#rebuild-story .hero{top:var(--hdr);min-height:0;
  height:calc(100svh - var(--hdr));max-height:calc(100svh - var(--hdr))}
#rebuild-story .intro{top:clamp(64px,9vh,96px)}
#rebuild-story .street-controls{bottom:clamp(66px,9.5vh,96px)}
#rebuild-story .street-meter{bottom:clamp(16px,3.5vh,32px)}
#rebuild-story .scroll-hint{top:auto;bottom:clamp(126px,17vh,166px);transform:translate(-50%,0)}
#rebuild-story .scroll-hint.show{transform:translate(-50%,0)}

@media (max-height:720px){
  #rebuild-story .intro h1{font-size:clamp(2rem,4.4vw,3rem)}
  #rebuild-story .intro p{font-size:16px}
  #rebuild-story .street-controls{bottom:62px}
  
  #rebuild-story .scroll-hint{bottom:114px}
}

@media (max-height:600px){
  #rebuild-story .intro p{display:none}
  #rebuild-story .scroll-hint{display:none}
}

/* Reduced motion keeps the scene static and lets the page scroll normally.
   This has to undo the pin completely (position, top, height and max-height) because the fitted rule above it would otherwise win on source order. */
@media (prefers-reduced-motion:reduce){
  #rebuild-story{height:auto;min-height:0}
  #rebuild-story .hero{position:relative;top:auto;
    height:auto;min-height:560px;max-height:none}
}

/* ==========================================================================
   Hotspot mode
   Shows every clickable tile at once. Red is the brand's action colour and it
   sits directly on the navy street furniture, so the old red outline broke the
   badge rule and read as an error state. Gold is the badge's marker colour, what the rays and the stars are made of, so the tiles wash gold and
   each one carries the same round gold pin the repaired hotspots use.
   ========================================================================== */




/* The pin: centred in its tile, and shown for every hotspot rather than only
   the ones already repaired. */
/* The tile itself stays invisible: no fill, no outline, no label chip. A
   single gold pin marks each hotspot, centred in its region. */




/* The two hero toggles carry no wording change any more, so their on-state has
   to be visible. Gold fill, navy label: the same inversion the buttons use on
   a navy ground elsewhere. */
#rebuild-story .btn-tertiary[aria-pressed="true"]{
  background:var(--ca-gold-500);
  border-color:var(--ca-gold-500);
  color:var(--ca-navy-900)
}

/* The tooltip now carries the office and what it does, not just the hook. */
#rebuild-story .tooltip{display:grid;gap:var(--s-1)}
#rebuild-story .tip-hover{font:600 16px/1.25 var(--text);color:var(--ca-paper)}
#rebuild-story .tip-office{font:600 13px/1.2 var(--accent);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ca-gold-500)}
#rebuild-story .tip-does{font:400 14px/1.4 var(--text);color:var(--ca-navy-100)}

/* The plates sit edge to edge across the track, so a drop-shadow on each one
   drew a dark seam at every 100vw boundary, a divider between scenes. One
   shadow on the whole strip keeps the street lifted off the sky with no
   internal edges. */
#rebuild-story .street-track{filter:drop-shadow(0 12px 16px rgba(1,19,47,.22))}

/* Tooltip copy ranges left; it was inheriting the centred alignment of the
   scene around it. */
#rebuild-story .tooltip{text-align:left;justify-items:start}
#rebuild-story .tip-hover,
#rebuild-story .tip-office,
#rebuild-story .tip-does{text-align:left}

/* ==========================================================================
   Payoff rays
   The badge throws gold rays from behind its torch. This is the same idea at a
   fraction of the strength: thin gold spokes that fade up behind the red card
   once the street is finished, then hold while the reader carries on scrolling.

   Masked to a ring so the spokes only ever appear *around* the card. Gold over
   Torch Red would muddy both, and the badge never lets them touch either.
   ========================================================================== */
#rebuild-story .payoff-rays{
  position:absolute;
  z-index:0;
  left:50%;
  top:50%;
  width:210%;
  height:260%;
  transform:translate(-50%,-50%) scale(.88);
  background:repeating-conic-gradient(from 0deg at 50% 50%,
    var(--ca-gold-500) 0deg 0.45deg, transparent 0.45deg 7.5deg);
  /* An ellipse, not a circle: the card is far wider than it is tall, so a
     circular hole clears its top and bottom but cuts across its sides. */
  -webkit-mask-image:radial-gradient(ellipse 60% 52% at 50% 50%,
    transparent 46%, #000 53%, transparent 69%);
  mask-image:radial-gradient(ellipse 60% 52% at 50% 50%,
    transparent 46%, #000 53%, transparent 69%);
  opacity:0;
  pointer-events:none;
}

/* A burst rather than a fade: the spokes throw out past their resting size,
   then settle back. :has() drives them off the card's own show state. */
@keyframes payoff-rays-in{
  0%{opacity:0;transform:translate(-50%,-50%) scale(.5)}
  40%{opacity:.92;transform:translate(-50%,-50%) scale(1.13)}
  70%{opacity:.66;transform:translate(-50%,-50%) scale(.97)}
  100%{opacity:.58;transform:translate(-50%,-50%) scale(1)}
}

#rebuild-story .payoff-wrap:has(.payoff.show) .payoff-rays{
  animation:payoff-rays-in 1200ms cubic-bezier(.2,.75,.3,1) 220ms both;
}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .payoff-wrap:has(.payoff.show) .payoff-rays{
    animation:none;opacity:.58;transform:translate(-50%,-50%) scale(1)}
}


/* "Shape what's next." holds together on one line once the hero is wide enough
   to take it. Below that it wraps as before, because forcing it would push the
   headline past the edge on a narrow screen. */
@media (min-width:1100px){
  #rebuild-story .intro{width:min(860px,calc(100% - 36px))}
  #rebuild-story .intro h1{max-width:none}
  #rebuild-story .intro h1 .h1-hold{white-space:nowrap}
}

/* Hero calls to action. The intro block is pointer-events:none so the street
   behind it stays clickable, so the buttons have to opt back in. */
#rebuild-story .intro-cta{
  display:flex;
  flex-wrap:wrap;
  gap:var(--s-3);
  margin-top:var(--s-5);
  pointer-events:auto;
}

@media (max-height:720px){
  #rebuild-story .intro-cta{margin-top:var(--s-4)}
  #rebuild-story .intro-cta .btn{min-height:40px;padding:0 var(--s-4)}
}

@media (max-width:560px){
  #rebuild-story .intro-cta{gap:var(--s-2)}
  #rebuild-story .intro-cta .btn{width:100%}
}

/* Patches are rectangles cut out of the restored plate and laid over the
   decline, so their edges showed as hard boxes against the darker street. This
   feathers all four sides: two linear masks intersected, which keeps the shape
   rectangular while letting the boundary fall away instead of stopping dead. */
#rebuild-story .patch{
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(to right, transparent 0, #000 9%, #000 91%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-composite:intersect;
}

/* ==========================================================================
   Hotspot pins
   .viewport carries z-index:2, so it is its own stacking context and nothing
   inside it can rise above the atmosphere layers that follow it. The overcast
   at z-18 is a multiply wash, which is what turned the gold pins olive. In
   hotspot mode the street lifts above the overcast and the glow so the pins
   read as true Ray Gold; it stays below the top scrim, which is still doing
   legibility work behind the hero copy.
   ========================================================================== */
/* The street stays under the overcast, as it should. The pins live in
   their own layer above it instead. */

/* A ring of short gold spokes, thrown out from behind the pin on hover. Same
   idea as the payoff rays, at a fifteenth of the size. */




@media (prefers-reduced-motion:reduce){
  
  
}

/* ==========================================================================
   Pin layer
   The street sits under the overcast so it keeps its night hue. The pins do
   not: they are drawn in this layer, which is a sibling of .viewport and sits
   above the weather, and it mirrors the street track's transform so the pins
   travel with the blocks they belong to.
   ========================================================================== */
#rebuild-story .pin-layer{
  position:absolute;
  inset:0;
  z-index:21;
  overflow:hidden;
  pointer-events:none;
  opacity:0;
  visibility:hidden;
  transition:opacity 200ms ease;
}

#rebuild-story .debug .pin-layer{opacity:1;visibility:visible}

#rebuild-story .pin-track{
  position:absolute;
  inset:0 auto 0 0;
  height:100%;
  display:flex;
}

#rebuild-story .pin-block{position:relative;flex:0 0 100vw;height:100%}
#rebuild-story .pin-plate{overflow:visible;background:none}

#rebuild-story .pin{
  position:absolute;
  width:18px;
  height:18px;
  margin:-9px 0 0 -9px;
  border-radius:50%;
  background:var(--ca-gold-300);
  border:2px solid var(--ca-navy-900);
  box-shadow:0 0 0 2px var(--ca-paper), 0 3px 9px rgba(1,19,47,.55);
  transition:transform 160ms ease, background 160ms ease;
}

#rebuild-story .pin.is-hover{
  background:var(--ca-gold-300);
  transform:scale(1.12);
}

/* Rays: 16 spokes at 5.5deg, which measures roughly 1.3px rising to 2.4px at
   this radius. Anything thinner renders as a haze rather than as lines. */
#rebuild-story .pin::before{
  content:"";
  position:absolute;
  left:50%;
  top:50%;
  width:54px;
  height:54px;
  transform:translate(-50%,-50%) scale(.55);
  background:repeating-conic-gradient(from 0deg at 50% 50%,
    var(--ca-gold-500) 0deg 5.5deg, transparent 5.5deg 22.5deg);
  -webkit-mask-image:radial-gradient(circle,
    transparent 50%, #000 58%, #000 74%, transparent 94%);
  mask-image:radial-gradient(circle,
    transparent 50%, #000 58%, #000 74%, transparent 94%);
  opacity:0;
  pointer-events:none;
  transition:opacity 240ms ease, transform 420ms cubic-bezier(.2,.8,.3,1);
}

#rebuild-story .pin.is-hover::before{
  opacity:.9;
  transform:translate(-50%,-50%) scale(1);
}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .pin,
  #rebuild-story .pin::before{transition:none}
  #rebuild-story .pin.is-hover::before{transform:translate(-50%,-50%) scale(1)}
}

/* The scene's section is class="hero", the same name the site's own hero
   component uses, so site.css's `.hero{text-align:center}` was leaking in and
   centring everything here. Reset it once for the whole scene rather than
   chasing each element that turns up centred. */
#rebuild-story .hero{text-align:left;padding-block:0}

/* ==========================================================================
   Right-hand progress rail
   ==========================================================================
   The meter stands as a vertical rail against the right edge, titled with
   whichever block the reader is standing in so the scene is always named on
   screen. The scroll note reads immediately to its left. Everything here is
   unconditional and appended last, so it supersedes the earlier bottom-centre
   placement at every width. */
#rebuild-story{--rail-gap:clamp(16px,3vw,46px);--rail-w:42px;--rail-mid:46%}

#rebuild-story .street-meter{
  left:auto;right:var(--rail-gap);
  top:var(--rail-mid);bottom:auto;
  width:auto;
  transform:translateY(-50%);
}

/* The label's two spans belong in different cells of the rail, so the wrapper
   steps out of the box tree and lets the grid place them directly. Inherited
   type and colour still flow through to the spans. */
#rebuild-story .street-meter .meter-label{display:contents}
#rebuild-story .street-meter .meter-wrap{
  display:grid;
  grid-template-columns:auto auto;
  grid-template-areas:"pct pct"
                      "bar name";
  align-items:center;justify-items:center;
  gap:10px 9px;
  max-width:none;
}
#rebuild-story .street-meter #meter-percent{
  grid-area:pct;
  color:var(--ca-gold-300);
  font-variant-numeric:tabular-nums;
}
#rebuild-story .street-meter #meter-scene{
  grid-area:name;
  writing-mode:vertical-rl;text-orientation:mixed;
  letter-spacing:.18em;white-space:nowrap;
}
#rebuild-story .street-meter .meter{
  grid-area:bar;
  width:10px;height:min(38vh,300px);
}
/* Fills downward: empty at the top, complete at the foot, so the rail reads
   the same direction as the scroll that drives it. */
#rebuild-story .street-meter .meter-fill{
  /* --bp is the active block's own tally; --p stays the global scroll, which
     the sky and the sun still ride on. */
  transform:scaleY(var(--bp,0));
  transform-origin:top center;
  background:linear-gradient(180deg,var(--ca-gold-500),#f3c758);
}

#rebuild-story .scroll-hint{
  left:auto;bottom:auto;
  top:var(--rail-mid);
  right:calc(var(--rail-gap) + var(--rail-w) + 12px);
  white-space:nowrap;
  transform:translate(6px,-50%);
}
#rebuild-story .scroll-hint.show{transform:translate(0,-50%)}

/* Short viewports: lift the rail and shorten the bar so it stays clear of the
   payoff card and the Quick Book tab, which both sit in the bottom-right. */
@media (max-height:780px){
  #rebuild-story{--rail-mid:40%}
}
@media (max-height:640px){
  #rebuild-story{--rail-mid:34%}
  #rebuild-story .street-meter .meter{height:min(30vh,300px)}
}

/* ==========================================================================
   Hero intro panel
   ==========================================================================
   The headline, lead and calls to action sit over a photographed street that
   is busy and keeps changing as the reader walks, so they get a navy panel of
   their own instead of leaning on a text-shadow to stay legible. Built from
   the same vocabulary as .tabs so the scene's furniture reads as one set. */
#rebuild-story .intro{
  padding:clamp(18px,2.4vw,30px) clamp(20px,2.6vw,34px);
  background:rgba(1,19,47,.86);
  border:1px solid rgba(248,248,248,.26);
  border-radius:var(--r-2);
  box-shadow:0 14px 40px rgba(1,19,47,.42);
}
/* The panel carries the contrast now. */
#rebuild-story .intro p{text-shadow:none}

/* ==========================================================================
   Intro collapse
   ==========================================================================
   LEAD_IN in rebuild.js reserves the head of the pinned scroll for this: the
   lead and the calls to action fold away, leaving the eyebrow and the
   headline, and only then does the first repair start. The heights come from
   measureIntro(), which reads the real line box, so the panel is never left
   holding empty space that the faded text used to occupy. */
#rebuild-story .intro p,
#rebuild-story .intro-cta{
  overflow:hidden;
  /* rebuild.js sets these in whole line boxes, so each step is one line
     leaving. Short enough to keep up with the scroll, long enough that the
     line slides away rather than blinking out. */
  transition:max-height 150ms ease, margin-top 150ms ease, opacity 150ms ease;
}
/* Once folded the buttons are invisible, so take them out of the tab order
   and out of the way of the street behind them. */
#rebuild-story .hero.intro-collapsed .intro-cta{pointer-events:none;visibility:hidden}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .intro p,
  #rebuild-story .intro-cta{transition:none}
}

/* ==========================================================================
   Dismissing the intro
   ==========================================================================
   The scroll fold leaves the eyebrow and the headline standing. The X takes
   the panel away entirely for readers who would rather just look at the
   street. Fade, lift and a slight squash rather than an animated height: the
   headline wraps to a different number of lines at different widths, so any
   max-height would either clip it or spend most of the transition on empty
   space. */
#rebuild-story .intro{
  transform-origin:top left;
  transition:opacity 260ms ease, transform 300ms cubic-bezier(.4,0,.2,1),
             visibility 0s linear 300ms;
}
#rebuild-story .hero.intro-dismissed .intro{
  opacity:0;
  transform:translateY(-14px) scaleY(.92);
  visibility:hidden;
  pointer-events:none;
}

#rebuild-story .intro-close{
  position:absolute;
  top:8px;
  right:8px;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  width:40px;
  height:40px;
  padding:0;
  background:transparent;
  border:1px solid rgba(248,248,248,.3);
  border-radius:var(--r-1);
  color:var(--ca-navy-100);
  cursor:pointer;
  /* .intro is pointer-events:none so the street stays draggable behind it. */
  pointer-events:auto;
  transition:background-color 140ms ease, color 140ms ease, border-color 140ms ease;
}
#rebuild-story .intro-close svg{width:16px;height:16px}
#rebuild-story .intro-close:hover{
  background:rgba(248,248,248,.14);
  border-color:var(--ca-paper);
  color:var(--ca-paper);
}
#rebuild-story .intro-close:focus-visible{outline:3px solid var(--ca-gold-500);outline-offset:2px}
/* Keep the eyebrow clear of the button. */
#rebuild-story .intro .eyebrow{padding-right:52px}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .intro{transition:none}
  #rebuild-story .hero.intro-dismissed .intro{transform:none}
}

/* At full collapse the panel holds only the eyebrow and the headline, so the
   headline gets the whole width. The break stays in: "What's Next." keeps its
   own line in both states. */
#rebuild-story .hero.intro-collapsed .intro h1{max-width:none}

/* ==========================================================================
   Frozen regions
   ==========================================================================
   Same crop geometry as .patch, but never animated: it sits above the decline
   image for the whole sequence. Feathered a little harder than a patch because
   the two plates are lit differently and the crop is small, so a hard edge
   would read as a lighter box around the sign. */
#rebuild-story .frozen{
  position:absolute;
  /* Above the patches and the brush canvas, both of which paint the restored
     plate and would bring the garbled lettering back over the top; below the
     hotspots at 8 so nothing is stolen from the pins. The slot is free since
     the duplicate courthouse clock came out of it. */
  z-index:6;
  overflow:hidden;
  pointer-events:none;
  -webkit-mask-image:
    linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 5%, #000 95%, transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(to right, transparent 0, #000 6%, #000 94%, transparent 100%),
    linear-gradient(to bottom, transparent 0, #000 5%, #000 95%, transparent 100%);
  mask-composite:intersect;
}
#rebuild-story .frozen img{position:absolute;max-width:none;pointer-events:none;user-select:none}

/* ==========================================================================
   Payoff calls to action
   ==========================================================================
   The rays sweep in first, then the two buttons arrive one after the other, so
   the eye lands on the headline, then the burst, then the choice. `both` holds
   them at the 0% frame through the delay, so nothing flashes before its turn. */
@keyframes payoff-btn-pop{
  0%{opacity:0;transform:translateY(10px) scale(.9)}
  62%{opacity:1;transform:translateY(0) scale(1.05)}
  100%{opacity:1;transform:translateY(0) scale(1)}
}
#rebuild-story .payoff-wrap:has(.payoff.show) .card-actions .btn{
  animation:payoff-btn-pop 380ms cubic-bezier(.2,.9,.3,1) both;
}
#rebuild-story .payoff-wrap:has(.payoff.show) .card-actions .btn:first-child{animation-delay:820ms}
#rebuild-story .payoff-wrap:has(.payoff.show) .card-actions .btn:last-child{animation-delay:980ms}

@media (prefers-reduced-motion:reduce){
  #rebuild-story .payoff-wrap:has(.payoff.show) .card-actions .btn{animation:none}
}

/* ==========================================================================
   Walk controls: one row, one height
   ==========================================================================
   The two arrows and the block list are a single control group, so they share
   a height token and the same 2px paper outline. The list carried a 1px 30%
   white border, which read as a different weight of control sitting between
   two solid ones. */
#rebuild-story{--ctrl-h:52px}

#rebuild-story .street-controls .tabs{
  height:var(--ctrl-h);
  align-items:center;
  padding:4px;
  border:2px solid var(--ca-paper);
  border-radius:3px;
}
#rebuild-story .street-controls .tab{min-height:40px}

@media (max-width:760px){
  #rebuild-story{--ctrl-h:44px}
  #rebuild-story .street-controls .tabs{padding:3px}
  #rebuild-story .street-controls .tab{min-height:34px}
  #rebuild-story .chevron svg{width:19px;height:19px}
}
@media (max-height:720px){
  #rebuild-story{--ctrl-h:44px}
  #rebuild-story .street-controls .tabs{padding:3px}
  #rebuild-story .street-controls .tab{min-height:34px}
  #rebuild-story .chevron svg{width:19px;height:19px}
}

/* The meter moved to the right-hand rail, which freed the foot of the hero, so
   the walk controls drop into it rather than floating in mid-air. */
#rebuild-story .street-controls{bottom:clamp(20px,4vh,40px)}
@media (max-height:720px){
  #rebuild-story .street-controls{bottom:18px}
}

/* At full collapse the headline is the last thing in the panel and only its
   descender reaches the bottom padding, so an equal padding top and bottom
   reads as a deeper gap below: 51px from the baseline against 34px above the
   eyebrow's caps. Drop the headline's trailing margin, which has nothing to
   separate it from once the lead has folded, and take 8px off the bottom. */
#rebuild-story .hero.intro-collapsed .intro{padding-bottom:clamp(11px,1.75vw,22px)}
#rebuild-story .hero.intro-collapsed .intro h1{margin-bottom:0}

/* A clear 25px above the headline, rather than the .16em it inherited, which
   scaled with the type and closed up as the h1 shrank on narrow screens. */
#rebuild-story .intro h1{margin-top:25px}
