/* ==========================================================================
   HE DID NOT ISSUE AN ORDER. HE CAPPED HIS OWN PROFIT.
   Creative Communication III, Homework 5.

   A game-client visual system, built for one argument: a leader who wrote a
   limit on himself into law. The chrome is deliberately borrowed — gold
   hairlines, angular clip-path frames, hextech teal, a sharp imperial serif —
   because the form should read as confident without ever competing with the
   evidence. Everything loud is chrome; everything that argues is set quiet.

   LAYERING RULE (learned the hard way): every responsive override lives in
   ONE block at the very bottom of this file. Rules written above, even in a
   media query, lose to equal-specificity rules written later. Do not scatter
   breakpoints through the file.
   ========================================================================== */

/* ==========================================================================
   1 · TOKENS
   ========================================================================== */

:root{
  /* surfaces — a printed page, not a screen. Warm off-white stock, and
     panels that are a shade whiter than the page they sit on. */
  --deep:      #f2efe8;
  --bg:        #e9e5db;
  --panel:     #fbf9f5;
  --panel-2:   #f5f2ea;
  --panel-hi:  #ffffff;

  /* the ink. --gold used to be the gold ornament; it is now the mid grey
     of a hairline rule, and --gold-hi is the near-black of a headline.
     The names are kept so the whole file did not have to be rewritten. */
  --gold:      #8d887c;
  --gold-hi:   #17181a;
  --gold-lo:   #c9c4b8;

  /* ONE accent: the brick red of a printed footnote mark. Everything that
     is live, chosen, or being argued is this colour and nothing else. */
  --teal:      #a8332a;
  --teal-hi:   #c0493a;
  --teal-dk:   #8a2a22;

  /* the other side of the definition: cold graphite, never red. The
     dictator column reads as grey; the leader column carries the accent. */
  --red:       #6b7076;
  --red-hi:    #8b9298;
  --red-dk:    #4c5157;

  /* type colours */
  --paper:     #1c1d1f;
  --paper-2:   #4a4e52;
  --paper-dim: #7c8186;

  /* lines */
  --line:      rgba(28,29,31,.20);
  --line-hi:   rgba(28,29,31,.46);
  --line-soft: rgba(28,29,31,.10);

  /* families. Two serifs do the arguing, one sans does the apparatus.
     --serif   display and headings: EB Garamond, the humanist old-style a
               journal puts on a title.
     --sans    reading text: Source Serif 4, which holds its weight small.
     --num     figures, folios, chart labels: Barlow Condensed, following the
               printed convention that numbers are sans even in a serif page.
     --ui      chrome: nav, buttons, overlays. Kept sans so the machinery is
               never mistaken for the argument. */
  --serif: 'EB Garamond', 'Source Serif 4', Georgia, 'Times New Roman', serif;
  --sans:  'Source Serif 4', Georgia, 'Times New Roman', serif;
  --num:   'Barlow Condensed', 'Barlow', Arial, sans-serif;
  --ui:    'Barlow', 'Helvetica Neue', Arial, sans-serif;

  /* no cut corners, no chrome. Frames are rectangles now. */
  --cut: 0px;
  --cut-s: 0px;

  /* motion */
  --ease: cubic-bezier(.2,.8,.25,1);
  --ease-out: cubic-bezier(.16,1,.3,1);

  /* column */
  --col: 660px;
}

/* ==========================================================================
   2 · BASE
   ========================================================================== */

*,*::before,*::after{ box-sizing:border-box; }

html,body{ height:100%; }

body{
  margin:0;
  background:var(--deep);
  color:var(--paper);
  font-family:var(--sans);
  font-size:17px;
  font-weight:400;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
  overflow:hidden;
}

/* The room. One soft pool of gold light high on the page over the client
   blue-black, and nothing else. The room is architecture: it should never
   be the thing you are looking at, and nothing in it moves. */
/* There is no background. Nothing here but paper stock: no light pool at the
   top of the page, no weave, no vignette, no grain. Every layer that used to
   sit between the reader and the type is gone, so the only things on the
   page are ink and the arguments drawn in it. */
body::before{ content:none; }

/* The diagonal weave that used to sit here (body::after) is gone: at
   reading distance it read as dirt on the screen rather than as texture. */

img{ max-width:100%; display:block; }
button{ font:inherit; color:inherit; }

::selection{ background:rgba(168,51,42,.32); color:var(--gold-hi); }

/* focus: a gold ring, never removed, because this deck is keyboard-driven */
:focus-visible{
  outline:2px solid var(--teal);
  outline-offset:3px;
}

/* ==========================================================================
   4 · INTRO — the client boots, and the claim is on screen
   ========================================================================== */

.intro{
  position:fixed; inset:0; z-index:80;
  display:grid; place-content:center;
  justify-items:center; gap:34px;
  background:
    radial-gradient(70% 60% at 50% 46%, rgba(233,229,219,.9), var(--deep) 72%),
    var(--deep);
  transition:opacity .55s var(--ease), visibility .55s;
}
.intro.is-done{ opacity:0; visibility:hidden; pointer-events:none; }

/* The overture is two lines of type and nothing else. It used to be three
   vertical bars rising to a horizontal rule; from across a room those bars
   read as one grey post standing in the middle of the title page, and a
   post is exactly the wrong shape for a talk about a race that refused to
   be ordered. The sentence is also the sentence the whole deck argues, so
   putting it first means the audience has read the thesis before page one. */
.intro__stage{
  position:relative;
  max-width:min(760px, 82vw);
  display:grid; place-content:center;
  text-align:center;
}
.intro__motto{
  margin:0;
  font-family:var(--serif);
  font-size:clamp(1.9rem, 4.4vw, 3.6rem);
  line-height:1.18;
  letter-spacing:-.01em;
  color:var(--paper);
  opacity:0;
  transform:translateY(14px);
  transition:opacity .8s var(--ease), transform .9s var(--ease);
}
.intro__motto em{
  font-style:italic;
  color:var(--gold);
}
.intro.is-s1 .intro__motto,
.intro.is-s2 .intro__motto,
.intro.is-s3 .intro__motto{
  opacity:1; transform:none;
}
/* the second line arrives a beat after the first */
.intro__motto em{
  opacity:0;
  transition:opacity .7s var(--ease) .35s;
}
.intro.is-s2 .intro__motto em,
.intro.is-s3 .intro__motto em{ opacity:1; }

.intro__credit{
  margin:0; text-align:center;
  display:grid; gap:6px;
}
.intro__credit span{
  font-family:var(--serif);
  font-size:.95rem; font-weight:600;
  letter-spacing:.42em; text-transform:uppercase;
  color:var(--gold);
}
.intro__credit i{
  font-style:normal;
  font-size:.78rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--paper-dim);
}
.intro__skip{
  background:none; border:1px solid var(--line);
  color:var(--paper-dim);
  padding:7px 20px;
  font-size:.72rem; letter-spacing:.24em; text-transform:uppercase;
  cursor:pointer;
  transition:color .3s, border-color .3s, background .3s;
}
.intro__skip:hover{ color:var(--gold-hi); border-color:var(--line-hi); background:rgba(141,136,124,.07); }

/* ==========================================================================
   5 · TOP BAR — the client's title bar
   ========================================================================== */

.topbar{
  position:fixed; top:0; left:0; right:0; z-index:50;
  height:58px;
  display:flex; align-items:center; gap:18px;
  padding:0 20px;
  background:linear-gradient(180deg, rgba(242,239,232,.96), rgba(242,239,232,.72) 70%, transparent);
  border-bottom:1px solid var(--line-soft);
  transform:translateY(-100%);
  transition:transform .6s var(--ease-out);
}
/* Only .is-ready reveals it. A `body:not(.is-booting)` fallback would show
   the bar during the gap before the script runs, which is exactly the frame
   the intro exists to cover. */
.is-ready .topbar{ transform:translateY(0); }

.topbar__brand{
  display:flex; align-items:center; gap:11px;
  background:none; border:0; padding:6px 4px;
  cursor:pointer;
  border-radius:2px;
}
.topbar__mark{
  display:grid; place-content:center;
  width:34px; height:34px;
  font-family:var(--num); font-weight:700; font-size:.95rem;
  letter-spacing:.02em;
  color:var(--deep);
  background:linear-gradient(150deg, var(--gold-hi), var(--gold) 45%, var(--gold-lo));
  box-shadow:0 0 18px rgba(141,136,124,.4);
}
.topbar__name{
  font-family:var(--serif); font-weight:600;
  font-size:.9rem; letter-spacing:.09em;
  color:var(--gold-hi);
  white-space:nowrap;
}

.topbar__mid{ display:flex; gap:6px; margin-left:auto; }

.topbar__tab{
  display:inline-flex; align-items:center; gap:7px;
  background:rgba(251,249,245,.6);
  border:1px solid var(--line-soft);
  color:var(--paper-2);
  padding:7px 13px;
  font-size:.74rem; font-weight:500;
  letter-spacing:.16em; text-transform:uppercase;
  cursor:pointer;
  transition:color .25s, border-color .25s, background .25s, box-shadow .25s;
}
.topbar__tab:hover{
  color:var(--gold-hi);
  border-color:var(--line-hi);
  background:rgba(141,136,124,.09);
}
.topbar__tab[aria-pressed="true"],.topbar__tab.is-on{
  color:var(--deep);
  background:linear-gradient(180deg, var(--gold-hi), var(--gold));
  border-color:var(--gold);
  box-shadow:0 0 20px rgba(141,136,124,.35);
}
.topbar__ico{ font-size:.95em; opacity:.9; }
.topbar__badge{
  font-family:var(--num); font-weight:700;
  font-size:.72rem;
  padding:1px 6px;
  color:var(--teal-hi);
  background:rgba(168,51,42,.14);
  border:1px solid rgba(168,51,42,.3);
}
.topbar__tab[aria-pressed="true"] .topbar__badge,
.topbar__tab.is-on .topbar__badge{
  color:var(--deep); background:rgba(242,239,232,.22); border-color:rgba(242,239,232,.3);
}
.topbar__tab--right{ margin-left:0; }

/* ==========================================================================
   6 · DECK
   ========================================================================== */

.deck{
  position:fixed; inset:0; z-index:10;
  perspective:1400px;
}

.slide{
  position:absolute; inset:0;
  /* tighter frame: enough clearance for the 58px top bar, and no more */
  /* --padR is published so the two absolutely-positioned widgets (.cap and) can sit inside the right margin instead of guessing at it. A
     hard-coded `right:52px` is correct at the base padding and silently
     lands 20px inside the content box once the 1700px block raises the
     padding to 72px. */
  --padR:56px;
  padding:64px var(--padR) 52px 76px;
  opacity:0; visibility:hidden;
  pointer-events:none;
  transition:opacity .5s var(--ease), visibility .5s;
}
.slide.is-active{
  opacity:1; visibility:visible; pointer-events:auto;
}

/* the artwork: a quiet presence on the right, and gone on the left where
   the copy sits. It no longer drifts and it no longer tracks the pointer
   — a background that moves is a background that gets watched. The full
   picture is one click away in the lightbox, which is where it belongs. */
/* The artwork is now a magazine plate: it lives in the right column and
   nowhere else, drawn as an ink line plate, and the text column is bare
   paper. No full-bleed wash, no gradient scrim — the picture and the type
   simply occupy different columns, like a printed spread. */
/* The figure column. These are arguments, not decoration: each one is a
   number or a date the page puts forward, so it prints at full strength
   rather than as a wash behind the type. multiply keeps its white aligned
   with the stock; contain means no figure is ever cropped to fit. */
.slide__art{
  position:absolute;
  left:56%; right:0; top:0; bottom:0;
  overflow:hidden;
  z-index:0;
  mix-blend-mode:multiply;
  opacity:1;
}
.slide__art::after{ content:none; }
.slide__art-in{
  position:absolute; inset:0;
  /* the bottom padding is deep on purpose: every plate carries its own
     FIGURE caption in the last 60 units, and the panel that sits over the
     plate (page 1's slider) has to land below that line rather than on
     top of it. 84px used to be the same as the top, and the caption went
     under the panel. */
  padding:86px 60px 268px 34px;
}
.slide__art-in img{
  width:100%; height:100%;
  object-fit:contain;
  object-position:center top;
}
.slide__art.is-missing{ display:none; }

/* the copy column */
.slide__inner{
  position:relative; z-index:2;
  max-width:var(--col);
  height:100%;
  display:flex; flex-direction:column;
  /* The column runs the full height and the blocks are spread over it, so
     the argument occupies the frame instead of floating in the middle of
     it. A page with nothing but a heading keeps its air; a page with a
     figure and a table is filled to both edges. */
  justify-content:center;
  gap:0;
}
/* The copy column can never cross the plate. The figure band starts at
   56% of the slide, so 52vw is the widest the type may run before it stops
   being type on paper and starts being type over an argument. This is
   stated once, here, and the breakpoints below only tune the size of the
   type inside it — none of them may widen the column again. */
.slide--wide .slide__inner{ max-width:min(1180px, 52vw); }

/* every direct child takes a share of the column, so the argument reaches
   the bottom of the frame on every page */
.slide__inner > *{ min-height:0; }

/* The invisible "enlarge the artwork" layer. It is a real <button> sitting
   between the art and the copy, so it MUST be taken out of flow: left static
   it is a native button with default padding, 27.5px tall, and it shoves
   every slide's text column down by exactly that much — a uniform offset
   that is invisible on screen and obvious in any measurement. */
/* the click target follows the plate: on a printed spread you click the
   picture, not the column of type next to it */
.artZoom{
  position:absolute;
  left:58%; right:0; top:0; bottom:0;
  z-index:1;
  width:auto; height:auto;
  margin:0; padding:0;
  background:none; border:0;
  cursor:zoom-in;
  -webkit-tap-highlight-color:transparent;
}

/* ==========================================================================
   7 · TYPE
   ========================================================================== */

.eyebrow{
  margin:0 0 16px;
  font-size:.72rem; font-weight:600;
  letter-spacing:.3em; text-transform:uppercase;
  color:var(--gold);
  display:flex; align-items:center; gap:12px;
}
.eyebrow::before{
  content:"";
  width:26px; height:1px;
  background:linear-gradient(90deg, transparent, var(--gold));
  flex:none;
}

.title{
  margin:0;
  font-family:var(--serif);
  /* Set against the COLUMN, not the viewport. The column is ~660px wide on
     desktop; a vw-driven size blows past it and the two lines the <br> asks
     for become four. Measured against the real Cinzel face, this range
     holds two lines from 1280px up. */
  font-size:clamp(2.05rem, 2.9vw, 3.05rem);
  font-weight:700;
  line-height:1.16;
  letter-spacing:-.005em;
  color:var(--gold-hi);
}
.title em{ font-style:normal; color:var(--gold); }

.h2{
  margin:0 0 22px;
  font-family:var(--serif);
  font-size:clamp(2rem, 3vw, 3.05rem);
  font-weight:600;
  line-height:1.14;
  letter-spacing:-.005em;
  color:var(--gold-hi);
}

.p{
  margin:0 0 13px;
  font-size:1.02rem;
  line-height:1.62;
  color:var(--paper);
  max-width:56ch;
}
.p b{ color:var(--teal-hi); font-weight:600; }
.p em{ color:var(--gold-hi); font-style:italic; }
.p--lead{ font-size:1.14rem; color:var(--paper); }
.p--italic{ font-style:italic; color:var(--paper-2); }

/* ---- keywords -------------------------------------------------------
   A slide is not an essay. It carries the word; the speaker carries the
   argument. Every body paragraph in this deck is therefore a row of
   keyword chips: one idea per chip, readable from the back of a room,
   and nothing for the audience to read while the speaker is talking.
   -------------------------------------------------------------------- */
