/* ============================================================
   I Stopped Hiding My Accent — Homework 4
   Full-screen slide deck.

   Art direction: VOICE MADE VISIBLE.

   The story is an accent — a voice that was hidden and then let
   out. So the palette is built from a lit lamp in a cold room:

     ember  warm amber, the colour of a spoken word and of a
            light switched on. The hero's own light, and the
            only warm thing on the page.
     tide   cool teal for the world that does not listen: the
            tram, the shop, the English-speaking classroom.
     paper  cold off-white type, not ivory-on-gold.

   Typography is Fraunces (a warm old-style with real personality,
   chosen over Didone, which reads fashion-magazine rather than
   first-person) over Source Sans 3.

   Layout is keynote-style: type sits directly on the artwork,
   no boxes, no frosted panels.
   (Original artwork — no game assets, trademarks or logos used.)
   ============================================================ */

:root{
  /* ground — cool near-black, never flat #000 */
  --ink:       #0C1017;
  --ink-2:     #131923;
  --ink-3:     #1C242F;
  --ink-4:     #28323F;

  /* ember — the voice, the lamp, the one warm light */
  --ember:     #E08A4E;
  --ember-lt:  #F4B583;
  --ember-pale:#FBD8B6;
  --ember-dim: #A86234;
  --ember-deep:#6E3E1E;

  /* tide — the world outside: cold, indifferent, not malevolent */
  --tide:      #5E93A8;
  --tide-lt:   #93BECD;
  --tide-dim:  #3E6476;

  /* paper — cold off-white, never ivory */
  --paper:     #EDF1F5;
  --paper-2:   #BAC5D0;
  --paper-3:   #8593A1;

  /* semantic pair: the rule asks for outside -> inside, so the two
     sides of the story get the two temperatures */
  --before:      #B0503C;   /* external challenge — a shut door, warm red */
  --before-lt:   #D98066;
  --after:       #4E9C86;   /* inner life changed — a window opening */
  --after-lt:    #86C6B0;

  /* hairlines */
  --line:      rgba(224,138,78,.15);
  --line-2:    rgba(224,138,78,.32);
  --line-soft: rgba(224,138,78,.07);
  --line-hot:  rgba(224,138,78,.6);
  --line-tide: rgba(94,147,168,.3);

  --serif:"Fraunces","Iowan Old Style","Palatino Linotype",Georgia,serif;
  --sans:"Source Sans 3","Segoe UI",-apple-system,"Helvetica Neue",Arial,sans-serif;

  --pad:clamp(26px,4vw,58px);
  /* The frame sits this far in from the viewport edge. Every fixed
     control is placed *inside* that line — otherwise the frame's bottom
     hairline slices straight through the page counter. */
  --frame:clamp(16px,1.7vw,26px);

  /* The page-note tab lives in the margin between the frame and the text,
     and that margin is exactly one --pad wide. --tab-w + --tab-gap must
     therefore never exceed --pad at the width being rendered, which is why
     both are stepped down at the same breakpoints --pad is. Declared here
     as numbers rather than lengths on purpose: the tab's width has to be
     known to CSS so its position needs no measurement. */
  --tab-w:24px;
  --tab-gap:8px;

  /* The slide's OWN horizontal padding. It equals --pad everywhere except
     on a phone, where the copy column has to give the note tab its own
     strip. The tab is positioned from this rather than from --pad directly:
     `left` resolves against the padding box, so the two must not be allowed
     to drift apart or the tab walks off the left edge of the screen. */
  --pad-x:var(--pad);
}

*{box-sizing:border-box;margin:0;padding:0;}

html,body{height:100%;}
body{
  font-family:var(--sans);
  color:var(--paper);
  background:var(--ink);
  line-height:1.72;
  overflow:hidden;
  -webkit-font-smoothing:antialiased;
}

/* ============================================================
   ILLUSTRATION LAYER (per-slide original vector art)
   ============================================================ */
.slide__art{
  position:absolute;inset:0;z-index:0;overflow:hidden;
  opacity:0;transform:scale(1.05);
  transition:opacity 1s ease,transform 2s cubic-bezier(.2,.7,.3,1);
  /* An opaque bed of its own. Inheriting the slide's ink used to be
     invisible; once the artwork was brightened it showed through the
     Ken Burns offset as a hard black rectangle in the corner. */
  background:#141A23;
}
/* the lift: a cool ambient wash rather than a heavier filter, so the
   drawing's own gradients keep their smoothness */
.slide__art::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  /* Two layers doing different jobs: a soft key light where each drawing's
     subject sits, and a floor bounce so the lower third is not a void.
     plain alpha, not screen -- screen against an already-dark plate barely
     registers, and the multiply-safe route is to lift with opaque warmth. */
  background:
    radial-gradient(74% 58% at 63% 38%,rgba(233,168,116,.38),rgba(224,138,78,.18) 50%,rgba(224,138,78,0) 78%),
    radial-gradient(130% 76% at 50% 106%,rgba(120,148,168,.34),rgba(86,116,138,.16) 46%,rgba(70,96,116,0) 76%),
    linear-gradient(180deg,rgba(96,120,142,.18),rgba(72,94,116,.06) 52%,rgba(56,74,94,.2));
  animation:ambientBreath 15s ease-in-out infinite;
  --amb:.88;
}
@keyframes ambientBreath{
  0%,100%{opacity:var(--amb,.88)}
  50%    {opacity:min(1,calc(var(--amb,.88) * 1.14))}
}
.slide__art-in{
  position:absolute;inset:0;
  transform-origin:72% 50%;
  will-change:transform;
}
.slide__art img{
  width:100%;height:100%;object-fit:cover;object-position:60% 50%;display:block;
  /* A large brightness() multiplier amplifies 8-bit banding: the artwork's
     soft sky gradient turns into visible rectangular contours. Lifting the
     midtones gently and adding a cool ambient wash gets the same readable
     range without touching the quantisation. */
  filter:saturate(1.08) contrast(.98) brightness(1.2);
}
/* The artwork also carries its own left-edge quiet zone, baked into each
   SVG. That is eased in build-tools/anim.py, not here. */
/* Per-page framing. The subject of each drawing lives in a different part
   of the canvas, and the copy always holds the left — so pick, per page,
   the horizontal window that keeps the subject in the clear right half.
   Every plate here is composed with its subject on the x 880..1760 band
   and its own baked-in quiet zone across the left, so the windows sit a
   little further right than Homework 4's did. */
.slide:nth-child(1)  .slide__art img{object-position:66% 50%;}  /* the cap      */
.slide:nth-child(2)  .slide__art img{object-position:68% 50%;}  /* conductors   */
.slide:nth-child(3)  .slide__art img{object-position:64% 50%;}  /* the split    */
.slide:nth-child(4)  .slide__art img{object-position:67% 50%;}  /* the votes    */
.slide:nth-child(5)  .slide__art img{object-position:67% 50%;}  /* the frames   */
.slide:nth-child(6)  .slide__art img{object-position:64% 50%;}  /* the chair    */
.slide:nth-child(7)  .slide__art img{object-position:67% 50%;}  /* resolution   */
.slide:nth-child(8)  .slide__art img{object-position:63% 50%;}  /* the stake    */
.slide:nth-child(9)  .slide__art img{object-position:56% 50%;}  /* two ways     */
.slide:nth-child(10) .slide__art img{object-position:63% 50%;}  /* the building */
.slide:nth-child(11) .slide__art img{object-position:67% 50%;}  /* the doors    */

/* Brightness ceiling per page. The pendant lamp, the projected seal and the
   three open doors carry their own light; the shared ambient wash would push
   them into overexposure, so its ceiling drops per page. Because the
   keyframes animate opacity, this has to be a variable, not a plain
   opacity (an animation always wins over a static declaration). */
.slide:nth-child(6)  .slide__art::after{--amb:.74;}
.slide:nth-child(7)  .slide__art::after{--amb:.70;}
.slide:nth-child(8)  .slide__art::after{--amb:.72;}
.slide:nth-child(9)  .slide__art::after{--amb:.72;}
.slide:nth-child(11) .slide__art::after{--amb:.70;}
/* The ambient-light layer lives on .slide__art::after (see MOTION/ART
   section). Nothing is disabled here -- every illustration carries its own
   feathered quiet zone exactly where the copy sits. */
.slide.is-active .slide__art{opacity:1;transform:scale(1);}
.slide.is-prev  .slide__art{opacity:0;transform:scale(1.03);}

/* ============================================================
   DECK / SLIDES
   ============================================================ */
/* overflow:hidden is load-bearing, not tidiness. An inactive .slide sits at
   translateX(48px) as its entrance offset, and every slide is inset:0, so
   without a clip the stage is 45px wider than the viewport and the whole
   document can be scrolled sideways off a slide you are not looking at. */
.deck{height:100vh;height:100dvh;width:100%;position:relative;overflow:hidden;}

.slide{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:flex-start;
  padding:calc(var(--pad) + 22px) var(--pad-x) calc(var(--pad) + 22px);
  opacity:0;visibility:hidden;transform:translateX(48px) scale(.996);
  transition:opacity .6s ease,transform .6s ease,visibility .6s;
  overflow:hidden;
  background:var(--ink);
}

/* ---- the frame: one hairline + four corner marks ----
   z 11, above the copy column (10) and the art hot zone (2), so the
   hairline reads as a frame drawn OVER the page rather than a border
   the content can hide behind. */
.slide::before{
  content:"";position:absolute;
  inset:var(--frame);
  border:1px solid var(--line);
  pointer-events:none;z-index:11;
}
.slide::after{
  content:"";position:absolute;
  inset:var(--frame);
  background:
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 0 0/22px 1px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 0 0/1px 22px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 100% 0/100% 1px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 100% 0/1px 22px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 0 100%/22px 1px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 0 100%/1px 22px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 100% 100%/100% 1px no-repeat,
    linear-gradient(90deg,var(--line-hot),var(--line-hot)) 100% 100%/1px 22px no-repeat;
  pointer-events:none;z-index:11;opacity:.9;
}

.slide.is-active{opacity:1;visibility:visible;transform:none;z-index:2;}
.slide.is-prev{opacity:0;visibility:visible;transform:translateX(-48px) scale(.996);z-index:1;}

@media (prefers-reduced-motion:reduce){
  .slide,.slide__art{transition:none;}
}

/* ============================================================
   CONTENT — text sits directly on the artwork
   ============================================================ */
.slide__inner{
  position:relative;z-index:10;width:100%;max-width:min(600px, 47vw);
  margin:0 auto 0 0;
  padding:clamp(4px,1vh,10px) 0;
  background:none;
  border:none;box-shadow:none;backdrop-filter:none;
}
/* the only scrim allowed: a soft directional veil, no edges, no frame.
   it is deliberately wide and very light — the illustration's own baked-in
   quiet zone does most of the work. */
.slide__inner::before{
  content:"";position:absolute;
  left:-18%;right:-52%;top:-22%;bottom:-22%;
  /* Sized so the gradient reaches zero INSIDE its own box. A radial veil
     whose ellipse is smaller than the element it sits on gets clipped at
     a non-zero alpha, and that clip is a visible rectangle. The colour is
     the ink hue, not neutral black: over a cool scene a neutral scrim also
     shifts hue, so the veil reads as a plate rather than as shade. */
  background:radial-gradient(118% 96% at 6% 50%,
    rgba(11,15,22,.66) 0%, rgba(11,15,22,.46) 38%,
    rgba(11,15,22,.17) 64%, rgba(11,15,22,0) 82%);
  pointer-events:none;z-index:0;
}
.slide__inner > *{position:relative;z-index:1;}

/* ============================================================
   TYPE
   ============================================================ */
.eyebrow{
  font-size:clamp(.66rem,.86vw,.8rem);font-weight:400;
  letter-spacing:.38em;text-transform:uppercase;
  color:var(--ember);
  margin-bottom:14px;
  text-shadow:0 0 22px rgba(224,138,78,.35);
}

.title{
  font-family:var(--serif);
  /* The headline is set against its COLUMN, not the viewport. The column is
     600px wide from 1280 to 1700px, and 6.2vw put the type at 99px there:
     four lines instead of the two the <br> asks for, and 476px of headline
     in a 740px slide. Measured against the real font: 48px is the largest
     size that still sets both lines whole in a 600px column, so the ceiling
     is 3.1rem and the viewport term only has to carry the narrow end. */
  font-size:clamp(2.4rem,3vw,3.1rem);
  /* Display type needs real leading. At 99px with line-height 1 the
     descenders of line one ("Stopped", "Hiding") bottom out ~4px BELOW
     the cap of line two -- the two lines touch, and there is no room at
     all for the acute mark. 1.2 opens a genuine gap. */
  font-weight:500;line-height:1.2;letter-spacing:-.022em;
  color:var(--paper);
  text-shadow:0 2px 30px rgba(0,0,0,.8);
}
.title em{
  font-style:italic;font-weight:400;
  color:var(--ember-lt);
  text-shadow:0 0 34px rgba(224,138,78,.45);
}

/* ============================================================
   THE ACUTE  ´
   The whole story turns on one word with two meanings: an accent
   of speech, and the mark ´ that tells you where to stress it.
   So the mark is drawn over "Accent" -- it falls into place, the
   way a spoken word lands, then breathes like a lit filament.
   ============================================================ */
.stressed{position:relative;display:inline-block;}
.stressed::before{
  content:"\00B4";                 /* MODIFIER LETTER ACUTE ACCENT */
  position:absolute;
  left:.30em;top:-.34em;
  font-family:var(--sans);
  font-size:.60em;font-style:normal;font-weight:500;
  line-height:1;
  color:#FFF3E2;
  text-shadow:0 0 10px rgba(255,243,226,.95),
              0 0 30px rgba(240,170,110,.9),
              0 0 64px rgba(224,138,78,.6);
  pointer-events:none;
}
/* it lands, then keeps a small pulse -- the "stress" in stress-mark */
@keyframes acuteDrop{
  0%  {opacity:0;transform:translateY(-.9em) scale(.6) rotate(-14deg);}
  55% {opacity:1;transform:translateY(.06em) scale(1.12) rotate(3deg);}
  78% {transform:translateY(-.03em) scale(.97) rotate(-1deg);}
  100%{opacity:1;transform:none;}
}
.slide.is-active .stressed::before{
  animation:acuteDrop .95s cubic-bezier(.2,.9,.3,1) .78s both;
}
@keyframes acuteGlow{
  0%,100%{opacity:.72;filter:saturate(1);}
  50%    {opacity:1;  filter:saturate(1.15) brightness(1.12);}
}
.slide.is-active .stressed::after{
  content:"";position:absolute;
  left:.23em;top:-.40em;
  width:.42em;height:.24em;
  border-radius:50%;
  background:radial-gradient(circle,rgba(255,232,206,.6),rgba(224,138,78,0) 70%);
  pointer-events:none;
  animation:acuteGlow 4.2s ease-in-out 1.7s infinite;
}

.h2{
  font-family:var(--serif);
  font-size:clamp(2.15rem,3.9vw,3.7rem);
  font-weight:500;line-height:1.04;letter-spacing:-.016em;
  color:var(--paper);margin-bottom:22px;
  text-shadow:0 2px 30px rgba(0,0,0,.9),0 0 90px rgba(0,0,0,.7);
}

.lede{
  font-size:clamp(1.24rem,1.62vw,1.62rem);font-weight:300;line-height:1.5;
  color:var(--paper-2);max-width:30ch;margin-top:22px;
  text-shadow:0 2px 24px rgba(0,0,0,.95),0 0 60px rgba(0,0,0,.7);
}

.p{
  font-size:clamp(1.12rem,1.32vw,1.42rem);font-weight:300;line-height:1.62;
  color:var(--paper-2);margin-bottom:15px;max-width:34ch;
  text-shadow:0 2px 22px rgba(0,0,0,.95),0 0 58px rgba(0,0,0,.7);
}
.p--lead{color:var(--paper);font-weight:400;}
.p--italic{font-style:italic;color:var(--paper-3);}

