/* Word Detail Styles */

.word-detail-card {
    border-radius: 0.75rem;
    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1);
    border: none;
    padding: 2rem;
}

.word-main h1 {
    font-size: 3.5rem;
    /* Large Thai Text */
    line-height: 1.2;
    margin-bottom: 0.5rem;
    color: var(--ink);
}

@media (max-width: 768px){
    .word-main h1 {
        font-size: 2.5rem;
    }
}

.word-romanization .romanization {
    color: var(--color-primary);
    font-weight: 600;
    font-size: 1.25rem;
    font-family: var(--font-family-romanization);
}

.word-romanization .ipa {
    color: var(--ink-faint);
    margin-left: 0.5rem;
    cursor: help;
}

.tone-info {
    font-family: monospace;
    color: var(--ink-muted);
}

/* Audio Speed Buttons.
   The circle itself is the shared `.action-circle` control (assets/css/tailwind/
   input.css): white with a slate border and glyph, a slate wash on hover, and
   emerald + a pulsing ring while playing. Only the JS-driven states and the
   "½" label live here — the gold hover that used to override the circle is
   gone, so the button reads like every other control on the page. */
.audio-speed-btn {
    position: relative;
    transition: all 0.2s;
}

.audio-speed-btn .slow-label {
    font-size: 0.6rem;
    font-weight: 700;
    position: absolute;
    bottom: 4px;
    right: 6px;
    line-height: 1;
    color: var(--ink-faint);
}

.audio-speed-btn .bi-play-fill {
    font-size: 1.1rem;
}

.audio-speed-btn:hover .slow-label {
    color: var(--ink-label);
}

.audio-speed-btn.playing .slow-label {
    color: var(--color-primary);
}

.audio-speed-btn.loading {
    opacity: 0.6;
    pointer-events: none;
}

.audio-speed-btn.disabled {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: none;
}

.audio-speed-btn.no-audio {
    animation: shake 0.3s ease;
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    25% { transform: translateX(-3px); }
    75% { transform: translateX(3px); }
}

/* Action Buttons */
.ui-btn-icon {
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    background: var(--surface-hover);
    border: none;
    border-radius: 0.5rem;
    transition: background 0.2s;
    color: var(--ink-label);
    text-decoration: none;
}

.ui-btn-icon:hover {
    background: var(--surface-active);
    color: var(--ink);
}

/* Sections */
.definition-main {
    font-size: 1.25rem;
    color: var(--ink);
}

.definition-extended,
.word-usage p,
.word-cultural p {
    color: var(--ink-muted);
    line-height: 1.7;
}

.word-usage,
.word-cultural {
    margin-top: 1.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--border);
}

h3 {
    font-size: 0.875rem;
    color: var(--ink-faint);
    text-transform: uppercase;
    font-weight: 600;
    margin-bottom: 0.5rem;
}

/* Examples */


.example-card .thai-text {
    font-size: 1.25rem;
    margin-bottom: 0.5rem;
    display: block;
}

.example-card .romanization {
    color: var(--ink-faint);
    font-size: 0.875rem;
    margin-bottom: 0.25rem;
    display: block;
}







/* Word Meta Badge Alignment */
.word-meta .ui-badge {
    display: inline-flex;
    align-items: center;
    height: 28px;
    line-height: 1;
}

/* Tag Link Hover Effects */
.tag-link .ui-badge {
    transition: all 0.2s ease;
    transform: translateY(0);
}

.tag-link:hover .ui-badge {
    transform: translateY(-2px);
    box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
    filter: brightness(1.1);
}

/* Lesson Card Hover Effects */
.lesson-card {
    transition: all 0.2s ease;
    display: block;
}

.lesson-card .ui-card {
    transition: all 0.2s ease;
}

.lesson-card:hover .ui-card {
    transform: translateY(-4px);
    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
}

.lesson-card:hover {
    text-decoration: none;
}

/* Letter inspection ------------------------------------------------------- */

/* The headword is a sequence of CLUSTERS: one base character plus the
   combining marks the font draws on it (รี, รู้, รั้). Each cluster is emitted
   as ONE text node and that is load-bearing — marks only keep their
   mark-to-base placement (GPOS) while the cluster shapes as a single text run.
   A span per character split the run, so every mark was painted at its solo
   altitude: a stacked pair (ั + ้) collapsed onto itself and the tone dropped
   onto the vowel. The click targets below are OUT-OF-FLOW bands, so they add
   boxes without adding inline content and the run stays whole.

   Both states share this markup; every rule is scoped by
   .letter-inspection-on, so until the reader turns the toggle on the heading
   reads as plain text. */