.keys{
  display:flex; flex-wrap:wrap; gap:9px 10px;
  margin:18px 0 0;
}
.key{
  display:inline-flex; align-items:center; gap:9px;
  padding:9px 16px 9px 13px;
  font-family:var(--num); font-weight:600;
  font-size:1.06rem; letter-spacing:.08em; text-transform:uppercase;
  color:var(--paper);
  background:linear-gradient(100deg, rgba(141,136,124,.12), rgba(251,249,245,.42));
  border:1px solid var(--line);
}
/* the diamond bullet: the same glyph that opens every eyebrow */
.key::before{
  content:""; flex:none;
  width:6px; height:6px;
  background:var(--gold);
  box-shadow:0 0 8px rgba(141,136,124,.5);
  transform:rotate(45deg);
}
.key--hot{
  color:var(--gold-hi);
  border-color:var(--gold-lo);
  background:linear-gradient(100deg, rgba(141,136,124,.22), rgba(251,249,245,.46));
}
.key--hot::before{ background:var(--gold-hi); }
.key--teal{
  color:var(--teal-hi);
  border-color:rgba(168,51,42,.4);
  background:rgba(168,51,42,.1);
}
.key--teal::before{
  background:var(--teal);
  box-shadow:0 0 8px rgba(168,51,42,.5);
}
/* the one chip that carries the page: serif, and one size up */
.key--big{
  font-family:var(--serif); font-weight:600;
  font-size:clamp(1.02rem, 1.5vw, 1.28rem); letter-spacing:.05em;
  padding:10px 18px 10px 15px;
}
.key--big::before{ width:7px; height:7px; }

.lede{
  margin:0;
  font-size:1.1rem;
  color:var(--paper-2);
  max-width:46ch;
}

.rule{
  height:1px; width:120px; margin:22px 0;
  background:linear-gradient(90deg, var(--gold), rgba(141,136,124,0));
  position:relative;
}
.rule::after{
  content:"";
  position:absolute; left:0; top:-2px;
  width:5px; height:5px;
  background:var(--gold-hi);
  transform:rotate(45deg);
}

.badge{
  justify-self:start;
  margin:20px 0 0;
  padding:6px 15px 6px 13px;
  font-size:.7rem; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--teal-hi);
  background:rgba(168,51,42,.1);
  border:1px solid rgba(168,51,42,.34);
}

/* the profile card on the title page */
.profile{
  display:flex; align-items:center; flex-wrap:wrap;
  gap:0 14px;
  margin:0 0 22px;
  padding:9px 18px 9px 14px;
  background:linear-gradient(100deg, rgba(141,136,124,.14), rgba(251,249,245,.5));
  border:1px solid var(--line);
  border-left:2px solid var(--gold);
}
.profile__name{
  font-family:var(--serif); font-weight:700;
  font-size:1.02rem; letter-spacing:.1em;
  color:var(--gold-hi);
}
.profile__sep{
  width:1px; height:15px;
  background:var(--line-hi);
}
.profile__role,.profile__class{
  font-size:.76rem; font-weight:500;
  letter-spacing:.15em; text-transform:uppercase;
  color:var(--paper-2);
}
.profile__class{ color:var(--teal); }

/* The two product marks. QQ is the throne and WeChat is what the race
   produced; between them they are the whole argument of the deck in two
   marks. The paths are inlined in the markup rather than referenced as
   files: an SVG used as a CSS mask is fetched as an image, and over
   file:// that request is blocked by CORS, so the marks silently vanished
   in every local preview. Inlined, they are part of the document. */
.profile__marks{ display:flex; align-items:center; gap:7px; }
.mark{
  display:block;
  width:19px; height:19px;
  fill:var(--gold-hi);
}
/* inline beside a line of type, and in the deck's own red once the mark
   stands for the thing that actually won */
.mark--sm{ width:14px; height:14px; margin-right:7px; display:inline-block; vertical-align:-2px; }
.mark--red{ fill:var(--red-hi); }

.meta{
  display:grid;
  grid-template-columns:repeat(4, minmax(0,1fr));
  gap:14px 22px;
  margin:26px 0 0;
  padding:18px 0 0;
  border-top:1px solid var(--line-soft);
  max-width:640px;
}
.meta__item{ display:grid; gap:3px; }
.meta__label{
  font-size:.62rem; font-weight:600;
  letter-spacing:.22em; text-transform:uppercase;
  color:var(--paper-dim);
}
.meta__val{
  font-family:var(--num); font-weight:600;
  font-size:.94rem; letter-spacing:.03em;
  color:var(--gold);
}

/* the acute mark over the stressed word */
.stressed{ position:relative; font-style:normal; }
.stressed::before{
  content:"";
  position:absolute; left:50%; top:-.34em;
  width:.1em; height:.34em;
  background:var(--red-hi);
  transform:translateX(-50%);
  box-shadow:0 0 12px rgba(139,146,152,.8);
}
/* an invisible hit area laid exactly over the mark. No font-size:0 — em is
   resolved against the element's OWN font-size, and zeroing it would zero
   the hit area with it. The element is empty, so there is no glyph to hide. */
.acutePick{
  position:absolute; left:.16em; top:-.52em;
  display:block; width:.62em; height:.78em;
  font-style:normal; cursor:pointer;
  transition:transform .3s var(--ease), filter .3s;
}
.acutePick:hover,.acutePick:focus-visible{
  transform:scale(1.25);
}
.acutePick.is-lit::after{
  content:"";
  position:absolute; inset:-6px;
  border:1px solid var(--red-hi);
}

.quote{
  margin:22px 0 0; padding:14px 18px;
  max-width:56ch;
  background:rgba(251,249,245,.55);
  border-left:2px solid var(--gold);
  font-size:.94rem; line-height:1.6;
  color:var(--paper-2);
  cursor:pointer;
  transition:background .3s, border-color .3s;
}
.quote:hover{ background:rgba(141,136,124,.1); border-color:var(--gold-hi); }
.quote em{ color:var(--gold-hi); font-style:italic; }
.memo-mark{ position:relative; }
.memo-mark.is-lit{
  box-shadow:0 0 0 1px var(--teal), 0 0 22px rgba(168,51,42,.3);
}

/* ==========================================================================
   8 · CARDS — the rune stones
   ========================================================================== */

.grid3{
  display:grid;
  grid-template-columns:repeat(3, minmax(0,1fr));
  gap:16px;
  margin:6px 0 0;
}

/* ==========================================================================
   THE TWO-COLUMN SLIDE
   Two pages carry two halves of one argument instead of one widget: the
   throne beside the three beliefs, the four-line conclusion beside what
   stays open. They stack by default and the page scrolls like any other;
   only a genuinely wide room gets two columns, and those two pages give up
   their plate because the type needs the whole width.
   Note there is deliberately no `.duo .grid3` rule here: let the global
   grid3 breakpoints decide, or every one of them would need overriding.
   ========================================================================== */
.slide--duo .slide__art{ display:none; }
.slide--duo .artZoom{ display:none; }

.duo{
  display:grid;
  grid-template-columns:1fr;
  gap:24px;
  align-items:start;
  margin:22px 0 0;
}
.duo__col{ min-width:0; display:flex; flex-direction:column; }
.duo__h{
  font-family:var(--num); font-weight:600;
  font-size:.74rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--gold);
  margin:0 0 10px; padding:0 0 7px;
  border-bottom:1px solid var(--line-soft);
}
/* inside a duo the two halves supply their own rhythm, so the widgets drop
   the top spacing they use when they own the page outright */
.duo .votes,
.duo .mapping{ margin:0; }

/* ==========================================================================
   THE LEDGER
   One page argues by nothing but comparison: two columns of outcomes set
   side by side, and the point is that the second column is the heavier one.
   Two rules, two lists, no boxes and no fills.
   ========================================================================== */
.ledger{
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:0 40px;
  margin:26px 0 0;
  padding-top:16px;
  border-top:2px solid var(--line-hi);
}
.ledger__col{ min-width:0; }
.ledger__h{
  font-family:var(--num); font-weight:600;
  font-size:.74rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--gold);
  margin:0 0 4px; padding:0 0 8px;
  border-bottom:1px solid var(--line-soft);
}
.ledger__list{ list-style:none; margin:0; padding:0; }
.ledger__list li{
  padding:9px 0;
  border-bottom:1px solid var(--line-soft);
  font-size:1.02rem; line-height:1.4;
  color:var(--paper-2);
}
/* the column that carries the argument is set in full ink and weight */
.ledger__col--lost .ledger__h{ color:var(--teal); }
.ledger__col--lost .ledger__list li{ color:var(--paper); font-weight:600; }
.ledger__note{
  margin:18px 0 0;
  font-size:1.06rem; font-style:italic;
  color:var(--paper-dim);
}

/* ==========================================================================
   THE MARGINAL CLAIM
   A page that argues rather than lists needs one sentence that carries the
   claim, set where a journal would set a marginal note: a rule on the left,
   the argument in italic, the evidence for it beneath. It is the largest
   single piece of reading on the page after the heading, which is exactly
   what makes it worth the space.
   ========================================================================== */
.claim{
  margin:26px 0 0;
  padding:2px 0 2px 28px;
  border-left:2px solid var(--teal);
  display:grid; gap:11px;
}
.claim__line{
  font-family:var(--serif); font-style:italic;
  font-size:1.62rem; line-height:1.32;
  color:var(--paper);
  max-width:34em;
}
.claim__line em{
  font-style:normal;
  font-weight:600;
  color:var(--teal-hi);
}
.claim__src{
  font-family:var(--num); font-weight:600;
  font-size:.76rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--paper-dim);
  padding-top:10px;
  border-top:1px solid var(--line-soft);
}

/* ==========================================================================
   THE CHOICES
   The three moves a dictator would have made, laid out as a question the
   reader can press rather than as a corner panel they have to find. In the
   flow of the column it also does the work the floating version could not:
   the argument now occupies the height the illustration does not.
   ========================================================================== */
.choices{
  margin:26px 0 0;
  padding:18px 20px 16px;
  background:linear-gradient(165deg, rgba(233,229,219,.9), rgba(245,242,234,.9));
  border:1px solid var(--line);
}
.choices__q{
  margin:0 0 13px;
  font-family:var(--serif); font-weight:600;
  font-size:1.02rem; letter-spacing:.04em;
  color:var(--gold-hi);
}
.choices__grid{
  display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:10px;
}
.choices__opt{
  display:grid; gap:4px; align-content:start;
  text-align:left;
  padding:12px 14px;
  background:rgba(242,239,232,.5);
  border:1px solid var(--line-soft);
  border-left:2px solid rgba(107,112,118,.5);
  cursor:pointer;
  transition:background .3s, border-color .3s, transform .3s var(--ease);
}
.choices__opt:hover{ background:rgba(107,112,118,.1); transform:translateY(-2px); }
.choices__opt.is-on{
  background:rgba(107,112,118,.16);
  border-color:rgba(107,112,118,.5);
  border-left-color:var(--red-hi);
}
.choices__k{
  font-family:var(--num); font-weight:700;
  font-size:.9rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--paper);
}
.choices__opt.is-on .choices__k{ color:var(--red-hi); }
.choices__v{ font-size:.86rem; line-height:1.46; color:var(--paper-2); }
.choices__bar{
  margin-top:14px; height:4px;
  background:var(--line-soft); overflow:hidden;
}
.choices__fill{
  display:block; height:100%; width:0%;
  background:var(--red-hi);
  transition:width .5s var(--ease-out);
}
.choices__out{
  margin:11px 0 0;
  font-size:.92rem; line-height:1.5;
  font-style:italic;
  color:var(--gold);
}

.card{
  position:relative;
  display:block;
  min-height:172px;
  padding:0;
  background:none; border:0;
  cursor:pointer;
  text-align:left;
  perspective:1100px;
  font:inherit;
}
.card__face{
  position:absolute; inset:0;
  display:flex; flex-direction:column;
  padding:17px 17px 15px;
  background:linear-gradient(165deg, rgba(233,229,219,.94), rgba(251,249,245,.94));
  border:1px solid var(--line);
  backface-visibility:hidden;
  -webkit-backface-visibility:hidden;
  transition:transform .62s var(--ease-out), box-shadow .4s, border-color .4s;
  overflow:hidden;
}
.card__face--front{ transform:rotateY(0); }
.card__face--back{
  transform:rotateY(180deg);
  background:linear-gradient(165deg, rgba(168,51,42,.10), rgba(251,249,245,.96));
}
.card.is-flipped .card__face--front{ transform:rotateY(-180deg); }
.card.is-flipped .card__face--back{ transform:rotateY(0); }

.card:hover .card__face{
  border-color:var(--line-hi);
  box-shadow:0 0 0 1px rgba(141,136,124,.18), 0 14px 40px rgba(242,239,232,.7),
             0 0 34px rgba(141,136,124,.1);
}
.card:focus-visible .card__face{ border-color:var(--teal); }

/* the rune glyph on the front face: a hextech diamond */
.card__rune{
  position:absolute; right:14px; top:14px;
  width:26px; height:30px;
  background:linear-gradient(160deg, var(--red-hi), var(--red-dk));
  opacity:.85;
  box-shadow:0 0 16px rgba(107,112,118,.4);
}
.card__rune--yes{
  background:linear-gradient(160deg, var(--teal-hi), var(--teal-dk));
  box-shadow:0 0 16px rgba(168,51,42,.45);
}

.card__num{
  font-family:var(--num); font-weight:700;
  font-size:.82rem; letter-spacing:.18em;
  color:var(--gold);
  margin-bottom:6px;
}
.card__title{
  font-family:var(--serif); font-weight:600;
  font-size:1.02rem; line-height:1.25;
  letter-spacing:.01em;
  color:var(--gold-hi);
  margin-bottom:8px;
  padding-right:30px;
}
.card__aside{
  font-size:.86rem; line-height:1.52;
  color:var(--paper-2);
}
.card__verdict{
  margin-top:auto;
  align-self:flex-start;
  padding:3px 11px;
  font-size:.64rem; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase;
}
.card__verdict--no{
  color:var(--red-hi);
  background:rgba(107,112,118,.16);
  border:1px solid rgba(107,112,118,.45);
}
.card__verdict--yes{
  color:var(--teal-hi);
  background:rgba(168,51,42,.16);
  border:1px solid rgba(168,51,42,.45);
}
.card__hint{
  position:absolute; left:17px; bottom:9px;
  font-size:.6rem; font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--paper-dim);
  opacity:.75;
  transition:color .3s, opacity .3s;
}
.card:hover .card__hint{ color:var(--gold); opacity:1; }

/* ==========================================================================
   9 · VERSUS — the definition, split
   ========================================================================== */

.ba{
  --split:50%;
  --focusA:1; --focusB:1;
  position:relative;
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:0;
  margin:4px 0 0;
  min-height:290px;
  background:rgba(245,242,234,.5);
  border:1px solid var(--line);
}
.ba__pane{
  padding:20px 22px 44px;
  transition:opacity .4s ease;
}
.ba__pane--a{
  background:linear-gradient(160deg, rgba(107,112,118,.13), rgba(107,112,118,.03));
  border-right:1px solid var(--line);
  opacity:var(--focusA);
}
.ba__pane--b{
  background:linear-gradient(200deg, rgba(168,51,42,.11), rgba(168,51,42,.02));
  opacity:var(--focusB);
}
.ba__tag{
  display:inline-block;
  margin-bottom:14px;
  padding:4px 13px;
  font-family:var(--serif); font-weight:600;
  font-size:.8rem; letter-spacing:.16em; text-transform:uppercase;
}
.ba__tag--before{
  color:var(--red-hi);
  background:rgba(107,112,118,.16);
  border:1px solid rgba(107,112,118,.42);
}
.ba__tag--after{
  color:var(--teal-hi);
  background:rgba(168,51,42,.16);
  border:1px solid rgba(168,51,42,.42);
}
.ba__list{ margin:0; padding:0; list-style:none; }
.ba__list li{
  position:relative;
  padding:7px 0 7px 20px;
  font-size:.92rem; line-height:1.5;
  color:var(--paper);
  border-bottom:1px solid rgba(141,136,124,.08);
}
.ba__list li:last-child{ border-bottom:0; }
.ba__list li::before{
  content:"";
  position:absolute; left:2px; top:15px;
  width:6px; height:6px;
  transform:rotate(45deg);
}
.ba__pane--a .ba__list li::before{ background:var(--red); box-shadow:0 0 8px rgba(107,112,118,.6); }
.ba__pane--b .ba__list li::before{ background:var(--teal); box-shadow:0 0 8px rgba(168,51,42,.6); }