/* the rule — a hairline that fades out, never a solid bar */
.rule{
  width:104px;height:1px;margin:26px 0 0;
  background:linear-gradient(90deg,var(--ember),rgba(224,138,78,0));
  position:relative;
}
.rule::after{
  content:"";position:absolute;left:0;top:-1.5px;
  width:4px;height:4px;background:var(--ember-lt);
  transform:rotate(45deg);
}

/* ============================================================
   TITLE PAGE META
   ============================================================ */
.meta{
  display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:16px 24px;margin-top:28px;padding-top:22px;
  border-top:1px solid var(--line);
}
.meta__item{display:flex;flex-direction:column;gap:4px;}
.meta__label{
  font-size:.6rem;font-weight:400;letter-spacing:.3em;
  text-transform:uppercase;color:var(--ember-dim);
}
.meta__val{
  font-size:clamp(.88rem,1.18vw,.96rem);font-weight:300;
  color:var(--paper);letter-spacing:.01em;
}

.badge{
  display:inline-block;margin-top:26px;
  padding:6px 0;
  border:none;border-bottom:1px solid var(--line-2);
  font-size:.64rem;font-weight:400;letter-spacing:.3em;text-transform:uppercase;
  color:var(--ember-lt);background:none;
}


/* ============================================================
   QUOTE (the rule)
   ============================================================ */
.quote{
  position:relative;
  background:none;
  border-left:1px solid var(--ember);
  color:var(--paper);
  padding:18px 22px;margin:6px 0 16px;
  font-family:var(--serif);font-size:clamp(1.1rem,2.05vw,1.42rem);
  font-weight:400;font-style:italic;line-height:1.44;
  text-shadow:0 2px 20px rgba(0,0,0,.8);
}
.quoteSimple{
  font-size:clamp(.9rem,1.24vw,.98rem);font-weight:300;
  color:var(--paper-2);margin-bottom:22px;max-width:50ch;
  text-shadow:0 2px 18px rgba(0,0,0,.9);
}

/* ============================================================
   FLOW DIAGRAM
   ============================================================ */
.flow{display:flex;align-items:stretch;gap:12px;}
.flow__box{
  flex:1;position:relative;
  background:none;
  border-top:1px solid var(--line-2);
  padding:14px 4px 0;text-align:center;
}
.flow__box::before{
  content:"";position:absolute;left:50%;top:-1px;
  width:5px;height:5px;background:var(--ember);
  transform:translateX(-50%) rotate(45deg);
}
.flow__box--outside{border-color:rgba(158,59,76,.4);}
.flow__box--outside::before,.flow__box--outside::after{border-color:var(--before);}
.flow__box--inside{border-color:rgba(46,107,88,.44);}
.flow__box--inside::before,.flow__box--inside::after{border-color:var(--after-lt);}
.flow__tag{
  display:block;font-size:clamp(.72rem,.62vw,.82rem);font-weight:500;
  letter-spacing:.2em;text-transform:uppercase;margin-bottom:6px;
  color:var(--ember);
}
.flow__box--outside .flow__tag{color:var(--before-lt);}
.flow__box--inside .flow__tag{color:var(--after-lt);}
.flow__desc{display:block;font-size:.8rem;font-weight:300;color:var(--paper-3);line-height:1.5;}

.flow__arrow{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:4px;min-width:80px;
}
.flow__arrowLabel{
  font-size:clamp(.7rem,.6vw,.8rem);font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ember-dim);
}
.flow__arrowGlyph{
  font-size:1.15rem;color:var(--ember);line-height:1;
  text-shadow:0 0 18px rgba(224,138,78,.5);
}

/* ============================================================
   CARDS (two problems)
   ============================================================ */
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,2.6vw,34px);margin-bottom:20px;}

.card{
  position:relative;
  background:none;
  border:none;
  padding:0 0 0 20px;
  border-left:1px solid var(--line-2);
}
/* .card::after veil removed -- see .slide__inner::before */

.card > *{position:relative;z-index:1;}
/* a small warm tick at the head of the rule */
.card::before{
  content:"";position:absolute;left:-1px;top:3px;
  width:5px;height:5px;background:var(--ember);
  transform:rotate(45deg);
}
.card__title{
  font-family:var(--serif);
  font-size:clamp(1.2rem,1.55vw,1.5rem);
  font-weight:500;color:var(--ember-lt);margin-bottom:10px;letter-spacing:.005em;
}
.card p{
  font-size:clamp(1.02rem,1.16vw,1.2rem);font-weight:300;
  color:var(--paper-2);margin-bottom:9px;line-height:1.6;
}
.card__aside{
  font-style:italic;font-weight:300;
  color:var(--paper);padding-top:10px;border-top:1px solid var(--line);
}

/* ============================================================
   BAND (the hard part / in short)
   ============================================================ */
.band{
  position:relative;
  clear:both;
  background:none;
  border:none;
  border-left:1px solid var(--ember);
  padding:8px 0 8px 22px;
}
.band--outside{border-left-color:var(--before);}
.band--inside{border-left-color:var(--after-lt);}
.band--strong{border-left-width:2px;}
.band__tag{
  display:block;font-size:clamp(.72rem,.62vw,.82rem);font-weight:500;letter-spacing:.24em;
  text-transform:uppercase;color:var(--ember);margin-bottom:6px;
}
.band--outside .band__tag{color:var(--before-lt);}
.band--inside .band__tag{color:var(--after-lt);}
.band p{font-size:clamp(1.04rem,1.2vw,1.24rem);font-weight:300;color:var(--paper-2);margin:0;}
.band strong{color:var(--ember-lt);font-weight:400;}

/* ============================================================
   STATEMENT (turning point)
   ============================================================ */
.statement{
  position:relative;
  margin-top:22px;padding:4px 0 4px 24px;
  background:none;
  border-left:1px solid var(--ember);
  font-family:var(--serif);
  font-size:clamp(1.06rem,1.95vw,1.38rem);
  font-weight:400;font-style:italic;line-height:1.46;color:var(--paper);
  text-shadow:0 2px 20px rgba(0,0,0,.8);
}

/* ============================================================
   COMPARE (before / after)
   ============================================================ */
.grid2--compare{gap:16px;}
.compare{
  position:relative;
  background:none;
  border:none;
  padding:0 0 0 20px;
  border-left:1px solid var(--line-2);
}
.compare::before{
  content:"";position:absolute;left:-1px;top:2px;
  width:5px;height:5px;background:currentColor;
  color:var(--ember-dim);transform:rotate(45deg);
}
/* .compare::after veil removed -- see .slide__inner::before */

.compare > *{position:relative;z-index:1;}
.compare--before{border-left-color:rgba(176,80,60,.5);}
.compare--after{border-left-color:rgba(78,156,134,.55);}
.compare__tag{
  font-family:var(--serif);
  font-size:clamp(.84rem,1.36vw,.98rem);font-weight:500;
  letter-spacing:.3em;text-transform:uppercase;
  margin-bottom:12px;
}
.compare--before .compare__tag{color:var(--before-lt);}
.compare--after .compare__tag{color:var(--after-lt);}
.compare ul{list-style:none;}
.compare li{
  position:relative;padding-left:18px;margin-bottom:9px;
  font-size:clamp(1.04rem,1.18vw,1.22rem);font-weight:300;
  color:var(--paper-2);line-height:1.56;
}
.compare ul{margin-bottom:2px;}
.compare li:last-child{margin-bottom:0;}
.compare li::before{
  content:"";position:absolute;left:0;top:.66em;
  width:8px;height:1px;background:var(--ember);
}
.compare--before li::before{background:var(--before-lt);}
.compare--after li::before{background:var(--after-lt);}

/* ============================================================
   MAPPING (rule applied)
   ============================================================ */
.mapping{
  position:relative;
  background:none;
  border:none;
  margin-bottom:20px;
  border-top:1px solid var(--line-2);
}
/* .mapping::after veil removed -- see .slide__inner::before */

.mapping > *{position:relative;z-index:1;}
.mapping__row{
  display:grid;grid-template-columns:130px 1fr;gap:18px;align-items:start;
  padding:14px 20px;border-bottom:1px solid var(--line-soft);
}
.mapping__row:last-child{border-bottom:none;}
.mapping__label{
  font-size:clamp(.74rem,.64vw,.84rem);font-weight:500;letter-spacing:.18em;
  text-transform:uppercase;line-height:1.55;padding-top:2px;
}
.mapping__label--outside{color:var(--before-lt);}
.mapping__label--inside{color:var(--after-lt);}
.mapping__label--proof{color:var(--ember);}
.mapping__row p{
  font-size:clamp(1.02rem,1.16vw,1.2rem);font-weight:300;
  color:var(--paper-2);margin:0;line-height:1.6;
}

.closing{
  font-family:var(--serif);
  font-size:clamp(1.08rem,2vw,1.38rem);
  font-style:italic;font-weight:400;line-height:1.46;color:var(--ember-pale);
  padding:16px 22px;
  border-top:1px solid var(--line-2);
  text-shadow:0 0 30px rgba(224,138,78,.28);
}

/* ============================================================
   CONTROLS
   ============================================================ */
.dots{
  position:fixed;left:50%;transform:translateX(-50%);
  bottom:calc(var(--frame) + 16px);z-index:40;
  display:flex;gap:10px;
}
.dots button{
  width:7px;height:7px;padding:0;transform:rotate(45deg);
  background:transparent;
  border:1px solid rgba(224,138,78,.4);
  cursor:pointer;transition:all .35s ease;
}
.dots button:hover{background:var(--ember);border-color:var(--ember-lt);box-shadow:0 0 12px rgba(224,138,78,.7);}
.dots button.is-on{
  background:var(--ember-lt);border-color:var(--ember-lt);
  box-shadow:0 0 16px rgba(224,138,78,.8);
}

.navbtns{
  position:fixed;right:calc(var(--frame) + 14px);
  bottom:calc(var(--frame) + 12px);z-index:40;display:flex;gap:9px;
}
.navbtn{
  width:38px;height:38px;
  background:none;
  border:1px solid var(--line);
  color:var(--ember);
  font-size:1.1rem;line-height:1;cursor:pointer;
  transition:all .3s ease;
}
.navbtn:hover{
  background:rgba(224,138,78,.12);
  border-color:var(--ember);color:var(--ember-lt);
  box-shadow:0 0 22px rgba(224,138,78,.3);
}

.counter{
  position:fixed;left:calc(var(--frame) + 18px);
  bottom:calc(var(--frame) + 17px);z-index:40;
  font-family:var(--serif);font-size:.98rem;font-weight:400;
  color:var(--paper-3);letter-spacing:.12em;
}
.counter #curNum{color:var(--ember);}

/* ============================================================
   MOTION LAYER
   Everything moves: the artwork drifts, the copy rises in a
   cascade, the frame breathes, dust floats up in the lamplight.
   All of it collapses to static under prefers-reduced-motion.
   ============================================================ */

/* ---- 1. KEN BURNS: the illustration is never still ---- */
/* Scale only. A translate() here drags the drawing's own edge into frame
   and it reads as a rectangle seam against the art layer's bed. */
@keyframes kbDrift{
  0%   {transform:scale(1.055);}
  50%  {transform:scale(1.008);}
  100% {transform:scale(1.055);}
}
.slide.is-active .slide__art-in{animation:kbDrift 34s ease-in-out infinite;}
@media (min-aspect-ratio:1/1){
  .slide.is-active .slide__art-in{animation-name:kbDriftWide;}
}
@keyframes kbDriftWide{
  0%   {transform:scale(1.07);}
  50%  {transform:scale(1.02);}
  100% {transform:scale(1.07);}
}
@media (max-width:760px){
  @keyframes kbDrift{
    0%{transform:scale(1.04)}
    50%{transform:scale(1.008)}
    100%{transform:scale(1.04)}
  }
}

/* ---- 2. COPY CASCADE: each block rises on its own beat ---- */
@keyframes riseIn{
  from{opacity:0;transform:translate3d(0,26px,0);filter:blur(6px);}
  to  {opacity:1;transform:none;filter:blur(0);}
}
html.js .slide__inner > *{
  opacity:0;
}
.slide.is-active .slide__inner > *{
  animation:riseIn .95s cubic-bezier(.18,.72,.24,1) both;
}
/* staggered beats down the column */
.slide.is-active .slide__inner > *:nth-child(1){animation-delay:.06s;}
.slide.is-active .slide__inner > *:nth-child(2){animation-delay:.16s;}
.slide.is-active .slide__inner > *:nth-child(3){animation-delay:.26s;}
.slide.is-active .slide__inner > *:nth-child(4){animation-delay:.36s;}
.slide.is-active .slide__inner > *:nth-child(5){animation-delay:.46s;}
.slide.is-active .slide__inner > *:nth-child(6){animation-delay:.56s;}
.slide.is-active .slide__inner > *:nth-child(7){animation-delay:.66s;}
.slide.is-active .slide__inner > *:nth-child(8){animation-delay:.76s;}
.slide.is-active .slide__inner > *:nth-child(9){animation-delay:.86s;}
.slide.is-active .slide__inner > *:nth-child(10){animation-delay:.96s;}

/* inner rows of a block also cascade */
.slide.is-active .card,
.slide.is-active .compare,
.slide.is-active .flow__box,
.slide.is-active .mapping__row,
.slide.is-active .mapping,
.slide.is-active .band,
.slide.is-active .quote,
.slide.is-active .statement,
.slide.is-active .closing{
  animation:riseIn .9s cubic-bezier(.18,.72,.24,1) both;
}
.slide.is-active .grid2 > :nth-child(1){animation-delay:.34s;}
.slide.is-active .grid2 > :nth-child(2){animation-delay:.46s;}
.slide.is-active .flow__box--outside{animation-delay:.36s;}
.slide.is-active .flow__arrow{animation:riseIn .9s cubic-bezier(.18,.72,.24,1) .46s both;}
.slide.is-active .flow__box--inside{animation-delay:.56s;}
.slide.is-active .mapping__row:nth-child(1){animation-delay:.30s;}
.slide.is-active .mapping__row:nth-child(2){animation-delay:.40s;}
.slide.is-active .mapping__row:nth-child(3){animation-delay:.50s;}
.slide.is-active .compare--before{animation-delay:.30s;}
.slide.is-active .compare--after{animation-delay:.44s;}
.slide.is-active .band{animation-delay:.66s;}
.slide.is-active .closing{animation-delay:.62s;}

/* list items inside the compare cards */
@keyframes riseInSm{
  from{opacity:0;transform:translate3d(-10px,0,0);}
  to  {opacity:1;transform:none;}
}
.slide.is-active .compare li{animation:riseInSm .7s cubic-bezier(.2,.7,.3,1) both;}
.slide.is-active .compare--before li:nth-child(1){animation-delay:.42s;}
.slide.is-active .compare--before li:nth-child(2){animation-delay:.50s;}
.slide.is-active .compare--before li:nth-child(3){animation-delay:.58s;}
.slide.is-active .compare--before li:nth-child(4){animation-delay:.66s;}
.slide.is-active .compare--after  li:nth-child(1){animation-delay:.56s;}
.slide.is-active .compare--after  li:nth-child(2){animation-delay:.64s;}
.slide.is-active .compare--after  li:nth-child(3){animation-delay:.72s;}
.slide.is-active .compare--after  li:nth-child(4){animation-delay:.80s;}

/* ---- 3. THE FRAME: a slow shimmer runs round the border ---- */
@keyframes frameSweep{
  0%,100%{opacity:.55;}
  50%    {opacity:1;}
}
.slide.is-active::after{animation:frameSweep 6.5s ease-in-out infinite;}

@keyframes frameBreathe{
  0%,100%{opacity:.62;}
  50%    {opacity:1;}
}
.slide.is-active::before{animation:frameBreathe 6.5s ease-in-out infinite;}

