/* ==========================================================================
   Entity peek (.epk-*) — the hover "remind me" card (js/entity-peek.js)
   --------------------------------------------------------------------------
   One washi slip for bare KANJI glyphs (kanji-only, owner ruling 2026-07-03
   — word names already carry reading + gloss on every surface).

   (a) CONTENT — the card says what the character IS: the glyph, its
       meaning and the school mark (骨 the bones, owner ruling 2026-08-01).
       In KANJI mode only it adds the readings row, because the page prints
       no reading there (owner ruling 2026-08-06). js/entity-peek.js owns
       both rulings and argues each one.

   (b) MATERIAL — the slip is cut from the sentence glance's (round 4,
       14 October 2026: one stock, one dress, the content its own). The
       paper, the lit lip, the contact line and the left-thrown lift are the
       --slip-* stock in css/tokens.css, read here exactly as
       css/sentence-tokens.css reads them; only the shape is the card's own,
       a centred portrait where the glance reads as left-aligned lines. What
       the 2026-08-01 re-cut took off the slip stays off:
         · the 10px UI radius — the house's one earned box, .kjp-card, is 3px
         · the cool grey stroke, the OS-tooltip tell; and since round 4 the
           warm seating ring too: a lifted sheet is read by its lightness and
           the shadow under it, never by an outline
         · noise laid OVER the paper — the grain multiplies into the fibres
         · cold #2C2C2C ink — kanji-page.css moved off it deliberately
           because it "read as plastic" on warm paper
         · the translateY slide — paper does not slide. It is laid down, and
           the only thing that moves is the shadow settling as it lands

   pointer-events:none — the card is a whisper, never a surface. Sits under
   the 9999 play popover (they never coexist) and above the 9300 word panel.
   ========================================================================== */

