/* ═══════════════════════════════════════════════════════════════
   1,000 WHYS
   Concept: a lift-the-flap board book, screenprinted, for a very
   small scientist. Flat saturated inks on chalky board. All the
   typographic furniture stays disciplined and printerly; every bit
   of exuberance is spent on the cartoon plate and the flap.
   ═══════════════════════════════════════════════════════════════ */

@font-face{
  font-family:'Fraunces';
  src:url('fonts/fraunces-latin.woff2') format('woff2-variations');
  font-weight:300 900; font-display:swap;
}
@font-face{
  font-family:'Schibsted';
  src:url('fonts/schibsted-latin.woff2') format('woff2-variations');
  font-weight:400 900; font-display:swap;
}
/* Andika is SIL's literacy face, drawn for beginning readers. This is the
   type Hudson is actually learning to read, so it gets the reading surfaces. */
@font-face{
  font-family:'Andika';
  src:url('fonts/andika-400.woff2') format('woff2');
  font-weight:400; font-display:swap;
}
@font-face{
  font-family:'Andika';
  src:url('fonts/andika-700.woff2') format('woff2');
  font-weight:700; font-display:swap;
}
/* the book's "You know what?" is a scribbled note on ruled lines, so it gets a hand */
@font-face{
  font-family:'Hand';
  src:url('fonts/patrickhand-400.woff2') format('woff2');
  font-weight:400; font-display:swap;
}

:root{
  /* the four printing inks — each one is a topic, so color carries information */
  --ink-animals:#D8452F;
  --ink-sky:#2F6FA8;
  --ink-body:#177A72;
  --ink-weather:#C98219;

  /* board stock, biased green-gray off cream so it reads as pulp, not parchment */
  --board:#EFE9DA;
  --board-2:#E2DAC4;
  --board-3:#D3C9AE;

  /* deep printing ink — navy-teal, never black */
  --ink:#1A3038;
  --ink-70:rgba(26,48,56,.70);
  --ink-45:rgba(26,48,56,.45);
  --ink-15:rgba(26,48,56,.15);

  --ground:var(--ink);          /* the plate's own ink, set by JS */
  --ground-deep:var(--ink);     /* a denser pass of it, for the page */
  --pad:clamp(1.1rem,4.5vw,2rem);
  --card-r:14px;

  --display:'Fraunces',Georgia,serif;
  --body:'Schibsted',system-ui,-apple-system,sans-serif;
  --read:'Andika','Schibsted',system-ui,sans-serif;   /* everything he reads */
  --hand:'Hand','Bradley Hand',cursive;
  --mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;

  /* motion: one curve per job, per Emil. Press is the system answering, so it
     is snappy; the flap is a physical page turn, so it gets the drawer curve;
     bounce is reserved for the playful reveal. */
  --ease-out:cubic-bezier(.23,1,.32,1);        /* enters, presses, feedback */
  --ease-drawer:cubic-bezier(.32,.72,0,1);     /* the flap */
  --lift:cubic-bezier(.22,1.2,.36,1);          /* overshoot, reveal only */
}


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

/* Any author `display` beats the UA rule for [hidden], which silently turns a
   hidden overlay into an invisible click-eater. Make hidden mean hidden. */
[hidden]{display:none!important}

html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  min-height:100dvh;
  background:var(--ground-deep);
  color:var(--board);
  font-family:var(--body);
  font-size:17px;
  line-height:1.5;
  overflow-x:hidden;
  -webkit-tap-highlight-color:transparent;
  transition:background-color .45s ease;
  overscroll-behavior-y:none;
}

/* printed-paper grain over the whole sheet */
.grain{
  position:fixed;inset:0;width:100%;height:100%;
  opacity:.16;pointer-events:none;z-index:99;
  mix-blend-mode:overlay;
}

/* ── screens ────────────────────────────────────────────────── */
.screen{display:none;min-height:100dvh;flex-direction:column}
.screen.is-on{display:flex}

/* ── top bar ────────────────────────────────────────────────── */
.bar{
  display:flex;align-items:center;gap:.4rem;
  padding:max(.45rem,env(safe-area-inset-top)) var(--pad) .45rem;
  border-bottom:1px solid rgba(239,233,218,.22);
  /* Sticky, because the back arrow is Hudson's only way out and he cannot read
     his way around a missing one. It has to be opaque to sit over the page. */
  position:sticky;top:0;z-index:20;
  background:var(--ground-deep);
}
/* Every child declares its own flex behavior. Leaving the index unconstrained
   let it fight the title for space and pushed the actions off the screen. */
.bar-btn{
  flex:none;width:44px;height:44px;
  display:grid;place-items:center;
  background:transparent;border:none;border-radius:12px;
  color:var(--board);cursor:pointer;
  transition:background-color 140ms ease,transform 120ms var(--ease-out);
}
.bar-btn svg{width:22px;height:22px;fill:currentColor;display:block}
.bar-btn:active{transform:scale(.9);background:rgba(239,233,218,.2)}
@media (hover:hover) and (pointer:fine){.bar-btn:hover{background:rgba(239,233,218,.14)}}
.bar-btn:focus-visible{background:rgba(239,233,218,.16)}
.bar-title{
  flex:1 1 auto;min-width:0;margin:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:.74rem;font-weight:800;letter-spacing:.15em;text-transform:uppercase;opacity:.9;
}
.bar-index{
  flex:none;font-family:var(--mono);font-size:.72rem;letter-spacing:.04em;
  opacity:.7;font-variant-numeric:tabular-nums;white-space:nowrap;
}
.bar-actions{flex:none;display:flex;align-items:center;gap:.1rem;margin-left:auto}
/* the two he needs most: out of this why, and all the way home */
.bar-btn-back{width:56px;height:56px}
.bar-btn-back svg{width:30px;height:30px}
.bar-btn-home{width:52px;height:52px;margin-left:.1rem}
.bar-btn-home svg{width:25px;height:25px}
.bar-btn-star{color:var(--board)}
.bar-btn-gear{opacity:.5}
.bar-btn-gear svg{width:19px;height:19px}
@media (hover:hover) and (pointer:fine){.bar-btn-gear:hover{opacity:1}}

/* the count belongs with the collection it counts, not wedged into the bar */
.shelf-count{
  margin:0;padding:calc(var(--pad) * .8) var(--pad) 0;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.05em;
  color:var(--board);opacity:.65;font-variant-numeric:tabular-nums;
}

