/* First-visit intro: five atlas spreads over the map (direction C, docs/design/intro-stills/c.html).
   Desktop: a printed two-page spread, 1360 x 844, scaled to the window. Phone and short windows: one column, words
   above the plate. Same closed palette as the map; the only motion is the scene change, the walks drawing in, and
   small fades. Reduced motion: every scene change is instant and every drawing is complete. */
.intro{display:none}
:root[data-intro="open"] .intro{display:block}
:root[data-intro="open"] body{overflow:hidden}
/* the map keeps its size and loads underneath, but is not drawn while the intro fully covers it */
:root[data-cover] .app{visibility:hidden}
.intro{position:fixed;inset:0;z-index:100;
  /* 0.4% see-through, as the phone sheet: Chrome then keeps painting the map canvas underneath (see --paper-veil) */
  background:rgb(242 239 243 / .996);color:var(--ink);font:400 16px/1.5 var(--f-body);
  overscroll-behavior:contain;touch-action:none;outline:none;
  --ease-in-3:cubic-bezier(.32,0,.67,0)}
.intro.closing{opacity:0;transition:opacity 220ms var(--ease-in-3)}
.intro.opening{animation:intro-in 260ms var(--ease-out-4) both}
@keyframes intro-in{from{opacity:0}to{opacity:1}}
.intro p{margin:0}
.intro .vh{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ---------------- the spread (desktop) ---------------- */
.ispread{position:absolute;left:50%;top:50%;width:1360px;height:844px;transform:translate(-50%,-50%) scale(var(--s,1));transform-origin:50% 50%}
/* the spread is one sheet of paper; the gutter between its pages is a hairline element (no box or pseudo-element sits
   behind the words, so contrast tools can read them) */
.ispread{background:var(--paper);border:1px solid var(--hatch)}
.gutter{position:absolute;left:679px;top:0;bottom:0;width:1px;background:var(--hatch);z-index:3;pointer-events:none}
.rh,.folio,.skipb,.ictl{z-index:4}   /* furniture above the scenes */
.rh{position:absolute;top:24px;font-size:13px;line-height:1.3;color:var(--ink-2)}
.rh.rl{left:72px}
.rh.rr{left:728px}
.folio{position:absolute;left:72px;bottom:22px;display:flex;align-items:center;gap:12px;font:400 13px/1 var(--f-display);color:var(--ink-2)}
.folio .pips{display:flex;gap:4px}
.folio .pips i{display:block;width:14px;height:6px;border:1px solid var(--ink-2);transition:background-color 240ms var(--ease-out-3)}
.folio .pips i.on{background:var(--ink);border-color:var(--ink)}

/* the spread is scaled to fit the window; the buttons grow back so they stay 44 px or more on screen */
.ibtn{min-height:44px;min-height:max(44px,calc(44px / var(--s,1)));padding:0 16px;border:1px solid var(--ink);border-radius:3px;background:var(--paper);color:var(--ink);cursor:pointer;
  font:600 15px/1 var(--f-body);display:inline-flex;align-items:center;justify-content:center;gap:8px;
  transition:background-color 180ms var(--ease-out-3),color 180ms var(--ease-out-3),transform 180ms var(--ease-out-3)}
.ibtn.pri{background:var(--ink);color:var(--paper)}
.ibtn:active{transform:scale(.97)}
.ibtn:focus-visible{outline:2px solid var(--blue);outline-offset:2px}
.ibtn[hidden]{display:none!important}
@media (hover:hover){.ibtn:hover{background:var(--tint)}.ibtn.pri:hover{background:#3a3742}}
.skipb{position:absolute;right:40px;top:14px}
.ictl{position:absolute;right:40px;bottom:14px;display:flex;align-items:center;gap:10px}
.ictl .hint{font-size:13px;color:var(--ink-2);margin-right:6px}
kbd{font:400 12px/1 var(--f-display);border:1px solid var(--ink-2);border-radius:3px;padding:2px 5px;color:var(--ink)}

/* scenes: both pages of one spread; only the words and plates change, the paper stays */
.scene{position:absolute;inset:0;visibility:hidden;pointer-events:none}
.scene.on{visibility:visible;pointer-events:auto;z-index:1}
.scene.off{visibility:visible;z-index:2}
.scene .lp{position:absolute;left:0;top:0;width:680px;height:844px;padding:88px 72px 64px;display:flex;flex-direction:column}
.scene .rp{position:absolute;left:680px;top:0;width:680px;height:844px}
.scene h2{font:600 49px/1.04 var(--f-body);letter-spacing:-.015em;margin:0 0 24px;text-wrap:balance}
.scene .big{font-size:24px;line-height:1.4;text-wrap:pretty;max-width:34em}
.scene .big + .big{margin-top:14px}
.scene .big.res{font-weight:600}
.scene .key{margin-top:auto}
.intro .cap{font-size:13px;color:var(--ink-2);margin:0 0 6px}
.ktab{border-collapse:collapse;width:100%;font-size:14px;line-height:1.25;border-top:1px solid var(--ink)}
.ktab th,.ktab td{text-align:left;padding:5px 8px 5px 0;border-bottom:1px solid var(--rule);font-weight:400;vertical-align:baseline}
.ktab th{font-weight:600;white-space:nowrap}
.ktab td.l{font:700 13px/1 var(--f-display);color:var(--vermilion);width:20px}
.ktab td.m{font-family:var(--f-display);font-variant-numeric:tabular-nums;text-align:right;width:52px;padding-right:16px;white-space:nowrap}
.ktab td.pl{color:var(--ink-2)}
.ktab td.w{width:56px}
.ktab td.w svg{display:block}
.steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:16px;counter-reset:st}
.steps li{display:grid;grid-template-columns:36px 1fr;gap:8px;font-size:22px;line-height:1.38;text-wrap:pretty}
.steps li::before{counter-increment:st;content:counter(st);font:700 15px/1 var(--f-display);width:26px;height:26px;border-radius:50%;
  border:1.5px solid var(--ink);display:flex;align-items:center;justify-content:center;margin-top:3px}
.scene .note{font-size:15px;line-height:1.45;color:var(--ink-2);margin-top:12px;max-width:52ch}
.go{min-height:56px;padding:0 28px;font-size:19px;margin-top:28px;align-self:flex-start}

/* plates */
.plate{position:absolute;left:50px;top:72px;width:580px;height:600px;overflow:hidden}
.plate-svg{display:block;width:100%;height:100%;overflow:hidden}
.plate .plate-svg{position:absolute;inset:0}
.plate .ltop{will-change:transform}   /* its own layer: the walks repaint without the buildings under them */
.figcap{position:absolute;left:50px;top:684px;width:580px;font-size:14px;line-height:1.45;color:var(--ink-2)}
.figcap b{color:var(--ink);font-weight:600}
.plate-svg .sl,.plate-svg .snd,.plate-svg .end,.plate-svg .start{transform-box:fill-box;transform-origin:center}
/* scene 3: two street pieces */
.pieces{position:absolute;left:50px;top:72px;width:580px;display:grid;grid-template-columns:1fr 1fr;gap:32px}
.piece h3{font:600 17px/1.2 var(--f-body);margin:10px 0 2px}
.piece .sub{font-size:14px;color:var(--ink-2);margin-bottom:8px}
.piece .q{display:flex;align-items:baseline;gap:8px;margin:2px 0 8px}
.piece .q b{font:700 34px/1 var(--f-display)}
.piece .q span{font-size:14px;color:var(--ink-2)}
.piece-svg{display:block;width:100%;height:auto}
.ftab{border-collapse:collapse;width:100%;font-size:14px;line-height:1.25;border-top:1px solid var(--ink)}
.ftab th,.ftab td{text-align:left;padding:5px 6px 5px 0;border-bottom:1px solid var(--rule);font-weight:400;vertical-align:baseline}
.ftab th{color:var(--ink-2)}
.ftab td{font-family:var(--f-display);font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap;padding-right:0}
.ftab tr.bad td{color:var(--vermilion)}
.ftab tr.good td{color:var(--good)}
.pieces .figcap{position:static;grid-column:1/-1;width:auto;margin-top:4px}
.ktab.vk tr.good th{color:var(--good)}
.ktab.vk tr.bad th{color:var(--vermilion)}
.scene .colo{margin-top:auto;font-size:13px;line-height:1.5;color:var(--ink-2);max-width:62ch}

/* scene 4: the map and its details, drawn as the site shows them */
.mock{position:absolute;left:50px;top:72px;width:580px;height:600px;border:1.2px solid var(--ink);background:var(--paper);display:flex;flex-direction:column}
.mk-search{position:relative;margin:12px 14px 10px;height:38px;border:1px solid var(--ink);border-radius:3px;display:flex;align-items:center;padding:0 10px;font-size:15px}
.mk-map{position:relative;height:184px;border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);overflow:hidden}
.map-svg{display:block;width:100%;height:100%}
.mk-nums{position:relative;display:grid;grid-template-columns:1fr 1fr 1fr;padding:10px 14px 8px;border-bottom:1px solid var(--rule)}
.mk-nums b{display:block;font:700 28px/1 var(--f-display)}
.mk-nums span{display:block;font-size:13px;color:var(--ink-2);margin-top:3px}
.mk-v{position:relative;padding:6px 14px 4px;flex:1 1 auto;min-height:0}
.mk-v .t{font:600 13px/1.2 var(--f-body);margin-bottom:4px}
.mk-v table{border-collapse:collapse;width:100%;font-size:13px;line-height:1.15}
.mk-v td,.mk-v th{padding:3.5px 8px 3.5px 0;border-bottom:1px solid var(--rule);text-align:left;font-weight:400;white-space:nowrap}
.mk-v tr:last-child td,.mk-v tr:last-child th{border-bottom:0}
.mk-v th{font-weight:600}
.mk-v td.l{font:700 12px/1 var(--f-display);width:16px}
.mk-v td.m{font-family:var(--f-display);text-align:right;width:56px;padding-right:14px}
.mk-v tr.bad td.m,.mk-v tr.bad td.v{color:var(--vermilion)}
.mk-v tr.good td.v{color:var(--good)}
.mk-st{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:12px;padding:8px 14px 10px;border-top:1px solid var(--rule);font-size:13px;line-height:1.3}
.mk-st .s{color:var(--ink-2);font-size:12px}
.mk-st b{font-weight:600}
.mk-st .num{font-family:var(--f-display);margin-right:4px}
.co{position:absolute;width:26px;height:26px;border-radius:50%;background:var(--ink);color:var(--paper);font:700 14px/26px var(--f-display);text-align:center;font-style:normal}
.mk-search .co{right:-13px;top:6px}
.mk-map .co{left:calc(50% + 14px);top:calc(50% - 40px)}
.mk-nums .co{right:-13px;top:14px}
.mk-v .co{right:-13px;top:6px}
.mk-st .co{right:-13px;top:8px}

/* scene 5: key to the map */
.kplate{position:absolute;left:50px;top:72px;width:580px;height:600px;border:1.2px solid var(--ink);background:var(--paper);padding:32px 36px;display:flex;flex-direction:column;justify-content:space-between}
.kplate h3{font:600 20px/1.2 var(--f-body);margin:0 0 18px}
.kplate h4{font:600 15px/1.2 var(--f-body);margin:0 0 8px}
.kplate .blk + .blk{padding-top:18px;border-top:1px solid var(--rule)}
.kplate h3{margin-bottom:0}
.kramp{display:grid;grid-template-columns:repeat(5,1fr);height:28px;border:1px solid var(--hatch)}
.kramp i{display:block}
.kcap{display:flex;justify-content:space-between;font-size:14px;color:var(--ink-2);margin-top:4px}
.kplate p.n{font-size:14px;line-height:1.45;color:var(--ink-2);margin-top:8px}
.klist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:8px;font-size:15px}
.klist li{display:flex;align-items:center;gap:12px;line-height:1.25}
.klist svg{flex:none}