/* ---- 4. THE RULE: draws itself, then the diamond pulses ---- */
@keyframes ruleDraw{
  from{width:0;opacity:0;}
  to  {width:104px;opacity:1;}
}
.slide.is-active .rule{animation:ruleDraw 1.1s cubic-bezier(.2,.8,.3,1) .34s both;}
@keyframes diamondPulse{
  0%,100%{transform:rotate(45deg) scale(1);box-shadow:0 0 0 rgba(244,181,131,0);}
  50%    {transform:rotate(45deg) scale(1.5);box-shadow:0 0 14px rgba(244,181,131,.9);}
}
.slide.is-active .rule::after{animation:diamondPulse 3.4s ease-in-out infinite .9s;}

/* ---- 5. TYPE: the ember line breathes ---- */
@keyframes emberBreath{
  0%,100%{text-shadow:0 0 22px rgba(224,138,78,.28);}
  50%    {text-shadow:0 0 40px rgba(224,138,78,.62);}
}
.slide.is-active .eyebrow{
  animation:riseIn .95s cubic-bezier(.18,.72,.24,1) .06s both,
            emberBreath 5.2s ease-in-out 1.1s infinite;
}
@keyframes emBreath{
  0%,100%{text-shadow:0 0 26px rgba(224,138,78,.34);}
  50%    {text-shadow:0 0 52px rgba(224,138,78,.72);}
}
.slide.is-active .title em{animation:emBreath 6s ease-in-out 1.4s infinite;}

/* ---- 6. GLASS CARDS: light drifts across the panels ---- */
@keyframes sheen{
  0%,100%{background-position:-160% 0;}
  50%    {background-position:260% 0;}
}

.slide.is-active .card,
.slide.is-active .flow__box,
.slide.is-active .band,
.slide.is-active .compare,
.slide.is-active .mapping{
  animation:riseIn .9s cubic-bezier(.18,.72,.24,1) both;
}

/* ---- 7. FLOATING DUST (global, above the art, below the copy) ---- */
.motes{
  position:fixed;inset:0;z-index:2;pointer-events:none;overflow:hidden;
}
.mote{
  position:absolute;border-radius:50%;
  background:radial-gradient(circle,rgba(251,216,182,.95),rgba(224,138,78,.28) 42%,rgba(224,138,78,0) 72%);
  animation:moteRise linear infinite;
  will-change:transform,opacity;
}
@keyframes moteRise{
  0%  {transform:translate3d(0,10vh,0) scale(.5);opacity:0;}
  12% {opacity:.85;}
  80% {opacity:.5;}
  100%{transform:translate3d(var(--dx,20px),-96vh,0) scale(1.15);opacity:0;}
}

/* ---- 8. FILM GRAIN: keeps the blacks from banding ---- */
.grain{
  position:fixed;inset:-40%;z-index:3;pointer-events:none;
  opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grainShift 1.1s steps(4,end) infinite;
}
@keyframes grainShift{
  0%  {transform:translate3d(0,0,0);}
  25% {transform:translate3d(-3%,2%,0);}
  50% {transform:translate3d(2%,-3%,0);}
  75% {transform:translate3d(-2%,-2%,0);}
  100%{transform:translate3d(0,0,0);}
}

/* ---- 9. UI: arrows pulse, the active diamond breathes ---- */
@keyframes arrowGlow{
  0%,100%{box-shadow:0 0 0 rgba(224,138,78,0);border-color:var(--line-2);}
  50%    {box-shadow:0 0 18px rgba(224,138,78,.28);border-color:var(--line-2);}
}
.navbtn{animation:arrowGlow 4.4s ease-in-out infinite;}
.navbtn:disabled{animation:none;}
@keyframes dotBreath{
  0%,100%{box-shadow:0 0 10px rgba(224,138,78,.55);}
  50%    {box-shadow:0 0 22px rgba(224,138,78,1);}
}
.dots button.is-on{animation:dotBreath 2.6s ease-in-out infinite;}

/* ---- 10. REDUCED MOTION: everything holds a still, elegant pose ---- */
@media (prefers-reduced-motion:reduce){
  .slide__inner > *,
  .slide.is-active .slide__inner > *,
  .slide.is-active .card,
  .slide.is-active .compare,
  .slide.is-active .flow__box,
  .slide.is-active .flow__arrow,
  .slide.is-active .mapping,
  .slide.is-active .mapping__row,
  .slide.is-active .band,
  .slide.is-active .quote,
  .slide.is-active .statement,
  .slide.is-active .closing,
  .slide.is-active .compare li,
  .slide.is-active .rule{
    animation:none !important;opacity:1 !important;
    transform:none !important;filter:none !important;
  }
  .slide.is-active .slide__art-in,
  .slide.is-active::before,
  .slide.is-active::after,
  .slide.is-active .rule::after,
  .slide.is-active .eyebrow,
  .slide.is-active .title em,
  .mote,.grain,.navbtn,.dots button.is-on,
  .card,.flow__box,.band,.compare,.mapping,
  /* the ambient light wash breathes too -- hold it at its resting value */
  .slide__art::after{
    animation:none !important;
  }
  .mote,.grain{display:none;}
  .slide__art::after{opacity:var(--amb,.88);}
}

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* Two-column layouts stack instead of sitting side by side: side by side,
   the right column always lands on top of the artwork's subject (p7's
   revealed face, p4's lit classroom). Stacking keeps the whole right
   half of every frame clear. */
.grid2--compare{grid-template-columns:1fr;gap:18px;margin-bottom:20px;}
.slide:has(.grid2) .slide__inner,
.slide:has(.mapping) .slide__inner{max-width:min(620px,50vw);}

@media (max-width:1240px){
  .slide__inner{max-width:min(620px,66vw);}
}

@media (max-width:980px){
  .slide__inner{max-width:min(600px,78vw);}
  .mapping__row{grid-template-columns:110px 1fr;gap:14px;}
}

@media (max-width:760px){
  /* The copy column is the whole slide here, so let it scroll rather than
     spill past the frame: on the two longest pages the content is taller
     than a phone viewport. */
  .slide{
    justify-content:flex-start;
    /* bottom padding clears the fixed controls: at 390px the frame is 16px,
       so the nav buttons' top edge lands ~66px above the viewport bottom. */
    padding:calc(var(--frame) + 30px) 20px calc(var(--frame) + 64px);
    overflow-y:auto;
    overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
  }
  .slide__inner{max-width:100%;margin:0;padding:0;flex:0 0 auto;}
  /* A 16:9 drawing cropped to a 390px phone shows only ~22% of its width, so
     a heavy scrim would bury the artwork completely. Keep it light and let
     the copy's own weight carry the contrast. */
  .slide__inner::before{
    left:-14%;right:-14%;top:-8%;bottom:-8%;
    background:linear-gradient(180deg,rgba(11,15,22,.42),rgba(11,15,22,.62) 34%,rgba(11,15,22,.7));
  }
  .slide__art img{object-position:56% 50%;}
  /* On a phone the copy fills the width, so the illustration has to yield:
     push the crop toward the subject's side so the figures clear the text. */
  /* A 16:9 canvas cropped to a 390px phone leaves only ~22% of the width,
     so pair the two figures and let the divider light between them carry
     the before/after reading. Vertical position stays high because the
     figures' faces sit in the upper half of the drawing. */
  .slide:nth-child(7) .slide__art img{object-position:66% 42%;}
  .slide:nth-child(1) .slide__art img{object-position:64% 50%;}
  .slide:nth-child(4) .slide__art img{object-position:78% 50%;}
  .slide:nth-child(8) .slide__art img{object-position:70% 50%;}

  /* No boxes left, so no box padding -- only the rule and the gap. */
  .grid2{grid-template-columns:1fr;gap:14px;}
  .card{padding:0 0 0 15px;}
  .card__title{font-size:.95rem;margin-bottom:6px;}
  .card p{font-size:.84rem;line-height:1.58;}
  .compare{padding:0 0 0 15px;}
  .compare li{font-size:.83rem;line-height:1.55;margin-bottom:5px;}
  .band{padding:0 0 0 15px;}
  .band__tag{font-size:.57rem;}
  .band p{font-size:.83rem;}
  .mapping__label{font-size:.59rem;}
  .mapping__row p{font-size:.82rem;}
  .mapping__row{grid-template-columns:1fr;gap:5px;padding:0 0 0 15px;}
  .quote,.statement{padding:0 0 0 15px;}
  .flow__box{padding:0 0 0 15px;}

  .p{font-size:.88rem;line-height:1.62;}
  .h2{font-size:clamp(1.15rem,5.4vw,1.55rem);}
  .title{font-size:clamp(1.7rem,8.4vw,2.4rem);}
  .lede{font-size:.88rem;}
  .meta{grid-template-columns:1fr;gap:9px;margin-top:14px;padding-top:12px;}
  .flow{flex-direction:column;}
  .flow__box{width:100%;}
  .flow__arrow{flex-direction:row;width:100%;gap:9px;}
  .flow__arrowGlyph{transform:rotate(90deg);}
  .badge{margin-top:12px;}
  .rule{margin-top:13px;}
}

@media (max-height:620px){
  .title{font-size:clamp(1.6rem,4.2vw,2.6rem);}
  .meta{margin-top:14px;padding-top:11px;gap:9px 20px;}
  .badge{margin-top:11px;}
  .compare li{margin-bottom:6px;}
  .slide__inner{padding:0;max-width:min(740px,76vw);}
  .mapping__row{padding:0 0 0 15px;}
  .mapping__row p{font-size:.88rem;}
  .band,.quote,.statement{padding:0 0 0 15px;}
  .closing{padding:0 0 0 15px;}
  .card{padding:0 0 0 15px;}
  .flow__box{padding:0 0 0 15px;}
  .rule{margin-top:12px;}
  .eyebrow{margin-bottom:8px;}
}

@media (max-height:540px){
  .slide__inner{max-width:min(860px,90vw);}
  .h2{font-size:clamp(1.1rem,2.8vw,1.45rem);margin-bottom:9px;}
  .mapping__row p{font-size:.82rem;}
  .rule{margin-top:11px;}
}

/* ============================================================
   WIDE-SCREEN: keep the illustration subject readable
   ============================================================ */
@media (min-aspect-ratio: 1/1){
  .slide__art-in{transform-origin:80% 50%;}
}
@media (min-width:1700px){
  .slide__art-in{transform-origin:82% 50%;}
  .slide__inner{max-width:min(710px,48vw);}
}
@media (min-width:2200px){
  .slide__art-in{transform-origin:84% 50%;}
  .slide__inner{max-width:min(830px,42vw);}
}

/* ==========================================================================
   INTERACTIVE LAYER
   Everything above this line is the deck as it was: type on artwork, one
   slide at a time. Everything below makes it operable.

   Z-order, bottom to top:
     0  .slide__art      the illustration
     3  .slide__inner    the copy
     6  .fork/.wave/...  the per-page interactive prop
     9  .artZoom         hit area that opens the lightbox
    10  .topbar .panel .overview .zoom   overlays
    20  fixed controls, hover tip
   ========================================================================== */

/* ---------------------------------------------------------------- TOP BAR */
.topbar{
  position:fixed;top:0;left:0;right:0;z-index:12;
  display:flex;align-items:center;gap:14px;
  padding:12px calc(var(--frame) + 16px);
  pointer-events:none;
  opacity:0;transform:translateY(-14px);
  transition:opacity .5s ease,transform .5s ease;
}
/* the controls themselves take clicks back */
.topbar > *{pointer-events:auto;}
body.is-ready .topbar{opacity:1;transform:none;}

.topbar__brand{
  display:flex;align-items:center;gap:9px;
  background:none;border:0;padding:6px 2px;cursor:pointer;
  font-family:var(--serif);font-size:.92rem;font-weight:500;
  color:var(--paper-2);letter-spacing:.01em;
  transition:color .25s ease;
}
.topbar__brand:hover{color:var(--ember-lt);}
.topbar__mark{
  display:grid;place-items:center;
  width:20px;height:20px;
  color:var(--ember-lt);font-size:1.05rem;line-height:1;
  text-shadow:0 0 14px rgba(244,181,131,.7);
  transform:translateY(-2px);
}
.topbar__name{white-space:nowrap;}

.topbar__mid{display:flex;gap:6px;margin-left:auto;}
.topbar__tab{
  display:inline-flex;align-items:center;gap:7px;
  padding:7px 13px;cursor:pointer;
  background:rgba(12,16,23,.5);
  border:1px solid var(--line);
  color:var(--paper-3);
  font-family:var(--sans);font-size:.72rem;font-weight:400;
  letter-spacing:.14em;text-transform:uppercase;
  backdrop-filter:blur(9px);-webkit-backdrop-filter:blur(9px);
  transition:color .25s,border-color .25s,background .25s,transform .25s;
}
.topbar__tab:hover{
  color:var(--paper);border-color:var(--line-2);transform:translateY(-1px);
}
.topbar__tab[aria-pressed="true"],.topbar__tab.is-on{
  color:var(--ember-lt);border-color:var(--line-2);
  background:rgba(224,138,78,.1);
  box-shadow:0 0 20px rgba(224,138,78,.14);
}
.topbar__ico{font-size:.92rem;line-height:1;}
.topbar__badge{
  min-width:17px;padding:1px 4px;
  font-size:.6rem;letter-spacing:.04em;text-align:center;
  color:var(--ember-pale);
  background:rgba(224,138,78,.2);
}
.topbar__tab--right{margin-left:0;}

/* ------------------------------------------------------- LIGHTBOX HIT AREA */
/* An invisible button sitting over the illustration. It has to sit ABOVE
   the art but BELOW the copy, so clicking the artwork opens it while the
   text stays selectable. */
.artZoom{
  position:absolute;z-index:2;
  inset:0;border:0;padding:0;margin:0;
  background:none;cursor:zoom-in;
  /* the copy column is not a hole to click through -- it stays on top */
  clip-path:polygon(46% 0,100% 0,100% 100%,46% 100%);
}
/* On the wide pages the copy column runs to ~62vw and every widget hangs off
   its right edge, so the zoom target shrinks to the strip of illustration the
   layout still leaves free. Without this the invisible button sat ABOVE the
   copy (z 9 over z 3) and swallowed the clicks meant for the props. The copy
   column is lifted above it instead of the other way round, so the text stays
   selectable and every widget keeps its pointer. */
.slide--wide .artZoom{clip-path:polygon(64% 0,100% 0,100% 100%,64% 100%);}
.slide--title .artZoom{clip-path:polygon(40% 0,100% 0,100% 100%,40% 100%);}
.artZoom:hover{background:radial-gradient(60% 60% at 68% 46%,rgba(224,138,78,.09),rgba(224,138,78,0) 70%);}
.artZoom:focus-visible{outline:2px solid var(--ember);outline-offset:-6px;}

/* ------------------------------------------------------------------ PANEL */
.panel{
  position:fixed;z-index:14;
  top:0;right:0;bottom:0;
  width:min(400px,90vw);
  display:flex;flex-direction:column;
  background:linear-gradient(180deg,rgba(13,18,26,.97),rgba(10,14,20,.98));
  border-left:1px solid var(--line-2);
  box-shadow:-30px 0 70px rgba(0,0,0,.55);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
  transform:translateX(100%);
  transition:transform .46s cubic-bezier(.2,.8,.25,1);
}
.panel[hidden]{display:flex;}   /* hidden only pre-boot; JS drives it after */
body.is-ready .panel[hidden]{display:none;}
.panel.is-open{transform:none;}