.letter-inspection-on .word-letter-cluster {
    position: relative;
    /* Opens the word up while the mode is on: adjacent bases stop touching, so
       the pointer lands on the character the reader means. The gap must be
       letter-spacing inside the run — never margin, padding, a gap element or
       an inline-block. The shaper distributes letter-spacing over the run, so
       the glyphs keep their painted positions (ั + ้ still stack, ำ still
       paints its ring once); each of those alternatives splits the run and
       fuses the marks. The extra advance lands AFTER the cluster, so there is
       no leading gap and none at a wrapped line's start. */
    letter-spacing: 0.14em;
}

/* Every band is measured at runtime by letter-inspection.js: the script
   rasterizes the word's shaped prefixes (the same HarfBuzz shaping the DOM run
   uses) and pixel-diffs consecutive prefixes, so each band lands exactly on the
   pixels ITS character paints — however the font positions that ink (stacked
   ั+้, a tone lowered after ื or ึ, ็ riding high, ำ gluing into the previous
   base). Fixed per-class zones cannot do that: a tone paints at a different
   height over every base, so any static zone either floats above the ink or
   swallows a neighbour, which is what made อ้ land on อั.

   The band IS the box: absolutely positioned inside its cluster, so it is out
   of flow and cannot reflow the word or move a glyph. The four custom
   properties are em units relative to the CLUSTER box, which starts at the
   first character's pen origin: --li-bx/--li-bw horizontal, --li-by/--li-bh
   vertical from the cluster box top. Defaults keep an unpainted but clickable
   fallback should the measurer fail (e.g. canvas blocked). */
.letter-inspection-on .word-letter[data-letter] {
    position: absolute;
    left: var(--li-bx, -0.05em);
    width: var(--li-bw, 1.05em);
    top: var(--li-by, 0em);
    height: var(--li-bh, 1.2em);
    border-radius: 0.25rem;
    cursor: pointer;
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

/* Bands overlap, and only their z-index decides who gets the pointer:
   letter-inspection.js ranks them (see rankBands) — earlier line first, then
   the smaller box, so a tone mark keeps its own column even where ำ's
   one-rectangle box for ring + า body covers it. No z-index is set here: before
   the script runs, DOM order is the same answer it always gave. */

.letter-inspection-on .word-letter[data-letter]:hover,
.letter-inspection-on .word-letter[data-letter]:focus-visible {
    background-color: rgb(33 150 243 / 0.16);
    box-shadow: 0 0 0 2px rgb(33 150 243 / 0.55);
}

/* One block per letter is pre-rendered inside #letterModal; the script reveals
   the clicked one, so the combining-mark carrier stays server-side.

   The dialog reads top to bottom as the questions a learner asks: glyph and
   name, the sound at the start of a syllable, the sound at the end (with a
   worked example), where the name comes from, and the rest of the class in its
   class colour. Every colour comes from the alphabet tokens so the class tint
   is the same one the alphabet pages use, in both themes. */
.letter-peek-dialog > .modal-dialog {
    max-width: min(34rem, calc(100vw - 2rem));
}

/* A letter with a long description or two example words can be taller than the
   viewport, so the body scrolls inside the dialog instead of pushing the
   footer out of reach. */
.letter-peek-dialog .modal-body {
    overflow-y: auto;
}

.letter-peek__hero {
    display: flex;
    align-items: center;
    gap: 0.875rem;
}

.letter-peek__glyph {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 4.25rem;
    height: 4.25rem;
    border: 1px solid var(--border);
    border-radius: 0.875rem;
    background: rgb(148 163 184 / 0.1);
    color: var(--ink);
    font-size: 2.5rem;
    line-height: 1;
}

.letter-peek__glyph.class-mid {
    border-color: var(--alphabet-mid-border);
    background: var(--alphabet-mid-surface);
    color: var(--alphabet-mid-ink);
}

.letter-peek__glyph.class-high {
    border-color: var(--alphabet-high-border);
    background: var(--alphabet-high-surface);
    color: var(--alphabet-high-ink);
}

.letter-peek__glyph.class-low {
    border-color: var(--alphabet-low-border);
    background: var(--alphabet-low-surface);
    color: var(--alphabet-low-ink);
}

.letter-peek__identity {
    min-width: 0;
}

.letter-peek__name {
    margin: 0;
    color: var(--ink);
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.3;
}

.letter-peek__thai-name {
    margin: 0.1rem 0 0;
    color: var(--ink-muted);
    font-size: 1rem;
    line-height: 1.5;
}

.letter-peek__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin: 0.4rem 0 0;
}