/* motion: things entering decelerate, things leaving accelerate and go faster */
.rv{opacity:0;transform:translate3d(var(--dx,0),var(--dy,12px),0);
  transition:opacity 200ms var(--ease-in-3),transform 200ms var(--ease-in-3)}
.rp .rv{--dx:44px;--dy:0px}   /* the right page turns in from the side */
.intro[data-dir="back"] .rv{--dy:-12px}
.intro[data-dir="back"] .rp .rv{--dx:-44px;--dy:0px}
.scene.on .rv{opacity:1;transform:none;transition:opacity 420ms var(--ease-out-4) calc(80ms + var(--d,0) * 60ms),transform 520ms var(--ease-out-4) calc(80ms + var(--d,0) * 60ms)}
.scene.off .rv{opacity:0;transform:translate3d(calc(var(--dx,0) * -.6),calc(var(--dy,12px) * -1),0)}
/* scene 2: the eight walks draw themselves in, nearest first; each end mark and its minutes follow its walk */
.route{stroke-dasharray:1 1;stroke-dashoffset:1}
.scene.on .route{stroke-dashoffset:0;transition:stroke-dashoffset 560ms var(--ease-out-3) calc(420ms + var(--i) * 90ms)}
.end,.snd.m{opacity:0;transform:scale(.6);transform-box:fill-box;transform-origin:center}
.scene.on .end,.scene.on .snd.m{opacity:1;transform:none;transition:opacity 200ms var(--ease-out-3) calc(860ms + var(--i) * 90ms),transform 240ms var(--ease-out-4) calc(860ms + var(--i) * 90ms)}
/* scene 1: the cells fill, then the soundings appear one by one */
/* scene 1: the cells fill palest first, deepest last, then their outlines */
.lhex use{opacity:0}
.scene.on .lhex use{opacity:1;transition:opacity 420ms var(--ease-out-3) calc(220ms + var(--i,5) * 110ms)}
.snds .snd{opacity:0}
.scene.on .snds .snd{opacity:1;transition:opacity 240ms var(--ease-out-3) calc(560ms + var(--i) * 40ms)}
/* scene 4: the numbered marks */
/* scene 4: the panel builds up as the site's does (search, map, numbers, the eight needs one by one, the streets),
   and each numbered mark arrives with its part */