.panel__head{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:20px 22px 16px;
  border-bottom:1px solid var(--line);
}
.panel__title{
  font-family:var(--serif);font-size:1.16rem;font-weight:500;
  color:var(--ember-lt);letter-spacing:.005em;
}
.panel__x,.overview__x,.zoom__x{
  width:34px;height:34px;flex:0 0 auto;
  display:grid;place-items:center;
  background:none;border:1px solid var(--line);
  color:var(--paper-3);font-size:1.3rem;line-height:1;cursor:pointer;
  transition:color .22s,border-color .22s,transform .22s;
}
.panel__x:hover,.overview__x:hover,.zoom__x:hover{
  color:var(--ember-lt);border-color:var(--line-2);transform:rotate(90deg);
}
.panel__body{
  flex:1;overflow-y:auto;overscroll-behavior:contain;
  padding:22px;
}
.panel__foot{
  display:flex;align-items:center;justify-content:space-between;
  gap:12px;padding:14px 22px 20px;
  border-top:1px solid var(--line);
}
.panel__nav{
  width:38px;height:34px;
  background:none;border:1px solid var(--line);
  color:var(--paper-3);font-size:1rem;cursor:pointer;
  transition:color .22s,border-color .22s;
}
.panel__nav:hover{color:var(--ember-lt);border-color:var(--line-2);}
.panel__count{
  font-family:var(--serif);font-size:.86rem;
  color:var(--paper-3);letter-spacing:.1em;
}

/* a single note */
.note{margin:0;}
.note__page{
  display:block;margin-bottom:12px;
  font-size:.64rem;letter-spacing:.3em;text-transform:uppercase;
  color:var(--ember);
}
.note__h{
  font-family:var(--serif);font-size:1.34rem;font-weight:500;
  line-height:1.24;color:var(--paper);margin-bottom:14px;
}
.note__body{
  font-size:1rem;line-height:1.72;color:var(--paper-2);
}
.note__quote{
  margin:18px 0 0;padding:2px 0 2px 16px;
  border-left:2px solid var(--line-2);
  font-family:var(--serif);font-style:italic;font-size:1.02rem;
  color:var(--ember-lt);line-height:1.5;
}
.note__quote em{
  display:block;margin-top:8px;
  font-family:var(--sans);font-style:normal;
  font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--paper-3);
}

/* glossary list */
.gloss{display:block;width:100%;text-align:left;
  margin-bottom:2px;padding:14px 0;
  background:none;border:0;border-bottom:1px solid var(--line-soft);
  cursor:pointer;color:inherit;
  transition:background .22s,padding-left .22s;
}
.gloss:hover{background:rgba(224,138,78,.06);padding-left:8px;}
.gloss__t{
  display:flex;align-items:baseline;gap:10px;
  font-family:var(--serif);font-size:1.08rem;color:var(--ember-lt);
}
.gloss__t b{font-weight:500;}
.gloss__t i{
  font-family:var(--sans);font-style:normal;
  font-size:.62rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--paper-3);margin-left:auto;
}
.gloss__d{
  display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .4s cubic-bezier(.2,.8,.25,1);
}
.gloss__d > span{overflow:hidden;}
.gloss.is-open .gloss__d{grid-template-rows:1fr;}
.gloss__d span > p{
  padding-top:10px;
  font-size:.94rem;line-height:1.68;color:var(--paper-2);
}
.gloss__d em{
  display:block;margin-top:8px;
  font-style:normal;font-size:.82rem;color:var(--paper-3);
}

/* --------------------------------------------------------------- OVERVIEW */
.overview{
  position:fixed;inset:0;z-index:15;
  display:flex;flex-direction:column;
  background:rgba(8,11,16,.95);
  backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);
  opacity:0;transition:opacity .4s ease;
  padding:calc(var(--frame) + 22px) calc(var(--frame) + 26px) calc(var(--frame) + 22px);
}
.overview.is-open{opacity:1;}
body.is-ready .overview[hidden]{display:none;}
.overview__head{
  display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding-bottom:18px;margin-bottom:22px;
  border-bottom:1px solid var(--line);
}
.overview__title{
  font-family:var(--serif);font-size:1.6rem;font-weight:500;
  color:var(--paper);
}
.overview__grid{
  flex:1;overflow-y:auto;overscroll-behavior:contain;
  display:grid;gap:16px;
  grid-template-columns:repeat(4,1fr);
  align-content:start;
}
.ovc{
  position:relative;
  display:flex;flex-direction:column;gap:8px;
  padding:0;cursor:pointer;text-align:left;
  background:none;border:1px solid var(--line);
  transition:border-color .3s,transform .3s,box-shadow .3s;
}
.ovc:hover{
  border-color:var(--line-2);transform:translateY(-4px);
  box-shadow:0 18px 40px rgba(0,0,0,.5);
}
.ovc.is-on{border-color:var(--ember);box-shadow:0 0 0 1px var(--ember),0 0 30px rgba(224,138,78,.2);}
.ovc__art{
  position:relative;aspect-ratio:16/9;overflow:hidden;
  background:#141A23;
}
.ovc__art img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(1.08) brightness(.86);
  transition:transform .5s cubic-bezier(.2,.7,.3,1),filter .3s;
}
.ovc:hover .ovc__art img{transform:scale(1.06);filter:saturate(1.12) brightness(1);}
/* a hairline top rule, the same device the deck uses for emphasis */
.ovc__art::after{
  content:"";position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg,var(--ember),rgba(224,138,78,0));
}
.ovc__num{
  position:absolute;right:9px;top:8px;
  font-family:var(--serif);font-size:1.5rem;font-weight:500;
  color:rgba(237,241,245,.5);
  text-shadow:0 2px 14px rgba(0,0,0,.9);
}
.ovc__meta{padding:0 13px 14px;}
.ovc__label{
  display:block;
  font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--ember);margin-bottom:5px;
}
.ovc__title{
  font-family:var(--serif);font-size:1rem;font-weight:500;
  color:var(--paper);line-height:1.28;
}

/* ------------------------------------------------------------------ ZOOM */
.zoom{
  position:fixed;inset:0;z-index:16;
  display:grid;place-items:center;
  background:rgba(6,9,13,.96);
  backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
  opacity:0;transition:opacity .34s ease;
}
.zoom.is-open{opacity:1;}
body.is-ready .zoom[hidden]{display:none;}
.zoom__stage{
  width:100%;height:100%;
  display:grid;place-items:center;
  overflow:hidden;
  cursor:grab;
  padding:calc(var(--frame) + 58px) calc(var(--frame) + 74px);
}
.zoom__stage.is-drag{cursor:grabbing;}
.zoom__img{
  max-width:100%;max-height:100%;
  transform-origin:center center;
  will-change:transform;
  box-shadow:0 30px 90px rgba(0,0,0,.7);
  -webkit-user-drag:none;user-select:none;
}
.zoom__cap{
  position:absolute;left:50%;bottom:calc(var(--frame) + 66px);
  transform:translateX(-50%);
  max-width:min(760px,84vw);
  padding:11px 20px;cursor:pointer;
  background:rgba(12,16,23,.82);border:1px solid var(--line);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  font-size:.92rem;line-height:1.5;color:var(--paper-2);
  transition:color .22s,border-color .22s;
}
.zoom__cap:hover{color:var(--ember-lt);border-color:var(--line-2);}
.zoom__bar{
  position:absolute;right:calc(var(--frame) + 16px);bottom:calc(var(--frame) + 18px);
  display:flex;align-items:center;gap:8px;
}
.zoom__btn{
  min-width:40px;height:38px;padding:0 12px;
  display:grid;place-items:center;
  background:rgba(12,16,23,.82);border:1px solid var(--line);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  color:var(--paper-2);font-size:1.06rem;cursor:pointer;
  transition:color .22s,border-color .22s,background .22s;
}
.zoom__btn:hover{color:var(--ember-lt);border-color:var(--line-2);background:rgba(224,138,78,.12);}
.zoom__pct{
  min-width:62px;text-align:center;
  font-family:var(--serif);font-size:.9rem;color:var(--paper-3);
  letter-spacing:.06em;
}

/* ------------------------------------------------------------- HOVER TIP */
.tip{
  position:fixed;z-index:20;
  max-width:300px;padding:10px 14px;
  background:rgba(10,14,20,.95);
  border:1px solid var(--line-2);
  border-left:2px solid var(--ember);
  box-shadow:0 16px 44px rgba(0,0,0,.6);
  font-size:.86rem;line-height:1.55;color:var(--paper-2);
  pointer-events:none;
  opacity:0;transform:translateY(6px);
  transition:opacity .22s ease,transform .22s ease;
}
.tip.is-on{opacity:1;transform:none;}
.tip b{display:block;margin-bottom:4px;
  font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--ember);font-weight:400;}

/* ==========================================================================
   PER-PAGE INTERACTIVE PROPS
   Each page gets one object you can operate. They share the panel
   language: a hairline, a small caps label, one warm accent.

   z-index 10, not 6. The props sit bottom-right, which is exactly the
   region .artZoom (z 9) makes clickable to open the lightbox, so at 6 the
   props were swallowed by their own slide's hit area. They must sit ABOVE
   the hot zone and BELOW the top bar (12).
   ========================================================================== */

.fork,.wave,.meter,.voices{
  position:absolute;z-index:10;
  right:calc(var(--frame) + 22px);
  bottom:calc(var(--frame) + 46px);
  width:min(340px,30vw);
  opacity:0;transform:translateY(16px);
  transition:opacity .6s ease,transform .6s cubic-bezier(.2,.8,.25,1);
}
.slide.is-active .fork,
.slide.is-active .wave,
.slide.is-active .meter,
.slide.is-active .voices{opacity:1;transform:none;}

/* ---- p1 · THE FORK ---------------------------------------------------- */
.fork{
  display:flex;flex-direction:column;gap:7px;
}
.fork__opt{
  display:flex;align-items:flex-start;gap:11px;
  padding:11px 13px;cursor:pointer;text-align:left;
  background:rgba(12,16,23,.42);border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .28s,background .28s,transform .28s;
}
.fork__opt:hover{border-color:var(--line-2);transform:translateX(-3px);}
.fork__opt.is-on{
  border-color:var(--ember);
  background:rgba(224,138,78,.12);
  box-shadow:inset 3px 0 0 var(--ember),0 0 26px rgba(224,138,78,.14);
}
.fork__ico{font-size:1.05rem;line-height:1.35;filter:saturate(.85);}
.fork__opt.is-on .fork__ico{filter:saturate(1.3) drop-shadow(0 0 8px rgba(244,181,131,.7));}
.fork__txt{display:flex;flex-direction:column;gap:2px;}
.fork__txt b{
  font-family:var(--serif);font-size:.98rem;font-weight:500;
  color:var(--paper);
}
.fork__opt.is-on .fork__txt b{color:var(--ember-lt);}
.fork__txt i{
  font-style:normal;font-size:.78rem;line-height:1.45;color:var(--paper-3);
}
.fork__echo{
  margin-top:3px;padding-left:2px;
  font-family:var(--serif);font-style:italic;
  font-size:.92rem;line-height:1.5;color:var(--ember-pale);
  min-height:2.6em;
}

/* ---- p3 · VOICEPRINT -------------------------------------------------- */
.wave{
  display:flex;flex-direction:column;gap:8px;
}
.wave__lbl{
  font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--paper-3);
}
.wave__canvas{
  width:100%;height:66px;display:block;
  background:rgba(12,16,23,.42);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  cursor:crosshair;
}
.wave__hint{
  align-self:flex-start;padding:0;cursor:pointer;
  background:none;border:0;
  font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ember-dim);
  transition:color .22s;
}
.wave__hint:hover{color:var(--ember-lt);}

/* ---- p5 · THE METER --------------------------------------------------- */
.meter{
  display:flex;flex-direction:column;gap:8px;
}
.meter__q{
  font-size:.62rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--paper-3);
}
.meter__opts{display:flex;flex-direction:column;gap:5px;}
.meter__opt{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:9px 12px;cursor:pointer;text-align:left;
  background:rgba(12,16,23,.42);border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .28s,background .28s;
}
.meter__opt:hover{border-color:var(--line-2);}
.meter__opt.is-on{
  border-color:var(--ember);background:rgba(224,138,78,.12);
  box-shadow:inset 3px 0 0 var(--ember);
}
.meter__k{font-size:.94rem;color:var(--paper);}
.meter__opt.is-on .meter__k{color:var(--ember-lt);}
.meter__v{
  font-family:var(--serif);font-size:.8rem;color:var(--paper-3);
  white-space:nowrap;
}
.meter__bar{
  height:3px;background:rgba(224,138,78,.14);overflow:hidden;
}
.meter__bar i{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--ember-deep),var(--ember),var(--ember-lt));
  transform-origin:left center;
  transition:transform .55s cubic-bezier(.2,.8,.25,1);
}
.meter__out{
  font-family:var(--serif);font-style:italic;
  font-size:.92rem;line-height:1.5;color:var(--ember-pale);
  min-height:3em;
}

/* ---- p6 · TWO VOICES -------------------------------------------------- */
.voices{
  display:flex;flex-direction:column;gap:6px;
}
.voices__meter{
  height:2px;background:rgba(224,138,78,.14);overflow:hidden;
  margin-bottom:3px;
}
/* the sweep: one side full, the other empty -- the two voices competing */
.voices__meter::after{
  content:"";display:block;height:100%;width:100%;
  background:linear-gradient(90deg,var(--ember),var(--tide));
  transform-origin:left center;
  transition:transform .5s cubic-bezier(.2,.8,.25,1);
}
.voices__btn{
  display:flex;flex-direction:column;gap:3px;
  padding:11px 13px;cursor:pointer;text-align:left;
  background:rgba(12,16,23,.42);border:1px solid var(--line);
  border-left:2px solid transparent;
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .3s,background .3s,transform .3s,opacity .3s;
}
.voices__btn:hover{transform:translateX(-3px);}
.voices__btn.is-on{
  border-left-color:var(--ember);
  background:rgba(224,138,78,.1);
}
/* the voice not in use recedes -- that is the whole point of the control */
.voices__btn:not(.is-on){opacity:.5;}
.voices__btn:not(.is-on):hover{opacity:.8;}
.voices__lbl{
  font-size:.6rem;letter-spacing:.26em;text-transform:uppercase;
  color:var(--paper-3);
}
.voices__btn.is-on .voices__lbl{color:var(--ember);}
.voices__q{
  font-family:var(--serif);font-style:italic;
  font-size:.94rem;line-height:1.42;color:var(--paper);
}

/* ==========================================================================
   p7 · BEFORE / AFTER — the draggable divider
   ========================================================================== */
.ba{
  position:relative;
  margin-bottom:18px;
  --split:50%;
  /* Two real columns, always both readable.
     The wipe-slider version of this page was the wrong instrument: a
     wipe only works when both halves show the SAME thing at the same
     offset (one photo, masked left and right). These two halves are
     different sentences, so masking either one truncates it mid-word.
     What the drag DOES control here is EMPHASIS: the divider runs down
     the middle, the "Before" column dims as it is crossed and the
     "After" column warms up, so pushing the line right feels like
     pushing the old life out of the frame. */
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:0 28px;
  --focusA:1;   /* 1 = before at full strength, 0 = fully receded */
  --focusB:0;   /* 1 = after at full strength                */
}
/* The divider, the invisible range and the hint are all direct children of
   .ba, so as grid items they would take cells of their own and push the two
   panes onto a second row. Take them out of the grid flow: only the two
   panes are allowed to be grid items here. */