/* ═══ COVER ══════════════════════════════════════════════════ */
/* The cover is exactly one screen, never a scroll. Everything is fixed except
   Pip, who takes whatever height is left over — so it composes itself down to
   an iPhone SE and back up to a Pro Max without a breakpoint. */
#cover{
  --ground:var(--ink);background:var(--ink);
  height:100dvh;align-items:center;justify-content:center;
  padding:max(.5rem,env(safe-area-inset-top)) var(--pad) max(.5rem,env(safe-area-inset-bottom));
}
.cover-plate{
  width:min(560px,100%);height:100%;text-align:center;
  display:flex;flex-direction:column;
  padding:clamp(.4rem,2vh,1.6rem) 0;
}
.cover-rule{flex:none;height:3px;background:var(--board);opacity:.85;margin:0 auto;width:100%}
.cover-rule+.cover-rule{margin-top:0}
.cover-kicker{
  flex:none;margin:clamp(.45rem,1.6vh,1.4rem) 0 .1rem;
  font-size:clamp(.68rem,1.6vh,.8rem);font-weight:700;
  letter-spacing:.26em;text-transform:uppercase;opacity:.8;
}
.cover-title{flex:none;margin:0;line-height:.86;font-family:var(--display);font-weight:900}
.cover-num{
  display:block;font-size:min(20vw,9.4vh,7.6rem);
  font-variation-settings:'SOFT' 40,'WONK' 1,'opsz' 144;
  letter-spacing:-.03em;
}
.cover-word{
  display:block;font-size:min(14vw,6.6vh,5.4rem);
  font-variation-settings:'SOFT' 90,'WONK' 1,'opsz' 144;
  font-style:italic;letter-spacing:-.01em;color:var(--board);
}
.cover-for{flex:none;margin:clamp(.3rem,1.2vh,.9rem) 0 clamp(.4rem,1.6vh,1.3rem);
  font-size:clamp(.85rem,1.9vh,1rem);letter-spacing:.04em;opacity:.85}
/* Pip is the only flexible element on the cover: he takes whatever height is
   left after the fixed pieces, so the page composes itself down to an SE and
   back up to an iPad without a single breakpoint. */
.cover-pip{
  flex:1 1 0;min-height:0;overflow:hidden;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(.3rem,1.2vh,.6rem);
  width:100%;margin:clamp(.3rem,1.2vh,1rem) auto;
  padding:0;background:none;border:none;cursor:pointer;
  transition:transform 160ms var(--ease-out);
}
.cover-pip img{
  display:block;min-height:0;
  /* capped off the viewport, not a percentage of a flex-derived height —
     browsers will not resolve that reliably during the shrink pass */
  height:auto;width:auto;
  max-height:min(34vh,300px);max-width:min(230px,54vw);
  object-fit:contain;
}
.cover-pip-cue{
  display:inline-flex;align-items:center;justify-content:center;gap:.45rem;
  flex:none;min-height:44px;padding:.4rem .9rem;
  border:2px solid rgba(239,233,218,.45);border-radius:999px;
  font-family:var(--body);font-size:clamp(.74rem,1.7vh,.82rem);
  font-weight:700;color:var(--board);
}
@media (hover:hover) and (pointer:fine){
  .cover-pip:hover .cover-pip-cue{border-color:var(--board)}
}
.cover-pip:focus-visible .cover-pip-cue{border-color:var(--board)}
.cover-pip:active{transform:scale(.96)}
.cover-pip.is-playing{transform:scale(1.03)}
.cover-count{
  flex:none;margin:clamp(.6rem,1.8vh,1.5rem) 0 0;font-family:var(--mono);font-size:.74rem;
  letter-spacing:.05em;opacity:.7;font-variant-numeric:tabular-nums;
}
.cover-count b{font-weight:700;opacity:1}

/* the one big button a four-year-old needs to find */
.btn-big{
  display:block;width:100%;flex:none;margin-top:clamp(.3rem,1.2vh,.6rem);
  padding:clamp(.75rem,2.2vh,1.15rem) 1.4rem;
  background:var(--board);color:var(--ink);
  border:none;border-radius:var(--card-r);cursor:pointer;
  box-shadow:0 5px 0 var(--board-3);
  font-family:inherit;
}
.btn-big-label{
  display:block;font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 70,'WONK' 1,'opsz' 72;
  font-size:clamp(1.35rem,3.4vh,1.7rem);line-height:1.1;
}
.btn-big-sub{display:block;margin-top:.2rem;font-size:.85rem;font-weight:600;color:var(--ink-70)}
.btn-big:active{transform:translateY(4px);box-shadow:0 1px 0 var(--board-3)}
.btn-big{transition:transform 120ms var(--ease-out),box-shadow 120ms var(--ease-out)}

/* A phone turned sideways is short, not small: stand the cover up in two
   columns rather than squeezing everything into a letterbox. */
@media (max-height:560px) and (orientation:landscape){
  .cover-plate{
    display:grid;grid-template-columns:1fr auto;
    grid-template-areas:'text pip';
    align-items:center;gap:0 clamp(1rem,4vw,2.5rem);
    text-align:left;
  }
  .cover-rule,.cover-kicker,.cover-title,.cover-for,.btn-big,.cover-count{grid-column:text}
  .cover-pip{grid-area:pip;align-self:center;margin:0}
  .cover-pip img{max-height:min(62vh,240px)}
  .cover-num{font-size:min(9vw,15vh)}
  .cover-word{font-size:min(6.5vw,11vh)}
}

/* ═══ TOPICS — the shelf ═════════════════════════════════════
   Ten kinds of why. This exists to keep any one grid short: past roughly
   sixty tiles a single list stops being browsable for a four-year-old. */
.shelf{
  list-style:none;margin:0;
  padding:calc(var(--pad) * .6) var(--pad) calc(var(--pad) + env(safe-area-inset-bottom));
  display:grid;gap:.85rem;grid-template-columns:repeat(auto-fill,minmax(min(100%,165px),1fr));
  overflow-y:auto;
}
.shelf li{display:flex}
.topic{
  position:relative;display:flex;flex-direction:column;
  width:100%;padding:0;overflow:hidden;
  background:var(--board);color:var(--ink);
  border:none;border-radius:var(--card-r);cursor:pointer;text-align:left;
  font-family:inherit;box-shadow:0 4px 0 var(--board-3);
  transition:transform 120ms var(--ease-out),box-shadow 120ms var(--ease-out);
}
.topic:active{transform:translateY(3px);box-shadow:0 1px 0 var(--board-3)}
.topic-art{display:block;aspect-ratio:4/3;background:var(--tile-ink);
  border-bottom:3px solid var(--tile-ink);position:relative}
