/* ==========================================================================
   Sentence tokens (.st-*) — an example sentence read as WORDS
   --------------------------------------------------------------------------
   Two surfaces, both cut from material the app already owns:

     THE LINE — the sentence keeps the 例文 dress exactly (.wp-ex-jp still sets
     the type). Tokens add NO resting decoration: a beginner's sentence would
     light up almost end to end, and a mark that fires everywhere says nothing
     (owner, 2026-08-02). Only two words ever carry ink — the one the page is
     about, and the one under the pointer.

     THE GLANCE — the same washi slip as the kanji peek, down to the pigment
     formula and the 3px PRINT corner, because it is the same gesture one tier
     over, and like that peek it holds no door: the app's ladder is
     hover = remind me · click = the panel, so the TOKEN's click opens the
     word's 図録 panel and the slip only ever says the reading and the meaning.

   KANA MODE gets word spacing — 分かち書き. Applied as margin BETWEEN tokens,
   never as literal spaces in the text, so a copied sentence stays the sentence
   and no gap opens before the full stop.
   ========================================================================== */

/* ── the line ────────────────────────────────────────────────────────────── */

.st-tk {
  border-radius: 2px;
  /* the reading rides above the line; a background must not crowd it */
  padding: 0 0.02em;
  transition: background-color 140ms var(--ease-page, ease),
              box-shadow 140ms var(--ease-page, ease);
}
.st-tk:not(.st-tk--inert) { cursor: pointer; }

/* the word the page is ABOUT — the reason this sentence is on the page.
   A hairline seat under the word, never a highlight over it: the sentence
   stays a sentence and the ruby above stays legible. */
.st-tk--target {
  box-shadow: inset 0 -2px 0 -1px rgba(61, 90, 128, 0.42);
}

/* under the pointer / open. Warm paper-shadow rather than a selection blue —
   the word is being LIFTED off the page, not selected in a text field.

   ⛔ :hover is GATED on hover capability, on exactly the query the JS uses
   (`HOVER_OK`, js/sentence-tokens.js). Ungated, CSS and JS disagreed about what
   a touch device is: iPad — a PRIMARY device on the desktop product — leaves
   :hover latched on the last thing tapped, so a word the learner had already
   closed went on wearing the OPEN tint. `.is-open` is the honest signal there
   and stays ungated: it is set and cleared by the glance itself. */
.st-tk.is-open {
  background-color: rgba(201, 169, 110, 0.16);
}
@media (hover: hover) and (pointer: fine) {
  .st-tk:not(.st-tk--inert):hover {
    background-color: rgba(201, 169, 110, 0.16);
  }
}
.st-tk.is-open { box-shadow: inset 0 -2px 0 -1px rgba(201, 169, 110, 0.85); }