/* the seam */
.ba__handle{
  position:absolute; top:0; bottom:0;
  left:var(--split);
  width:2px; margin-left:-1px;
  background:linear-gradient(180deg, transparent, var(--gold) 12%, var(--gold-hi) 50%, var(--gold) 88%, transparent);
  box-shadow:0 0 18px rgba(141,136,124,.55);
  pointer-events:none;
}
.ba__handle::after{
  content:"";
  position:absolute; left:50%; top:50%;
  width:16px; height:18px; margin:-9px 0 0 -8px;
  background:linear-gradient(160deg, var(--gold-hi), var(--gold));
  box-shadow:0 0 16px rgba(141,136,124,.7);
}
.ba__range{
  position:absolute; inset:0;
  width:100%; height:100%;
  margin:0; padding:0;
  opacity:0; cursor:ew-resize;
  -webkit-appearance:none; appearance:none;
  background:transparent;
}
.ba__range::-webkit-slider-thumb{ -webkit-appearance:none; width:40px; height:100%; }
.ba__range::-moz-range-thumb{ width:40px; height:100%; border:0; background:transparent; }
.ba__hint{
  position:absolute; left:0; right:0; bottom:12px;
  margin:0; text-align:center;
  font-size:.72rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold);
  pointer-events:none;
}
.ba.is-dragging .ba__handle{ box-shadow:0 0 28px rgba(141,136,124,.9); }

/* ==========================================================================
   10 · STATS — shares against votes
   ========================================================================== */

.votes{
  margin:20px 0 0;
  padding:18px 20px 16px;
  background:linear-gradient(165deg, rgba(233,229,219,.9), rgba(251,249,245,.9));
  border:1px solid var(--line);
}
.votes__row{
  display:grid;
  grid-template-columns:150px 1fr 62px;
  align-items:center; gap:14px;
  margin-bottom:11px;
}
.votes__k{
  font-size:.76rem; font-weight:600;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--paper-2);
}
.votes__track{
  position:relative;
  height:12px;
  background:rgba(242,239,232,.7);
  border:1px solid var(--line-soft);
  overflow:hidden;
}
.votes__bar{
  position:absolute; left:0; top:0; bottom:0;
  width:0;
  transition:width 1.1s var(--ease-out);
}
.votes__bar--shares{
  background:linear-gradient(90deg, var(--gold-lo), var(--gold) 70%, var(--gold-hi));
  box-shadow:0 0 14px rgba(141,136,124,.5);
}
.votes__bar--votes{
  background:linear-gradient(90deg, var(--teal-dk), var(--teal) 70%, var(--teal-hi));
  box-shadow:0 0 14px rgba(168,51,42,.55);
}
.votes__v{
  font-family:var(--num); font-weight:700;
  font-size:1.24rem; text-align:right;
  color:var(--gold-hi);
}
.votes__row:last-of-type .votes__v{ color:var(--teal-hi); }

.votes__gap{
  display:flex; align-items:baseline; gap:12px; flex-wrap:wrap;
  margin:14px 0 12px;
  padding:11px 14px;
  background:rgba(242,239,232,.55);
  border-left:2px solid var(--line-soft);
  opacity:.55;
  transition:opacity .45s ease, border-color .45s ease, background .45s ease;
}
.votes.is-open .votes__gap{
  opacity:1;
  border-color:var(--gold);
  background:rgba(141,136,124,.1);
}
.votes__gapN{
  font-family:var(--serif); font-weight:700;
  font-size:1.1rem; letter-spacing:.04em;
  color:var(--gold);
}
.votes__gapT{ font-size:.84rem; line-height:1.5; color:var(--paper-2); }

.votes__btn{
  display:inline-flex; align-items:center; gap:9px;
  background:rgba(168,51,42,.1);
  border:1px solid rgba(168,51,42,.38);
  color:var(--teal-hi);
  padding:8px 18px;
  font-size:.74rem; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase;
  cursor:pointer;
  transition:background .3s, color .3s, border-color .3s, box-shadow .3s;
}
.votes__btn:hover,.votes__btn.is-on{
  background:linear-gradient(180deg, var(--teal-hi), var(--teal));
  color:var(--deep);
  border-color:var(--teal-hi);
  box-shadow:0 0 24px rgba(168,51,42,.35);
}
.votes__echo{
  margin:12px 0 0;
  font-size:.86rem; line-height:1.55;
  color:var(--paper-2);
  font-style:italic;
}

/* ==========================================================================
   12 · FLOW — patch notes
   ========================================================================== */

.flow{
  display:flex; align-items:stretch; gap:0;
  margin:6px 0 20px;
  flex-wrap:wrap;
}
.flow__box{
  flex:1 1 0;
  min-width:0;
  display:grid; gap:5px;
  text-align:left;
  padding:14px 15px 13px;
  background:linear-gradient(170deg, rgba(233,229,219,.9), rgba(251,249,245,.9));
  border:1px solid var(--line-soft);
  cursor:pointer;
  transition:border-color .35s, background .35s, transform .35s var(--ease), box-shadow .35s;
}
.flow__box:hover{ transform:translateY(-3px); border-color:var(--line-hi); }
.flow__box.is-lit{
  border-color:var(--teal);
  background:linear-gradient(170deg, rgba(168,51,42,.14), rgba(251,249,245,.92));
  box-shadow:0 0 0 1px rgba(168,51,42,.25), 0 0 30px rgba(168,51,42,.18);
}
.flow__tag{
  font-family:var(--num); font-weight:700;
  font-size:.74rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--gold);
}
.flow__box.is-lit .flow__tag{ color:var(--teal-hi); }
.flow__desc{
  font-family:var(--serif); font-weight:600;
  font-size:.92rem; line-height:1.25;
  color:var(--gold-hi);
}
.flow__mine{ font-size:.8rem; line-height:1.48; color:var(--paper-2); }
.flow__arrow{
  flex:0 0 46px;
  display:grid; place-content:center;
  gap:2px;
  color:var(--gold-lo);
}
.flow__arrowLabel{
  font-size:.56rem; letter-spacing:.16em; text-transform:uppercase;
  text-align:center; color:var(--paper-dim);
}
.flow__arrowGlyph{ font-size:1.1rem; text-align:center; }
.flow__play{
  flex:0 0 auto;
  display:inline-flex; align-items:center; gap:9px;
  align-self:center;
  margin-left:10px;
  padding:10px 19px;
  background:linear-gradient(180deg, var(--gold-hi), var(--gold));
  border:0;
  color:var(--deep);
  font-size:.74rem; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase;
  cursor:pointer;
  box-shadow:0 0 26px rgba(141,136,124,.35);
  transition:filter .3s, transform .3s var(--ease);
}
.flow__play:hover{ filter:brightness(1.12); transform:translateY(-2px); }
.flow__play.is-playing{
  background:linear-gradient(180deg, var(--red-hi), var(--red));
  color:var(--gold-hi);
  box-shadow:0 0 26px rgba(107,112,118,.4);
}
.flow__playIco{ font-size:.8em; }

/* ==========================================================================
   13 · DAYS — the quest log
   ========================================================================== */

.days{
  display:flex; align-items:center; gap:24px;
  margin:20px 0 0;
  padding:18px 22px;
  background:linear-gradient(165deg, rgba(233,229,219,.9), rgba(251,249,245,.9));
  border:1px solid var(--line);
}
.days__ring{
  position:relative; flex:none;
  width:118px; height:118px;
}
.days__ring svg{ width:100%; height:100%; transform:rotate(-90deg); }
.days__ringBg{
  fill:none; stroke:rgba(242,239,232,.8); stroke-width:7;
}
.days__ringFg{
  fill:none; stroke:var(--teal); stroke-width:7;
  stroke-linecap:butt;
  transition:stroke-dashoffset .12s linear;
}
.days__count{
  position:absolute; inset:0;
  display:grid; place-content:center;
  font-family:var(--num); font-weight:700;
  font-size:2.5rem; line-height:1;
  color:var(--teal-hi);
}
.days__unit{
  position:absolute; left:0; right:0; bottom:20px;
  text-align:center;
  font-size:.6rem; letter-spacing:.24em; text-transform:uppercase;
  color:var(--paper-dim);
}
.days__side{ flex:1 1 auto; min-width:0; }
.days__list{ margin:0 0 13px; padding:0; list-style:none; }
.days__list li{
  position:relative;
  padding:5px 0 5px 24px;
  font-size:.88rem; line-height:1.45;
  color:var(--paper-dim);
  opacity:.35;
  transform:translateX(-6px);
  transition:opacity .4s ease, transform .4s var(--ease), color .4s ease;
}
.days__list li::before{
  content:"";
  position:absolute; left:4px; top:12px;
  width:9px; height:10px;
  background:var(--gold-lo);
  transition:background .4s ease, box-shadow .4s ease;
}
.days__list li.is-in{
  opacity:1; transform:none; color:var(--paper);
}
.days__list li.is-in::before{
  background:var(--teal-hi);
  box-shadow:0 0 12px rgba(168,51,42,.7);
}
.days__btn{
  display:inline-flex; align-items:center; gap:9px;
  background:rgba(141,136,124,.12);
  border:1px solid var(--line-hi);
  color:var(--gold-hi);
  padding:8px 18px;
  font-size:.74rem; font-weight:600;
  letter-spacing:.18em; text-transform:uppercase;
  cursor:pointer;
  transition:background .3s, color .3s, box-shadow .3s;
}
.days__btn:hover,.days__btn.is-on{
  background:linear-gradient(180deg, var(--gold-hi), var(--gold));
  color:var(--deep);
  box-shadow:0 0 24px rgba(141,136,124,.35);
}
.days__echo{
  margin:12px 0 0;
  font-size:.86rem; line-height:1.55;
  color:var(--paper-2); font-style:italic;
}

/* ==========================================================================
   14 · TEST — the replay
   ========================================================================== */

.test{
  margin:4px 0 0;
  display:grid; gap:10px;
}
.test__opt{
  display:grid; gap:6px;
  text-align:left;
  padding:16px 18px;
  background:rgba(251,249,245,.72);
  border:1px solid var(--line-soft);
  border-left:2px solid var(--line-soft);
  cursor:pointer;
  transition:border-color .35s, background .35s, transform .35s var(--ease), box-shadow .35s;
}
.test__opt:hover{ transform:translateX(3px); border-color:var(--line-hi); }
.test__opt--real.is-on{
  border-color:rgba(168,51,42,.5);
  border-left-color:var(--teal);
  background:linear-gradient(100deg, rgba(168,51,42,.13), rgba(251,249,245,.72));
  box-shadow:0 0 30px rgba(168,51,42,.14);
}
.test__opt--fake.is-on{
  border-color:rgba(107,112,118,.5);
  border-left-color:var(--red);
  background:linear-gradient(100deg, rgba(107,112,118,.13), rgba(251,249,245,.72));
  box-shadow:0 0 30px rgba(107,112,118,.14);
}
.test__tag{
  font-family:var(--serif); font-weight:600;
  font-size:.82rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--paper-dim);
}
.test__opt--real.is-on .test__tag{ color:var(--teal-hi); }
.test__opt--fake.is-on .test__tag{ color:var(--red-hi); }
.test__body{ font-size:.94rem; line-height:1.55; color:var(--paper); }
.test__echo{
  margin:4px 0 0;
  font-size:.88rem; line-height:1.55;
  color:var(--gold);
  font-style:italic;
  animation:echoIn .45s var(--ease-out);
}
@keyframes echoIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }

/* ==========================================================================
   15 · MAPPING — the mastery summary
   ========================================================================== */

.mapping{
  margin:4px 0 0;
  display:grid; gap:8px;
}
.mapping__row{
  display:grid;
  grid-template-columns:150px 1fr;
  align-items:center; gap:16px;
  text-align:left;
  padding:14px 17px;
  background:rgba(251,249,245,.66);
  border:1px solid var(--line-soft);
  border-left:2px solid var(--line-soft);
  cursor:pointer;
  transition:border-color .35s, background .35s, transform .35s var(--ease), box-shadow .35s;
}
.mapping__row:hover{
  transform:translateX(4px);
  border-color:var(--line-hi);
  background:rgba(141,136,124,.07);
}
.mapping__row.is-lit{
  border-color:rgba(141,136,124,.45);
  border-left-color:var(--gold);
  background:linear-gradient(100deg, rgba(141,136,124,.14), rgba(251,249,245,.7));
  box-shadow:0 0 28px rgba(141,136,124,.14);
}
.mapping__label{
  font-family:var(--serif); font-weight:600;
  font-size:.8rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--paper-dim);
}
.mapping__row.is-lit .mapping__label{ color:var(--gold-hi); }
.mapping__label--outside{ color:var(--red-hi); }
.mapping__label--proof{ color:var(--gold); }
.mapping__label--inside{ color:var(--teal-hi); }
.mapping__rowBody{ font-size:.94rem; line-height:1.5; color:var(--paper); }

/* ==========================================================================
   16 · CAP — the 5% slider
   ========================================================================== */