.topic-art img{display:block;width:100%;height:100%;object-fit:cover}
.topic-body{display:flex;flex-direction:column;gap:.25rem;padding:.7rem .8rem .85rem;flex:1}
.topic-name{
  margin:0;font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 70,'WONK' 1,'opsz' 48;
  font-size:1.14rem;line-height:1.12;text-wrap:balance;
}
.topic-count{font-family:var(--mono);font-size:.66rem;letter-spacing:.05em;
  color:var(--tile-ink);font-variant-numeric:tabular-nums}
/* how much of this kind he has found, as a real printed gauge */
.topic-gauge{height:5px;border-radius:0 3px 3px 0;background:rgba(26,48,56,.14);margin-top:.15rem}
.topic-gauge span{display:block;height:100%;border-radius:0 3px 3px 0;background:var(--tile-ink);
  width:0;transition:width 520ms var(--ease-out)}
.topic.is-done .topic-art::after{
  content:'';position:absolute;top:.5rem;right:.5rem;width:24px;height:24px;
  background:var(--board);border-radius:50%;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22Zm5.3 8.1-6.4 6.4a1.2 1.2 0 0 1-1.7 0L6.7 12.6a1.2 1.2 0 1 1 1.7-1.7l1.6 1.6 5.6-5.6a1.2 1.2 0 0 1 1.7 1.7Z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22Zm5.3 8.1-6.4 6.4a1.2 1.2 0 0 1-1.7 0L6.7 12.6a1.2 1.2 0 1 1 1.7-1.7l1.6 1.6 5.6-5.6a1.2 1.2 0 0 1 1.7 1.7Z'/%3E%3C/svg%3E") center/contain no-repeat;
}
.shelf li{animation:settle 320ms var(--ease-out) both}
.shelf li:nth-child(1){animation-delay:0ms}
.shelf li:nth-child(2){animation-delay:40ms}
.shelf li:nth-child(3){animation-delay:80ms}
.shelf li:nth-child(4){animation-delay:120ms}
.shelf li:nth-child(5){animation-delay:160ms}
.shelf li:nth-child(n+6){animation-delay:200ms}

/* ═══ CONTENTS ═══════════════════════════════════════════════ */
.tiles{
  list-style:none;margin:0;padding:var(--pad) var(--pad) calc(var(--pad) + env(safe-area-inset-bottom));
  display:grid;gap:.85rem;grid-template-columns:repeat(auto-fill,minmax(min(100%,165px),1fr));
  overflow-y:auto;
}
/* picture-first: Hudson cannot read, so the plate IS the label. The text
   underneath is for whoever is reading along with him. */
.tile{
  position:relative;display:flex;flex-direction:column;
  width:100%;padding:0;overflow:hidden;
  background:var(--board);color:var(--ink);
  border:none;border-radius:var(--card-r);cursor:pointer;text-align:left;
  font-family:inherit;
  box-shadow:0 4px 0 var(--board-3);
  transition:transform 120ms var(--ease-out),box-shadow 120ms var(--ease-out);
}
.tiles li{display:flex}                 /* so cards in a row match height */
/* the shelf settles rather than snapping in; 40ms apart, capped so a long
   grid never makes the last card wait */
.tiles li{animation:settle 320ms var(--ease-out) both}
.tiles li:nth-child(1){animation-delay:0ms}
.tiles li:nth-child(2){animation-delay:40ms}
.tiles li:nth-child(3){animation-delay:80ms}
.tiles li:nth-child(4){animation-delay:120ms}
.tiles li:nth-child(5){animation-delay:160ms}
.tiles li:nth-child(n+6){animation-delay:200ms}
@keyframes settle{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
.shuffle-slot{grid-column:1/-1}
.tile-shuffle{
  flex-direction:row;align-items:center;gap:.9rem;
  padding:.75rem 1.1rem .75rem .75rem;
  background:var(--board);
  --tile-ink:var(--ink);
}
.shuffle-pip{width:64px;height:auto;flex:none}
.shuffle-copy{display:flex;flex-direction:column;gap:.1rem}
.shuffle-word{
  font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 80,'WONK' 1,'opsz' 72;
  font-size:1.5rem;line-height:1.05;color:var(--ink);font-style:italic;
}
.shuffle-sub{font-size:.86rem;font-weight:600;color:var(--ink-70)}
.tile:active{transform:translateY(3px);box-shadow:0 1px 0 var(--board-3)}
.tile-art{
  display:block;aspect-ratio:4/3;background:var(--tile-ink);
  border-bottom:3px solid var(--tile-ink);
}
.tile-art img{display:block;width:100%;height:100%;object-fit:cover}
.tile-body{display:flex;flex-direction:column;gap:.3rem;padding:.7rem .8rem .85rem;flex:1}
/* the index line is set in that plate's own ink, so color stays informational */
.tile-n{
  font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;
  color:var(--tile-ink);font-variant-numeric:tabular-nums;
}
.tile-q{
  margin:0;font-family:var(--read);font-weight:700;
  font-size:1rem;line-height:1.22;text-wrap:balance;
}
/* found: a printed tick stamped into the corner of the plate */
.tile.is-found .tile-art::after{
  content:'';position:absolute;top:.55rem;right:.55rem;
  width:26px;height:26px;border-radius:50%;
  background:var(--board);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22Zm5.3 8.1-6.4 6.4a1.2 1.2 0 0 1-1.7 0L6.7 12.6a1.2 1.2 0 1 1 1.7-1.7l1.6 1.6 5.6-5.6a1.2 1.2 0 0 1 1.7 1.7Z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22Zm5.3 8.1-6.4 6.4a1.2 1.2 0 0 1-1.7 0L6.7 12.6a1.2 1.2 0 1 1 1.7-1.7l1.6 1.6 5.6-5.6a1.2 1.2 0 0 1 1.7 1.7Z'/%3E%3C/svg%3E") center/contain no-repeat;
  filter:drop-shadow(0 0 2px rgba(26,48,56,.45));
}

/* ═══ QUESTION PAGE ══════════════════════════════════════════
   A why is one screen. Nothing here scrolls: the page is a fixed-height
   column and the pieces size themselves off the viewport, because a
   four-year-old will not scroll to find the answer he was promised. */
#page{height:100dvh;overflow:hidden}
#page .scroll{
  flex:1;min-height:0;overflow:hidden;
  display:flex;flex-direction:column;
  padding:clamp(.5rem,1.4vh,1.1rem) var(--pad) calc(clamp(.5rem,1.2vh,1rem) + env(safe-area-inset-bottom));
}
#page .col{flex:1;min-height:0;display:flex;flex-direction:column}
.scroll{
  flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:var(--pad) var(--pad) calc(3rem + env(safe-area-inset-bottom));
}
/* One column element holds the page, so children align to it naturally and no
   child has to center itself. A shrink-to-fit control like the audio button
   then sits flush with the column's left edge instead of the viewport's. */