.mk{opacity:0;transform:translate3d(0,8px,0)}
.scene.on .mk{opacity:1;transform:none;transition:opacity 320ms var(--ease-out-3) calc(320ms + var(--b,0) * 140ms),transform 380ms var(--ease-out-4) calc(320ms + var(--b,0) * 140ms)}
.vr{opacity:0}
.scene.on .vr{opacity:1;transition:opacity 220ms var(--ease-out-3) calc(800ms + var(--i,0) * 50ms)}
.co{opacity:0;transform:scale(.6)}
.scene.on .co{opacity:1;transform:none;transition:opacity 200ms var(--ease-out-3) calc(700ms + var(--c,0) * 300ms),transform 240ms var(--ease-out-4) calc(700ms + var(--c,0) * 300ms)}
/* scene 2: each key row arrives while its walk draws; scene 3: the blue bands run along the two streets, then the
   facts; scene 5: the key, block by block */
.kr{opacity:0;transform:translate3d(-6px,0,0)}
.scene.on .kr{opacity:1;transform:none;transition:opacity 240ms var(--ease-out-3) calc(640ms + var(--i,0) * 90ms),transform 300ms var(--ease-out-4) calc(640ms + var(--i,0) * 90ms)}
.halo{stroke-dasharray:1 1;stroke-dashoffset:1}
.scene.on .halo{stroke-dashoffset:0;transition:stroke-dashoffset 600ms var(--ease-out-3) 480ms}
.fr{opacity:0}
.scene.on .fr{opacity:1;transition:opacity 240ms var(--ease-out-3) calc(560ms + var(--i,0) * 60ms)}
.kplate .blk{opacity:0;transform:translate3d(0,8px,0)}
.scene.on .kplate .blk{opacity:1;transform:none;transition:opacity 320ms var(--ease-out-3) calc(260ms + var(--i,0) * 90ms),transform 380ms var(--ease-out-4) calc(260ms + var(--i,0) * 90ms)}