.ba__handle,.ba__range,.ba__hint{grid-column:1 / -1;}
.ba__handle,.ba__range{position:absolute;}
.ba__hint{position:static;}
.ba__pane{
  min-width:0;
  padding:0 0 0 20px;
  border-left:2px solid var(--line-2);
  transition:opacity .34s ease,filter .34s ease;
}
.ba__pane{grid-row:1;}
.ba__pane--b{
  border-left-color:rgba(78,156,134,.7);
  /* calc() rather than a bare var(): the raw custom property arrives as a
     token stream, and opacity does not always re-resolve it on the
     transition path. calc() makes it a definite number every time. */
  opacity:calc(var(--focusB,1));
  filter:saturate(calc(.35 + .65 * var(--focusB,1)));
}
.ba__pane--a{
  border-left-color:rgba(176,80,60,.75);
  opacity:calc(var(--focusA,1));
  filter:saturate(calc(.3 + .7 * var(--focusA,1)));
}
.ba__pane ul{list-style:none;margin:0;padding:0;}
.ba__pane li{
  position:relative;padding-left:20px;margin-bottom:11px;
  /* The two columns are the argument of the whole deck, and at .94-1.08rem
     they were the smallest body text on the site — the one page where the
     reader is actually comparing sentences deserved to be read, not
     squinted at. Bumped to 1.02-1.2rem with a little more leading. */
  font-size:clamp(1.02rem,1.16vw,1.2rem);font-weight:300;
  color:var(--paper-2);line-height:1.56;
}
.ba__pane li:last-child{margin-bottom:0;}
.ba__pane--b li::before,.ba__pane--a li::before{
  content:"";position:absolute;left:0;top:.66em;
  width:8px;height:1px;background:var(--ember);
}
.ba__pane--a li::before{background:var(--before-lt);}
.ba__tag{
  font-family:var(--serif);
  font-size:clamp(.92rem,1.5vw,1.08rem);font-weight:500;
  letter-spacing:.3em;text-transform:uppercase;
  margin-bottom:14px;
}
.ba__tag--after{color:var(--after-lt);}
.ba__tag--before{color:var(--before-lt);}

.ba__handle{
  position:absolute;top:-4px;bottom:-4px;
  left:var(--split);
  width:2px;margin-left:-1px;
  background:linear-gradient(180deg,
    rgba(224,138,78,0),rgba(224,138,78,.55) 18%,rgba(224,138,78,.55) 82%,rgba(224,138,78,0));
  cursor:ew-resize;
  pointer-events:none;
  z-index:3;
}
.ba__grip{
  position:absolute;left:50%;top:16px;
  transform:translate(-50%,0);
  width:34px;height:34px;
  display:grid;place-items:center;
  background:var(--ember);color:#12161D;
  font-size:.9rem;font-weight:700;
  border-radius:50%;
  box-shadow:0 0 26px rgba(224,138,78,.7);
  animation:gripPulse 2.8s ease-in-out infinite;
}
@keyframes gripPulse{
  0%,100%{box-shadow:0 0 22px rgba(224,138,78,.55);}
  50%    {box-shadow:0 0 34px rgba(244,181,131,.95);}
}
/* the native range is the accessible control; make it invisible but real */
.ba__range{
  position:absolute;z-index:3;
  left:0;width:100%;top:0;bottom:0;height:100%;
  margin:0;padding:0;
  opacity:0;cursor:ew-resize;
  -webkit-appearance:none;appearance:none;background:none;
}
.ba__range::-webkit-slider-thumb{-webkit-appearance:none;width:44px;height:220px;}
.ba__range::-moz-range-thumb{width:44px;height:220px;border:0;}
.ba__range:focus-visible + .ba__handle .ba__grip,
.ba__range:focus-visible{outline:none;}
.ba:focus-within .ba__grip{background:var(--ember-lt);}
.ba__hint{
  margin-top:12px;
  font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ember-dim);
  transition:color .3s;
}
.ba.is-dragging .ba__hint{color:var(--ember-lt);}

/* ==========================================================================
   p4 · FLIPPING CARDS
   ========================================================================== */
.card--flip{
  display:block;width:100%;
  padding:0 0 0 20px;
  background:none;border:0;
  border-left:1px solid var(--line-2);
  cursor:pointer;text-align:left;
  perspective:1100px;
}
.card--flip .card__face{
  display:block;
  transition:opacity .34s ease,transform .46s cubic-bezier(.2,.8,.25,1);
  transform-style:preserve-3d;
}
.card--flip .card__face--back{
  position:absolute;left:20px;right:0;top:0;
  opacity:0;transform:translateY(10px);
  pointer-events:none;
}
.card--flip{position:relative;min-height:150px;}
.card--flip.is-flipped .card__face--front{
  opacity:0;transform:translateY(-10px);
  pointer-events:none;
}
.card--flip.is-flipped .card__face--back{
  opacity:1;transform:none;
}
.card__hint{
  display:block;margin-top:10px;
  font-size:.62rem;letter-spacing:.22em;text-transform:uppercase;
  color:var(--ember-dim);
  transition:color .24s,opacity .24s;
}
.card--flip:hover .card__hint{color:var(--ember-lt);}
.card--flip.is-flipped .card__hint{color:var(--ember);}
/* the tick at the head of the rule becomes the flip affordance */
.card--flip::before{
  content:"";position:absolute;left:-1px;top:3px;
  width:5px;height:5px;background:var(--ember);
  transform:rotate(45deg);
  transition:transform .4s cubic-bezier(.2,.8,.25,1),background .3s;
}
.card--flip.is-flipped::before{
  transform:rotate(225deg);background:var(--ember-lt);
  box-shadow:0 0 12px rgba(244,181,131,.8);
}

/* ==========================================================================
   p2 · THE RULE, ASSEMBLED
   ========================================================================== */
.flow{position:relative;}
.flow__box{cursor:pointer;text-align:left;width:100%;}
.flow__mine{
  display:block;max-height:0;overflow:hidden;
  font-size:.82rem;line-height:1.5;color:var(--ember-pale);
  opacity:0;
  transition:max-height .44s cubic-bezier(.2,.8,.25,1),opacity .3s,margin-top .4s;
  margin-top:0;
}
.flow__box.is-lit{border-top-color:var(--ember);}
.flow__box.is-lit .flow__mine{
  max-height:5em;opacity:1;margin-top:8px;
}
.flow__play{
  position:absolute;left:50%;bottom:-38px;
  transform:translateX(-50%);
  display:inline-flex;align-items:center;gap:7px;
  padding:6px 14px;cursor:pointer;
  background:none;border:1px solid var(--line);
  color:var(--ember-dim);
  font-size:.64rem;letter-spacing:.22em;text-transform:uppercase;
  transition:color .24s,border-color .24s,background .24s;
}
.flow__play:hover{color:var(--ember-lt);border-color:var(--line-2);background:rgba(224,138,78,.1);}
.flow__playIco{font-size:.7rem;}
.flow__play.is-playing .flow__playIco{animation:spinSlow 2s linear infinite;}
@keyframes spinSlow{to{transform:rotate(360deg);}}
/* the arrow fires when the rule is played through */
.flow__arrow{transition:color .3s;}
.flow.is-fired .flow__arrowGlyph{
  color:var(--ember-lt);
  text-shadow:0 0 22px rgba(244,181,131,.9);
  animation:nudge 1.6s ease-in-out infinite;
}
@keyframes nudge{0%,100%{transform:translateX(0);}50%{transform:translateX(5px);}}
.flow.is-fired .flow__arrowLabel{color:var(--ember);}

/* ==========================================================================
   p8 · MAPPING ROWS
   ========================================================================== */
.mapping__row{
  width:100%;cursor:pointer;text-align:left;
  background:none;border:0;border-bottom:1px solid var(--line-soft);
  transition:background .3s,padding-left .3s;
}
.mapping__row:hover{background:rgba(224,138,78,.05);padding-left:24px;}
.mapping__row.is-lit{
  background:rgba(224,138,78,.1);
  box-shadow:inset 3px 0 0 var(--ember);
}
/* the label picks up a count of which rule-part it is proving */
.mapping__label{position:relative;}
.mapping__row.is-lit .mapping__label::after{
  content:attr(data-n);
  position:absolute;left:0;top:-14px;
  font-size:.58rem;letter-spacing:.2em;
  color:var(--ember);
}

/* ==========================================================================
   THE ACUTE, now clickable
   ========================================================================== */
.acutePick{
  font-style:normal;cursor:pointer;
  /* The mark itself is drawn by .stressed::before, above the stressed word.
     This element used to carry a literal "%" in the flow of the sentence,
     which set the headline as "He Capped His Own Profit%" -- a stray per
     cent sign on the one slide that is about a five per cent cap. It is now
     a transparent hit area laid exactly over the mark, so there is one
     acute in the headline and it answers to a click. */
  position:absolute;left:.16em;top:-.52em;
  display:block;width:.62em;height:.78em;
  /* No font-size:0 here. The element is empty, so there is no glyph to
     hide -- but em is resolved against the element's OWN font-size, and
     zeroing it would zero the hit area with it. */
  transition:transform .3s cubic-bezier(.2,.8,.25,1),filter .3s;
}
.acutePick:hover{transform:translateY(-3px) scale(1.14);filter:drop-shadow(0 0 14px rgba(255,243,226,.95));}
.acutePick:focus-visible{outline:2px solid var(--ember);outline-offset:3px;}

/* elements that carry a note get a quiet marker */
[data-note]{cursor:help;}
.quote[data-note]:hover,.statement[data-note]:hover,.closing[data-note]:hover{
  color:var(--ember-lt);
  text-shadow:0 0 30px rgba(224,138,78,.5);
}
.quote,.statement,.closing{transition:color .3s,text-shadow .3s;}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width:1240px){
  .overview__grid{grid-template-columns:repeat(3,1fr);}
  .fork,.wave,.meter,.voices{width:min(300px,34vw);}
}
@media (max-width:980px){
  .topbar__lbl{display:none;}
  .topbar__tab{padding:7px 10px;}
  .overview__grid{grid-template-columns:repeat(2,1fr);}
  /* the prop moves under the copy: the right side is all illustration here */
  .fork,.wave,.meter,.voices{
    position:static;width:auto;margin-top:20px;
  }
  .slide{flex-direction:column;align-items:flex-start;justify-content:flex-start;}
  .slide__inner{margin:0;position:relative;z-index:10;}
  /* Once the props stack UNDER the copy they sit exactly where .artZoom
     (z 9) used to be the click target, and the invisible lightbox button
     swallows every one of their clicks. Two fixes together: the copy column
     now sits ABOVE the hot zone, and the hot zone drops back to covering
     only the strip of illustration the layout still leaves free. */
  .artZoom{clip-path:polygon(0 0,100% 0,100% 30%,0 30%);z-index:8;}
  .slide--title .artZoom{clip-path:polygon(0 0,100% 0,100% 24%,0 24%);}
  /* A phone has no room for two columns of prose side by side, and there
     is no pointer to drag a divider with. The pair stacks, and BOTH read
     at full strength -- the emphasis game needs the drag to mean anything,
     so without it the two states simply sit one above the other. */
  .ba{grid-template-columns:1fr;gap:18px;}
  /* grid-row has to be reset too: the desktop rule pins both panes to
     row 1 so they can sit side by side, and leaving it on stacks them
     into the same cell with the second one invisible. */
  .ba__pane--a,.ba__pane--b{grid-column:1;grid-row:auto;order:0!important;}
  .ba__pane--a{opacity:1;filter:none;}
  .ba__pane--b{opacity:1;filter:none;}
  .ba__handle,.ba__range{display:none;}
  .ba__hint{display:none;}
}
@media (max-width:760px){
  .topbar{padding:9px 12px;gap:8px;}
  .topbar__name{display:none;}
  .overview{padding:calc(var(--frame) + 14px) 14px;}
  .overview__grid{grid-template-columns:1fr;gap:12px;}
  .ovc__title{font-size:.94rem;}
  .panel{width:100%;}
  .zoom__stage{padding:calc(var(--frame) + 50px) 16px calc(var(--frame) + 108px);}
  .zoom__cap{bottom:calc(var(--frame) + 104px);font-size:.82rem;}
  .zoom__bar{
    left:calc(var(--frame) + 12px);right:calc(var(--frame) + 12px);
    bottom:calc(var(--frame) + 14px);justify-content:center;
  }
  .ba__pane li{font-size:1.06rem;}
  .card--flip{min-height:0;}
  .card--flip .card__face--back{position:static;opacity:1;transform:none;}
  /* no 3D flip affordance on a phone: stack both faces and let the hint go */
  .card--flip.is-flipped .card__face--front{opacity:1;transform:none;margin-bottom:16px;}
  .card--flip.is-flipped .card__face--back{opacity:1;}
}

/* ==========================================================================
   REDUCED MOTION — everything still operable, nothing moves on its own
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
  .topbar,.panel,.overview,.zoom,.tip{transition:none;}
  .fork,.wave,.meter,.voices{transition:none;}
  .card--flip .card__face,
  .card--flip .card__face--back,
  .mapping__row,.fork__opt,.meter__opt,.voices__btn,
  .flow__mine,.meter__bar i,.voices__meter::after{
    transition:none;
  }
  .ba__grip{animation:none;}
  .flow__play.is-playing .flow__playIco{animation:none;}
  .flow.is-fired .flow__arrowGlyph{animation:none;}
  .acutePick:hover{transform:none;}
}

/* ==========================================================================
   JS-DRIVEN STATES
   Small pieces of state that only exist because app.js writes them. Kept in
   one block at the end so it is obvious which selectors are event-driven
   rather than authored.
   ========================================================================== */

/* p1 · the road echo re-lands when the fork flips. The keyframes live with
   the rest of the slide animations; this just restarts them. */
.fork__echo{animation:riseIn .5s cubic-bezier(.2,.8,.25,1) both;}

/* p6 · the two-voice sweep is one bar whose filled fraction is the mix of
   the two voices. --vx is the knob. */
.voices__meter::after{
  transform:scaleX(var(--vx,.5));
}
.voices__meter.is-open{
  box-shadow:0 0 18px rgba(224,138,78,.22);
}

/* p5 · when both costs are on the table the bar is at 100%, and the bar
   itself gets hot so you can see the meter run out. */
.meter.is-full .meter__bar i{
  background:linear-gradient(90deg,var(--ember),var(--before));
  box-shadow:0 0 22px rgba(176,80,60,.45);
}

/* notes rail · a jump back to the slide a note belongs on. The rail covers
   the right of the screen, so this is how the art gets back in view. */
.note__jump{
  margin-top:16px;padding:9px 15px;cursor:pointer;
  background:rgba(224,138,78,.08);
  border:1px solid var(--line-2);
  font-family:var(--sans);font-size:.68rem;
  letter-spacing:.16em;text-transform:uppercase;
  color:var(--ember-lt);
  transition:background .22s,color .22s,transform .22s;
}
.note__jump:hover{
  background:rgba(224,138,78,.18);
  color:var(--ember-pale);
  transform:translateX(3px);
}

/* read-aloud · the tab lights while the browser is speaking. */
.topbar__tab--right.is-on .topbar__ico{animation:emberBreath 1.5s ease-in-out infinite;}

/* a broken image must not leave a hole in the slide: the ambient wash and
   the type carry the page on their own. */
.slide__art.is-missing .slide__art-in{display:none;}
.slide__art.is-missing{
  background:
    radial-gradient(74% 58% at 63% 38%,rgba(233,168,116,.30),rgba(224,138,78,0) 76%),
    radial-gradient(130% 76% at 50% 106%,rgba(120,148,168,.30),rgba(70,96,116,0) 76%),
    #141A23;
}

/* the narrow-screen artwork hot area needs to LOOK clickable, otherwise a
   strip of the page that opens a lightbox reads as dead space */
@media (max-width:980px){
  .artZoom::after{
    content:"tap to enlarge";
    position:absolute;right:14px;top:10px;
    padding:5px 11px;
    font-family:var(--sans);font-size:.58rem;
    letter-spacing:.2em;text-transform:uppercase;
    color:var(--ember-lt);
    background:rgba(12,16,23,.6);
    border:1px solid var(--line-2);
  }
  .artZoom::before{
    content:"";position:absolute;inset:0;
    background:radial-gradient(60% 42% at 50% 14%,rgba(224,138,78,.12),rgba(224,138,78,0) 72%);
    opacity:0;transition:opacity .3s;
  }
  .slide.is-active .artZoom::before{opacity:1;}
}