.col{width:100%;max-width:640px;margin-inline:auto}

/* the cartoon plate, with real printer's registration marks at the trim */
.plate{
  position:relative;margin:0 auto clamp(.5rem,1.6vh,1.3rem);
  border-radius:10px;background:var(--ground);
  aspect-ratio:4/3;
  box-shadow:0 0 0 1px rgba(239,233,218,.14);
}
/* on the why page the plate is the flexible one: it gives up its room to the
   words, and gives up most of it once the flap is open and the art has done
   its job */
#page .plate{
  flex:0 1 auto;min-height:0;aspect-ratio:auto;
  height:clamp(110px,30vh,320px);width:auto;max-width:100%;
  aspect-ratio:4/3;margin-inline:auto;
}
#page.revealed .plate{height:clamp(72px,13vh,150px)}
#page .plate img{border-radius:10px}
/* loading is the state he will see most once art is fetched on demand */
.plate.is-loading::after{
  content:'';position:absolute;inset:0;border-radius:10px;
  background:linear-gradient(100deg,
    transparent 20%, rgba(239,233,218,.16) 50%, transparent 80%) 0 0/220% 100%;
  animation:sweep 1.1s linear infinite;
}
@keyframes sweep{from{background-position:120% 0}to{background-position:-120% 0}}
.plate.is-loading img{opacity:0}
.plate img{transition:opacity 220ms var(--ease-out)}
.plate img{
  display:block;width:100%;height:100%;object-fit:cover;
  border-radius:10px;
}
.reg{
  position:absolute;width:15px;height:15px;opacity:.5;
  background:
    linear-gradient(var(--board),var(--board)) center/1px 100% no-repeat,
    linear-gradient(var(--board),var(--board)) center/100% 1px no-repeat;
}
.reg::after{
  content:'';position:absolute;inset:4px;border:1px solid var(--board);border-radius:50%;
}
.reg-tl{top:-22px;left:-4px}.reg-tr{top:-22px;right:-4px}
.reg-bl{bottom:-22px;left:-4px}.reg-br{bottom:-22px;right:-4px}

.q{
  flex:none;margin:0 0 clamp(.35rem,1vh,.9rem);
  font-family:var(--display);font-weight:700;
  font-variation-settings:'SOFT' 60,'WONK' 1,'opsz' 144;
  font-size:min(8.4vw,4.6vh,3.4rem);line-height:1.04;
  letter-spacing:-.018em;text-wrap:balance;
}
#page.revealed .q{font-size:min(6.2vw,3.2vh,2.2rem)}
/* the lead word knocked out of a board-colored screenprint swatch —
   readable on all four ink grounds, unlike a second accent color */
.q-lead{
  display:inline-block;background:var(--board);color:var(--ground);
  padding:.02em .26em .1em;border-radius:5px;
  transform:rotate(-1.4deg);margin-right:.1em;
}

.rule{flex:none;display:block;width:100%;height:clamp(8px,1.2vh,12px);
  margin:0 0 clamp(.4rem,1.2vh,1.25rem);fill:var(--board);opacity:.55}
#page.revealed .rule{display:none}

/* the guess prompt is on the page as WORDS. Reading is the point of this app;
   Grandpa is help Hudson asks for, never the default. */
.guess{
  flex:none;margin:0 0 clamp(.4rem,1.2vh,1.1rem);font-family:var(--read);
  font-size:min(4.6vw,2.1vh,1.16rem);line-height:1.45;font-weight:700;
  color:var(--board);opacity:.94;text-wrap:pretty;
}
/* once the flap is up the guessing is done — that room belongs to the answer */
#page.revealed .guess,#page.revealed .btn-hear{display:none}

/* ── read-along: the word Pappa is saying, right now ───────────
   A highlighter swipe, not a color change. It has to land instantly to stay
   in sync with the voice, so the mark itself is what moves, not the text. */
.w{
  position:relative;border-radius:3px;
  /* isolate creates a stacking context on the word itself, so the highlight
     paints above the card it sits on instead of behind it. Without this the
     mark vanishes on any surface that has its own background. */
  isolation:isolate;
}
.w::before{
  content:'';position:absolute;left:-.12em;right:-.12em;top:-.06em;bottom:-.04em;
  background:currentColor;opacity:0;border-radius:3px;z-index:-1;
  transform:scaleX(.4);transform-origin:left center;
  transition:opacity 90ms linear,transform 90ms var(--ease-out);
}
.w.is-now::before{opacity:.22;transform:scaleX(1)}
.answer-text .w.is-now::before,.ykw-text .w.is-now::before{opacity:.18}
@media (prefers-reduced-motion:reduce){
  .w::before{transform:none!important;transition:opacity 90ms linear!important}
}

/* ── the "have a guess" button ──────────────────────────────── */
.btn-hear{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  flex:none;min-height:52px;padding:.6rem 1.1rem;margin-bottom:clamp(.5rem,1.4vh,1.6rem);
  background:transparent;color:var(--board);
  border:2px solid rgba(239,233,218,.5);border-radius:10px;
  font-family:inherit;font-weight:700;font-size:.98rem;
  letter-spacing:.01em;cursor:pointer;
  transition:background-color .18s,border-color .18s;
}
.btn-hear{transition:background-color 140ms ease,border-color 140ms ease,transform 120ms var(--ease-out)}
.btn-hear:active{transform:scale(.97)}
@media (hover:hover) and (pointer:fine){
  .btn-hear:hover{background:rgba(239,233,218,.14);border-color:var(--board)}
}
.btn-hear:focus-visible{background:rgba(239,233,218,.14);border-color:var(--board)}
.btn-hear.is-playing{background:rgba(239,233,218,.2);border-style:solid}

/* little equaliser mark instead of an emoji speaker */
.spk{display:inline-flex;align-items:flex-end;gap:3px;height:22px;flex:none}
.spk i{display:block;width:4px;border-radius:2px;background:currentColor;height:8px}
.spk i:nth-child(2){height:18px}.spk i:nth-child(3){height:12px}
.is-playing .spk i{animation:eq .62s ease-in-out infinite alternate}
.is-playing .spk i:nth-child(2){animation-delay:.12s}
.is-playing .spk i:nth-child(3){animation-delay:.24s}
@keyframes eq{from{height:5px}to{height:22px}}