/* a leaving page keeps its drawing whole: only the page itself fades away */
.scene.off .mk,.scene.off .vr,.scene.off .co,.scene.off .kr,.scene.off .fr,.scene.off .kplate .blk,.scene.off .lhex use,.scene.off .end,.scene.off .snd.m,.scene.off .snds .snd{opacity:1;transform:none}
.scene.off .route,.scene.off .halo{stroke-dashoffset:0}

@media (prefers-reduced-motion:reduce){
  .intro,.intro *{transition:none!important;animation:none!important}
  .rv,.scene.off .rv{opacity:1;transform:none}
  .scene.off{visibility:hidden}
  .route{stroke-dashoffset:0}
  .end,.snd.m,.lhex use,.snds .snd,.co,.mk,.vr,.kr,.fr,.kplate .blk{opacity:1;transform:none}
  .halo{stroke-dashoffset:0}
}

/* ---------------- phone and short windows: one column ---------------- */
@media (max-width:899px),(max-height:599px){
  .ispread{position:absolute;inset:0;left:0;top:0;width:auto;height:auto;transform:none;background:var(--paper);border:0}
  .gutter{display:none}
  .rh,.ictl .hint{display:none}
  .folio{left:16px;bottom:auto;top:0;height:60px}
  .skipb{right:16px;top:8px}
  .ictl{left:16px;right:16px;bottom:max(12px,env(safe-area-inset-bottom));justify-content:flex-end;gap:8px}
  .ictl .ibtn{min-width:96px}
  .scene{top:60px;bottom:76px;display:flex;flex-direction:column}
  .scene .lp{position:relative;left:auto;top:auto;width:auto;height:auto;padding:4px 16px 0;display:block;flex:none}
  .scene .rp{position:relative;left:auto;top:auto;width:auto;height:auto;flex:1 1 auto;min-height:150px;margin:0 16px}
  .scene h2{font-size:clamp(26px,7.4vw,32px);line-height:1.08;margin:0 0 10px}
  .scene .big{font-size:17px;line-height:1.42}
  .scene .big + .big{margin-top:8px}
  .scene .key,.scene .note.desk,.figcap{display:none}
  .steps{gap:8px}
  .steps li{font-size:17px;grid-template-columns:30px 1fr;gap:6px}
  .steps li::before{width:22px;height:22px;font-size:13px;margin-top:0}
  .go{min-height:52px;font-size:18px;margin-top:14px}
  .scene .note{font-size:14px;margin-top:8px}
  .plate{left:0;top:12px;width:auto;right:0;bottom:12px;height:auto;border:1.2px solid var(--ink);background:var(--paper)}
  .plate-svg .grat,.plate-svg .neat,.plate-svg .scale,.plate-svg .north{display:none}
  /* a phone shows the plate smaller: intro.js sets --k (plate units per screen pixel), so the marks keep a fixed size
     on screen; the street names are left out there, the walks and numbers need the room */
  .plate-svg .sl{display:none}
  .plate-svg .snds .snd{scale:calc(var(--k,1) * 1.09)}
  .plate-svg .snd.m,.plate-svg .start{scale:calc(var(--k,1) * .93)}
  .plate-svg .end{scale:calc(var(--k,1) * .9)}
  /* grown marks take the places the generator worked out for a phone (--tx, --ty in plate units), so no minutes run
     into a marker; the drawing under the neat line continues past it, so a crop taller than the plate shows no paper */
  .plate-svg .end,.plate-svg .snd.m,.plate-svg .start{translate:calc(var(--tx,0) * 1px) calc(var(--ty,0) * 1px)}
  .plate-svg > g{clip-path:none}
  .plate-svg .routes{stroke-width:calc(var(--k,1) * 3px)}
  .pieces{left:0;right:0;top:12px;width:auto;gap:12px}
  .piece h3{font-size:15px;margin-top:6px}
  .piece .sub{font-size:13px;margin-bottom:2px}
  .piece .q{margin:0 0 4px}
  .piece .q b{font-size:24px}
  .ftab{font-size:13px}
  .ftab th,.ftab td{padding:3px 4px 3px 0}
  .mock{left:0;right:0;top:12px;width:auto;height:auto;bottom:12px}
  .mk-map{display:none}
  .mk-st{grid-template-columns:1fr;gap:2px;padding:6px 10px 8px;font-size:13px}
  .mk-st .s{display:inline;margin-right:6px}
  .mk-st br,.mk-st .why{display:none}
  .mk-st .co{right:4px;top:4px}
  .mk-v tr[hidden],.mk-v .t[hidden],.kplate .blk[hidden]{display:none}
  .mk-st .num{margin-left:6px}
  /* the panel ends where its content ends: no empty paper inside the frame */
  .mock{bottom:auto;max-height:calc(100% - 24px)}
  .mk-v{flex:0 1 auto}
  .mk-search{margin:10px 10px 8px}
  .mk-nums{padding:8px 40px 6px 10px}   /* the numbered badge sits in the right padding, never on the third label */
  .mk-nums b{font-size:24px}
  .mk-v{padding:4px 10px;overflow:hidden}
  .mk-search .co,.mk-nums .co,.mk-v .co{right:4px}
  .mk-v .co{top:2px}
  .kplate{left:0;right:0;top:12px;width:auto;height:auto;bottom:auto;max-height:calc(100% - 24px);padding:12px 14px;overflow:hidden;justify-content:flex-start;gap:8px}
  .colo{display:none}
  .kplate h3{font-size:17px}
  .kplate h4{font-size:14px;margin-bottom:5px}
  .kramp{height:20px}
  .kcap{font-size:13px;margin-top:2px}
  .kplate .blk + .blk{padding-top:8px}
  .kplate p.n{display:none}
  .klist{gap:2px;font-size:14px}
  .rp .rv{--dx:0px;--dy:12px}
  .intro[data-dir="back"] .rp .rv{--dx:0px;--dy:-12px}
}
@media (max-width:899px) and (max-height:700px),(max-height:599px){
  .scene .big.p2{display:none}
}
/* small phones: the street pieces and the panel need the room */
@media (max-width:899px) and (max-height:700px){
  .steps ~ .note{display:none}
  .piece-svg{max-height:120px;width:auto;max-width:100%;margin:0 auto}
  .piece .sub{display:none}
  .ftab th{white-space:nowrap}
}
/* short and wide (a phone held sideways): words on the left, the plate on the right, as the printed spread */
@media (max-height:599px) and (min-width:600px){
  .folio{height:48px}
  .skipb{top:2px}
  .ictl{bottom:max(8px,env(safe-area-inset-bottom))}
  .scene{top:48px;bottom:60px;flex-direction:row}
  .scene .lp{width:50%;max-width:520px;padding:0 20px 0 max(16px,env(safe-area-inset-left));overflow:hidden}
  .scene .rp{min-height:0;margin:0 max(16px,env(safe-area-inset-right)) 0 0}
  .scene h2{font-size:24px;margin-bottom:8px}
  .scene .big{font-size:15px;line-height:1.38}
  .steps{gap:6px}
  .steps li{font-size:15px;line-height:1.36}
  .scene .note{font-size:13px;margin-top:6px}
  .go{min-height:48px;font-size:17px;margin-top:10px}
  .plate{top:0;bottom:0}
  .mock,.kplate{top:0;max-height:100%}
  .steps ~ .note{display:block}
  .pieces{top:0;bottom:0;grid-template-rows:minmax(0,1fr)}
  .piece{display:flex;flex-direction:column;min-height:0}
  .piece .pc{flex:1 1 auto;min-height:0;display:flex;justify-content:center}
  .piece-svg{width:auto;height:100%;max-width:100%;max-height:none}
  .piece .sub,.piece .ftab{display:none}
  .piece h3{margin-top:4px}
}