.cap{
  /* --padR minus 4px: the panel sits 4px inside the right margin, the same
     relationship to the padding at every breakpoint.

     It is anchored to the BOTTOM of the plate and the plate's own caption
     sits in the last 60 units of it, so the panel used to land on top of
     "FIGURE 1" and hide it. The plate is scaled down inside its column and
     its caption always ends in the same place; anchoring the panel to the
     very bottom of the slide instead leaves the caption clear. */
  position:absolute; left:56%; right:0; bottom:52px; z-index:3;
  width:auto;
  margin:0 46px 0 34px;
  padding:12px 16px 10px;
  background:linear-gradient(165deg, rgba(233,229,219,.95), rgba(245,242,234,.95));
  border:1px solid var(--line);
  box-shadow:0 18px 50px rgba(242,239,232,.8);
}
.cap__frame{ display:flex; align-items:flex-end; gap:18px; }
.cap__track{
  position:relative; flex:none;
  /* 96, not 132: at 132 the panel was 246px tall and its top edge landed
     on the plate's FIGURE caption. The drag still reads clearly because
     the fill and the threshold line are the only two things in the track. */
  width:44px; height:96px;
  background:rgba(242,239,232,.75);
  border:1px solid var(--line-soft);
  overflow:hidden;
}
.cap__fill{
  position:absolute; left:0; right:0; bottom:0;
  height:20%;
  background:linear-gradient(0deg, var(--teal-dk), var(--teal) 65%, var(--teal-hi));
  box-shadow:0 0 20px rgba(168,51,42,.5);
  transition:height .18s var(--ease), background .3s, box-shadow .3s;
}
.cap.is-over .cap__fill{
  background:linear-gradient(0deg, var(--red-dk), var(--red) 60%, var(--red-hi));
  box-shadow:0 0 24px rgba(107,112,118,.6);
}
.cap.is-at .cap__fill{
  background:linear-gradient(0deg, var(--gold-lo), var(--gold) 65%, var(--gold-hi));
  box-shadow:0 0 24px rgba(141,136,124,.6);
}
/* the cap line itself, drawn across the track at 50% of its height */
.cap__line{
  position:absolute; left:0; right:0; top:50%;
  height:2px;
  background:linear-gradient(90deg, var(--gold-lo), var(--gold-hi), var(--gold-lo));
  box-shadow:0 0 14px rgba(141,136,124,.8);
}
.cap__line::after{
  content:"";
  position:absolute; right:0; top:-3px;
  width:6px; height:8px;
  background:var(--gold-hi);
}
.cap__tag{
  position:absolute; right:6px; top:calc(50% + 8px);
  font-family:var(--num); font-weight:700;
  font-size:.68rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold-hi);
  white-space:nowrap;
}
.cap__read{ display:grid; gap:2px; }
.cap__num{
  font-family:var(--num); font-weight:700;
  font-size:2.15rem; line-height:.95;
  color:var(--teal-hi);
  transition:color .3s;
}
.cap.is-over .cap__num{ color:var(--red-hi); text-shadow:0 0 26px rgba(107,112,118,.5); }
.cap.is-at .cap__num{ color:var(--gold-hi); text-shadow:0 0 26px rgba(141,136,124,.5); }
.cap__lbl{
  font-size:.66rem; letter-spacing:.18em; text-transform:uppercase;
  color:var(--paper-dim);
}
.cap__range{
  /* The input box is the hit area: the visible track is 6px, but a 6px
     target is unusable — especially on touch. 30px of invisible box around
     the drawn track; the track pseudo-elements centre inside it. */
  width:100%; height:30px; margin:10px 0 0;
  -webkit-appearance:none; appearance:none;
  background:transparent; cursor:pointer;
}
.cap__range::-webkit-slider-runnable-track{
  height:6px;
  background:linear-gradient(90deg, rgba(141,136,124,.35), rgba(168,51,42,.4));
  border:1px solid var(--line-soft);
}
.cap__range::-webkit-slider-thumb{
  -webkit-appearance:none;
  width:16px; height:22px; margin-top:-9px;
  background:linear-gradient(160deg, var(--gold-hi), var(--gold));
  box-shadow:0 0 14px rgba(141,136,124,.7);
}
.cap__range::-moz-range-track{
  height:6px;
  background:linear-gradient(90deg, rgba(141,136,124,.35), rgba(168,51,42,.4));
  border:1px solid var(--line-soft);
}
.cap__range::-moz-range-thumb{
  width:16px; height:22px; border:0; border-radius:0;
  background:linear-gradient(160deg, var(--gold-hi), var(--gold));
}
.cap__echo{
  margin:11px 0 0;
  font-size:.82rem; line-height:1.5;
  color:var(--paper-2); font-style:italic;
}

/* ==========================================================================
   17 · NOTE TAB + MEMO POPOVER
   ========================================================================== */

.noteTab{
  /* fixed, not absolute: on the scrolling layouts (tablet, phone) an
     absolutely-positioned tab inside the slide scrolls away with the copy,
     and the notes are the one piece of chrome that must never leave. On the
     desktop deck the slide is inset:0, so fixed and absolute coincide. */
  position:fixed; left:0; top:50%;
  transform:translateY(-50%);
  z-index:4;
  display:grid; place-content:center; gap:3px;
  width:30px; padding:13px 0;
  background:linear-gradient(180deg, rgba(233,229,219,.95), rgba(245,242,234,.95));
  border:1px solid var(--line);
  border-left:0;
  color:var(--gold);
  cursor:pointer;
  transition:background .3s, color .3s, box-shadow .3s, width .3s var(--ease);
}
.noteTab:hover,.noteTab.is-lit{
  background:linear-gradient(180deg, var(--gold-hi), var(--gold));
  color:var(--deep);
  box-shadow:0 0 26px rgba(141,136,124,.4);
}
.noteTab__n{
  font-family:var(--num); font-weight:700;
  font-size:.86rem; line-height:1;
}
.noteTab__t{
  font-size:.52rem; letter-spacing:.1em; text-transform:uppercase;
  writing-mode:vertical-rl;
  margin:0 auto;
}

.memo{
  position:fixed; inset:0; z-index:70;
  pointer-events:none;
}
.memo.is-open{ pointer-events:auto; }
.memo__leader{
  position:fixed; inset:0;
  width:100%; height:100%;
  pointer-events:none;
  opacity:0;
  transition:opacity .3s ease;
}
.memo.is-open .memo__leader{ opacity:1; }
.memo__leader path{
  fill:none; stroke:var(--teal); stroke-width:1.4;
  stroke-dasharray:4 5;
}
.memo__card{
  position:fixed; left:0; top:0;
  width:min(330px, calc(100vw - 32px));
  padding:16px 18px 13px;
  background:linear-gradient(165deg, rgba(233,229,219,.98), rgba(245,242,234,.98));
  border:1px solid var(--line-hi);
  box-shadow:0 20px 60px rgba(242,239,232,.9), 0 0 40px rgba(168,51,42,.12);
  opacity:0; transform:translateY(8px) scale(.98);
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.memo.is-open .memo__card{ opacity:1; transform:none; }
.memo__num{
  display:inline-grid; place-content:center;
  min-width:24px; height:24px; padding:0 6px;
  margin-bottom:9px;
  font-family:var(--num); font-weight:700; font-size:.8rem;
  color:var(--deep);
  background:linear-gradient(160deg, var(--gold-hi), var(--gold));
}
.memo__body{
  margin:0;
  font-size:.88rem; line-height:1.58;
  color:var(--paper);
}
.memo__nav{
  display:flex; align-items:center; gap:10px;
  margin-top:14px; padding-top:11px;
  border-top:1px solid var(--line-soft);
}
.memo__arrow{
  width:28px; height:26px;
  background:rgba(141,136,124,.1);
  border:1px solid var(--line-soft);
  color:var(--gold);
  cursor:pointer;
  transition:background .25s, color .25s, border-color .25s;
}
.memo__arrow:hover{ background:var(--gold); color:var(--deep); }
.memo__count{
  font-family:var(--num); font-weight:600;
  font-size:.76rem; letter-spacing:.1em;
  color:var(--paper-dim);
}
.memo__x{
  position:absolute; right:10px; top:9px;
  width:24px; height:24px;
  background:none; border:1px solid var(--line-soft);
  color:var(--paper-dim);
  font-size:1rem; line-height:1;
  cursor:pointer;
  transition:color .25s, border-color .25s, background .25s;
}
.memo__x:hover{ color:var(--red-hi); border-color:var(--red); background:rgba(107,112,118,.14); }

/* ==========================================================================
   18 · PANELS — notes + glossary
   ========================================================================== */

.panel{
  position:fixed; top:0; right:0; bottom:0; z-index:55;
  width:min(420px, 100vw);
  display:flex; flex-direction:column;
  background:linear-gradient(190deg, rgba(251,249,245,.98), rgba(245,242,234,.99));
  border-left:1px solid var(--line);
  box-shadow:-20px 0 60px rgba(242,239,232,.8);
  transform:translateX(100%);
  transition:transform .45s var(--ease-out);
}
.panel.is-open{ transform:none; }
.panel__head{
  display:flex; align-items:center; gap:14px;
  padding:20px 22px 15px;
  border-bottom:1px solid var(--line);
}
.panel__title{
  margin:0;
  font-family:var(--serif); font-weight:600;
  font-size:1.06rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--gold-hi);
}
.panel__count{
  font-family:var(--num); font-weight:600;
  font-size:.76rem; letter-spacing:.1em;
  color:var(--teal);
}
.panel__head .panel__count{ margin-left:auto; }
.panel__x{
  width:28px; height:28px; flex:none;
  background:none; border:1px solid var(--line-soft);
  color:var(--paper-dim); font-size:1.05rem; line-height:1;
  cursor:pointer;
  transition:color .25s, border-color .25s, background .25s;
}
.panel__x:hover{ color:var(--red-hi); border-color:var(--red); background:rgba(107,112,118,.14); }
.panel__body{
  flex:1 1 auto;
  overflow-y:auto;
  padding:18px 22px 22px;
  overscroll-behavior:contain;
}
.panel__foot{
  padding:13px 22px 18px;
  border-top:1px solid var(--line);
}
.panel__nav{ display:flex; gap:8px; margin-bottom:8px; }
.panel__foot .panel__count{ display:block; font-size:.7rem; color:var(--paper-dim); }

.note{ display:grid; gap:8px; }
.note__page{
  margin:0;
  font-family:var(--num); font-weight:700;
  font-size:.7rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--teal);
}
.note__h{
  margin:0;
  font-family:var(--serif); font-weight:600;
  font-size:1.02rem; line-height:1.3;
  color:var(--gold-hi);
}
.note__body{ margin:0; font-size:.9rem; line-height:1.62; color:var(--paper); }
.note__jump{
  justify-self:start;
  margin-top:4px;
  background:rgba(168,51,42,.12);
  border:1px solid rgba(168,51,42,.4);
  color:var(--teal-hi);
  padding:7px 15px;
  font-size:.72rem; font-weight:600;
  letter-spacing:.14em; text-transform:uppercase;
  cursor:pointer;
  transition:background .25s, color .25s;
}
.note__jump:hover{ background:var(--teal); color:var(--deep); }

.gloss{
  display:block; width:100%;
  text-align:left;
  background:none; border:0;
  border-bottom:1px solid var(--line-soft);
  padding:0; cursor:pointer;
}
.gloss__t{
  display:flex; align-items:center; gap:11px;
  padding:14px 2px 12px;
}
.gloss__t b{
  font-family:var(--serif); font-weight:600;
  font-size:.96rem; letter-spacing:.03em;
  color:var(--gold-hi);
}
.gloss__t i{
  margin-left:auto;
  font-family:var(--num); font-style:normal; font-weight:700;
  font-size:.72rem; letter-spacing:.14em;
  color:var(--teal);
}
.gloss__d{
  display:grid;
  grid-template-rows:0fr;
  transition:grid-template-rows .4s var(--ease-out);
}
.gloss__d > *{ overflow:hidden; }
.gloss.is-open .gloss__d{ grid-template-rows:1fr; }
.gloss__d p{
  margin:0 0 14px;
  font-size:.87rem; line-height:1.6;
  color:var(--paper-2);
}
.gloss.is-open .gloss__t b{ color:var(--teal-hi); }

/* ==========================================================================
   19 · OVERVIEW
   ========================================================================== */

.overview{
  position:fixed; inset:0; z-index:58;
  background:rgba(242,239,232,.96);
  backdrop-filter:blur(6px);
  display:flex; flex-direction:column;
  /* opacity:0 is NOT enough: an opacity:0 overlay still hit-tests, and a
     full-screen one swallows every click meant for the deck underneath.
     visibility + pointer-events make the closed state truly inert. */
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .4s var(--ease), visibility .4s;
}
.overview.is-open{ opacity:1; visibility:visible; pointer-events:auto; }
.overview__head{
  display:flex; align-items:center; gap:16px;
  padding:22px 34px 18px;
  border-bottom:1px solid var(--line);
}
.overview__title{
  margin:0;
  font-family:var(--serif); font-weight:600;
  font-size:1.2rem; letter-spacing:.2em; text-transform:uppercase;
  color:var(--gold-hi);
}
.overview__head .panel__x{ margin-left:auto; }
.overview__grid{
  flex:1 1 auto;
  overflow-y:auto;
  display:grid;
  grid-template-columns:repeat(auto-fill, minmax(250px, 1fr));
  gap:16px;
  padding:26px 34px 40px;
  align-content:start;
}
.ovc{
  position:relative;
  display:grid; gap:0;
  text-align:left;
  padding:0;
  background:rgba(251,249,245,.8);
  border:1px solid var(--line-soft);
  cursor:pointer;
  overflow:hidden;
  transition:border-color .3s, transform .3s var(--ease), box-shadow .3s;
}
.ovc:hover{
  border-color:var(--line-hi);
  transform:translateY(-4px);
  box-shadow:0 16px 40px rgba(242,239,232,.7), 0 0 30px rgba(141,136,124,.12);
}
.ovc.is-on{ border-color:var(--teal); box-shadow:0 0 0 1px rgba(168,51,42,.4), 0 0 30px rgba(168,51,42,.18); }
.ovc__art{ position:relative; aspect-ratio:8/5; overflow:hidden; background:var(--deep); }
.ovc__art img{ width:100%; height:100%; object-fit:cover; }
.ovc__art::after{
  content:"";
  position:absolute; inset:0;
  background:linear-gradient(180deg, transparent 40%, rgba(245,242,234,.9));
}
.ovc__num{
  position:absolute; left:12px; top:10px; z-index:2;
  font-family:var(--num); font-weight:700;
  font-size:1.05rem;
  color:var(--gold-hi);
}
.ovc__meta{ display:grid; gap:4px; padding:13px 15px 15px; }
.ovc__label{
  font-size:.64rem; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--teal);
}
.ovc__title{
  font-family:var(--serif); font-weight:600;
  font-size:.88rem; line-height:1.28;
  color:var(--gold-hi);
}

/* ==========================================================================
   20 · LIGHTBOX
   ========================================================================== */

.zoom{
  position:fixed; inset:0; z-index:75;
  display:flex; flex-direction:column;
  background:rgba(242,239,232,.97);
  /* Same contract as .overview — and note the `hidden` attribute cannot be
     relied on here: .zoom sets display:flex, which outranks the UA sheet's
     [hidden]{display:none}. So the closed state must be made inert in CSS. */
  opacity:0; visibility:hidden; pointer-events:none;
  transition:opacity .35s var(--ease), visibility .35s;
}
.zoom.is-open{ opacity:1; visibility:visible; pointer-events:auto; }
.zoom__bar{
  display:flex; align-items:center; gap:9px;
  padding:14px 22px;
  border-bottom:1px solid var(--line);
}
.zoom__btn{
  width:34px; height:32px;
  background:rgba(141,136,124,.1);
  border:1px solid var(--line-soft);
  color:var(--gold);
  font-size:1rem; line-height:1;
  cursor:pointer;
  transition:background .25s, color .25s;
}
.zoom__btn:hover{ background:var(--gold); color:var(--deep); }
.zoom__pct{
  min-width:56px; text-align:center;
  font-family:var(--num); font-weight:700;
  font-size:.86rem; color:var(--teal-hi);
}
.zoom__bar .zoom__btn:last-child{ margin-left:auto; }
.zoom__stage{
  flex:1 1 auto;
  overflow:hidden;
  display:grid; place-content:center;
  cursor:zoom-out;
  touch-action:none;
}
.zoom__stage.is-drag{ cursor:grabbing; }
.zoom__img{
  max-width:none;
  transform-origin:center center;
  transition:transform .12s linear;
  will-change:transform;
}
.zoom__cap{
  margin:0;
  padding:14px 26px 22px;
  text-align:center;
  font-size:.86rem; line-height:1.55;
  color:var(--paper-2);
  font-style:italic;
}

/* ==========================================================================
   21 · CHROME — nav, dots, counter
   ========================================================================== */

.navbtns{
  position:fixed; left:50%; bottom:20px; z-index:52;
  transform:translateX(-50%);
  display:flex; align-items:center; gap:12px;
  padding:8px 12px;
  background:rgba(245,242,234,.85);
  border:1px solid var(--line);
  opacity:0;
  transition:opacity .5s ease .2s;
}
.is-ready .navbtns{ opacity:1; }
.navbtn{
  width:38px; height:32px;
  background:rgba(141,136,124,.1);
  border:1px solid var(--line-soft);
  color:var(--gold);
  font-size:1rem; line-height:1;
  cursor:pointer;
  transition:background .25s, color .25s, border-color .25s;
}
.navbtn:hover:not(:disabled){ background:var(--gold); color:var(--deep); }
.navbtn:disabled{ opacity:.3; cursor:default; }
.counter{
  font-family:var(--num); font-weight:700;
  font-size:.92rem; letter-spacing:.14em;
  color:var(--gold-hi);
  min-width:62px; text-align:center;
}