.letter-peek__chip {
    display: inline-flex;
    align-items: center;
    height: 1.375rem;
    padding: 0 0.5rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--ink-muted);
    font-size: 0.75rem;
    font-weight: 600;
    white-space: nowrap;
}

.letter-peek__chip.class-mid {
    border-color: var(--alphabet-mid-border);
    background: var(--alphabet-mid-surface);
    color: var(--alphabet-mid-ink);
}

.letter-peek__chip.class-high {
    border-color: var(--alphabet-high-border);
    background: var(--alphabet-high-surface);
    color: var(--alphabet-high-ink);
}

.letter-peek__chip.class-low {
    border-color: var(--alphabet-low-border);
    background: var(--alphabet-low-surface);
    color: var(--alphabet-low-ink);
}

/* The listen button is the word page's own `.action-circle`, parked on the
   hero's baseline instead of floating after the Thai name. */
.letter-peek__audio {
    margin-left: auto;
    flex: 0 0 auto;
}

.letter-peek__rows {
    display: grid;
    gap: 0.75rem;
    margin-top: 1rem;
}

.letter-peek__row {
    display: grid;
    gap: 0.1rem;
}

.letter-peek__label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    color: var(--ink-muted);
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.letter-peek__value {
    color: var(--ink);
    font-size: 1rem;
    font-weight: 600;
}

.letter-peek__ipa {
    color: var(--ink-muted);
    font-weight: 500;
}

.letter-peek__note {
    color: var(--ink-muted);
    font-size: 0.8125rem;
    line-height: 1.5;
}

.letter-peek__examples {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.2rem;
}

/* Each example is its own chip: two words in a row of plain text read as one
   phrase, and the point here is that they are two separate closing sounds. */
.letter-peek__example {
    padding: 0.1rem 0.45rem;
    border: 1px solid var(--border);
    border-radius: 0.4rem;
    color: var(--ink-muted);
    font-size: 0.8125rem;
    line-height: 1.6;
}

.letter-peek__example .thai-text {
    color: var(--ink);
    font-size: 1rem;
}

/* The "i" is a real button: it opens the explanation under the row, so touch
   and keyboard get the same text a hover tooltip would only tease. */
.letter-peek__info {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.0625rem;
    height: 1.0625rem;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: transparent;
    color: var(--ink-muted);
    font-family: Georgia, "Times New Roman", serif;
    font-size: 0.6875rem;
    font-style: italic;
    font-weight: 700;
    line-height: 1;
    cursor: pointer;
    text-transform: none;
    letter-spacing: 0;
}

.letter-peek__info:hover,
.letter-peek__info:focus-visible {
    border-color: var(--ink-muted);
    color: var(--ink);
}

.letter-peek__info[aria-expanded="true"] {
    border-color: var(--ink-muted);
    background: var(--ink-muted);
    color: var(--surface);
}

.letter-peek__help {
    margin-top: 0.4rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 0.5rem;
    background: rgb(148 163 184 / 0.08);
    color: var(--ink);
    font-size: 0.8125rem;
    line-height: 1.55;
}

.letter-peek__help p {
    margin: 0;
}

.letter-peek__finals {
    display: grid;
    gap: 0.25rem 0.6rem;
    margin: 0.6rem 0 0;
    padding: 0;
    list-style: none;
    /* Two columns when there is room, one when the dialog is phone-wide. */
    grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
}

.letter-peek__final {
    display: flex;
    gap: 0.4rem;
    align-items: baseline;
    padding: 0.15rem 0.4rem;
    border-radius: 0.35rem;
    color: var(--ink-muted);
    font-size: 0.75rem;
    line-height: 1.6;
}

.letter-peek__final.is-current {
    background: var(--letter-peek-tint, rgb(148 163 184 / 0.16));
    color: var(--ink);
}

.letter-peek[data-letter-class="mid"] {
    --letter-peek-tint: var(--alphabet-mid-surface);
}

.letter-peek[data-letter-class="high"] {
    --letter-peek-tint: var(--alphabet-high-surface);
}

.letter-peek[data-letter-class="low"] {
    --letter-peek-tint: var(--alphabet-low-surface);
}