.entity-peek {
  position: fixed;
  z-index: 9998;
  display: none;
  pointer-events: none;

  /* the pigment: pull the subject's own tone toward warm clay first (hue
     direction, never chroma), then soak the stock's paper 6%, the glance's
     mix (round 4; the peek soaked 8% into a darker paper before): a tint
     the eye feels, never sees */
  --slip-pigment: color-mix(in srgb, var(--slip-tone, #b0a090) 62%, #b0a090);
  background-color: color-mix(in srgb, var(--slip-paper, #FFFDF8) 94%, var(--slip-pigment) 6%);
  border: 0;
  border-radius: 3px;
  box-shadow: var(--slip-lip), var(--slip-contact), var(--slip-lift);

  min-width: 122px;
  max-width: 264px;
  padding: 15px 18px 14px;
  text-align: center;
  color: var(--slip-quiet, #6E6860);
  font: 400 12px/1.5 var(--font-ui);

  opacity: 0;
  transition: opacity 160ms ease;
}
/* the grain, MULTIPLIED into the fibres rather than laid over them */
.entity-peek::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background-image: var(--slip-grain);
  opacity: 0.05; mix-blend-mode: multiply; pointer-events: none;
}
/* THE LANDING — the slip arrives with its in-the-air shadow lit, and that
   shadow fades as it comes to rest. No transform: paper is laid down. */
.entity-peek::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: var(--slip-air); opacity: 1; pointer-events: none;
  transition: opacity var(--slip-land, 300ms) var(--ease-settle);
}
.entity-peek > * { position: relative; }
/* .epk-below survives as a POSITIONAL marker for js/entity-peek.js; with the
   slide gone it no longer carries a transform of its own. */
.entity-peek.epk-below { transform: none; }
.entity-peek.epk-in { opacity: 1; transition: opacity var(--slip-in, 190ms) var(--ease-page); }
.entity-peek.epk-in::after { opacity: 0; }

/* THE SCHOOL MARK — the corner note (js/entity-peek.js owns which label).
   Set in Klee, so it rhymes with the glyph above it instead of bringing a
   third typeface into the corner; faint-warm at the card's own quiet weight,
   never competing with the meaning. Selector carries the card so it outranks
   the `.entity-peek > * { position: relative }` stacking rule above.
   The card also gains a min-width: on a one-word card like 一 "one" the slip
   shrinks to about 76px, and a 2-character chip would have landed on top of
   the 46px glyph. */
.entity-peek .epk-grade {
  position: absolute;
  top: 9px;
  right: 11px;
  font: 400 10px/1 'Klee One', 'Noto Sans JP', serif;
  color: var(--slip-quiet, #6E6860);
  opacity: 0.72;
  letter-spacing: 0.02em;
  pointer-events: none;
  user-select: none;
}

/* ── the portrait: inked glyph, meaning, bones ──────────────────────────── */
.epk-k { display: block; }

/* the glyph IS the card. 46px against a 12.5px keyword is a real hierarchy;
   at the old 34px beside 13px type it read as one more data row — and as a
   1.4x echo of the very character the pointer was already resting on. The
   deboss pair is the drawer's, without its 26px bloom (a bloom smears here). */
.epk-glyph {
  display: block;
  margin: 0 0 11px;
  font: 400 46px/1.08 'Klee One', 'Noto Sans JP', sans-serif;
  color: var(--slip-ink, #3A3633);
  filter: drop-shadow(0 1px 0 rgba(255, 251, 243, .85))
          drop-shadow(0 -1px 0 rgba(58, 40, 20, .07));
}

/* the meaning, hung on the kanji page's own framing rules — dense at the
   words and fading to the margin (.hero .kw, css/kanji-page.css) */
/* OVERFLOW LAW (2026-08-01). This line used to be a bare flex row with
   `width: fit-content` and no max-width, so with the default `flex-wrap:
   nowrap` it could not wrap and simply grew past the card: 60 of 760 kanji
   spilled, worst case 士 "samurai · gentleman · professional" needing 307px
   of line. 192 kanji carry three senses and the longest keyword runs 39
   characters, so this was never an edge case.

   Two things fix it. The senses now live in their OWN box (.kwb) which wraps
   freely, while the framing rules stay flanking and vertically centred
   against however many lines it takes — so the device survives the fix. And
   the row is bounded by the card (max-width:100%), which is what lets the
   wrap happen at all.

   The framing was also eating the card: two 18px rules + two 9px gaps = 54px
   of a 200px inner width, 27% spent on decoration before a single letter.
   Trimmed to 14px rules and an 8px gap (44px), and the card widened 236→264,
   which takes the text budget from 146px to 184px. */
.epk-kw {
  display: flex;
  width: fit-content;
  max-width: 100%;          /* the bound that makes wrapping possible */
  margin: 0 auto;
  align-items: center;      /* rules centre against a 1- or 2-line meaning */
  gap: 8px;
  font: 500 12.5px/1.5 var(--font-ui);
  letter-spacing: 0.05em;
  color: var(--slip-ink, #3A3633);   /* the answer, in ink, as the glance's meaning is */
}
.epk-kw .kwb {
  min-width: 0;             /* a flex item will not shrink below content without this */
  text-wrap: balance;       /* a two-line meaning splits evenly, never 5 words + 1 */
  word-spacing: 0.06em;
}
.epk-kw::before, .epk-kw::after {
  content: ''; width: 14px; height: 1px; flex: 0 0 auto;
  background: linear-gradient(90deg, transparent,
              color-mix(in srgb, var(--slip-pigment) 52%, transparent));
}
.epk-kw::after {
  background: linear-gradient(90deg,
              color-mix(in srgb, var(--slip-pigment) 52%, transparent), transparent);
}
.epk-kw .s { white-space: nowrap; }          /* a sense never breaks mid-phrase */
.epk-kw .sep { margin-left: 0.42em; opacity: 0.6; }   /* rides with the sense it follows */

/* No parts block: the card is the glyph and its meaning (owner ruling
   2026-08-01 — see js/entity-peek.js for why each layer earned its removal),
   plus the readings row below in KANJI mode only (2026-08-06). A card is
   therefore one shape within a mode, and the slip never resizes under the
   pointer. */

/* ── the shared peek READINGS ROW (.kpk-*) — KanjiPage.readingsRowHTML ────
   This card prints it in kanji mode, and the 稽古 walk's own hover card
   (.kw-kxpeek) renders the same markup, so the block is styled once, here.
   One line per reading family; the tiny lowercase label carries the kun/on
   colour (kun = accent indigo, on = the kanji surfaces' terracotta token);
   kana rests in ink; romaji keeps the app-wide amber italic "how it sounds"
   voice. The lowercase labels are a dated owner ruling (2026-07-16) — do not
   "tidy" them to uppercase tags without the owner. ── */
.kpk { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; min-width: 0; }
.kpk-line, .kpk-ctx { display: flex; align-items: baseline; gap: 7px; white-space: nowrap; }
.kpk-lbl {
  font: 600 9.5px/1 var(--font-ui, Inter, sans-serif);
  letter-spacing: 0.04em;
  width: 24px;
  flex: 0 0 auto;
}
.kpk-lbl--kun { color: var(--color-accent); }
.kpk-lbl--on  { color: var(--color-kanji-on, #9E5E43); }
.kpk-rs { min-width: 0; }
.kpk [lang="ja"] { font: 400 13px/1.35 'Klee One', 'Noto Sans JP', sans-serif; color: var(--text-primary, #2C2C2C); }
.kpk-r { white-space: nowrap; }
.kpk-ro { font: italic 400 10px var(--font-ui, Inter, sans-serif); color: var(--color-amber-deep, #8A6E35); margin-left: 3px; }
.kpk-dot { font: 400 10px var(--font-ui, Inter, sans-serif); color: var(--color-faint-warm, #6E6860); opacity: 0.55; margin: 0 4px; }
/* the in-word lead: larger, its kana wears the family colour */
.kpk-ctx [lang="ja"] { font-size: 16px; }
.kpk-ctx--kun [lang="ja"] { color: var(--color-accent); }
.kpk-ctx--on  [lang="ja"] { color: var(--color-kanji-on, #9E5E43); }
/* the demoted tail — every other reading, one quiet line */
.kpk-also { font: 400 10.5px/1.5 var(--font-ui, Inter, sans-serif); color: var(--color-faint-warm, #6E6860); white-space: nowrap; }
.kpk-also [lang="ja"] { font-size: 12px; color: var(--color-stone, #57534e); }

@media (prefers-reduced-motion: reduce) {
  /* the end state must still LAND — an animation:none over an opacity:0 base
     is invisible forever (pinned by tests/css/hidden_reset_test.js) */
  .entity-peek { transition: opacity 120ms linear; }
  .entity-peek::after { opacity: 0; transition: none; }
  .entity-peek.epk-in { opacity: 1; }
}