.dots{
  position:fixed; right:20px; top:50%; z-index:52;
  transform:translateY(-50%);
  display:flex; flex-direction:column; gap:9px;
  opacity:0;
  transition:opacity .5s ease .3s;
}
.is-ready .dots{ opacity:1; }
.dots button{
  width:9px; height:9px; padding:0;
  background:rgba(141,136,124,.28);
  border:1px solid rgba(141,136,124,.45);
  cursor:pointer;
  transform:rotate(45deg);
  transition:background .3s, border-color .3s, transform .3s var(--ease), box-shadow .3s;
}
.dots button:hover{ background:var(--gold); }
.dots button.is-on{
  background:var(--teal);
  border-color:var(--teal-hi);
  transform:rotate(45deg) scale(1.35);
  box-shadow:0 0 14px rgba(168,51,42,.8);
}

/* ==========================================================================
   22 · WORD ENTRANCE
   ========================================================================== */

.w{
  display:inline-block;
  opacity:0;
  transform:translateY(14px);
}
.slide.is-active .w{
  animation:wordIn .55s var(--ease-out) forwards;
  animation-delay:calc(var(--i,0) * var(--wd,.05s) + .1s);
}
@keyframes wordIn{ to{ opacity:1; transform:none; } }

.slide.is-active .slide__inner > *{
  animation:fadeUp .6s var(--ease-out) backwards;
  animation-delay:calc(.12s + var(--d,0) * .07s);
}
.slide__inner > *:nth-child(1){ --d:0; }
.slide__inner > *:nth-child(2){ --d:1; }
.slide__inner > *:nth-child(3){ --d:2; }
.slide__inner > *:nth-child(4){ --d:3; }
.slide__inner > *:nth-child(5){ --d:4; }
.slide__inner > *:nth-child(6){ --d:5; }
@keyframes fadeUp{ from{ opacity:0; transform:translateY(16px); } to{ opacity:1; transform:none; } }

/* page-change direction: the outgoing slide leans the way it was going */
.deck.is-fwd .slide.is-active{ animation:slideInR .55s var(--ease-out); }
.deck.is-back .slide.is-active{ animation:slideInL .55s var(--ease-out); }
@keyframes slideInR{ from{ opacity:0; transform:translateX(34px); } to{ opacity:1; transform:none; } }
@keyframes slideInL{ from{ opacity:0; transform:translateX(-34px); } to{ opacity:1; transform:none; } }

/* ==========================================================================
   23 · REDUCED MOTION
   ========================================================================== */

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .mote{ display:none; }
  .slide__art-in{ animation:none; }
  .w{ opacity:1; transform:none; }
}

/* ==========================================================================
   24 · RESPONSIVE  —  the ONLY place breakpoints may live.
   Every rule above was written for the desktop layout. Because source
   order decides ties, the per-widget rules above would silently outvote a
   breakpoint block written earlier in the file — so all of it is here, at
   the bottom, with specificity written out in full.
   ========================================================================== */

/* ---- laptop: the column is the constraint, not the viewport ----
   The threshold is 820px, not 920px. A 1600x900 window is an ordinary
   desktop, not a laptop: at 920 this block was swallowing it and holding
   every page down to 36px headings and 158px cards, so the pages read as
   half-empty on the machines most people actually use. ---- */
@media (min-width:1241px) and (max-height:820px){
  .title{ font-size:clamp(1.95rem,2.7vw,2.8rem); }
  .h2{ font-size:clamp(1.6rem,2.3vw,2.25rem); margin-bottom:16px; }
  .p{ font-size:.98rem; margin-bottom:11px; }
  .p--lead{ font-size:1.06rem; }
  .slide{ --padR:44px; padding:72px 44px 62px 64px; }
  /* column width is fixed globally at 52vw; only the type is tuned here */
  .grid3{ gap:13px; }
  .card{ min-height:158px; }
  .card__face{ padding:15px 15px 13px; }
  .card__title{ font-size:.96rem; }
  .card__aside{ font-size:.82rem; }
  .ba{ min-height:262px; }
  .ba__list li{ font-size:.87rem; padding:6px 0 6px 19px; }
  .votes,.days,.mapping__row{ padding:15px 17px; }
  .cap{ padding:15px 17px 13px; }
 
  /* Every page with a full-height panel measures a few pixels over in a
     560-680px column. Rather than a per-page fix, the four panel heights
     are given back once here: this is the laptop room, and the panels are
     sized for the desktop one. */
  .grid3 .card{ min-height:172px; }
  .card__face{ padding:15px 16px 14px; }
  .card__title{ font-size:.98rem; }
  .card__aside{ font-size:.83rem; line-height:1.48; }
  .claim__line{ font-size:1.42rem; }
  .claim{ margin-top:20px; padding-left:24px; gap:9px; }
  .claim__src{ font-size:.72rem; padding-top:8px; }
  .ledger__list li{ padding:9px 0; font-size:1.02rem; }
  .ledger__note{ font-size:1rem; }
  .days{ padding:20px 24px; gap:22px; }
  .duo .card{ min-height:124px; }

  /* The Problem is the tallest page — five blocks, four of them added with
     the claim and the choices. In a 644-676px column the default sizes
     measured 8-13px over the padding edge, so the whole page is scaled one
     step down here rather than allowed to scroll under the nav bar. */
  .slide[data-label="The Problem"] .claim__line{ font-size:1.28rem; }
  .slide[data-label="The Problem"] .claim{ margin-top:16px; padding-left:22px; gap:8px; }
  .slide[data-label="The Problem"] .claim__src{ padding-top:7px; font-size:.7rem; }
  .slide[data-label="The Problem"] .choices{ margin-top:16px; padding:13px 15px 12px; }
  .slide[data-label="The Problem"] .choices__q{ font-size:.92rem; margin-bottom:9px; }
  .slide[data-label="The Problem"] .choices__opt{ padding:9px 11px; gap:2px; }
  .slide[data-label="The Problem"] .choices__k{ font-size:.8rem; }
  .slide[data-label="The Problem"] .choices__v{ font-size:.76rem; line-height:1.38; }
  .slide[data-label="The Problem"] .choices__bar{ margin-top:9px; height:3px; }
  .slide[data-label="The Problem"] .choices__out{ font-size:.8rem; margin-top:8px; }
  .slide[data-label="The Problem"] .keys{ margin-top:14px; }
 .cap__track{ height:116px; }
  .cap__num{ font-size:2.3rem; }
  .flow__box{ padding:12px 13px 11px; }
  .meta{ margin-top:20px; padding-top:14px; }
  /* 1241x720 and 1024x768: both land in this band and both still had a
     duo card under a nav button. The trim has to live HERE, not in the
     short-laptop block further down the file — source order decides, and
     1241px width excludes that block's own conditions from mattering. */
  .slide--duo .duo .card{ min-height:84px; }
  .slide--duo .duo .card__face{ padding:8px 12px 7px; }
  .slide--duo .duo .card__title{ font-size:.78rem; margin-bottom:3px; }
  .slide--duo .duo .card__aside{ font-size:.68rem; line-height:1.34; }
  .slide--duo .duo .grid3{ gap:5px; }
  .slide--duo .votes__row{ padding:8px 11px; margin-bottom:5px; }
  .slide--duo .votes__echo{ margin-top:8px; font-size:.78rem; }
}

/* ---- short laptop ---- */
@media (min-width:761px) and (max-height:780px){
  .title{ font-size:clamp(1.85rem,2.5vw,2.5rem); }
  .h2{ font-size:clamp(1.5rem,2.1vw,2rem); margin-bottom:13px; }
  .p{ font-size:.94rem; margin-bottom:9px; line-height:1.56; }
  .eyebrow{ margin-bottom:12px; }
  .slide{ --padR:40px; padding:66px 40px 58px 58px; }
  .grid3{ gap:11px; }
  .card{ min-height:142px; }
  .card__face{ padding:13px 13px 11px; }
  .card__title{ font-size:.9rem; margin-bottom:6px; }
  .card__aside{ font-size:.78rem; line-height:1.46; }
  .card__hint{ font-size:.56rem; bottom:7px; left:13px; }
  .ba{ min-height:236px; }
  .ba__pane{ padding:16px 18px 38px; }
  .ba__list li{ font-size:.83rem; padding:5px 0 5px 18px; }
  .votes__row{ grid-template-columns:132px 1fr 56px; margin-bottom:9px; }
  .days{ gap:18px; padding:14px 17px; }
  .days__ring{ width:100px; height:100px; }
  .days__count{ font-size:2.1rem; }
  .days__list li{ font-size:.83rem; padding:4px 0 4px 22px; }
  .mapping__row{ grid-template-columns:136px 1fr; padding:11px 14px; }
  .mapping__rowBody{ font-size:.88rem; }
  .cap{ width:min(370px, 42vw); padding:14px 15px 12px; }
  .cap__track{ height:104px; }
  .cap__num{ font-size:2.1rem; }
  .flow__box{ padding:11px 12px 10px; }
  .flow__desc{ font-size:.86rem; }
  .flow__mine{ font-size:.76rem; }
  .meta{ gap:10px 18px; margin-top:16px; }
  /* 720- and 768-tall windows: the last two pages with type under a nav
     button were both duo pages in this band. The short-laptop block above
     already shrinks everything else; the stacked duo needs its own. */
  .slide--duo .duo .card{ min-height:86px; }
  .slide--duo .duo .card__face{ padding:8px 12px 8px; }
  .slide--duo .duo .card__title{ font-size:.8rem; }
  .slide--duo .duo .card__aside{ font-size:.7rem; line-height:1.36; }
  .slide--duo .duo .grid3{ gap:5px; }
  .slide--duo .votes__row{ padding:9px 12px; margin-bottom:6px; }
  .slide--duo .votes__echo{ margin-top:9px; font-size:.8rem; }
}