/* ── THE FLAP — the one orchestrated moment ─────────────────── */
.flapwrap{position:relative;perspective:1900px;margin-bottom:1.7rem}
#page .flapwrap{flex:1 1 auto;min-height:0;margin-bottom:clamp(.5rem,1.4vh,1.2rem)}

.answer{
  background:var(--board);color:var(--ink);
  border-radius:var(--card-r);padding:1.4rem 1.3rem 1.3rem;
  box-shadow:0 5px 0 var(--board-3);
  /* closed, the card is clamped to a chunky board-book proportion so the flap
     covering it is a slab you want to lift, not a tall empty panel */
  height:100%;
  overflow:hidden;
  visibility:hidden;
  display:flex;flex-direction:column;
}
.flapwrap.is-open .answer{visibility:visible}
.answer-text{
  flex:none;margin:0 0 clamp(.45rem,1.2vh,1.1rem);
  font-family:var(--read);
  font-size:min(4.7vw,2.1vh,1.3rem);line-height:1.48;font-weight:400;
  letter-spacing:.006em;text-wrap:pretty;
}
.btn-replay{
  display:inline-flex;align-items:center;gap:.55rem;
  min-height:52px;padding:.6rem 1.1rem;
  background:transparent;color:var(--ink-70);
  border:2px solid var(--ink-15);border-radius:10px;
  font-family:inherit;font-size:.92rem;font-weight:700;cursor:pointer;
  transition:border-color .18s,color .18s;
}
.btn-replay{transition:border-color 140ms ease,color 140ms ease,transform 120ms var(--ease-out)}
.btn-replay:active{transform:scale(.97)}
@media (hover:hover) and (pointer:fine){
  .btn-replay:hover{border-color:var(--ink-45);color:var(--ink)}
}
.btn-replay:focus-visible{border-color:var(--ink-45);color:var(--ink)}
.btn-replay-sm{min-height:46px;font-size:.86rem;margin-top:clamp(.35rem,.9vh,.7rem)}

/* "You know what?" — the book's ruled note, redrawn as an overprint sticker */
.ykw{
  flex:none;
  margin:clamp(.5rem,1.3vh,1.2rem) -.35rem 0;padding:clamp(.5rem,1.3vh,.95rem) 1rem;
  background:var(--board-2);
  border:2px solid var(--ink-15);border-radius:8px;
  transform:rotate(-1deg);
  opacity:0;
}
/* a transition, not a keyframe, so opening and closing quickly retargets
   smoothly instead of restarting from zero */
.ykw{transform:rotate(2.5deg) translateY(14px) scale(.97);
  transition:opacity 380ms var(--lift) 260ms,transform 380ms var(--lift) 260ms}
.flapwrap.is-open .ykw{opacity:1;transform:rotate(-1deg) translateY(0) scale(1)}
.ykw-head{
  margin:0 0 .5rem;font-family:var(--hand);font-weight:400;
  font-size:min(5.4vw,2.6vh,1.5rem);color:var(--ink);
}
/* ruled like the notebook line in the book — the rules are generated from the
   same 30px line box the text sits in, so every line lands on its own rule */
.ykw-text{
  margin:0;font-family:var(--hand);
  font-size:min(4.6vw,2.05vh,1.28rem);line-height:clamp(20px,2.9vh,29px);
  color:var(--ink-70);font-weight:400;
  background:repeating-linear-gradient(
    transparent 0 28px, rgba(26,48,56,.18) 28px 29px, transparent 29px 30px);
}

/* the die-cut panel itself */
.flap{
  position:absolute;inset:0;padding:0;border:none;background:none;
  transform-origin:left center;transform-style:preserve-3d;
  cursor:pointer;
  transition:transform 420ms var(--ease-drawer),box-shadow 420ms ease;
  box-shadow:0 6px 0 var(--board-3),14px 12px 26px rgba(0,0,0,.22);
  border-radius:var(--card-r);
}
.flapwrap.is-open .flap{
  transform:rotateY(-162deg);
  box-shadow:0 2px 0 rgba(0,0,0,.08),-16px 14px 30px rgba(0,0,0,.16);
  pointer-events:none;
}
.flap:active:not([aria-expanded="true"]) .flap-front{transform:scale(.985)}
.flap-front{transition:transform 120ms var(--ease-out)}
.flap-face{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  border-radius:var(--card-r);
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
  background:var(--board);
  overflow:hidden;
}
.flap-back{transform:rotateY(180deg);background:var(--board-2)}
/* stitched hinge down the spine edge */
.flap-hinge{
  position:absolute;top:0;bottom:0;left:0;width:14px;
  background:var(--board-2);
  border-right:2px dashed var(--board-3);
}
.flap-back .flap-hinge{left:auto;right:0;border-right:none;border-left:2px dashed var(--board-3)}
.flap-copy{display:block;text-align:center;padding:1.7rem 3rem 1.7rem 2.4rem;color:var(--ink)}
.flap-kicker{
  display:block;font-size:.72rem;font-weight:800;letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-45);margin-bottom:.3rem;
}
.flap-word{
  display:block;font-family:var(--display);font-weight:900;
  font-variation-settings:'SOFT' 90,'WONK' 1,'opsz' 96;
  font-size:clamp(2.3rem,10vw,3.1rem);line-height:1;font-style:italic;
  color:var(--ground);
}
.flap-sub{display:block;margin-top:.35rem;font-size:.9rem;font-weight:600;color:var(--ink-70)}
/* the thumb notch you actually put your finger in */
.flap-notch{
  position:absolute;right:-1px;top:50%;transform:translateY(-50%);
  width:34px;height:64px;border-radius:34px 0 0 34px;
  background:var(--ground);opacity:.16;
}