/* ==========================================================================
   THE SECOND PASS  —  light, entry, and marginalia

   Everything above this line makes the deck readable and operable. This
   block is what makes it feel authored: a room that lights when you enter
   it, a light that follows you around, and notes in the margin instead of
   notes in a drawer.
   ========================================================================== */

/* ========================================================== CURSOR HALO ===
   The cheapest possible proof that the page is alive. A fixed pair of
   radial gradients follows the pointer with a deliberate lag, so the
   light feels like it has weight. Over anything interactive it tightens
   and warms up: the deck's clickable regions announce themselves by
   being lit rather than by being labelled.
   ========================================================================== */

.halo{
  position:fixed;left:0;top:0;
  width:0;height:0;
  z-index:11;
  pointer-events:none;
  opacity:0;
  transition:opacity .5s ease;
  will-change:transform;
}
body.has-pointer .halo{opacity:1;}
body.is-booting .halo{opacity:0 !important;}

.halo__ring,
.halo__core{
  position:absolute;left:50%;top:50%;
  border-radius:50%;
  transform:translate(-50%,-50%);
}
.halo__ring{
  width:220px;height:220px;
  background:radial-gradient(circle,
    rgba(224,138,78,.11) 0%,rgba(224,138,78,.05) 38%,rgba(224,138,78,0) 70%);
  transition:width .34s cubic-bezier(.2,.8,.25,1),height .34s cubic-bezier(.2,.8,.25,1);
}
.halo__core{
  width:26px;height:26px;
  background:radial-gradient(circle,
    rgba(255,240,220,.5) 0%,rgba(240,186,142,.2) 34%,rgba(224,138,78,0) 72%);
  transition:width .34s cubic-bezier(.2,.8,.25,1),height .34s cubic-bezier(.2,.8,.25,1);
}
/* over something clickable: the light narrows to a focus and warms up,
   the way a lamp does when you bring a page up to it */
body.halo-hot .halo__ring{width:120px;height:120px;}
body.halo-hot .halo__core{
  width:9px;height:9px;
  background:radial-gradient(circle,
    rgba(255,246,232,.85) 0%,rgba(244,181,131,.45) 40%,rgba(224,138,78,0) 74%);
}
/* while dragging the before/after divider: cool it down, because that
   control is about the cold half of the story */
body.halo-cold .halo__ring{
  width:150px;height:150px;
  background:radial-gradient(circle,
    rgba(147,190,205,.13) 0%,rgba(94,147,168,.05) 40%,rgba(94,147,168,0) 72%);
}
/* a touch device has no cursor to follow: never show it */
@media (hover:none) and (pointer:coarse){
  .halo{display:none;}
}

/* ============================================================== INTRO ===
   Four seconds, once. The room is dark and there is one lit point; the
   point draws the acute accent mark; the mark drops onto the word; the
   landing is what switches the lights on. It is the argument of the whole
   site in one gesture -- a small mark that changes how everything reads.
   ========================================================================== */

.intro{
  position:fixed;inset:0;z-index:30;
  display:grid;place-items:center;
  background:
    radial-gradient(70% 55% at 50% 46%,rgba(28,38,52,.9),rgba(8,11,16,.99) 72%),
    #070A0F;
  transition:opacity .8s ease,visibility .8s;
}
.intro.is-done{
  opacity:0;visibility:hidden;pointer-events:none;
}
.intro__stage{
  position:relative;
  width:min(220px,52vw);
  height:min(220px,52vw);
  display:grid;place-items:center;
}
.intro__mark{
  width:100%;height:100%;
  overflow:visible;
  opacity:0;
}
/* the stroke is DRAWN, not faded: stroke-dasharray runs the length of the
   path so the mark appears to be written by the light itself */
.intro__stroke{
  fill:none;
  stroke:#FFF1DC;
  stroke-width:3;
  stroke-linecap:round;
  stroke-dasharray:72;
  stroke-dashoffset:72;
  filter:drop-shadow(0 0 12px rgba(255,241,220,.9))
         drop-shadow(0 0 40px rgba(224,138,78,.7));
}
.intro__spark{
  fill:#FFF6E8;
  opacity:0;
  filter:drop-shadow(0 0 10px rgba(255,246,232,1));
}
.intro__shock{
  position:absolute;left:50%;top:50%;
  width:12px;height:12px;
  margin:-6px 0 0 -6px;
  border-radius:50%;
  background:radial-gradient(circle,rgba(255,243,226,.9),rgba(224,138,78,0) 70%);
  opacity:0;
  pointer-events:none;
}
.intro__credit{
  position:absolute;
  left:0;right:0;bottom:12vh;
  margin:0;text-align:center;
  opacity:0;
  font-family:var(--sans);
}
.intro__credit span{
  display:block;
  font-size:.66rem;letter-spacing:.34em;text-transform:uppercase;
  color:var(--ember);
}
.intro__credit i{
  display:block;margin-top:9px;
  font-family:var(--serif);font-size:1rem;font-style:italic;
  color:var(--paper-3);letter-spacing:.01em;
}
.intro__skip{
  position:absolute;right:22px;bottom:20px;
  padding:7px 14px;
  background:none;border:1px solid rgba(224,138,78,.24);
  color:var(--paper-3);
  font-family:var(--sans);font-size:.6rem;
  letter-spacing:.22em;text-transform:uppercase;
  cursor:pointer;opacity:0;
  transition:color .25s,border-color .25s;
}
.intro__skip:hover{color:var(--ember-lt);border-color:var(--line-2);}

/* --- the sequence itself, driven by is-done-* classes from app.js --- */
.intro.is-s1 .intro__mark{opacity:1;transition:opacity .2s;}
.intro.is-s1 .intro__spark{opacity:1;}
.intro.is-s1 .intro__stroke{
  animation:introDraw 1.05s cubic-bezier(.3,.8,.3,1) forwards;
}
.intro.is-s2 .intro__spark{animation:introSpark 1.5s ease-in-out infinite;}
.intro.is-s2 .intro__credit{opacity:1;transition:opacity .7s ease .35s;}
/* The skip is an escape hatch, so it should not arrive late: at s2 plus a
   .9s delay it only became readable around 2.9s of a 3.9s entrance, which
   means anyone who wanted out in the first two seconds had nothing to click
   and no way of knowing that Esc or a click worked. It now rides s1 with a
   short delay — present for most of the entrance, still after the first
   beat so it does not undercut the opening. */
.intro.is-s1 .intro__skip{opacity:1;transition:opacity .45s ease .55s;}
.intro.is-s2 .intro__skip{opacity:1;transition:opacity .45s ease .55s;}
/* the landing: the mark drops, the shock ring expands, and the deck
   itself fades up underneath it */
.intro.is-s3 .intro__stage{animation:introDrop .72s cubic-bezier(.5,0,.75,0) both;}
.intro.is-s3 .intro__shock{animation:introShock 1.15s cubic-bezier(.15,.7,.3,1) both;}
.intro.is-s3 .intro__mark{animation:introFadeOut .5s ease .3s both;}
.intro.is-s3 .intro__credit{opacity:0;transition:opacity .3s;}
.intro.is-s3 .intro__skip{opacity:0;}

@keyframes introDraw{
  0%  {stroke-dashoffset:72;}
  60% {stroke-dashoffset:0;}
  100%{stroke-dashoffset:0;}
}
@keyframes introSpark{
  0%,100%{opacity:.35;transform:scale(.7);}
  50%    {opacity:1;  transform:scale(1.5);}
}
@keyframes introDrop{
  0%  {transform:translateY(-46px) scale(1.5);opacity:1;}
  55% {transform:translateY(0) scale(1);opacity:1;}
  72% {transform:translateY(-7px) scale(1.04);}
  100%{transform:translateY(0) scale(1);opacity:1;}
}
@keyframes introShock{
  0%  {opacity:.95;transform:scale(1);}
  100%{opacity:0;transform:scale(46);}
}
@keyframes introFadeOut{
  to{opacity:0;}
}

/* the room coming up: the whole deck fades in behind the mark */
body.is-booting .deck,
body.is-booting .topbar,
body.is-booting .dots,
body.is-booting .navbtns,
body.is-booting .counter{
  opacity:0;
}
body.is-booting .deck{filter:brightness(.34) saturate(.5);}

/* the overlays carry [hidden] before boot, but a bare[hidden] is not a
   display:none guarantee once a class rule sets display on them. An
   opacity:0 overlay is still focusable and still swallows clicks, so during
   the entrance they have to be genuinely inert — not merely invisible. */
body.is-booting .panel,
body.is-booting .overview,
body.is-booting .zoom,
body.is-booting .memo{
  display:none !important;
}
/* and nothing inside them may take the keyboard while the room is dark */
body.is-booting :is(.panel, .overview, .zoom, .memo) :is(button, a, input, [tabindex]){
  pointer-events:none;
}

/* ========================================================== MARGIN NOTE ===
   A teacher's mark on a script: a numbered note pinned beside the words
   it belongs to, with a leader line running back to them. It replaces the
   "click and hope a panel opens" pattern -- the note lands where the
   reader's eye already is.
   ========================================================================== */

.memo{
  position:fixed;inset:0;z-index:18;
  pointer-events:none;
}
body.is-ready .memo[hidden]{display:none;}
.memo__leader{
  position:absolute;inset:0;
  width:100%;height:100%;
  pointer-events:none;
  overflow:visible;
}
.memo__leader path{
  fill:none;
  stroke:rgba(224,138,78,.5);
  stroke-width:1;
  stroke-dasharray:3 4;
  opacity:0;
  transition:opacity .3s ease;
}
.memo.is-open .memo__leader path{opacity:1;}

.memo__card{
  position:absolute;
  width:min(320px,84vw);
  padding:16px 18px 13px;
  background:linear-gradient(165deg,rgba(18,24,33,.98),rgba(12,16,23,.99));
  border:1px solid var(--line-2);
  box-shadow:0 26px 64px rgba(0,0,0,.62),0 0 0 1px rgba(224,138,78,.08);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  pointer-events:auto;
  opacity:0;
  transform:translateY(8px) scale(.97);
  transform-origin:0 0;
  transition:opacity .28s ease,transform .34s cubic-bezier(.2,.8,.25,1);
}
.memo.is-open .memo__card{opacity:1;transform:none;}
/* the little numbered tab that marks the note as one of a series */
.memo__num{
  position:absolute;left:-1px;top:-1px;
  min-width:26px;padding:5px 7px 4px;
  background:var(--ember);color:#0D1117;
  font-family:var(--serif);font-size:.76rem;font-weight:600;
  text-align:center;letter-spacing:.02em;
}
.memo__body{
  margin:6px 0 12px;
  padding-right:14px;
  font-size:.92rem;line-height:1.62;color:var(--paper);
}
.memo__nav{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding-top:10px;
  border-top:1px solid var(--line);
}
.memo__arrow{
  width:30px;height:26px;
  background:none;border:1px solid var(--line);
  color:var(--paper-3);font-size:.92rem;cursor:pointer;
  transition:color .22s,border-color .22s;
}
.memo__arrow:hover{color:var(--ember-lt);border-color:var(--line-2);}
.memo__count{
  font-family:var(--serif);font-size:.78rem;
  color:var(--paper-3);letter-spacing:.1em;
}
.memo__x{
  position:absolute;right:8px;top:8px;
  width:24px;height:24px;
  display:grid;place-items:center;
  background:none;border:0;
  color:var(--paper-3);font-size:1.15rem;line-height:1;cursor:pointer;
  transition:color .22s,transform .22s;
}
.memo__x:hover{color:var(--ember-lt);transform:rotate(90deg);}

/* the marker that shows which words the open note belongs to */
/* ---- the page-level note tab ----------------------------------------
   Eight of the twelve notes belong to a whole page rather than to a phrase,
   and a .slide is 1434x896 — as a hit area that makes the entire page a
   button, so clicking the artwork would open the lightbox AND a note. The
   slide therefore carries the text but not the role; this tab, pinned to the
   left edge at the vertical centre, is the handle instead. It sits above the
   artwork (z 10) but below the top bar (z 12).

   FIXED WIDTH, and that is the whole point. The gutter it lives in is one
   --pad wide: clamp(26px, 4vw, 58px). A tab carrying the word "note" beside
   the number measured 45px, so at every width the gutter was either too
   narrow (the tab hung off the left edge of the screen) or, once squeezed
   in, sitting on top of the first letter. Three rounds of min()/max() on the
   offset only traded one failure for the other — the arithmetic was never
   wrong, the box was.

   The fix is to stop asking CSS to measure text. A printed book indexes its
   marginalia by superscript number alone, and so does this: the number sits
   in a fixed --tab-w box, so the position needs no measurement at all and
   the JS no longer has to publish a width. `writing-mode:vertical-rl` sets
   the label reading downward, which keeps the horizontal footprint at one
   digit no matter how long the word is. */
.noteTab{
  position:absolute;z-index:10;
  /* `left` resolves against the slide's padding box, whose outer edge is the
     viewport edge — so this is the far right of the margin, and walking back
     by the tab's own fixed width lands it inside. No measurement, no --nw,
     and no min()/max() to choose between. */
  left:var(--pad-x);
  margin-left:calc(-1 * (var(--tab-w) + var(--tab-gap)));
  top:50%;
  transform:translateY(-50%);
  top:50%;
  transform:translateY(-50%);
  width:var(--tab-w);
  min-height:104px;
  /* vertical-rl puts the inline axis top-to-bottom, so flex-direction:row
     stacks the number above the label while the horizontal footprint stays
     one digit wide. In the horizontal writing mode a reader would set
     flex-direction:column and the two would end up side by side. */
  writing-mode:vertical-rl;
  display:flex;flex-direction:row;
  align-items:center;justify-content:center;
  gap:8px;
  padding:12px 0;
  background:rgba(12,17,25,.86);
  border:1px solid rgba(224,138,78,.22);
  border-right:none;
  border-radius:3px 0 0 3px;
  color:var(--paper-3);
  font-family:var(--sans);cursor:pointer;
  transition:background .26s ease,border-color .26s ease,color .26s ease;
}
.noteTab__n{
  font-family:var(--serif);
  font-size:.86rem;line-height:1;
  color:var(--ember);
  letter-spacing:0;
}
.noteTab__t{
  font-size:.54rem;
  letter-spacing:.24em;text-transform:uppercase;
}
.noteTab:hover,
.noteTab:focus-visible{
  background:rgba(224,138,78,.14);
  border-color:rgba(224,138,78,.5);
  color:var(--paper);
}
.noteTab.is-lit{
  background:rgba(224,138,78,.2);
  border-color:var(--ember);
  color:var(--paper);
}
.noteTab:focus-visible{outline:1px solid var(--ember);outline-offset:2px;}
/* The gutter is one --pad wide and --pad itself shrinks with the viewport, so
   the tab has to shrink with it or the pair no longer fits: at 761px the
   gutter is 30.4px, which is exactly 20 + 8 + 2. Below 980 the label drops
   (a bare superscript number is still a handle, and it is what the printed
   page uses anyway) and the tab narrows to match. */
@media (max-width:980px){
  :root{--tab-w:20px;--tab-gap:8px;}
  .noteTab{
    min-height:0;
    padding:7px 0;
    gap:5px;
  }
  .noteTab__t{display:none;}
  .noteTab__n{font-size:.78rem;}
}
@media (max-width:760px){
  /* Here the copy column is the full width of the slide, so the tab cannot
     share a row with it — the slide gives up 10px of left padding to keep
     the handle in the same place it occupies on every other viewport.
     Anchored to the top of the gutter rather than the middle: the slide
     scrolls on a phone, and a tab at 50% of a two-screen-tall page is off
     screen exactly when you have finished reading the first screen. */
  :root{--tab-w:20px;--tab-gap:8px;--pad-x:30px;}
  .slide{padding-left:var(--pad-x);}
  .noteTab{
    top:calc(var(--frame) + 10px);
    bottom:auto;
    transform:none;
    padding:6px 0;
    border-radius:3px;
    border-right:1px solid rgba(224,138,78,.22);
  }
}
.memo-mark{
  background-image:linear-gradient(90deg,var(--ember),rgba(224,138,78,0));
  background-repeat:no-repeat;
  background-position:0 100%;
  background-size:0% 1px;
  transition:background-size .34s ease .08s;
}
.memo-mark.is-lit{background-size:100% 1px;}