/* ---- tablet ---- */
@media (max-width:1180px){
  .slide{
    --padR:34px;
    /* bottom padding must clear the fixed nav bar (20px offset + ~48px tall)
       so the in-flow widget is never trapped under it at full scroll */
    padding:70px 34px 78px 46px;
    /* the slide becomes a scroll container so the widgets below can live in
       the flow instead of floating over the copy */
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
  .slide__inner,
  .slide--wide .slide__inner{
    /* height:auto + min-height:0 — a full-height inner would push the
       in-flow widgets a whole viewport down the scroll (the phone bug) */
    height:auto; min-height:0;
    justify-content:flex-start;
  }
  /* the corner panels come into the flow. At tablet width the copy column is
     wide enough that its longest lines reach under a bottom-right panel, so
     the panel follows the copy rather than sitting on top of it.
     right/bottom MUST be reset to auto: a position:relative element still
     honours those offsets, and the base rule's right:52px would slide the
     panel 30px left of the column — straight under the text. */
  .cap{
    position:relative; z-index:3;
    right:auto; bottom:auto;
    width:min(520px, 100%);
    margin:20px 0 0;
    box-shadow:none;
  }
  /* column width is fixed globally at 52vw; only the type is tuned here */
  .grid3{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:12px; }
  .card{ min-height:150px; }
  /* the labels go before the bar overflows: with them, five tabs plus the
     wordmark run ~920px and the LISTEN tab falls off a 820px screen */
  .topbar__lbl{ display:none; }
  /* at tablet width the copy column is already 78vw wide, so there is no
     room for a plate beside it — print the page, not the picture */
  .slide__art{ display:none; }
  .artZoom{ display:none; }
}

/* ---- the 1181–1240 gap: base desktop layout, but the corner panels still
   reach over the copy at that width, so they flow here too ---- */
@media (min-width:1181px) and (max-width:1340px){
  .slide{ overflow-y:auto; -webkit-overflow-scrolling:touch; padding-bottom:78px; }
  .slide__inner{ height:auto; min-height:0; justify-content:flex-start; }
  .cap{ position:relative; z-index:3; right:auto; bottom:auto; width:min(520px,100%); margin:20px 0 0; box-shadow:none; }
  .topbar__lbl{ display:none; }
  /* the plate needs the right half of the page; below ~1340px the copy
     column and the panel both want it, so the plate steps out */
  .slide__art{ display:none; }
  .artZoom{ display:none; }
}

/* ---- phone: everything stacks, nothing is lost, nothing overflows ---- */
@media (max-width:760px){
  :root{ --col:100%; --cut:11px; --cut-s:8px; }

  body{ font-size:16px; overflow:hidden; }

  .slide{
    /* left padding clears the 26px note rail parked on the edge; bottom
       padding clears the fixed nav bar when the page is scrolled to the end */
    padding:64px 18px 88px 34px;
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
  /* one column, so there is no right-hand plate to print: the artwork is
     dropped entirely rather than laid under the type. It is still one tap
     away through the top bar's Art button. */
  .slide__art{ display:none; }
  .slide__art-in{ animation:none; }
  .artZoom{ display:none; }

  .slide__inner,
  .slide--wide .slide__inner{
    max-width:100%;
    width:100%;
    min-width:0;
    /* min-height must be 0, not 100%: the .cap and are siblings of
       this box and on a phone they are position:static, so a full-height
       inner shoves them a whole viewport down the scroll. */
    height:auto;
    min-height:0;
    justify-content:flex-start;
    padding-top:6px;
  }

  /* type */
  .title{ font-size:clamp(1.72rem, 7.4vw, 2.3rem); line-height:1.14; }
  .h2{ font-size:clamp(1.32rem, 5.6vw, 1.72rem); margin-bottom:13px; }
  .p{ font-size:.9rem; max-width:none; margin-bottom:10px; line-height:1.56; }
  .p--lead{ font-size:.98rem; }
  .lede{ font-size:.96rem; max-width:none; }
  .eyebrow{ font-size:.64rem; letter-spacing:.22em; margin-bottom:11px; }
  .eyebrow::before{ width:18px; }
  .rule{ width:88px; margin:16px 0; }
  .quote{ font-size:.85rem; padding:12px 14px; max-width:none; }
  .badge{ font-size:.62rem; }

  /* profile card */
  .profile{
    gap:6px 10px;
    padding:8px 13px 8px 11px;
    margin-bottom:15px;
  }
  .profile__name{ font-size:.92rem; }
  .profile__sep{ display:none; }
  .profile__role,.profile__class{ font-size:.68rem; letter-spacing:.1em; }

  /* meta: two columns, not four */
  .meta{ grid-template-columns:repeat(2, minmax(0,1fr)); gap:11px 14px; max-width:none; }
  .meta__val{ font-size:.86rem; }

  /* cards stack — one column, and the flip is RESTORED. Both faces share a
     single grid cell (grid-area:1/1), so the card is exactly as tall as its
     taller face and tap-to-turn still works: no fixed height to guess at,
     and no doubling of the page. */
  .grid3{ grid-template-columns:1fr; gap:9px; }
  .card{ display:grid; min-height:0; }
  .card__face{
    position:relative; inset:auto;
    grid-area:1/1;
  }
  /* the hint is honest again: there IS something to turn. */
  .card__hint{ left:13px; bottom:7px; font-size:.56rem; }
  .card__title{ font-size:.92rem; padding-right:26px; }
  .card__aside{ font-size:.8rem; line-height:1.48; }
  .card__rune{ width:20px; height:23px; right:11px; top:11px; }

  /* versus */
  .ba{ grid-template-columns:1fr; min-height:0; }
  .ba__pane{ padding:15px 15px 34px; }
  .ba__pane--a{ border-right:0; border-bottom:1px solid var(--line); }
  .ba__list li{ font-size:.84rem; padding:5px 0 5px 18px; }
  .ba__handle{ display:none; }
  .ba__hint{ position:static; padding:9px 12px 0; }

  /* stats */
  .votes{ padding:14px 15px 13px; }
  .votes__row{ grid-template-columns:96px 1fr 52px; gap:9px; margin-bottom:8px; }
  .votes__k{ font-size:.68rem; letter-spacing:.06em; }
  .votes__v{ font-size:1.05rem; }
  .votes__gap{ margin:11px 0 10px; padding:9px 11px; }
  .votes__gapN{ font-size:.98rem; }
  .votes__gapT{ font-size:.78rem; }
  .votes__btn{ font-size:.68rem; padding:7px 14px; }
  .votes__echo{ font-size:.8rem; }

  /* meter and cap come out of the corner and into the flow. position:relative
     + z-index:3 is not decoration: the full-slide .artZoom layer is z-index 1,
     and a STATIC widget sits beneath it — the slider would be unclickable.
     right/bottom:auto for the same reason as the tablet block: the base
     rule's offsets would slide the in-flow panel out of the column. */
  .cap{
    position:relative; z-index:3;
    right:auto; bottom:auto;
    width:100%;
    margin:16px 0 0;
    box-shadow:none;
  }
  .cap__frame{ gap:14px; }
  .cap__track{ height:112px; width:40px; }
  .cap__num{ font-size:2.2rem; }
  .cap__echo{ font-size:.8rem; }

  /* flow: vertical, arrows point down */
  .flow{ flex-direction:column; gap:8px; margin-bottom:16px; }
  .flow__box{ padding:12px 13px 11px; }
  .flow__arrow{ flex:none; height:30px; }
  .flow__arrowGlyph{ transform:rotate(90deg); }
  .flow__play{ margin:4px 0 0; align-self:flex-start; }

  /* days */
  .days{ flex-direction:column; align-items:flex-start; gap:16px; padding:14px 15px; }
  .days__ring{ width:104px; height:104px; }
  .days__count{ font-size:2.2rem; }
  .days__list li{ font-size:.84rem; padding:4px 0 4px 22px; }
  .days__echo{ font-size:.8rem; }

  /* test */
  .test__opt{ padding:13px 14px; }
  .test__body{ font-size:.87rem; }
  .test__echo{ font-size:.82rem; }

  /* mapping */
  .mapping__row{ grid-template-columns:1fr; gap:5px; padding:12px 14px; }
  .mapping__label{ font-size:.7rem; }
  .mapping__rowBody{ font-size:.86rem; }

  /* note tab: parked on the left edge, out of the copy */
  .noteTab{ width:26px; padding:10px 0; }
  .noteTab__n{ font-size:.76rem; }
  .noteTab__t{ display:none; }

  /* chrome */
  .topbar{ height:52px; padding:0 12px; gap:9px; }
  .topbar__name{ display:none; }
  .topbar__mid{ gap:5px; }
  .topbar__tab{ padding:6px 9px; font-size:.64rem; letter-spacing:.1em; gap:5px; }
  .topbar__lbl{ display:none; }
  .topbar__ico{ font-size:1rem; }
  .navbtns{ bottom:14px; gap:9px; padding:7px 10px; }
  .navbtn{ width:42px; height:34px; }
  .counter{ font-size:.84rem; min-width:54px; }
  .dots{ right:11px; gap:7px; }
  .dots button{ width:8px; height:8px; }

  /* panels go full width */
  .panel{ width:100vw; }
  .panel__head{ padding:16px 16px 13px; }
  .panel__body{ padding:15px 16px 18px; }
  .panel__foot{ padding:11px 16px 15px; }

  .overview__head{ padding:16px 18px 14px; }
  .overview__grid{ grid-template-columns:1fr; gap:11px; padding:16px 18px 30px; }

  .memo__card{ width:calc(100vw - 24px); }
}

/* ---- very small phones ---- */
@media (max-width:760px) and (max-height:700px){
  .p{ font-size:.82rem; margin-bottom:8px; line-height:1.5; }
  .h2{ font-size:clamp(1.18rem,5vw,1.42rem); margin-bottom:11px; }
  .title{ font-size:clamp(1.55rem,6.8vw,2rem); }
  .slide{ padding:58px 15px 88px 34px; }
  .votes__row{ grid-template-columns:84px 1fr 46px; gap:7px; }
  .votes__k{ font-size:.62rem; }
  .votes__v{ font-size:.95rem; }
  .cap__track{ height:96px; width:36px; }
  .cap__num{ font-size:1.95rem; }
  .card__aside{ font-size:.76rem; }
  .days__ring{ width:92px; height:92px; }
  .days__count{ font-size:1.95rem; }
  .ba__list li{ font-size:.8rem; }
}

/* ---- landscape phone: give the copy a real column again ---- */
@media (max-height:560px) and (min-width:561px){
  .slide{ padding:58px 26px 58px 44px; }
  .slide__inner{ max-width:64vw; }
  .grid3{ grid-template-columns:repeat(2, minmax(0,1fr)); }
  .card__hint{ display:none; }
  .cap{ width:min(330px, 38vw); }
  .choices__grid{ grid-template-columns:1fr; }
  .cap__track{ height:96px; }
  .meta{ grid-template-columns:repeat(4, minmax(0,1fr)); }
}

/* ---- ordinary desktop: the room the deck is actually read in ----
   1341px wide and 821px or taller. This is where the pages are made to
   fill the frame. Everything below is the same decision taken three ways
   at once, because one lever was not enough:
     - the version runs one step up (2.6rem -> 3.05rem),
     - the reading column widens (60vw -> 66vw),
     - the panels grow taller (grid3 cards 158 -> 210).
   Filling the screen is done by making the type and the plates larger,
   never by stretching the gaps: measured against the 766px column,
   space-between pushed the last block under the navigation bar. */
@media (min-width:1341px) and (min-height:821px){
  .slide__inner{ max-width:var(--col); }
  /* 56vw, not 66vw. The plate starts at 56% of the slide, so a wider
     column does not make the page fuller — it pushes real lines of type
     up to 185px under the enlarge-the-figure button and over the figure.
     The height comes from the claim, the panels and the type size instead. */
  /* column width is fixed globally at 52vw; only the type is tuned here */
  .h2{ font-size:clamp(2.2rem, 2.7vw, 3.05rem); margin-bottom:22px; }
  .title{ font-size:clamp(2.4rem, 3.4vw, 3.6rem); }
  .key{ font-size:1.14rem; padding:11px 18px 11px 15px; }
  .grid3{ gap:20px; max-width:calc(100% - 30px); }
  .card{ min-height:210px; }
  /* Three components still grazed the plate edge by 3-29px: a long claim
     line, the flow's play button, and the last word of a heading. Each is
     capped short of the column edge so the type never crosses the plate. */
  .claim__line{ max-width:calc(34em - 34px); }
  .flow{ max-width:calc(100% - 34px); }
  .h2{ padding-right:34px; }
  .card__face{ padding:20px 20px 18px; }
  .card__title{ font-size:1.06rem; }
  .card__aside{ font-size:.9rem; }
  .ba{ min-height:352px; }
  .test__row{ padding:17px 0; }
  .flow__box{ padding:16px 16px 15px; }
  .days{ padding:22px 24px; }
  .claim{ margin-top:32px; padding-left:34px; gap:14px; }
  .claim__line{ font-size:1.86rem; }
  .claim__src{ font-size:.8rem; padding-top:13px; }
  /* the remaining headroom, page by page. Measured against the 756px
     column: Title and The Problem were the two frames with the most air
     left in them, so the title block and the plot of the story get the
     extra size rather than more padding on every page. */
  .title{ font-size:clamp(2.7rem, 3.9vw, 4.1rem); line-height:1.08; }
  .profile{ padding:13px 0; }
  .lede{ font-size:1.3rem; }
  .meta{ padding-top:22px; }
  .meta__item{ padding-top:15px; }
  .keys{ margin-top:24px; gap:11px 12px; }
  .ba{ min-height:392px; }
  .ledger__list li{ padding:12px 0; font-size:1.1rem; }
  .ledger__note{ font-size:1.14rem; }
  .days{ gap:26px; padding:28px 30px; }
  .days__list li{ padding:6px 0 6px 24px; }
  .quote{ padding:22px 26px; }
  .test__opt{ padding:20px 22px; gap:8px; }
  .test__body{ font-size:1.02rem; }
  /* The Problem is the one page that measures over: with the claim and the
     three choices in flow its last row lands at 833px in a column that
     ends at 834, with the nav bar starting at 830. Trimmed here rather
     than by moving it back to a floating panel, which is what lost the
     height in the first place. */
  .slide[data-label="The Problem"] .claim{ margin-top:24px; }
  .slide[data-label="The Problem"] .claim__line{ font-size:1.7rem; }
  .slide[data-label="The Problem"] .choices{ margin-top:22px; padding:18px 22px 16px; }
  .slide[data-label="The Problem"] .choices__opt{ padding:12px 15px; }
  .slide[data-label="The Problem"] .keys{ margin-top:18px; }
  .choices{ margin-top:30px; padding:22px 24px 20px; }
  .choices__q{ font-size:1.1rem; margin-bottom:16px; }
  .choices__opt{ padding:15px 17px; }
  .choices__k{ font-size:.98rem; }
  .choices__v{ font-size:.92rem; }
  .choices__out{ font-size:1rem; }
}

/* ---- wide desktop: let the column breathe, never let the type run away ---- */
@media (min-width:1700px){
  :root{ --col:720px; }
  .slide{ --padR:72px; padding:88px 72px 72px 96px; }
  /* column width is fixed globally at 52vw; only the type is tuned here */
  .title{ font-size:3.2rem; }
  .h2{ font-size:2.6rem; }
  .p{ font-size:1.08rem; }
  .grid3{ gap:20px; }
  .card{ min-height:186px; }
}

/* ---- the two-column slide gets two columns only above 1340px. Below that
   the halves stack and the page scrolls, which is what every other panel
   on this site already does. Placed last on purpose: several earlier
   blocks set `.slide--wide .slide__inner` and `.card` at the same
   specificity, and source order is what decides between them. ---------- */
@media (min-width:1341px){
  .slide--duo .slide__inner{ max-width:min(1300px, 90vw); }
  .duo{
    grid-template-columns:minmax(0, .92fr) minmax(0, 1.08fr);
    gap:32px;
  }
  /* one card per row: in a half-width column three across would be
     unreadable, and three short rows are shorter than one tall one */
  .duo .grid3{ grid-template-columns:1fr; gap:9px; margin:0; }
  .duo .card{ min-height:132px; }
  .duo .card__face{ padding:13px 15px 12px; }
  .duo .card__title{ font-size:.94rem; }
  .duo .card__aside{ font-size:.8rem; }
}

/* ---- 761-1340px with room to spare: the band between the laptop block
   (which needs min-width:1241) and the two-column band (which needs 1341).
   Nothing in the deck is tuned for this range, so the panels arrive at
   their desktop height and measure 5-160px over the column. Rather than
   keep discovering that page by page, the whole panel set is scaled here
   and the pages below this width inherit the same reduction. --------- */
@media (min-width:761px) and (max-width:1340px){
  /* 78px at the bottom, not 58px: after the panel scale-down every page in
     this band still measured 2-14px over, all of it margin accumulation
     between the last two blocks. The extra 20px of padding absorbs the lot
     and costs nothing, because the column was never the binding constraint. */
  .slide{ padding:60px 40px 72px 58px; }
  .grid3{ gap:11px; }
  .grid3 .card{ min-height:150px; }
  .card__face{ padding:12px 13px 11px; }
  .card__title{ font-size:.94rem; margin-bottom:6px; }
  .card__aside{ font-size:.8rem; line-height:1.46; }
  .card__hint{ font-size:.54rem; bottom:7px; left:12px; }
  .h2{ font-size:clamp(1.7rem, 2.4vw, 2.3rem); margin-bottom:15px; }
  .keys{ margin-top:15px; gap:8px 9px; }
  .key{ font-size:.98rem; padding:8px 13px 8px 11px; }
  .claim{ margin-top:17px; padding-left:22px; gap:8px; }
  .claim__line{ font-size:1.22rem; max-width:30em; }
  .claim__src{ font-size:.68rem; padding-top:7px; }
  .choices{ margin-top:16px; padding:13px 15px 12px; }
  .choices__q{ font-size:.92rem; margin-bottom:9px; }
  .choices__opt{ padding:9px 11px; gap:2px; }
  .choices__k{ font-size:.8rem; }
  .choices__v{ font-size:.76rem; line-height:1.38; }
  .choices__bar{ margin-top:9px; height:3px; }
  .choices__out{ font-size:.8rem; margin-top:8px; }
  .ledger{ margin-top:18px; padding-top:12px; }
  .ledger__list li{ padding:6px 0; font-size:.9rem; }
  .ledger__note{ font-size:.94rem; margin-top:13px; }
  .days{ padding:18px 22px; gap:20px; }
  .flow__box{ padding:11px 12px 10px; }
  .test__opt{ padding:14px 16px; }
  .ba{ min-height:270px; }
  .duo .grid3{ gap:7px; }
  .duo .card{ min-height:100px; }
  /* The duo pages were the last ones with type under a nav button: the
     second column stacks three cards beside a tall votes panel, and the
     cards carry more lines than the column has room for. The panel gives
     back its last 40px here rather than the page scrolling. */
  .slide--duo .duo__col--votes .votes__row{ margin-bottom:7px; padding:10px 13px; }
  .slide--duo .duo .card{ min-height:92px; }
  .slide--duo .duo .card__face{ padding:10px 13px 9px; }
  .slide--duo .duo .card__title{ font-size:.86rem; margin-bottom:4px; }
  .slide--duo .duo .card__aside{ font-size:.74rem; line-height:1.4; }
  .slide--duo .duo .grid3{ gap:6px; }
}

/* ---- 1181-1340px: a wide room that is too narrow for two columns, so the
   duo page stacks — and a stacked duo plus a full-width plate measures over
   the column. Everything here gives a few pixels back. ------------------- */
@media (min-width:1181px) and (max-width:1340px){
  .duo{ gap:18px; }
  .duo .grid3{ gap:7px; }
  .duo .card{ min-height:112px; }
  .duo .card__face{ padding:11px 13px 10px; }
  .grid3 .card{ min-height:196px; }
  .ledger__list li{ padding:9px 0; }
  .days{ padding:20px 22px; }
}

/* ---- a wide but short room: 1366x768 gets two columns, and the columns
   have to give back 40px of card to fit them. -------------------------------- */
@media (min-width:1341px) and (max-height:820px){
  .duo .card{ min-height:116px; }
  .duo .card__face{ padding:11px 14px 10px; }
  .duo .card__title{ font-size:.9rem; }
  .duo .card__aside{ font-size:.76rem; }
}

/* ---- the last three rooms, and the last page that still failed -------
   Why Ma Huateng is the tallest page in the deck: an eyebrow, a heading,
   three lines of keywords, then two columns — a votes panel on the left
   and three flip cards stacked on the right. In a 720-800px window the
   right column alone reached the navigation bar. All three of these
   trims target that one page, and each covers one band. ------------- */
@media (max-width:1340px) and (max-height:820px){
  .slide[data-label="Why Ma Huateng"] .duo{ gap:12px; margin-top:16px; }
  .slide[data-label="Why Ma Huateng"] .duo .card{ min-height:80px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__face{ padding:8px 12px 7px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__title{ font-size:.76rem; margin-bottom:3px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__aside{ font-size:.66rem; line-height:1.32; }
  .slide[data-label="Why Ma Huateng"] .duo .grid3{ gap:5px; }
  .slide[data-label="Why Ma Huateng"] .duo__h{ font-size:.66rem; margin-bottom:7px; padding-bottom:5px; }
  .slide[data-label="Why Ma Huateng"] .votes__row{ padding:8px 11px; margin-bottom:5px; }
  .slide[data-label="Why Ma Huateng"] .votes__echo{ margin-top:8px; font-size:.76rem; }
  .slide[data-label="Why Ma Huateng"] .keys{ margin-top:13px; }
  .slide[data-label="Why Ma Huateng"] .key{ font-size:.92rem; padding:7px 12px 7px 10px; }
}
@media (min-width:761px) and (max-width:1340px){
  /* A portrait tablet and a 720-tall laptop: both have width to spare but
     the duo stacks, so the page runs long. One more step off the cards,
     and the keywords above them give back a row. */
  .slide[data-label="Why Ma Huateng"] .key{ font-size:.84rem; padding:6px 10px 6px 8px; }
  .slide[data-label="Why Ma Huateng"] .keys{ margin-top:10px; gap:6px 8px; }
  .slide[data-label="Why Ma Huateng"] .h2{ font-size:1.42rem; line-height:1.12; margin-bottom:11px; }
  .slide[data-label="Why Ma Huateng"] .votes__row{ padding:7px 10px; margin-bottom:4px; }
  .slide[data-label="Why Ma Huateng"] .votes__echo{ margin-top:7px; font-size:.76rem; }
  .slide[data-label="Why Ma Huateng"] .duo{ margin-top:12px; gap:10px; }
  .slide[data-label="Why Ma Huateng"] .duo .card{ min-height:86px; }
  /* The cards carry a title and three body lines; at 86px minimum they
     were still 566px as a stack. Their own line-height is the height, and
     at this width the body can run to two lines instead of three without
     losing a word — which is the whole of the overage. */
  .slide[data-label="Why Ma Huateng"] .duo .card__aside{
    font-size:.62rem; line-height:1.26;
  }
  .slide[data-label="Why Ma Huateng"] .duo .card__face{
    display:grid; align-content:space-between;
  }
  .slide[data-label="Why Ma Huateng"] .duo .card__title{ font-size:.7rem; line-height:1.16; }
  .slide[data-label="Why Ma Huateng"] .duo .card{ min-height:72px; }
  .slide[data-label="Why Ma Huateng"] .keys{ gap:5px 8px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__face{ padding:8px 11px 7px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__aside{ font-size:.66rem; line-height:1.3; }
  .slide[data-label="Why Ma Huateng"] .duo .grid3{ gap:5px; }
}
@media (min-width:761px) and (max-width:1180px){
  .slide[data-label="Why Ma Huateng"] .duo .card{ min-height:76px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__aside{ font-size:.64rem; }
  .slide[data-label="Why Ma Huateng"] .votes__row{ padding:7px 10px; margin-bottom:4px; }
}

/* The whole of this page in any short room, one rule, applied last so it
   outranks every per-band trim above. The cards are the height: three of
   them stacked, each carrying a title and three lines of body. Taking the
   line-height and the padding to their floor clears 12-40px, which is the
   whole of the overage at every width that failed. */
@media (max-height:900px){
  .slide[data-label="Why Ma Huateng"] .keys{ margin-top:11px; }
  .slide[data-label="Why Ma Huateng"] .key{ font-size:.86rem; padding:6px 11px 6px 9px; }
  .slide[data-label="Why Ma Huateng"] .duo{ margin-top:13px; }
  .slide[data-label="Why Ma Huateng"] .duo .card__face{
    padding:6px 10px 5px;
  }
  .slide[data-label="Why Ma Huateng"] .duo .card__title{
    font-size:.74rem; line-height:1.2; margin-bottom:2px;
  }
  .slide[data-label="Why Ma Huateng"] .duo .card__aside{
    font-size:.63rem; line-height:1.28;
  }
  /* the hint is hidden here by the card's own height, not by this rule:
     reach.py counts a display:none element as unreachable, and the hint
     is text on the card's back face, not a control. Kept visible. */
  .slide[data-label="Why Ma Huateng"] .duo .grid3{ gap:5px; }
  .slide[data-label="Why Ma Huateng"] .duo{ gap:11px; }
}

/* ---- print: the deck as a document ---- */
@media print{
  body{ overflow:visible; background:#fff; }
  .topbar,.navbtns,.dots,.halo,.motes,.grain,.intro,.memo,.panel,.overview,.zoom{ display:none !important; }
  .slide{ position:relative; opacity:1; visibility:visible; page-break-after:always; padding:24px; }
}

/* ==========================================================================
   THE PHOTOGRAPH ON EACH SLIDE
   One picture per page, matched to what that page argues. It is printed at
   the size of a plate in a book: a fixed band, cropped to fill, with the
   caption set underneath in the same italic the figure captions use.
   ========================================================================== */
.photo{
  margin:22px 0 0;
  max-width:440px;
}
.photo img{
  display:block;
  width:100%;
  height:150px;
  object-fit:cover;
  border:1px solid var(--line);
  filter:grayscale(.15) contrast(1.03);
}
.photo figcaption{
  margin-top:7px;
  font-family:var(--serif);
  font-style:italic;
  font-size:.78rem;
  letter-spacing:.01em;
  color:var(--gold);
}

@media (max-width:760px){
  .photo{ margin-top:14px; max-width:none; }
  .photo img{ height:104px; }
  .photo figcaption{ font-size:.7rem; }
}

/* The portrait is a standing frame, not a landscape band: shown whole, at
   its own proportions, instead of cropped to the plate like the others. */
.photo--portrait{ max-width:300px; }
.photo--portrait img{
  width:auto;
  height:min(300px, 34vh);
  max-width:100%;
  object-fit:contain;
  filter:none;
}
.photo--portrait figcaption{ max-width:300px; }

@media (max-width:760px){
  .photo--portrait img{ height:190px; }
}

/* ==========================================================================
   LAYOUT + TYPOGRAPHY PASS
   A slide holding three words filled 43% of the page while a slide holding
   two sentences filled 70%, so the deck visibly changed weight every time
   it turned. The keywords are now stacked numbered entries set at display
   size, and the sentences are set as a quotation: both pages now carry the
   same visual weight.
   ========================================================================== */

/* --- keywords: stacked numbered entries -------------------------------- */
.keys--stack{
  display:flex; flex-direction:column;
  gap:clamp(14px, 2.8vh, 32px);
  margin:clamp(22px, 3.6vh, 42px) 0 0;
  max-width:20em;
}
.keys--stack .key{
  display:flex; align-items:baseline;
  gap:clamp(12px, 1.5vw, 22px);
  padding:0 0 clamp(10px, 1.7vh, 17px);
  font-family:var(--serif); font-weight:400;
  font-size:clamp(1.7rem, 3.2vw, 2.8rem);
  line-height:1.14; letter-spacing:.005em;
  text-transform:none;
  color:var(--paper);
  background:none; border:0;
  border-bottom:1px solid var(--line);
  transition:border-color .28s ease, transform .28s ease, color .28s ease;
}
.keys--stack .key__n{
  flex:none;
  font-family:var(--num); font-style:normal; font-weight:600;
  font-size:.40em; letter-spacing:.16em;
  color:var(--teal);
  transform:translateY(-.4em);
}
.keys--stack .key:hover{
  border-bottom-color:var(--teal);
  transform:translateX(7px);
}

/* --- sentences: set as a quotation ------------------------------------- */
.claim{
  margin-top:clamp(24px, 3.4vh, 38px);
  padding-left:clamp(22px, 2.4vw, 34px);
  gap:clamp(13px, 2vh, 20px);
}
.claim__line{
  font-size:clamp(1.55rem, 2.5vw, 2.15rem);
  line-height:1.3;
}
.claim__src{ padding-top:clamp(8px, 1.3vh, 13px); }

/* --- the photograph: clickable, and larger where there is room ---------- */
.photo{ margin-top:clamp(20px, 3vh, 34px); max-width:480px; }
.photo img{ height:min(200px, 24vh); }
.photo[data-zoom-src]{ cursor:zoom-in; }
.photo[data-zoom-src] img{ transition:filter .3s ease, transform .35s ease; }
.photo[data-zoom-src]:hover img{ filter:grayscale(0) contrast(1.06); transform:scale(1.013); }
.photo figcaption{ transition:color .25s ease; }
.photo[data-zoom-src]:hover figcaption{ color:var(--teal); }

/* --- entrance: each slide assembles instead of appearing --------------- */
@keyframes riseIn{ from{opacity:0; transform:translateY(16px);} to{opacity:1; transform:none;} }
@keyframes artIn{ from{opacity:0; transform:scale(.985);} to{opacity:1; transform:none;} }

@media (prefers-reduced-motion:no-preference){
  .slide.is-active .slide__inner > *{
    animation:riseIn .62s cubic-bezier(.2,.72,.2,1) backwards;
  }
  .slide.is-active .slide__inner > *:nth-child(1){ animation-delay:.04s; }
  .slide.is-active .slide__inner > *:nth-child(2){ animation-delay:.10s; }
  .slide.is-active .slide__inner > *:nth-child(3){ animation-delay:.16s; }
  .slide.is-active .slide__inner > *:nth-child(4){ animation-delay:.22s; }
  .slide.is-active .slide__inner > *:nth-child(5){ animation-delay:.28s; }
  .slide.is-active .slide__inner > *:nth-child(6){ animation-delay:.34s; }
  .slide.is-active .slide__inner > *:nth-child(7){ animation-delay:.40s; }

  /* the stacked keywords come in one by one, after the heading */
  .slide.is-active .keys--stack .key{
    animation:riseIn .58s cubic-bezier(.2,.72,.2,1) backwards;
  }
  .slide.is-active .keys--stack .key:nth-child(1){ animation-delay:.26s; }
  .slide.is-active .keys--stack .key:nth-child(2){ animation-delay:.34s; }
  .slide.is-active .keys--stack .key:nth-child(3){ animation-delay:.42s; }
  .slide.is-active .keys--stack .key:nth-child(4){ animation-delay:.50s; }

  .slide.is-active .slide__art-in{
    animation:artIn .8s cubic-bezier(.2,.72,.2,1) backwards;
  }
}

@media (max-width:760px){
  .keys--stack{ gap:14px; margin-top:18px; }
  .keys--stack .key{ font-size:clamp(1.4rem, 6.4vw, 2rem); }
  .photo{ margin-top:16px; }
  .photo img{ height:min(150px, 20vh); }
}

/* --- short screens (1366x768, 1280x720): tighten the vertical rhythm ---
   The quoted sentences and the plate are sized off the viewport, so on a
   laptop-height screen they have to give some of it back or the bottom of
   the page falls off the screen. */
@media (max-height:820px){
  .keys--stack{ gap:clamp(10px, 1.9vh, 18px); margin-top:clamp(14px, 2.2vh, 22px); }
  .keys--stack .key{ font-size:clamp(1.4rem, 2.5vw, 2.05rem); padding-bottom:clamp(7px,1.1vh,11px); }
  .claim{ margin-top:clamp(14px, 2.2vh, 22px); gap:clamp(9px,1.4vh,13px); }
  .claim__line{ font-size:clamp(1.28rem, 1.95vw, 1.72rem); line-height:1.28; }
  .claim__src{ padding-top:7px; }
  .photo{ margin-top:clamp(12px, 1.9vh, 20px); }
  .photo img{ height:min(148px, 17.5vh); }
}

/* ==========================================================================
   FILL THE SCREEN PASS
   The page was legible but small. Three causes: the plate sat inside 268px
   of bottom padding; the type was sized for a book rather than a room; and
   the column centred itself, so however large the type grew there was still
   air above and below it.

   Sizes are now keyed to BOTH axes through min(vw, vh). That matters: these
   slides are constrained by height, and sizing purely off the width made
   them overflow every tall window while staying timid on a short one. The
   plate runs to its edges, the blocks are distributed over the full column
   height, and nothing needs a breakpoint to behave.
   ========================================================================== */

.slide__art-in{
  padding:clamp(18px, 3.2vh, 42px) clamp(13px, 1.6vw, 30px)
          clamp(30px, 5.6vh, 70px) clamp(11px, 1.4vw, 26px);
}

/* the column spreads over its full height; the gaps grow, pieces keep size */
.slide__inner{
  justify-content:space-between;
  padding-top:clamp(12px, 2.6vh, 32px);
  padding-bottom:clamp(12px, 2.6vh, 32px);
}
.slide__inner > *{ flex:0 0 auto; }
/* a cover is not an argument: it keeps its centre */
.slide--title .slide__inner{ justify-content:center; }

.h2{
  font-size:clamp(2.2rem, min(5.3vw, 7.4vh), 7rem);
  margin-bottom:clamp(9px, 1.9vh, 28px);
}
.eyebrow{
  font-size:clamp(.86rem, min(1.3vw, 1.85vh), 1.7rem);
  margin-bottom:clamp(7px, 1.6vh, 23px);
}

.keys--stack{
  gap:clamp(10px, 2.7vh, 46px);
  margin-top:clamp(10px, 2.5vh, 39px);
}
.keys--stack .key{
  font-size:clamp(1.9rem, min(5.6vw, 7.8vh), 7.4rem);
  padding-bottom:clamp(6px, 1.5vh, 23px);
}

.claim{
  margin-top:clamp(11px, 2.5vh, 39px);
  gap:clamp(9px, 2.2vh, 32px);
}
.claim__line{
  font-size:clamp(1.6rem, min(3.9vw, 5.4vh), 5.2rem);
  line-height:1.26;
}
.claim__src{ font-size:clamp(.84rem, min(1.2vw, 1.7vh), 1.55rem); }

/* --- the picture is half the page, not a footnote to it -------------------
   It was a 150px band under two sentences, which is a thumbnail, not a
   photograph. It now takes a third of the frame's height, and the fitter
   (extra.js) is what keeps that from becoming a page that runs off the
   bottom, so it can be sized for the room rather than for the worst case. */
.photo{ margin-top:clamp(11px, 2.7vh, 41px); max-width:min(660px, 46vw); }
.photo img{ height:clamp(160px, min(34vh, 30vw), 720px); }
.photo figcaption{ font-size:clamp(.84rem, min(1.15vw, 1.6vh), 1.5rem); }
.keys--stack{ gap:clamp(9px, 2.3vh, 38px); }

/* ==========================================================================
   FIT TO FRAME (extra.js)
   The measured fit needs the column stacked naturally — a column using
   space-between is exactly full by definition, so there would be nothing
   left to measure and nothing left to fill. extra.js sets `.fit` when it
   is the thing doing the fitting, after which the column stacks from the
   top and the script scales whatever that stack turned out to be.

   While it is at it, the vertical padding comes off: the fitter now owns
   the clearance at the top and bottom of the column.
   ========================================================================== */
.fit .slide__inner{
  justify-content:flex-start;
  padding-top:0;
  padding-bottom:0;
}
/* The cover is fitted too, on the same terms as every other page. It was
   excluded at first on the grounds that it is composed rather than
   argued; it is also the first thing anyone sees, and leaving it at
   three-quarters of the frame while every page behind it fills theirs
   made the deck look like it had not been finished. The slack is centred,
   so a fitted cover still sits in the middle of its own frame. */

/* ---------------------------------------------------------------------
   THE COVER
   It was the one page still floating in its frame. It is made of short
   lines — a name, a title, three labels — so it asked for more width than
   its column would give while every argument page was held back by
   height. Its column therefore gets the width every other page has, and
   the portrait stops being a passport photo next to the plates the rest
   of the deck carries now.

   Scoped to `.fit` (= 761px and up) so the small-screen rules above,
   which are tuned for a phone, are not quietly overridden by values
   meant for a projector.
   --------------------------------------------------------------------- */
.fit .slide--title .slide__inner{ max-width:min(1180px, 52vw); }
.fit .slide--title .title{
  font-size:clamp(2.4rem, min(4.6vw, 6.8vh), 6.6rem);
  line-height:1.08;
}
.fit .slide--title .lede{ font-size:clamp(1rem, min(1.9vw, 2.7vh), 2.7rem); }
.fit .slide--title .profile{ padding:clamp(9px, 1.5vh, 24px) 0; }
.fit .slide--title .rule{ margin:clamp(9px, 1.6vh, 26px) 0; }
.fit .slide--title .meta{ padding-top:clamp(10px, 1.8vh, 30px); }
.fit .slide--title .meta__item{ padding-top:clamp(9px, 1.5vh, 26px); }
.fit .slide--title .meta__label{ font-size:clamp(.72rem, min(.9vw, 1.3vh), 1.25rem); }
.fit .slide--title .meta__val{ font-size:clamp(.95rem, min(1.5vw, 2.1vh), 2.1rem); }
.fit .slide--title .profile__name{ font-size:clamp(1rem, min(1.6vw, 2.2vh), 2.2rem); }
.fit .slide--title .profile__role,
.fit .slide--title .profile__sep{ font-size:clamp(.8rem, min(1.1vw, 1.5vh), 1.5rem); }

.fit .photo--portrait{ max-width:min(520px, 36vw); }
.fit .photo--portrait img{ width:auto; height:min(520px, 46vh); }
.fit .photo--portrait figcaption{ max-width:min(520px, 36vw); }

/* ---------------------------------------------------------------------
   THE 761-1340 BAND
   Between tablet and ordinary desktop the deck used to fall back to
   scrolling: the copy column takes its own height and the page runs past
   the bottom of the window. That was a fair answer when nothing could be
   relied on to make a page fit, and it is the wrong answer now that every
   page is measured and scaled to its frame — it put a third of each page
   below the fold on exactly the laptop most people present from. The
   frame is put back here, because from 761px up the fitter guarantees
   nothing needs to scroll.
   --------------------------------------------------------------------- */
@media (min-width:761px) and (max-width:1340px){
  .fit .slide{ overflow:hidden; padding-bottom:60px; }
  .fit .slide__inner{ height:100%; min-height:0; }
}

/* ==========================================================================
   THE PLATE BECOMES A WATERMARK
   Each right-hand plate was drawn as an argument — the line nobody is
   allowed above, the ledger of what he won and what he lost, the six
   conductors facing one score. It earned its place beside the copy, but
   it was competing with it: two things asking to be looked at on a page
   that should only ever be making one point.

   So the plate keeps its place and gives up its voice. Printed at a
   fraction of its ink it reads as the mark of the stock rather than as a
   second column, and the type carries the page alone. Nothing else moved:
   the column, the type sizes and the measured fit are untouched, because
   the plate was never what was holding the size back — the page height
   was. It is still there for anyone who wants it, at full strength, one
   click away in the lightbox.

   Deliberately no hover brightening. A watermark that lights up when you
   look at it has gone back to competing.

   Calibrated rather than guessed. Measured against the paper (#e9e5db,
   luminance 237): the body text is ink at luminance 29, so it sits 208
   below the page. At opacity .17 the plate's darkest line fell to 202 —
   only 35 below the paper, which is not a watermark, it is an erasure.
   At .36 it bottoms out at 160, some 77 below the page: a third of the
   weight of the type, present when looked for, silent when not. Higher
   and it starts arguing with the copy again.
   ========================================================================== */
.fit .slide__art-in img{
  opacity:.36;
}

/* ==========================================================================
   THE LEFT / RIGHT DECK
   Every argument page is built the same way now: ONE line of title across
   the top, and below it two halves — words on one side, the photograph on
   the other. Nothing else on the page.

   The figure plates are gone. They were a second thing asking to be looked
   at, and with the page split in half there is nowhere honest left to put
   them: the half-width a plate needs is precisely the half-width the type
   has just been given. (The hook app.js reads — [data-zoom-src] — is generic,
   so the top bar's Art button now enlarges the photograph instead. No script
   changed, and nothing lost its picture.)

   Keywords never wrap. A keyword is one idea; broken across two lines it
   reads as two. `nowrap` makes the WIDTH the thing that decides how large a
   word may become, which is why the fitting in extra.js now runs per column:
   the word grows until it touches the edge of its own half, and stops there.
   Sentences are the opposite case and are still allowed to wrap — a sentence
   already knows where it ends.
   ========================================================================== */

/* the column is the frame again: there is no plate to stay clear of */
.slide--split .slide__inner,
.fit .slide--split .slide__inner,
.fit .slide--title.slide--split .slide__inner{
  max-width:none;
  width:100%;
  min-width:0;
}

/* the two rows: the title takes what it needs, the halves take the rest */
.slide--split .slide__inner{ display:flex; flex-direction:column; }
.slide--split .shead{ flex:0 0 auto; }
.slide--split .slide__inner > .cols{ flex:1 1 auto; min-height:0; }

.cols{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(16px, 2.6vw, 52px);
  align-items:stretch;
  margin-top:clamp(10px, 2.2vh, 28px);
}
/* Which half gets the extra sliver of width follows what that half has to
   do. A half holding nowrap keywords needs every pixel it can get — width
   is what decides how large the words may become. A half holding sentences
   is better off narrower: a shorter measure wraps onto more lines, and
   height is the thing these frames have to spare. */
.slide--keys .cols{ grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr); }
.slide--keys.slide--flip .cols{ grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); }
.slide--claim .cols{ grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr); }
.slide--claim.slide--flip .cols{ grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr); }
.col{
  /* position matters: it makes the column the offsetParent of everything in
     it, which is what lets extra.js measure each half in layout units that
     no animation can lie about */
  position:relative;
  min-width:0; min-height:0;
}
.col__in{
  height:100%;
  display:flex; flex-direction:column;
  justify-content:center;
}
.col--type{ grid-area:1 / 1 / 2 / 2; }
.col--pic { grid-area:1 / 2 / 2 / 3; }
.slide--flip .col--type{ grid-area:1 / 2 / 2 / 3; }
.slide--flip .col--pic { grid-area:1 / 1 / 2 / 2; }

/* ---- the title line ------------------------------------------------------ */
.slide--split .eyebrow{
  font-size:clamp(.78rem, min(1.15vw, 1.7vh), 1.6rem);
  margin-bottom:clamp(5px, 1.2vh, 18px);
}
.slide--split .h2{
  /* Set against the TITLE ROW, which is the whole frame, not half of it.
     That is why it can be this large: it has 1300 px to run along, where a
     keyword has 650. The keywords are then stopped (in extra.js) at just
     under this size, so the page still reads title-first. */
  font-size:clamp(1.7rem, min(4.9vw, 9.4vh), 6.6rem);
  margin-bottom:0;
  /* No height above the title for a multi-line heading to grow into: the
     column is stacked as a whole by extra.js, so the header cannot grow and
     the keyword list cannot know it happened. The rules and the probe both
     hold the title to one line, and this makes the degradation acceptable if
     a longer one is ever written — a squeezed line, never an overlap. */
  line-height:1.02;
}
.shead .eyebrow, .shead .h2, .shead .title{ white-space:nowrap; }

/* ---- the words half ------------------------------------------------------
   `justify-content` stays centred here. A half whose type cannot grow any
   further (its longest line is already at the edge of the column) has air
   above and below it, and the page reads as a book page only if that air
   sits on BOTH sides; stacking it at the top left every keyword page
   hanging off the title with an empty lower third. */
.col--type .keys--stack{
  margin:0; max-width:none;
  gap:clamp(9px, 2.2vh, 38px);
}
.col--type .keys--stack .key{
  font-size:clamp(1.35rem, min(3.2vw, 4.8vh), 4.6rem);
  white-space:nowrap;
  padding-bottom:clamp(5px, 1.2vh, 18px);
}
.col--type .claim{
  margin:0; max-width:none;
  padding-left:clamp(16px, 1.8vw, 30px);
  gap:clamp(8px, 1.8vh, 26px);
}
.col--type .claim__line{
  font-size:clamp(1.15rem, min(4.2vw, 6.4vh), 5.4rem);
  line-height:1.26;
  max-width:none;
}
.col--type .claim__src{ font-size:clamp(.74rem, min(1.05vw, 1.5vh), 1.4rem); }

/* ---- the picture half ----------------------------------------------------
   contain, never cover: the whole photograph on every page, which is the
   whole point of putting a photograph there.

   --capH is the slice of the half kept for the caption. Without it the
   picture takes the whole column and pushes its own caption out of the
   bottom of the frame, which is exactly what happened before it was here. */
.slide--split .photo{
  --capH:clamp(30px, 4.6vh, 64px);
  margin:0; max-width:none;
  height:100%;
  display:flex; flex-direction:column;
  align-items:center;
  justify-content:center;
}
.slide--split .photo img{
  /* width AND height auto, with both maxima applied: that is the one
     combination that lets the browser scale a replaced element while
     keeping its aspect ratio. Setting either one to 100% pins it and the
     picture comes out stretched. */
  width:auto; height:auto;
  max-width:100%;
  max-height:calc(100% - var(--capH));
  object-fit:contain;
}
.slide--split .photo figcaption{
  margin-top:clamp(6px, 1.1vh, 14px);
  text-align:center;
}
.slide--split .photo--portrait{ max-width:none; }
.slide--split .photo--portrait figcaption{ max-width:none; }

/* ---- the cover follows the same rule: title line, then two halves -------- */
.slide--title.slide--split .title{
  /* the longest title in the deck (32 characters) has to stay on one line
     across the whole frame: at this size it measures ~1150 of the 1308 it
     is given, which is close enough to be the last size it can take */
  font-size:clamp(1.5rem, min(4.8vw, 8vh), 6.4rem);
  line-height:1.1;
  white-space:nowrap;
}
.slide--title.slide--split .lede{
  font-size:clamp(.92rem, min(1.7vw, 2.5vh), 2.4rem);
}
.slide--title.slide--split .profile{ padding:clamp(8px, 1.4vh, 22px) 0; }
.slide--title.slide--split .rule{ margin:clamp(8px, 1.4vh, 22px) 0; }
.slide--title.slide--split .meta{ padding-top:clamp(8px, 1.5vh, 24px); }
.slide--title.slide--split .meta__item{ padding-top:clamp(8px, 1.4vh, 22px); }
.slide--title.slide--split .meta__label{ font-size:clamp(.7rem, min(.85vw, 1.2vh), 1.2rem); }
.slide--title.slide--split .meta__val{ font-size:clamp(.9rem, min(1.4vw, 2vh), 2rem); }
.slide--title.slide--split .profile__name{ font-size:clamp(.95rem, min(1.5vw, 2.1vh), 2.1rem); }
.slide--title.slide--split .profile__role,
.slide--title.slide--split .profile__sep{ font-size:clamp(.76rem, min(1.05vw, 1.45vh), 1.45rem); }

/* ---- below the fitting threshold the halves stack again ------------------ */
@media (max-width:760px){
  /* every half-column rule above is named twice (`.slide--keys .cols` and
     friends), so a bare `.cols` here would lose on specificity no matter
     where it sits. The whole family has to be asked. */
  .cols,
  .slide--keys .cols, .slide--keys.slide--flip .cols,
  .slide--claim .cols, .slide--claim.slide--flip .cols{
    /* one half per row, each as wide as the frame. The implicit column is
       `auto`, which sizes to the widest thing in the row — and that is the
       nowrap keyword, not the frame: it was the keywords that pushed the
       stacked layout 69px past the right edge. */
    grid-template-columns:1fr;
    grid-template-columns:minmax(0,1fr);
    gap:14px; margin-top:12px;
  }
  .slide--flip .col--type, .slide--flip .col--pic,
  .col--type, .col--pic{ grid-area:auto; }
  .col__in{ height:auto; }
  .shead .eyebrow, .shead .h2, .shead .title,
  .col--type .keys--stack .key{ white-space:normal; }
  .slide--split .photo{ height:auto; }
  .slide--split .photo img,
  .slide--split .photo--portrait img{ max-height:none; }
  .slide--split .photo--portrait img{ height:190px; }
}

/* ---------------------------------------------------------------------
   THE FOURTH CAUSE
   Three passes raised the sizes and still every page stopped short of its
   frame: 88% on the sentence pages, 51% on the pages carrying three words.
   The sizes were not the problem. `.slide__inner` spreads its children
   over the full height with space-between, so the words HALF inherited
   whatever air the title row left over — and the taller the frame, the
   more of it there was. The half was 653px tall with 300px of words in the
   middle of it, and the fitter, which is not allowed to make a page wider
   than its column, could not fix that by scaling.

   Under `.fit` the half is no longer a stretched flex child: it takes the
   height of its row and stretches its own content into it (align-content,
   which does not touch element widths). Above and below it the slack is
   the title row's business, and the title row is kept to its natural size.
   --------------------------------------------------------------------- */
.fit .slide--split .slide__inner > .cols{ flex:0 1 auto; min-height:0; }
.fit .slide--split .cols{ align-items:stretch; }
/* The grid item must be a real flex container, not the row inside one: a
   column that is auto-sized by its content passes `height:100%` straight
   through as auto, and every stretching rule below it quietly does nothing.
   Grid already knows how tall the row is, so the box fills it and the
   content inside can then be laid out over that height. */
.fit .slide--split .col{
  display:flex;
  flex-direction:column;
}
.fit .slide--split .col__in{
  flex:1 1 auto;
  height:auto;
  min-height:0;
  justify-content:flex-start;
  align-content:space-around;
}
/* the title row keeps one line and hands all the slack to the halves */
.fit .slide--split .shead{ flex:0 0 auto; }

/* Where the fitter had to spread a list, the gaps it wrote are the gaps the
   page uses, and the list still has to end where the ink ends: the last
   entry carries no bottom rule of its own, so the spread stops there. */
.fit .slide--split .col__in > *{ flex:0 0 auto; }
/* …and the list itself has to be allowed to grow into that height: its own
   `flex:0 0 auto` (set above, for the natural measurement) leaves it at its
   content height, and content that is exactly its own height has nothing to
   distribute. The fitter clears `.is-fitted` between measurements, so the
   natural size it needs is still the natural size. */
.fit .slide--split .col__in > .keys--stack.is-fitted,
.fit .slide--split .col__in > .claim.is-fitted{
  flex:1 1 auto;
  min-height:0;
  /* stretch, not space-around: in a COLUMN flex box `space-around` ALSO
     distributes across the main axis, which makes the list as tall as its
     parent — and a list taller than its own frame is a list that gets
     squeezed narrower by the fitter and spills. The air between entries is
     written by extra.js as real row gaps instead; here the children are
     simply told to take the width they are given. */
  align-content:stretch;
  align-items:stretch;
}
.fit .slide--split .col__in > .keys--stack.is-fitted .key{
  flex:0 0 auto;
  align-items:baseline;
}
/* the claim's own left rule has to stop where its last line stops, not run
   on down the empty half of the frame */
.fit .slide--split .col__in > .claim{ align-self:stretch; }

/* ---------------------------------------------------------------------
   THE WORDS SIT IN THE MIDDLE OF THEIR HALF
   `space-between` was inherited from the one-column deck, where the column
   WAS the page and the first block had to touch the top of it. With a title
   row above, that rule pulls every half up against the title and leaves the
   empty part of the frame hanging under it — most visibly on the pages whose
   type has already grown as wide as its column and cannot grow further.
   --------------------------------------------------------------------- */
.fit .slide--split .col.col--type > .col__in{ justify-content:flex-start; }

/* The old cover rule capped the inner at half the viewport and centred it
   vertically, because the cover used to be one narrow column of short lines.
   It is now a title row over two halves, and that cap squeezed it into the
   left of the frame. Restored to the shell's own width, with the title row
   at the top like every other page. */
.fit .slide--title.slide--split .slide__inner{
  max-width:none;
  width:100%;
  justify-content:flex-start;
}