.letter-peek__final-key {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.letter-peek__help-title {
    margin-bottom: 0.2rem !important;
    font-weight: 700;
}

.letter-peek__block {
    margin-top: 1rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border);
}

.letter-peek__mnemonic {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.2rem 0.5rem;
    margin: 0.3rem 0 0.25rem;
}

.letter-peek__mnemonic .thai-text {
    color: var(--ink);
    font-size: 1.375rem;
    line-height: 1.4;
}

.letter-peek__mnemonic-meaning {
    color: var(--ink-muted);
    font-size: 1rem;
}

.letter-peek__dot {
    margin-right: 0.4rem;
}

.letter-peek__mnemonic-link {
    display: inline-block;
    margin-top: 0.35rem;
    color: var(--ink-muted);
    font-size: 0.8125rem;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.letter-peek__mnemonic-link:hover,
.letter-peek__mnemonic-link:focus-visible {
    color: var(--ink);
}

.letter-peek__description {
    margin-top: 0.75rem;
}

.letter-peek__class {
    margin-top: 1rem;
    padding-top: 0.875rem;
    border-top: 1px solid var(--border);
}

.letter-peek__count {
    color: var(--ink-muted);
    font-weight: 600;
}

.letter-peek__class-letters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    margin: 0.4rem 0 0;
}

.letter-peek__class-letter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.75rem;
    height: 1.75rem;
    padding: 0 0.3rem;
    border: 1px solid transparent;
    border-radius: 0.5rem;
    font-size: 1.125rem;
    line-height: 1;
}

.letter-peek__class-letter.class-mid {
    background: var(--alphabet-mid-surface);
    color: var(--alphabet-mid-ink);
}

.letter-peek__class-letter.class-high {
    background: var(--alphabet-high-surface);
    color: var(--alphabet-high-ink);
}

.letter-peek__class-letter.class-low {
    background: var(--alphabet-low-surface);
    color: var(--alphabet-low-ink);
}

.letter-peek__class-letter.is-current {
    border-color: currentColor;
    font-weight: 700;
}


/* Letter inspection — the "on" treatment.
   A dashed frame names the mode so a reader never has to infer it from the
   pressed toggle alone. The frame's padding and border are reserved in both
   states (a transparent border still occupies its 1.5px), so switching the
   mode paints the border instead of moving the word under the cursor. */
.word-thai-frame {
    --word-frame-gutter: 18px;
    --word-frame-line: 1.5px;
    /* What the frame actually adds to the left of the glyphs: the gutter plus
       the border, which is laid out in whole pixels — the 1.5px above occupies
       1px. Cancelling exactly this much lands the first glyph on the card's text
       column, and keeps the headword on the same pixel grid as the rows below. */
    --word-frame-inset: calc(var(--word-frame-gutter) + 1px);
    position: relative;
    display: inline-block;
    max-width: 100%;
    /* Bottom padding clears a ุ ู band, which reaches below the line box. */
    padding: 16px var(--word-frame-gutter) 12px;
    border: var(--word-frame-line) dashed transparent;
    border-radius: 14px;
    /* The gutter is decoration around the word, not indentation. Shift the
       painted box left by the inset, so the headword starts on the column the
       romanization, badges and definition below share — without changing the
       box's width (a negative margin would shrink the shrink-to-fit frame and
       wrap a headword that fits on one line today) and without reflowing
       anything when the mode is toggled. */
    left: calc(-1 * var(--word-frame-inset));
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.letter-inspection-on .word-thai-frame,
.word-thai-frame.letter-inspection-on {
    border-color: rgba(16, 185, 129, 0.5);
    background: rgba(16, 185, 129, 0.05);
}

.word-thai-badge {
    position: absolute;
    top: -9px;
    left: 14px;
    display: none;
    padding: 1px 8px;
    border-radius: 999px;
    background: #059669;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    white-space: nowrap;
}

.word-thai-frame.letter-inspection-on .word-thai-badge {
    display: inline-block;
}

/* One line, always: turning the mode on widens the headword and squeezes this
   row, and a wrapped label would make the button 38px tall one state and 58px
   the other. */
.letter-inspection-toggle {
    white-space: nowrap;
}

/* The dialog explains the letter, not just names it: a silence marker that
   shows only a dash and "Special Character" tells a learner nothing. */
.letter-peek__description {
    margin: 0.75rem 0 0;
    color: var(--ink-muted);
}