/* ── pager ──────────────────────────────────────────────────── */
.pager{display:flex;gap:.7rem}
#page .pager{flex:none}
.btn-page{
  flex:1;min-height:56px;padding:.7rem 1rem;
  background:transparent;color:var(--board);
  border:2px solid rgba(239,233,218,.45);border-radius:var(--card-r);
  font-family:inherit;font-size:1rem;font-weight:700;cursor:pointer;
  transition:background-color .18s,border-color .18s;
}
.btn-page{transition:background-color 140ms ease,border-color 140ms ease,transform 120ms var(--ease-out)}
.btn-page:active{transform:scale(.98)}
@media (hover:hover) and (pointer:fine){
  .btn-page:hover{background:rgba(239,233,218,.14);border-color:var(--board)}
}
.btn-page:focus-visible{background:rgba(239,233,218,.14);border-color:var(--board)}
.btn-page-go{flex:1.5;background:var(--board);color:var(--ink);border-color:var(--board);box-shadow:0 4px 0 var(--board-3)}
@media (hover:hover) and (pointer:fine){
  .btn-page-go:hover{background:var(--board);color:var(--ink)}
}
.btn-page-go:focus-visible{background:var(--board);color:var(--ink)}
.btn-page-go:active{transform:translateY(3px);box-shadow:0 1px 0 var(--board-3)}
.btn-page[disabled]{opacity:.35;pointer-events:none}


/* ── the keeping star: a gold sticker pressed onto the plate ──
   This is Hudson's bookmark. A four-year-old does not go to page 738; he goes
   back to the one he liked, so he needs a way to say which one that is. */
.star{
  position:absolute;top:8px;right:8px;
  width:52px;height:52px;padding:0;border:none;border-radius:50%;
  display:grid;place-items:center;cursor:pointer;
  background:rgba(26,48,56,.34);
  transition:background-color 160ms ease,transform 140ms var(--ease-out);
}
.star svg{width:27px;height:27px;display:block;
  fill:none;stroke:var(--board);stroke-width:1.8;stroke-linejoin:round;
  transition:fill 180ms var(--ease-out),stroke 180ms var(--ease-out);}
.star:active{transform:scale(.88)}
@media (hover:hover) and (pointer:fine){.star:hover{background:rgba(26,48,56,.5)}}
.star[aria-pressed="true"]{background:rgba(26,48,56,.42)}
.star[aria-pressed="true"] svg{fill:#F5B921;stroke:#8A5B08}
/* the stamp: it lands, overshoots a touch, settles */
.star.pop svg{animation:stamp 420ms var(--lift)}
@keyframes stamp{
  0%{transform:scale(.5) rotate(-22deg)}
  55%{transform:scale(1.28) rotate(6deg)}
  100%{transform:scale(1) rotate(0)}
}
@media (prefers-reduced-motion:reduce){.star.pop svg{animation:none}}

.starlist{list-style:none;margin:0 0 1.7rem;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:.55rem}
.starlist button{
  position:relative;display:block;width:100%;padding:0;overflow:hidden;
  background:var(--board);border:none;border-radius:9px;cursor:pointer;
  box-shadow:0 3px 0 var(--board-3);
  transition:transform 120ms var(--ease-out),box-shadow 120ms var(--ease-out);
}
.starlist button:active{transform:translateY(2px);box-shadow:0 1px 0 var(--board-3)}
.starlist img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.starlist span{
  position:absolute;top:5px;right:5px;width:20px;height:20px;
  background:#F5B921;border-radius:50%;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.6l2.6 5.6 6.1.8-4.5 4.2 1.2 6-5.4-3-5.4 3 1.2-6L3.3 9l6.1-.8z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.6l2.6 5.6 6.1.8-4.5 4.2 1.2 6-5.4-3-5.4 3 1.2-6L3.3 9l6.1-.8z'/%3E%3C/svg%3E") center/contain no-repeat;
  filter:drop-shadow(0 0 1.5px rgba(26,48,56,.6));
}
/* a kept why is marked on the shelf too */
.tile.is-star .tile-art::before{
  content:'';position:absolute;top:.55rem;left:.55rem;z-index:1;
  width:22px;height:22px;background:#F5B921;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.6l2.6 5.6 6.1.8-4.5 4.2 1.2 6-5.4-3-5.4 3 1.2-6L3.3 9l6.1-.8z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2.6l2.6 5.6 6.1.8-4.5 4.2 1.2 6-5.4-3-5.4 3 1.2-6L3.3 9l6.1-.8z'/%3E%3C/svg%3E") center/contain no-repeat;
  filter:drop-shadow(0 0 1.5px rgba(26,48,56,.55));
}

/* Short phones: claw back room from padding and the audio buttons rather than
   shrinking the words, which are the thing he is here to read. */
@media (max-height:900px){
  #page .bar{padding-top:.3rem;padding-bottom:.3rem}
  #page .bar-btn-back{width:50px;height:50px}
  #page .bar-btn-back svg{width:27px;height:27px}
  #page .answer{padding:.7rem .9rem .75rem}
  #page .btn-replay{min-height:46px;padding:.45rem .9rem}
  #page .btn-replay-sm{min-height:44px;margin-top:.35rem}
  #page .ykw{margin-top:.6rem;padding:.55rem .8rem .6rem}
  #page .ykw-head{margin-bottom:.25rem}
  #page.revealed .plate{height:clamp(64px,10.5vh,120px)}
}
@media (max-height:600px){
  #page .answer{padding:.55rem .7rem .6rem}
  #page .ykw{margin-top:.4rem;padding:.4rem .65rem .45rem}
  #page .ykw-text{line-height:clamp(17px,2.9vh,26px)}
  #page .answer-text{margin-bottom:.35rem;line-height:1.42}
  #page .ykw-head{font-size:min(5vw,2.3vh,1.3rem)}
  #page .q{margin-bottom:.25rem}
  #page .btn-replay{min-height:44px;padding:.35rem .8rem;font-size:.85rem}
  #page .btn-replay-sm{min-height:42px;font-size:.8rem}
  #page.revealed .plate{height:clamp(52px,9vh,96px)}
  #page .pager{gap:.5rem}
  #page .btn-page{min-height:50px}
}

/* A phone on its side is wide and short: 375px of height cannot stack a plate,
   a question, an answer AND a bonus fact at a size worth reading. So landscape
   lays them out sideways instead. Once the flap is up the plate steps aside
   entirely and the two pieces of writing sit next to each other, each getting
   the full height of the screen. */
@media (max-height:520px) and (orientation:landscape){
  #page .col{
    display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1fr);
    grid-template-rows:minmax(0,1fr) auto;
    grid-template-areas:'art words' 'nav nav';
    column-gap:clamp(.7rem,2.2vw,1.4rem);
  }
  #page .plate{grid-area:art;align-self:start;height:clamp(90px,46vh,190px);margin:0 0 .45rem}
  #page .q{grid-area:art;align-self:end;margin:0 0 .3rem;font-size:min(3.4vw,7vh,1.8rem)}
  #page .rule{grid-area:art;align-self:end;margin:0 0 .3rem}
  #page .guess{grid-area:art;align-self:end;margin:0 0 .4rem;font-size:min(1.9vw,4vh,1rem)}
  #page .btn-hear{grid-area:art;align-self:end;margin:0}
  #page .flapwrap{grid-area:words;margin:0;min-height:0}
  #page .pager{grid-area:nav;margin-top:.5rem}
  #page .btn-page{min-height:46px;padding:.45rem 1rem}

  /* revealed: the art has done its job, so it gets out of the way and the
     answer and the bonus fact run side by side */
  #page.revealed .col{grid-template-columns:minmax(0,1fr);grid-template-areas:'words' 'nav'}
  #page.revealed .plate,#page.revealed .q{display:none}
  #page.revealed .answer{
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    column-gap:.9rem;align-items:start;padding:.7rem .9rem;
  }
  #page.revealed .answer-text{margin:0 0 .5rem;font-size:min(1.9vw,4.4vh,1.12rem);line-height:1.4}
  #page.revealed #replayBtn{grid-column:1;align-self:start}
  #page.revealed .ykw{grid-column:2;grid-row:1 / span 2;margin:0;align-self:stretch}
  #page.revealed .ykw-text{font-size:min(1.9vw,4.2vh,1.1rem);line-height:clamp(18px,4.2vh,25px)}
}

