/* zine-read.css — the shared reading furniture that zine-read.js builds.
 *
 * Ships WITH the engine rather than being re-authored per surface. The whole point of the engine is
 * that a zine reads the same everywhere; a bookmark that is styled three times is a bookmark that
 * looks three ways by next quarter.
 *
 * Ported from demos/book-reader/reader.html (#ribbon / #ribbonGrip / #ribbonRead, ~126-176), which
 * remains the source of truth for how a zine reads. Only the ANCHOR changed: the reader pins the
 * ribbon to its fore-edge gutter (`--gutter`), which is a book-only thing, so here it hangs off the
 * right edge of whatever column the zine is in.
 *
 * House rules per DESIGN.md: flat solid offsets, never a blur or a gradient; Coral for the ribbon;
 * the hand face for the readout; 44px-class touch targets.
 *
 * NO @font-face HERE, on purpose. Both documents that link this file — demos/book-reader/reader.html
 * (served at "/") and src/app/z/[id]/render.ts — also link /brand-fonts.css, which is src/app/fonts.css
 * served byte-for-byte by src/app/brand-fonts.css/route.ts and is the ONE home of the @font-face
 * layer. A copy of it in here would be a second thing to keep in step with the licence boundary in
 * fonts.css's header, and this file is the shared engine precisely so there is only ever one of
 * anything. A third surface adopting the engine must link /brand-fonts.css too: font-display:swap
 * means a missing face has no error and no failing test, only the wrong typeface.
 */

.dr-rib,
.dr-ribgrip,
.dr-ribread { --dr-coral:#F75458; --dr-ink:#414D57; --dr-oats:#FEF6E4; --dr-lazuli:#2496C9; }

/* THE RIBBON. It GROWS as you read — the straight part lengthens while the notched tail stays
   crisp, because the tail is a fixed-size ::after rather than part of the stretched box. */
.dr-rib{
  position:absolute; z-index:9; top:-7px; right:14px;
  width:14px; height:30px; pointer-events:none;
  background:var(--dr-coral);
  box-shadow:inset -3px 0 0 rgba(0,0,0,.2), 1px 0 0 rgba(65,77,87,.4);
  transition:height .1s linear, opacity .35s ease, width .18s ease;
  will-change:height;
}
.dr-rib::after{
  content:""; position:absolute; left:0; right:0; bottom:-9px; height:10px;
  background:var(--dr-coral);
  clip-path:polygon(0 0,100% 0,100% 100%,50% 45%,0 100%);
}
/* While a finger is on it the ribbon must track EXACTLY. The .1s height ease that makes passive
   reading feel liquid reads as lag the moment someone is pulling the other end of it. */
.dr-scrubbing .dr-rib{transition:opacity .35s ease; width:19px;
  box-shadow:inset -4px 0 0 rgba(0,0,0,.26), 2px 0 0 rgba(65,77,87,.5);}

/* THE HANDLE: a rail down the ribbon's whole length PLUS a fat pad at the tail.
   Tail-pad-only was shipped first and was wrong: people reach for the ribbon, not for its last
   76px, and an invisible target you have to be told about is not a target — missing it does
   nothing, which reads as the control being broken. The rail stays narrow (34px) because it runs
   the full length and that is the part that costs page; the pad is generous because that is where
   a hand goes first and it only occupies one spot. The pad is a ::after so it hit-tests as part of
   the grip — no extra listeners, no second code path. Slack is asymmetric on purpose: more of it
   inboard over the page, since outboard is the screen edge where a thumb has nothing to press on. */
.dr-ribgrip{
  position:absolute; z-index:16; top:-7px; right:4px;
  width:34px; height:54px; cursor:grab; background:transparent;
  touch-action:none; -webkit-tap-highlight-color:transparent;
  -webkit-user-select:none; user-select:none;
}
.dr-ribgrip::after{content:""; position:absolute; left:-24px; right:-8px; bottom:-30px; height:80px;}
.dr-ribgrip:active,.dr-scrubbing .dr-ribgrip{cursor:grabbing;}
.dr-ribgrip:focus-visible{outline:3px solid var(--dr-lazuli); outline-offset:-2px; border-radius:8px;}
/* Answer a hovering cursor before the commit, so on desktop the thing is discoverable at all. */
.dr-ribgrip:hover ~ .dr-rib,
.dr-rib:hover{width:19px;}

/* WHERE YOU ARE, IN WORDS, pinned to the tail. A scrubber with no readout is a guess.
   BIRDIE, not the marker. "43% in" is a data label written on the tag of a bookmark — a neat hand
   printing a caption, which is Birdie's role in the brand (eyebrows, captions, data); the marker
   hand is for asides and coach marks, and this is neither. Patrick Hand stays second in the stack:
   it is what this readout looked like before 2026-09-03, and it carries the accented characters
   Birdie's 223 glyphs do not.
   Birdie sets these strings about a third wider. Nothing here constrains that — the chip is
   white-space:nowrap, absolutely positioned off the column's right edge, and grows leftward over a
   page it only covers while you are actively scrubbing.
   ITS TWIN MOVED IN THE SAME COMMIT. #ribbonRead in demos/book-reader/reader.html is this element
   in the book reader — same widget, two documents — and it is on that file's `--font-hand`, which
   is the same Birdie-then-Patrick-Hand stack spelled with a token. They are kept in step by hand
   because neither document can import the other; change one and change both, or the ribbon reads in
   two different hands depending on which reader you happened to open. */
.dr-ribread{
  position:absolute; z-index:17; right:36px; top:0; transform:translateY(-50%);
  font-family:"Birdie","Patrick Hand","Comic Sans MS",cursive; font-size:1.05rem; line-height:1;
  color:var(--dr-ink); background:var(--dr-oats);
  border:2px solid var(--dr-ink); border-radius:7px; padding:5px 9px 6px;
  box-shadow:3px 3px 0 var(--dr-ink);
  white-space:nowrap; opacity:0; pointer-events:none; transition:opacity .13s ease;
}
.dr-scrubbing .dr-ribread{opacity:1;}

@media (prefers-reduced-motion:reduce){
  .dr-rib{transition:none;}
}