/* Every .slide also carries data-note, and this class is applied to the
   in-copy phrases only — never to the slides themselves. It must not set
   `position` either: the slides are absolutely stacked inside .deck, and a
   `position:relative` at equal specificity but later in the file drops all
   eight into normal flow and pushes page 7 to y=4035. The lit underline is
   drawn with a background gradient rather than an absolutely positioned
   ::after precisely because ::after would need a positioned ancestor. */

@media (max-width:760px){
  .memo__card{width:calc(100vw - 32px);}
  .memo__leader{display:none;}
}

/* ==========================================================================
   THE THIRD PASS — direction, and words that arrive one at a time
   ========================================================================== */

/* ---- 1. THE DECK REMEMBERS WHICH WAY YOU WENT -------------------------
   Paging back used to look exactly like paging forward, so the deck read as
   a slideshow rather than a walk through a room. The wrapper carries the
   direction and the slide's entrance offset flips to match: forward slides
   rise from the right (the road ahead), backward slides from the left.

   `:not(.is-active)` is load-bearing, not tidiness. This rule has to outrank
   `.slide.is-active{transform:none}`, and it does so on specificity — three
   classes to two. But that means it also matches the ACTIVE slide, which
   then sits 48px to the left of the stage for as long as the deck is
   travelling backwards: the whole page drifts off-centre and a 48px band of
   bare background opens up on the right. Rolling back was the only way to
   reproduce it, because `is-fwd` has no counterpart rule to over-match. */
.deck.is-back .slide:not(.is-active){transform:translateX(-48px) scale(.996);}
/* the outgoing slide leaves towards the OTHER side, which is what sells the
   direction; it is fading out, so where it goes is only half the statement */
.deck.is-back .slide.is-prev{transform:translateX(48px) scale(.996);}
/* the active slide is the one that moves, so its transition has to be a
   little longer than the outgoing one or the two overlap and smear */
.deck.is-fwd .slide.is-active,
.deck.is-back .slide.is-active{transition:opacity .52s ease,transform .62s cubic-bezier(.16,.84,.24,1),visibility .62s;}
.deck.is-fwd .slide.is-prev,
.deck.is-back .slide.is-prev{transition:opacity .34s ease,transform .5s cubic-bezier(.4,0,.7,.2),visibility .5s;}

/* ---- 2. WORDS, ONE AT A TIME -------------------------------------------
   JS wraps the words of .title / .h2 / .closing in .w spans (text nodes
   only, so the author's <em> and the note anchor survive) and sets --i on
   each. The stagger below is what reads as "the sentence is being spoken".

   The delay is capped: a nine-word heading must not take nine beats, so the
   per-word step shrinks as the count grows via --wn (set in JS below). */
@keyframes wordRise{
  from{opacity:0;transform:translate3d(0,.42em,0) rotate(1.1deg);filter:blur(3px);}
  to  {opacity:1;transform:none;filter:none;}
}
.slide.is-active .w{
  display:inline-block;
  animation:wordRise .78s cubic-bezier(.16,.82,.26,1) both;
  animation-delay:calc(.30s + var(--i,0) * var(--wd,.055s));
}
/* The heading block itself must not ALSO do riseIn, or the two animations
   fight over transform and the words judder on the way in. But note that
   `html.js .slide__inner > *{opacity:0}` above is what HIDES these blocks
   in the first place, so switching the animation off has to hand the
   opacity back explicitly — animation:none alone leaves the heading at 0. */
.slide.is-active :is(.h2,.title,.closing){animation:none;opacity:1;}

/* a word that carries meaning gets held a beat longer, so the eye lands on
   it: the ember-coloured phrases are the ones the argument turns on */
.slide.is-active .w:is(:first-child){animation-duration:.86s;}

/* ---- 3. THE ACCENT BREATHES THROUGH THE HEADING -----------------------
   On the title slide the acute mark drops after the words have arrived —
   the sentence lands, then the punctuation hits it. */
@keyframes acuteSettle{
  0%  {opacity:0;transform:translateY(-.5em) scale(.6);}
  60% {opacity:1;transform:translateY(.06em) scale(1.12);}
  100%{opacity:1;transform:none;}
}
@media (prefers-reduced-motion:reduce){
  .deck.is-back .slide,
  .deck.is-fwd .slide.is-active,
  .deck.is-back .slide.is-active{transition:opacity .2s linear;}
  .slide.is-active .w{animation:none;}
}

/* ---- 4. PARALLAX: THE ROOM'S LIGHT MOVES, THE ROOM DOES NOT ------------
   Written against the `translate` property rather than `transform`, because
   the inner layer is already animated by the Ken Burns drift and two
   transform declarations on one element means the last one simply wins.
   `translate` composes with `transform`, so the drift keeps breathing while
   the parallax offset is added on top of it.

   The two layers drift in opposite proportion (6px outside, 11px inside), so
   the depth between them changes as the pointer moves.

   The scales below are not decoration: they are HEADROOM. Both layers are
   clipped by .slide__art's overflow, and a layer scaled to exactly 1.0 has
   no pixel to give away — any parallax would expose the edge of the image.
   1.04 and 1.03 leave roughly 7% of margin, which at a 390px viewport is
   still ~27px against a maximum offset of 17px. */
.slide__art{
  translate:var(--px,0px) var(--py,0px);
  transition:translate .5s cubic-bezier(.2,.7,.3,1);
}
.slide.is-active .slide__art{transform:scale(1.04);}
.slide__art-in{
  translate:calc(var(--px,0px) * -1) calc(var(--py,0px) * -1);
  transition:translate .34s cubic-bezier(.2,.7,.3,1);
}
@keyframes kbDrift{
  0%   {transform:scale(1.075);}
  50%  {transform:scale(1.030);}
  100% {transform:scale(1.075);}
}
@keyframes kbDriftWide{
  0%   {transform:scale(1.085);}
  50%  {transform:scale(1.045);}
  100% {transform:scale(1.085);}
}
/* parallax is a pointer affordance: no pointer, no offset, and no need to
   keep recomposing transforms on a touch device that cannot see them */
@media (hover:none) and (pointer:coarse){
  .slide__art,.slide__art-in{translate:none !important;}
  .slide.is-active .slide__art{transform:scale(1);}
}
@media (prefers-reduced-motion:reduce){
  .slide__art,.slide__art-in{translate:none !important;}
  .slide.is-active .slide__art{transform:scale(1);}
}

/* ==========================================================================
   HOMEWORK 5 · additions
   The Homework 4 design system, extended for the Lei Jun deck. Nothing
   above this line was changed: every rule here is either new or an
   override scoped to a new class, so the two submissions stay visually
   identical where they overlap.
   ========================================================================== */

/* ---- a wider copy column, for the slides that carry a card grid -------
   The default 600px column is right for prose. Three flip cards will not
   fit in it, and squeezing them would make the type unreadable — which
   would be a worse sin than a wider text block. */
.slide--wide .slide__inner{max-width:min(940px,70vw);}
.slide--wide .slide__inner::before{right:-30%;}
@media (max-width:1240px){ .slide--wide .slide__inner{max-width:min(820px,78vw);} }
@media (max-width:980px){  .slide--wide .slide__inner{max-width:min(680px,88vw);} }
@media (max-width:760px){  .slide--wide .slide__inner{max-width:100%;} }

.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(16px,2vw,26px);margin:6px 0 4px;}
@media (max-width:760px){ .grid3{grid-template-columns:1fr;gap:14px;} }

/* ---- the brand mark: the cap glyph ------------------------------------
   Homework 4 drew an acute accent; this deck is about a number, so the
   mark is the number. It is set tighter than body text because it has to
   read as a glyph at 20px, not as a word. */
.topbar__mark--ceil{font-size:.72rem;font-weight:700;letter-spacing:-.02em;}

/* ---- the intro: a ceiling drawn, and a bar that stops under it -------- */
.intro__mark--ceil{overflow:visible;}
.intro__mark--ceil .intro__stroke{
  stroke-dasharray:88;stroke-dashoffset:88;
}
.intro.is-s1 .intro__mark--ceil .intro__stroke{
  animation:introDrawCeil .95s cubic-bezier(.3,.8,.3,1) forwards;
}
/* the bar rises to the line and stays there */
.intro__mark--ceil .intro__spark{
  transform-origin:50% 100%;
  transform:scaleY(0);
}
.intro.is-s2 .intro__mark--ceil .intro__spark{
  animation:ceilRise .78s cubic-bezier(.2,.85,.25,1) forwards;
}
/* the excess above the line is what the company gives back */
.intro__mark--ceil .intro__excess{
  fill:var(--ember-lt);opacity:0;
}
.intro.is-s2 .intro__mark--ceil .intro__excess{
  animation:ceilFall .9s cubic-bezier(.5,0,.75,0) .34s both;
}
@keyframes introDrawCeil{ to{stroke-dashoffset:0;} }
@keyframes ceilRise{ to{transform:scaleY(1);} }
@keyframes ceilFall{
  0%  {opacity:0;transform:translateY(0);}
  30% {opacity:1;}
  100%{opacity:0;transform:translateY(46px);}
}

/* ---- cards: the big number and the verdict pill ------------------------ */
.card__num{
  display:block;
  font-family:var(--serif);font-size:1.5rem;font-weight:600;
  color:var(--ember);line-height:1;margin-bottom:8px;
}
.card__verdict{
  display:inline-block;margin-top:12px;
  font-size:.58rem;letter-spacing:.22em;text-transform:uppercase;
  padding:3px 9px;border-radius:999px;
}
.card__verdict--no{ color:var(--before-lt);border:1px solid rgba(176,80,60,.45); }
.card__verdict--yes{color:var(--after-lt); border:1px solid rgba(78,156,134,.5); }
/* six conductors need a shorter card than the philosophy page does */
.grid3 .card--flip{min-height:168px;}
@media (max-width:760px){ .grid3 .card--flip{min-height:0;} }

/* ---- p3 · the definition list ----------------------------------------- */
.ba__list li{
  font-size:clamp(.9rem,1.05vw,1.02rem);
  line-height:1.5;
}

/* ---- p4 · the vote gap ------------------------------------------------- */
.votes{
  margin-top:18px;padding:16px 18px 14px;
  background:rgba(12,16,23,.42);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
.votes__row{
  display:grid;grid-template-columns:132px 1fr 62px;
  align-items:center;gap:12px;margin-bottom:9px;
}
.votes__k{
  font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--paper-3);
}
.votes__track{
  position:relative;display:block;height:8px;
  background:rgba(237,241,245,.08);border-radius:999px;overflow:hidden;
}
.votes__bar{
  position:absolute;left:0;top:0;bottom:0;width:0;
  border-radius:999px;
  transition:width .8s cubic-bezier(.2,.8,.25,1);
}
.votes__bar--shares{background:linear-gradient(90deg,var(--tide-dim),var(--tide));}
.votes__bar--votes{ background:linear-gradient(90deg,var(--ember-deep),var(--ember));}
.votes__v{
  font-family:var(--serif);font-size:.98rem;font-weight:600;
  color:var(--paper);text-align:right;
}
.votes__gap{
  display:flex;align-items:baseline;gap:10px;
  margin:12px 0 4px;padding-top:12px;
  border-top:1px solid var(--line-soft);
  opacity:.55;transition:opacity .4s ease;
}
.votes__gap.is-lit{opacity:1;}
.votes__gapN{
  font-family:var(--serif);font-size:1.02rem;font-weight:600;
  color:var(--ember-lt);white-space:nowrap;
}
.votes__gapT{font-size:.86rem;font-weight:300;color:var(--paper-2);line-height:1.5;}
.votes__btn{
  display:inline-block;margin-top:10px;padding:8px 16px;
  background:none;border:1px solid var(--line-2);border-radius:999px;
  color:var(--ember-lt);cursor:pointer;
  font-family:var(--sans);font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;
  transition:border-color .3s,color .3s,background .3s;
}
.votes__btn:hover{border-color:var(--ember);color:var(--ember-pale);}
.votes__btn.is-on{background:rgba(224,138,78,.12);border-color:var(--ember);}
.votes__echo{
  margin:12px 0 0;font-size:.94rem;font-weight:300;font-style:italic;
  color:var(--paper-2);line-height:1.6;
}
@media (max-width:760px){
  .votes__row{grid-template-columns:1fr;gap:5px;}
  .votes__v{text-align:left;}
}

/* ---- p6 · the dictator's toolbox (three options, not two) -------------- */
.meter__opts{gap:7px;}
.meter__opt{
  display:grid;grid-template-columns:1fr;gap:2px;
  padding:11px 14px;
}
.meter__k{
  font-size:.7rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ember-lt);
}
/* white-space:normal is load-bearing. The base rule carried nowrap from the
   wide horizontal meter, and a grid column cannot shrink below its item's
   min-content size — so the description stayed on one 598px line and ran
   clean out of the 340px panel. */
.meter__v{font-size:.9rem;font-weight:300;color:var(--paper-2);line-height:1.5;white-space:normal;}
.meter__opt.is-on{border-color:var(--ember);background:rgba(224,138,78,.1);}
.meter__opt.is-on .meter__k{color:var(--ember-pale);}
.meter__q{
  font-size:.7rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--paper-3);margin:0 0 10px;
}