/* ═══ STATS + GROWN-UPS ══════════════════════════════════════ */

/* the count is the headline: a stat tile, not a chart */
.stat-hero{margin:.6rem auto 1.6rem;text-align:center}
.stat-hero b{
  display:block;font-family:var(--display);font-weight:900;
  font-variation-settings:'SOFT' 40,'WONK' 1,'opsz' 144;
  font-size:min(34vw,9rem);line-height:.9;color:var(--board);
  font-variant-numeric:tabular-nums;
}
.stat-hero span{
  display:block;margin-top:.3rem;font-family:var(--read);
  font-size:1.1rem;font-weight:700;color:var(--board);opacity:.9;
}
.stat-h{
  margin:0 0 .6rem;font-size:.72rem;font-weight:800;letter-spacing:.18em;
  text-transform:uppercase;color:var(--board);opacity:.75;
}
.stat-note{margin:.6rem 0 0;font-family:var(--read);font-size:.92rem;color:var(--board);opacity:.8}
.stat-row{display:grid;grid-template-columns:1fr 1fr;gap:.8rem;margin-bottom:1.6rem}
.stat-tile{background:var(--board);border-radius:var(--card-r);padding:.9rem 1rem 1rem;box-shadow:0 4px 0 var(--board-3)}
.stat-tile .stat-h{color:var(--ink);opacity:.6}
.stat-big{
  margin:0;font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 60,'WONK' 1,'opsz' 72;
  font-size:2.4rem;line-height:1;color:var(--ink);font-variant-numeric:tabular-nums;
}

.fave{margin-bottom:1.7rem}
.fave-card{
  display:block;width:100%;padding:0;overflow:hidden;text-align:left;
  background:var(--board);border:none;border-radius:var(--card-r);cursor:pointer;
  box-shadow:0 5px 0 var(--board-3);font-family:inherit;
  transition:transform 120ms var(--ease-out),box-shadow 120ms var(--ease-out);
}
.fave-card:active{transform:translateY(3px);box-shadow:0 1px 0 var(--board-3)}
.fave-card img{display:block;width:100%;aspect-ratio:4/3;object-fit:cover}
.fave-body{display:block;padding:.85rem 1rem 1rem}
.fave-q{display:block;font-family:var(--display);font-weight:700;
  font-variation-settings:'SOFT' 60,'WONK' 1,'opsz' 48;
  font-size:1.25rem;line-height:1.15;color:var(--ink)}
.fave-n{display:block;margin-top:.3rem;font-family:var(--mono);font-size:.7rem;color:var(--ink-45)}

/* the collection: found whys are printed, the rest are blank plates waiting */
.collect{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(58px,1fr));gap:6px;
}
.collect li{aspect-ratio:4/3}
.collect button{
  display:block;width:100%;height:100%;padding:0;border:none;cursor:pointer;
  border-radius:5px;overflow:hidden;background:rgba(26,48,56,.22);
  transition:transform 120ms var(--ease-out),background-color 160ms ease;
}
.collect button:active{transform:scale(.9)}
.collect img{display:block;width:100%;height:100%;object-fit:cover}
.collect li.gap button{box-shadow:inset 0 0 0 1px rgba(239,233,218,.16);background:transparent}
/* seen but not lifted: a ghost of the plate, so a tap is never ignored */
.collect li.peek button{box-shadow:inset 0 0 0 1px rgba(239,233,218,.3)}
.collect li.peek img{opacity:.3;filter:saturate(.5)}
.collect li.gap button:active{background:rgba(239,233,218,.12)}
@media (hover:hover) and (pointer:fine){
  .collect li.gap button:hover{background:rgba(239,233,218,.08)}
}
/* they print in, one after another */
.collect li.got{animation:printIn 260ms var(--ease-out) both}
@keyframes printIn{from{opacity:0;transform:scale(.86)}to{opacity:1;transform:none}}

/* ── the PIN gate ─────────────────────────────────────────── */
.pin{max-width:340px;margin-inline:auto;text-align:center;padding-top:1.4rem}
.pin-h{margin:0 0 .3rem;font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 70,'WONK' 1,'opsz' 72;font-size:1.9rem;color:var(--board)}
.pin-sub{margin:0 0 1.4rem;font-family:var(--read);color:var(--board);opacity:.8}
.pin-dots{display:flex;justify-content:center;gap:.85rem;margin:0 0 .5rem;min-height:22px}
.pin-dots i{
  width:16px;height:16px;border-radius:50%;
  border:2px solid rgba(239,233,218,.55);background:transparent;
  transition:background-color 140ms var(--ease-out),transform 140ms var(--ease-out);
}
.pin-dots i.on{background:var(--board);border-color:var(--board);transform:scale(1.12)}
.pin-err{margin:0 0 1rem;min-height:1.3em;font-family:var(--read);font-size:.92rem;color:var(--board);opacity:0}
.pin-err.show{opacity:1}
.pin.shake{animation:shake 320ms var(--ease-out)}
@keyframes shake{0%,100%{transform:translateX(0)}22%{transform:translateX(-7px)}
  45%{transform:translateX(6px)}70%{transform:translateX(-3px)}}