.st-tk:focus-visible {
  outline: 2px solid var(--color-indigo, #3D5A80);
  outline-offset: 1px;
}

/* a kanji door inside a token keeps travelling — the word owns the glance,
   the character still owns its page. Nothing to restyle; just never let the
   token's own hover erase the door's affordance. */
.st-tk .wp-kt { border-radius: 2px; }

/* (the 分かち書き spaced-kana rule left with the kana display mode,
   2026-08-20 — no renderer emits .st-line--spaced any more) */

/* ── the invitation ──────────────────────────────────────────────────────── */

/* Said once per BLOCK — never per word — in the section head, and removed
   outright the first time a word is ever tapped (retireInvite). The DRESS is
   each surface's own: the word page and its panel whisper it in the romaji
   italic, the kanji page in its own label voice. All three share only this —
   the line never breaks in two. */
.st-invite { white-space: nowrap; }

/* ── the glance ──────────────────────────────────────────────────────────── */

/* A SLIP OF WASHI laid over the page — the word lifted out of the sentence for
   a moment. The first cut of this claimed the kanji peek's material in a
   comment and then delivered a flat panel with a grey hairline round it: the
   pigment was mixed at 8% (invisible), the grain sat at 0.05 (below threshold
   at this size), and nothing landed. What follows actually pays for the claim.
   Everything here is the house's own token — no new colour enters. */
.st-glance {
  position: fixed;
  z-index: 9998;              /* the peek's tier: under the 9999 play popover */
  display: none;
  max-width: 238px;           /* the house slip is 196px; a gloss needs a little more */
  min-width: 124px;
  padding: 16px 20px 17px;

  --slip-pigment: color-mix(in srgb, var(--slip-tone, #b0a090) 62%, #b0a090);
  background-color: color-mix(in srgb, var(--slip-paper, #FAF7EF) 88%, var(--slip-pigment) 12%);
  border: 0;
  border-radius: 3px;         /* a PRINT corner, not a 10px UI radius */
  /* thickness, not an outline: a lit top lip and a warm seating ring. The old
     rgba(96,80,60,.075) ring read as a cool grey stroke around a box this
     size — the OS-tooltip tell the kanji peek warns about by name. */
  box-shadow:
    inset 0 1px 0 rgba(255, 252, 246, 0.78),
    0 0 0 1px rgba(124, 100, 68, 0.10),
    var(--slip-rest);

  color: var(--slip-quiet, #6E6860);
  font: 400 12px/1.55 var(--font-ui);
  opacity: 0;
  transition: opacity 160ms ease;
}
.st-glance.is-open { display: block; opacity: 1; }

/* the grain, MULTIPLIED into the fibres rather than laid over them */
.st-glance::before {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  background-image: var(--slip-grain);
  opacity: 0.09; mix-blend-mode: multiply; pointer-events: none;
}
/* THE LANDING — the house signature. The slip arrives with its in-the-air
   shadow lit and that shadow fades as it comes to rest. No transform: paper
   is not slid across a surface, it is laid down. */
.st-glance::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, ease);
}
.st-glance.is-open::after { opacity: 0; }
.st-glance > * { position: relative; }

/* THE COMPOSITION IS A STAMP, NOT A DOCUMENT.  Measured against the house's
   own slip (the kanji peek, the one card the owner calls beautiful): that card
   is CENTRED and symmetrical, its subject is huge and owns the space, and its
   meaning sits beneath a flank of hairline rules. The first cut of this glance
   was a left-aligned document with a full-width divider — a different species
   of object sharing a colour palette. Centred here too, so the two cards read
   as one family seen at two tiers. */

/* the WORD — the subject, and sized like it */
.st-g-word {
  font-family: 'Klee One', 'Noto Sans JP', sans-serif;
  font-size: 28px;
  line-height: 1.28;
  color: var(--color-ink, #2C2C2C);
  text-align: center;
}
/* a long word must not force the card wider than its measure */
.st-g-word--long { font-size: 22px; }
/* the reading rides CLOSE to its kanji; loose ruby left the top airy while
   the bottom stayed dense */
.st-g-word rt {
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 10px;
  line-height: 1.1;
  color: var(--slip-quiet, #6E6860);
}
/* the sound — one quiet line under the word, in the romaji voice this app
   uses everywhere: italic, never a heading */
.st-g-ro {
  margin-top: 4px;
  text-align: center;
  font-style: italic;
  font-size: 12px;
  letter-spacing: 0.03em;
  color: var(--slip-quiet, #6E6860);
}
/* the reading spelled out — only in kanji mode, where the word hides it */
.st-g-read {
  margin-top: 4px;
  text-align: center;
  font-family: 'Noto Sans JP', sans-serif;
  font-size: 12.5px;
  color: var(--slip-quiet, #6E6860);
}
/* identity above, meaning below. A SHORT centred rule rather than a full-width
   divider: the peek flanks its meaning with hairlines, and a flank cannot
   survive text that wraps — this keeps the gesture and loses the fragility. */
.st-g-en,
.st-g-none {
  position: relative;
  margin-top: 15px;
  padding-top: 15px;
  text-align: center;
}
.st-g-en::before,
.st-g-none::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 26px;
  height: 1px;
  background: rgba(124, 100, 68, 0.22);
}
.st-g-en {
  font-size: 13.5px;
  line-height: 1.5;
  color: #44403c;             /* the word page's own body ink */
}
/* a word with no gloss at all — kept quiet, never an apology */
.st-g-none {
  font-style: italic;
  font-size: 12px;
  color: var(--slip-quiet, #6E6860);
}

@media (prefers-reduced-motion: reduce) {
  .st-tk, .st-glance, .st-glance::after { transition: none; }
  .st-glance::after { opacity: 0; }   /* Reduce Motion must LAND the end state */
}

/* ── R1 S2 — the cloze GAP + the scaffold's pre-explanation ──────────────── */

/* The gap (design §5.5): a due word seated for the BUILD is veiled as a slot,
   and the word's English gloss stands IN the slot — the cue, printed where
   the answer will land. Indigo dashes = interactive, the locked inline
   language; the gloss is quiet EN italic, unmistakably not Japanese. */
.st-gap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 3.2em;
  padding: 0 0.45em;
  border-bottom: 2px dashed rgba(61, 90, 128, 0.55);
  border-radius: 2px;
}
.st-gap i {
  font: italic 400 0.56em var(--font-ui, 'Inter', sans-serif);
  color: var(--color-stone, #57534e);
  letter-spacing: 0.01em;
  white-space: nowrap;
  max-width: 11em;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* The scaffold (design §5.1, the inversion's other half): a never-met word
   arrives PRE-EXPLAINED — its reading rides above as ruby in every written
   mode (a lesson is not a test), and romaji + gloss stand in a small stack
   under the word, printed free. Quiet on purpose: the lesson is a gift,
   the sentence stays the subject. */
/* THE SEAT (2026-09-16). The first cut hung the note OUT of layout
   (position:absolute, one nowrap line centred under the word) so the
   sentence's typography stayed untouched, and three never-met words in a
   row (もっとゆっくり話してください) printed "yukkuri slowly / hanashite to
   speak / kudasai to give" on top of each other: an absolute note knows
   nothing of its neighbour, and a note wider than its word overhangs both
   sides. Two traps had already ruled out the obvious in-flow dresses: a
   flex column split the token's ruby run and trailing kana into stacked
   pieces (分かりません in three), and inline-block lifted the word off the
   line's baseline (an inline-block's baseline is its LAST line's, i.e. the
   note's). So the seat is the third dress: the token is an INLINE GRID whose
   first row is the word (one wrapper, .st-w, so ruby + kana stay one piece)
   and whose second row is the note. A grid's first baseline is its FIRST
   row's, so the word stays on the line with its neighbours; the note is IN
   flow, so it can never cross a neighbour's; and it stacks romaji OVER gloss
   (the "small stack" the design asked for), which keeps it narrower than
   its word nearly always. When it is not, the word gains exactly the
   overhang on each side and the sentence spaces itself — a beginner's
   分かち書き — instead of printing two notes on one spot. The line box grows
   by the note's height on a scaffolded line; that is the honest cost, paid
   where the lesson is, never on a sentence without one. */
.st-tk--scaffold {
  display: inline-grid;
  justify-items: center;
  vertical-align: baseline;
}
.st-sc {
  display: grid;
  justify-items: center;
  row-gap: 1px;
  line-height: 1;
  /* the note rides up into the line's slack under the word, where the
     hanging note used to sit; the word row keeps the line's own leading */
  margin-top: -0.55em;
  /* a gutter that only bites when the note is the wider row: two
     neighbours' notes wider than their words would otherwise print edge
     to edge ("to look at carefullyto speak"); a note narrower than its
     word costs the sentence nothing */
  padding: 0 0.3em;
  text-align: center;
}
.st-sc-ro {
  font: italic 400 0.5em var(--font-ui, 'Inter', sans-serif);
  color: var(--color-faint-warm, #8a8378);
  white-space: nowrap;
}
.st-sc-en {
  font: 400 0.52em var(--font-ui, 'Inter', sans-serif);
  line-height: 1.15;
  color: var(--color-stone, #57534e);
  /* a long cue WRAPS — never clips (a beginner reads the whole cue) and
     never widens the sentence past this. ⚠ this em is the gloss's OWN
     0.52em, not the sentence's: 10em ≈ 125px under the walk's 1.5rem line,
     about five characters of sentence — the most a note may ask of it */
  max-width: 10em;
}

/* THE WORD KEEPS ITS DRESSES; THE NOTE WEARS NONE. The token's box now holds
   the note, so its hover wash, open seat and focus ring would paint a three-
   row chip and seat the hairline under the English (the review that caught
   it: 2026-09-16). The file's own law is "a hairline seat under the word,
   never a highlight over it" — so on a scaffold the three dresses move to
   .st-wi, the inline word inside the row, whose painted box is the font's
   content area: the same box a plain neighbour paints. Same guards as the
   originals: the hover half stays behind the hover-capability query (the
   iPad latched-hover law above). Later in the file + equal or higher
   specificity, so these win. */
.st-tk--scaffold:not(.st-tk--inert):hover,
.st-tk--scaffold.is-open { background-color: transparent; box-shadow: none; }
.st-tk--scaffold:focus-visible { outline: none; }
.st-wi {
  border-radius: 2px;
  transition: background-color 140ms var(--ease-page, ease),
              box-shadow 140ms var(--ease-page, ease);
}
.st-tk--scaffold.is-open .st-wi {
  background-color: rgba(201, 169, 110, 0.16);
  box-shadow: inset 0 -2px 0 -1px rgba(201, 169, 110, 0.85);
}
.st-tk--scaffold:focus-visible .st-wi {
  outline: 2px solid var(--color-indigo, #3D5A80);
  outline-offset: 1px;
}
@media (hover: hover) and (pointer: fine) {
  .st-tk--scaffold:not(.st-tk--inert):hover .st-wi {
    background-color: rgba(201, 169, 110, 0.16);
  }
}
@media (prefers-reduced-motion: reduce) { .st-wi { transition: none; } }

/* A NOTE WIDER THAN ITS WORD must not open paper between the word and the
   mark or particle that closes on it — the file's own law says no gap opens
   before the full stop, and 分かち書き glues a particle to its word. When the
   next token is punctuation or a particle the word pins to the column's END
   and the whole overhang falls BEFORE the word, where a beginner's text puts
   its spaces anyway. The note pins with it — word and note share a right
   edge, so a wide note still reads as THIS word's, not as a caption under
   the space before it. */
.st-tk--scaffold:has(+ .st-tk--punct),
.st-tk--scaffold:has(+ .st-tk[data-st-pid$="Particle"]) { justify-items: end; }
.st-tk--scaffold:has(+ .st-tk--punct) .st-sc,
.st-tk--scaffold:has(+ .st-tk[data-st-pid$="Particle"]) .st-sc {
  justify-items: end;
  text-align: right;
}