/* ---- p8 · the seventy-five days --------------------------------------- */
.days{
  display:grid;grid-template-columns:132px 1fr;gap:20px;align-items:center;
  margin-top:16px;padding:16px 18px;
  background:rgba(12,16,23,.42);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
.days__ring{position:relative;width:132px;height:132px;}
.days__ring svg{width:100%;height:100%;transform:rotate(-90deg);}
.days__ringBg{
  fill:none;stroke:rgba(237,241,245,.1);stroke-width:6;
}
.days__ringFg{
  fill:none;stroke:var(--ember);stroke-width:6;stroke-linecap:round;
  filter:drop-shadow(0 0 10px rgba(224,138,78,.45));
}
.days__count{
  position:absolute;left:0;right:0;top:44px;
  text-align:center;
  font-family:var(--serif);font-size:2.1rem;font-weight:600;color:var(--paper);
  line-height:1;
}
.days__unit{
  position:absolute;left:0;right:0;top:74px;
  text-align:center;
  font-size:.6rem;letter-spacing:.24em;text-transform:uppercase;color:var(--paper-3);
}
.days__list{list-style:none;margin:0 0 12px;padding:0;}
.days__list li{
  font-size:.92rem;font-weight:300;color:var(--paper-3);
  padding:5px 0 5px 18px;position:relative;
  opacity:.35;transform:translateX(-6px);
  transition:opacity .4s ease,transform .4s ease,color .4s ease;
}
.days__list li::before{
  content:"";position:absolute;left:0;top:12px;
  width:7px;height:7px;border-radius:50%;
  background:var(--ember-dim);
  transition:background .4s ease;
}
.days__list li.is-in{opacity:1;transform:none;color:var(--paper);}
.days__list li.is-in::before{background:var(--ember);}
.days__btn{
  display:inline-block;padding:8px 18px;
  background:none;border:1px solid var(--line-2);border-radius:999px;
  color:var(--ember-lt);cursor:pointer;
  font-family:var(--sans);font-size:.68rem;letter-spacing:.18em;text-transform:uppercase;
  transition:border-color .3s,color .3s,background .3s;
}
.days__btn:hover{border-color:var(--ember);color:var(--ember-pale);}
.days__btn.is-on{background:rgba(224,138,78,.12);border-color:var(--ember);}
.days__btn:disabled{opacity:.5;cursor:default;}
.days__echo{
  margin:12px 0 0;font-size:.94rem;font-weight:300;font-style:italic;
  color:var(--ember-pale);line-height:1.6;
}
@media (max-width:760px){ .days{grid-template-columns:1fr;} .days__ring{margin:0 auto;} }

/* ---- p9 · the counter-test -------------------------------------------- */
.test{margin-top:16px;display:grid;gap:12px;}
.test__opt{
  display:grid;gap:8px;padding:14px 16px;text-align:left;cursor:pointer;
  background:rgba(12,16,23,.42);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  transition:border-color .32s,background .32s;
}
.test__opt:hover{border-color:var(--line-2);}
.test__tag{
  font-size:.66rem;letter-spacing:.2em;text-transform:uppercase;
}
.test__tag--real{color:var(--after-lt);}
.test__tag--fake{color:var(--before-lt);}
.test__body{font-size:.94rem;font-weight:300;color:var(--paper-2);line-height:1.6;}
.test__opt--real.is-on{border-color:rgba(78,156,134,.65);background:rgba(78,156,134,.09);}
.test__opt--fake.is-on{border-color:rgba(176,80,60,.6); background:rgba(176,80,60,.09);}
.test.is-fake .test__opt--real{opacity:.5;}
.test.is-fake .test__opt--real.is-on{opacity:1;}
.test__echo{
  margin:4px 0 0;font-size:.96rem;font-weight:300;font-style:italic;
  color:var(--ember-pale);line-height:1.6;
  animation:echoLand .5s cubic-bezier(.2,.8,.25,1);
}
@keyframes echoLand{ from{opacity:0;transform:translateY(6px);} }

/* ---- p10 · the conclusion rows ---------------------------------------- */
.mapping__row{
  display:grid;grid-template-columns:130px 1fr;gap:18px;align-items:start;
  width:100%;text-align:left;cursor:pointer;
  padding:14px 20px;border-bottom:1px solid var(--line-soft);
  background:none;border-left:none;border-right:none;border-top:none;
  transition:background .3s ease;
}
.mapping__row:hover{background:rgba(224,138,78,.05);}
.mapping__row.is-lit{background:rgba(224,138,78,.08);}
.mapping__row.is-lit .mapping__rowBody{color:var(--paper);}
.mapping__rowBody{
  font-size:clamp(1.02rem,1.16vw,1.2rem);font-weight:300;
  color:var(--paper-2);line-height:1.6;
  transition:color .3s ease;
}

/* ---- p1 · the cap ----------------------------------------------------- */
.cap{
  margin-top:20px;padding:16px 18px 14px;
  background:rgba(12,16,23,.42);
  border:1px solid var(--line);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
}
.cap__frame{display:grid;grid-template-columns:1fr 118px;gap:18px;align-items:end;}
.cap__track{
  position:relative;height:118px;
  background:linear-gradient(180deg,rgba(237,241,245,.05),rgba(237,241,245,.02));
  border:1px solid var(--line-soft);border-radius:3px;
  overflow:hidden;
}
.cap__fill{
  position:absolute;left:0;right:0;bottom:0;height:20%;
  background:linear-gradient(180deg,var(--ember),var(--ember-deep));
  transition:height .12s linear;
}
/* the cap itself: the line the bar cannot pass */
.cap__line{
  position:absolute;left:0;right:0;bottom:50%;height:0;
  border-top:2px dashed var(--ember-lt);
  box-shadow:0 0 18px rgba(244,181,131,.45);
}
.cap__tag{
  position:absolute;right:8px;
  font-size:.58rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--ember-lt);white-space:nowrap;
}
.cap__tag--max{bottom:calc(50% + 6px);}
.cap__read{display:grid;gap:2px;}
.cap__num{
  font-family:var(--serif);font-size:2.2rem;font-weight:600;
  color:var(--paper);line-height:1;
  transition:color .3s ease;
}
.cap__lbl{
  font-size:.6rem;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-3);line-height:1.5;
}
.cap.is-over .cap__num{color:var(--before-lt);}
.cap.is-at  .cap__num{color:var(--ember-pale);}
.cap__range{
  -webkit-appearance:none;appearance:none;
  width:100%;height:26px;margin-top:12px;background:none;cursor:ew-resize;
}
.cap__range::-webkit-slider-runnable-track{
  height:2px;background:linear-gradient(90deg,var(--line-2),var(--ember));
}
.cap__range::-webkit-slider-thumb{
  -webkit-appearance:none;appearance:none;
  width:18px;height:18px;margin-top:-8px;border-radius:50%;
  background:var(--ember);box-shadow:0 0 16px rgba(224,138,78,.7);
}
.cap__range::-moz-range-track{height:2px;background:var(--line-2);}
.cap__range::-moz-range-thumb{
  width:18px;height:18px;border:0;border-radius:50%;
  background:var(--ember);box-shadow:0 0 16px rgba(224,138,78,.7);
}
.cap__echo{
  margin:10px 0 0;font-size:.92rem;font-weight:300;font-style:italic;
  color:var(--paper-2);line-height:1.55;
}
@media (max-width:760px){ .cap__frame{grid-template-columns:1fr;} .cap__read{order:-1;} }

/* ==========================================================================
   NARROW-SCREEN CORRECTIONS — the last word on ≤760px
   --------------------------------------------------------------------------
   Everything above was written in layers, and the per-widget layer landed
   AFTER the responsive layer. In CSS, source order decides ties, so the
   widget rules silently outvoted the phone rules they were never meant to
   beat:

     .slide:has(.mapping) .slide__inner{max-width:min(620px,50vw)}   -> 210px
                                                                        on a 420px
                                                                        screen, and
                                                                        the column
                                                                        shrank with
                                                                        it
     .mapping__row{grid-template-columns:130px 1fr}                  -> 84px left
                                                                        for the
                                                                        body text

   Both are re-asserted here, at the end of the file, where source order is
   finally on the phone's side. Specificity is still spelled out in full so
   the :has() rule above cannot win on weight instead.
   ========================================================================== */
@media (max-width:760px){
  /* the copy column is the whole slide: never a fraction of the viewport */
  .slide:has(.mapping) .slide__inner,
  .slide--wide .slide__inner,
  .slide:has(.grid3) .slide__inner,
  .slide:has(.ba) .slide__inner,
  .slide__inner{max-width:100%;width:100%;min-width:0;}

  /* a phone has no 130px to spare for a label: stack the two tracks */
  .mapping__row{
    grid-template-columns:1fr;
    gap:6px;padding:13px 0 13px 15px;
  }
  .mapping__label{min-width:0;padding-top:0;font-size:.6rem;letter-spacing:.14em;}
  .mapping__rowBody{min-width:0;}
  .mapping__row p{font-size:.84rem;}
  .mapping__row:hover{padding-left:15px;}

  /* the six conductors were 22px too tall for an 860px phone */
  .grid3{gap:10px;}
  .grid3 .card--flip{min-height:0;}
  .grid3 .card__face{padding:0 0 0 15px;}
  .grid3 .card__title{font-size:.9rem;margin-bottom:5px;}
  .grid3 .card p{font-size:.8rem;line-height:1.5;}

  /* keep the left gutter consistent with the right one */
  .slide{padding-left:20px;}
}

/* ==========================================================================
   HEIGHT-AWARE VERTICAL RHYTHM
   --------------------------------------------------------------------------
   The type scale is driven by viewport WIDTH (clamp(…,Nvw,…)), but a laptop
   at 1440x810 has the same width as a 1440x900 and 90px less height. Three
   pages were being clipped there: the title slide (its two display lines
   plus the margin-drag widget), the six flip cards, and the votes panel.

   A plain max-height query cannot separate 1440x810 from 1280x800 — 810 and
   800 are ten pixels apart — so the laptop rule is also gated on width.
   1600x900 and 1280x800 are left exactly as authored.
   ========================================================================== */
@media (min-width:1241px) and (max-height:920px){
  .title{font-size:clamp(2.3rem,2.8vw,2.95rem);}
  .lede{font-size:clamp(1.14rem,1.4vw,1.4rem);margin-top:16px;}
  .rule{margin-top:20px;}
  .meta{margin-top:22px;padding-top:18px;gap:13px 24px;}
  .badge{margin-top:20px;}
  .eyebrow{margin-bottom:11px;}
  .h2{font-size:clamp(2.05rem,3.55vw,3.25rem);margin-bottom:18px;}
  .p{font-size:clamp(1.02rem,1.16vw,1.24rem);margin-bottom:11px;}
  /* 34ch is a deliberate narrow measure over the artwork, but on a 940px
     column it costs this slide three whole lines it cannot spare. 46ch still
     reads as a column and takes two lines off the page. */
  .slide--wide .p{max-width:46ch;}
  .grid3{gap:clamp(13px,1.4vw,19px);}
  .grid3 .card--flip{min-height:148px;}
  .card__title{margin-bottom:8px;}
  .card p{line-height:1.55;}
  .cap{margin-top:14px;padding:12px 15px 10px;}
  .cap__track{height:96px;}
  .votes{margin-top:14px;padding:13px 16px 11px;}
  .votes__row{margin-bottom:7px;}
  .votes__gap{margin:10px 0 2px;padding-top:10px;}
  .mapping{margin-bottom:15px;}
  .mapping__row{padding:11px 18px;}
  .fork,.wave,.meter,.voices{margin-top:16px;}
  .flow,.days,.test{margin-top:14px;}
  .compare,.band{margin-top:14px;}
  .closing{margin-top:16px;}
}

/* a genuinely short window — half-height browser, split screen */
@media (min-width:761px) and (max-height:780px){
  .title{font-size:clamp(2.2rem,2.6vw,2.75rem);}
  .h2{font-size:clamp(1.95rem,3.3vw,3rem);margin-bottom:15px;}
  .p{font-size:clamp(1rem,1.14vw,1.22rem);margin-bottom:10px;line-height:1.56;}
  .lede{font-size:clamp(1.04rem,1.28vw,1.28rem);margin-top:13px;}
  .meta{margin-top:17px;padding-top:14px;gap:10px 24px;}
  .badge{margin-top:15px;}
  .eyebrow{margin-bottom:9px;}
  .rule{margin-top:16px;}
  .grid3{gap:clamp(11px,1.2vw,16px);}
  .grid3 .card--flip{min-height:128px;}
  .cap{margin-top:11px;padding:10px 13px 8px;}
  .cap__track{height:84px;}
  .votes{margin-top:11px;padding:10px 13px 9px;}
  .votes__row{margin-bottom:6px;}
  .votes__gap{margin:8px 0 2px;padding-top:8px;}
  .mapping{margin-bottom:12px;}
  .mapping__row{padding:9px 16px;}
  .fork,.wave,.meter,.voices{margin-top:13px;}
  .flow,.days,.test{margin-top:12px;}
}

/* --------------------------------------------------------------------------
   PHONE TUNING — every page has to survive 360px
   --------------------------------------------------------------------------
   A phone has no flip affordance, so both faces of a card are stacked and
   always visible (see the 760px block above). Six conductors is therefore
   six cards of two faces each: ~830px of copy in an 860px slide. The slide
   scrolls, but six cards should not need a scrollbar to be read.

   .card__aside carries no font-size of its own — it inherits — so the size
   is stated here rather than assumed. */
@media (max-width:760px){
  .h2{margin-bottom:15px;}
  .p{margin-bottom:10px;line-height:1.58;}
  .eyebrow{margin-bottom:10px;}

  /* the six conductors */
  .grid3{gap:8px;margin:4px 0 2px;}
  .grid3 .card__title{font-size:.88rem;margin-bottom:4px;}
  .grid3 .card__aside{font-size:.78rem;line-height:1.48;padding-top:8px;}
  .card__verdict{margin-top:8px;font-size:.54rem;padding:2px 8px;}
  /* The hint says "turn over". On a phone there is nothing to turn — both
     faces are already stacked and visible — so the hint is a lie. The 760px
     block above says as much in a comment; this is the rule it was missing. */
  .card__hint{display:none;}

  /* the votes panel and the margin drag */
  .votes{margin-top:12px;padding:12px 14px 10px;}
  .votes__row{grid-template-columns:100px 1fr 52px;gap:9px;margin-bottom:7px;}
  .votes__gap{margin:9px 0 2px;padding-top:9px;}
  .votes__btn{margin-top:8px;padding:7px 14px;font-size:.8rem;}
  .cap{margin-top:14px;padding:12px 14px 10px;}
  .cap__track{height:96px;}
  .cap__echo{font-size:.86rem;}

  /* the rest of the props */
  .fork,.wave,.meter,.voices{margin-top:14px;}
  .flow,.days,.test{margin-top:12px;}
  .mapping{margin-bottom:12px;}
  .mapping__row{padding:11px 0 11px 14px;}
  .mapping__row p{font-size:.82rem;line-height:1.55;}
  .quote,.statement,.closing{margin-top:14px;}
  .rule{margin-top:16px;}
  .badge{margin-top:16px;}
  .meta{margin-top:16px;padding-top:13px;gap:9px 20px;}
  .lede{margin-top:14px;}
}

/* --------------------------------------------------------------------------
   VERY SMALL PHONES — 375x667 and below
   --------------------------------------------------------------------------
   These slides scroll (the 760px block sets overflow-y:auto), so nothing is
   lost, but a page that needs 275px of scrolling to reach its last sentence
   is a page nobody finishes. Everything here is a tightening, never a
   removal: the same words at a smaller size. */
@media (max-width:760px) and (max-height:700px){
  .eyebrow{font-size:.58rem;letter-spacing:.28em;margin-bottom:8px;}
  .title{font-size:clamp(1.5rem,7.4vw,2.05rem);}
  .h2{font-size:clamp(1.05rem,5vw,1.35rem);margin-bottom:12px;}
  .p{font-size:.78rem;line-height:1.5;margin-bottom:8px;}
  .p--lead{font-size:.86rem;}
  .lede{font-size:.8rem;margin-top:11px;}
  .rule{margin-top:13px;width:84px;}
  .meta{gap:8px 16px;margin-top:13px;padding-top:11px;}
  .meta__label{font-size:.54rem;letter-spacing:.24em;}
  .meta__val{font-size:.8rem;}
  .badge{margin-top:13px;font-size:.58rem;letter-spacing:.24em;}
  .quote,.statement,.closing{margin-top:11px;}

  .grid3{gap:6px;margin:3px 0 2px;}
  .grid3 .card__title{font-size:.84rem;margin-bottom:3px;}
  .grid3 .card__aside{font-size:.74rem;line-height:1.44;padding-top:7px;}
  .card__verdict{margin-top:6px;font-size:.5rem;padding:2px 7px;}

  .mapping{margin-bottom:10px;}
  .mapping__row{padding:9px 0 9px 12px;}
  .mapping__label{font-size:.56rem;letter-spacing:.12em;}
  .mapping__row p{font-size:.78rem;line-height:1.5;}

  .votes{margin-top:10px;padding:10px 12px 9px;}
  .votes__row{grid-template-columns:86px 1fr 48px;gap:8px;margin-bottom:6px;}
  .votes__k{font-size:.72rem;}
  .votes__gap{margin:8px 0 2px;padding-top:8px;}
  .votes__gapN{font-size:.86rem;}
  .votes__gapT{font-size:.74rem;line-height:1.5;}
  .votes__btn{margin-top:7px;padding:6px 12px;font-size:.74rem;}

  .cap{margin-top:11px;padding:10px 12px 9px;}
  .cap__track{height:84px;}
  .cap__echo{font-size:.8rem;margin-top:8px;}

  .fork,.wave,.meter,.voices{margin-top:12px;}
  .flow,.days,.test{margin-top:10px;}
}