.pad{display:grid;grid-template-columns:repeat(3,1fr);gap:.7rem}
.pad button{
  min-height:62px;font-family:var(--display);font-weight:700;
  font-variation-settings:'SOFT' 60,'WONK' 1,'opsz' 48;font-size:1.6rem;
  background:transparent;color:var(--board);
  border:2px solid rgba(239,233,218,.4);border-radius:12px;cursor:pointer;
  transition:background-color 140ms ease,transform 120ms var(--ease-out);
}
.pad button:active{transform:scale(.95);background:rgba(239,233,218,.16)}
.pad .wide{grid-column:span 2}

/* ── grown-up panel ───────────────────────────────────────── */
.pset{margin-bottom:1.9rem}
.pset-today{margin:0 0 .5rem;font-family:var(--read);color:var(--board)}
.pset-today b{font-family:var(--display);font-size:1.9rem;font-weight:800;
  font-variation-settings:'SOFT' 60,'WONK' 1,'opsz' 72;font-variant-numeric:tabular-nums}
.meter{height:10px;border-radius:999px;background:rgba(239,233,218,.2);overflow:hidden}
.meter span{display:block;height:100%;background:var(--board);border-radius:999px;
  transition:width 420ms var(--ease-out)}
.meter.over span{background:#F0B429}

.chips{display:flex;flex-wrap:wrap;gap:.5rem}
.chips button{
  min-height:46px;padding:.5rem 1rem;border-radius:999px;cursor:pointer;
  background:transparent;color:var(--board);border:2px solid rgba(239,233,218,.4);
  font-family:var(--read);font-size:.95rem;font-weight:700;
  transition:background-color 140ms ease,border-color 140ms ease,transform 120ms var(--ease-out);
}
.chips button:active{transform:scale(.96)}
.chips button[aria-pressed="true"]{background:var(--board);color:var(--ground-deep);border-color:var(--board)}

/* magnitude, so one hue light to dark — not the ten topic inks, which fail
   a colorblind-separation check when used as categories */
.chart{margin:0;display:grid;gap:7px}
.chart-row{display:grid;grid-template-columns:1fr;gap:3px}
.chart-top{display:flex;justify-content:space-between;align-items:baseline;gap:.6rem}
.chart-name{font-family:var(--read);font-size:.9rem;color:var(--board)}
.chart-val{font-family:var(--mono);font-size:.76rem;color:var(--board);opacity:.75;font-variant-numeric:tabular-nums}
.chart-track{height:10px;border-radius:0 5px 5px 0;background:rgba(239,233,218,.14)}
.chart-fill{display:block;height:100%;border-radius:0 5px 5px 0;background:var(--board);
  width:0;transition:width 520ms var(--ease-out)}

.toplist{list-style:none;margin:0;padding:0;display:grid;gap:.5rem}
.toplist li{display:flex;align-items:center;gap:.7rem;
  font-family:var(--read);font-size:.95rem;color:var(--board)}
.toplist img{width:52px;height:39px;object-fit:cover;border-radius:4px;flex:none}
.toplist b{margin-left:auto;font-family:var(--mono);font-size:.76rem;opacity:.75;font-variant-numeric:tabular-nums}

.btn-danger{
  width:100%;min-height:52px;padding:.8rem 1rem;cursor:pointer;
  background:transparent;color:var(--board);
  border:2px solid rgba(239,233,218,.45);border-radius:var(--card-r);
  font-family:var(--read);font-size:1rem;font-weight:700;
  transition:background-color 140ms ease,transform 120ms var(--ease-out);
}
.btn-danger:active{transform:scale(.98)}
.btn-danger.armed{background:#8E2C2C;border-color:#8E2C2C}

/* ── time is up ───────────────────────────────────────────── */
.curtain{
  position:fixed;inset:0;z-index:60;display:grid;place-items:center;
  background:var(--ink);padding:var(--pad);
}
.curtain-card{max-width:380px;text-align:center}
.curtain-card img{width:min(180px,44vw);height:auto;display:block;margin:0 auto 1rem}
.curtain-h{margin:0 0 .5rem;font-family:var(--display);font-weight:800;
  font-variation-settings:'SOFT' 80,'WONK' 1,'opsz' 96;font-size:2rem;color:var(--board)}
.curtain-p{margin:0 0 1.4rem;font-family:var(--read);font-size:1.05rem;color:var(--board);opacity:.85}

/* ── focus, always visible ──────────────────────────────────── */
:focus-visible{outline:3px solid var(--board);outline-offset:3px}
.answer :focus-visible,.tile:focus-visible,.btn-big:focus-visible{outline-color:var(--ink)}

/* ── wider screens: give the plate and the flap room ────────── */
@media (min-width:900px){
  body{font-size:18px}
  /* On a wide-but-short laptop a 4:3 plate at full column width eats the whole
     screen and pushes the flap out of sight — and the flap is the point of the
     book. Narrow the whole column by viewport height so the plate shrinks with
     it and everything keeps one shared left edge. */
  .col{max-width:min(720px,calc(44vh * 4 / 3))}
}

/* A short laptop window is the tightest case: cap the plate harder and tighten
   the vertical rhythm so the flap always shows above the fold. */
@media (min-width:900px) and (max-height:820px){
  .col{max-width:min(720px,calc(37vh * 4 / 3))}
  .plate{margin-bottom:.9rem}
  .q{margin-bottom:.55rem}
  .rule{margin-bottom:.8rem}
  .guess{margin-bottom:.7rem}
  .btn-hear{margin-bottom:1rem}
  .scroll{padding-top:.8rem}
}

/* a genuinely small window: shrink the plate further still */
@media (min-width:900px) and (max-height:720px){
  .col{max-width:min(720px,calc(30vh * 4 / 3))}
  .q{font-size:clamp(1.8rem,5vh,2.6rem)}
}

/* ── reduced motion: the flap crossfades instead of swinging ── */
/* Reduced motion means gentler, not none: movement goes, opacity and color
   stay so state changes still read as changes rather than as glitches. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms!important;animation-iteration-count:1!important;
    transition-property:opacity,color,background-color,border-color,fill!important;
    transition-duration:180ms!important;
  }
  .tile:active,.btn-big:active,.btn-hear:active,.btn-replay:active,
  .btn-page:active,.bar-btn:active,.cover-pip:active{transform:none}
  .flap{transition:opacity 200ms linear}
  .flapwrap.is-open .flap{transform:none;opacity:0}
  .ykw{transform:rotate(-1deg);opacity:0;transition:opacity 200ms linear 120ms}
  .flapwrap.is-open .ykw{opacity:1}
  .tiles li{animation:none!important;opacity:1!important}
}
