/**
 * Letter Practice Widget - Styles
 *
 * Pre-spelling letter identification: one big target (or speaker), a short
 * row of large letter tiles. Fleet-blue theme, static frame (fixed-height
 * stimulus + tiles + countdown zones — zero layout shift between states).
 *
 * @package Aphasia_Exercises
 * @since 1.7.515
 */

/* =========================================================================
   1. CSS CUSTOM PROPERTIES
   ========================================================================= */

.letter-practice-root {
    /* Fleet blue (matches naming/listening/spelling primaries) */
    --lp-primary: #3b82f6;
    --lp-primary-dark: #2563eb;
    --lp-primary-light: #eff6ff;
    --lp-success: #22c55e;
    --lp-success-dark: #16a34a;
    --lp-success-light: #f0fdf4;
    --lp-error: #ef4444;
    --lp-error-light: #fef2f2;
    --lp-hint: #ca8a04;
    --lp-hint-light: #fef3c7;

    --lp-neutral-50: #f9fafb;
    --lp-neutral-100: #f3f4f6;
    --lp-neutral-200: #e5e7eb;
    --lp-neutral-300: #d1d5db;
    --lp-neutral-500: #6b7280;
    --lp-neutral-700: #374151;
    --lp-neutral-800: #1f2937;

    --lp-font: var(--as-font);
    --lp-radius-xl: 16px;
    --lp-radius-lg: 12px;
    --lp-radius-md: 8px;
    --lp-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --lp-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    --lp-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    --lp-transition: 0.2s ease;

    /* Shared component theme mapping (ex- classes) */
    --ex-primary: var(--lp-primary);
    --ex-primary-dark: var(--lp-primary-dark);
    --ex-primary-light: var(--lp-primary-light);
    --ex-primary-ring: #60a5fa;
    --ex-success: var(--lp-success);
    --ex-success-light: var(--lp-success-light);
    --ex-success-dark: var(--lp-success-dark);
    --ex-error: var(--lp-error);
    --ex-error-light: var(--lp-error-light);
    --ex-error-dark: #dc2626;
    --ex-neutral-50: var(--lp-neutral-50);
    --ex-neutral-100: var(--lp-neutral-100);
    --ex-neutral-200: var(--lp-neutral-200);
    --ex-neutral-500: var(--lp-neutral-500);
    --ex-neutral-700: var(--lp-neutral-700);
    --ex-neutral-800: var(--lp-neutral-800);
    --ex-radius-sm: 6px;
    --ex-radius-md: var(--lp-radius-md);
    --ex-radius-lg: var(--lp-radius-lg);
    --ex-radius-full: 9999px;
    --ex-shadow-sm: var(--lp-shadow-sm);
    --ex-transition: var(--lp-transition);
    --ex-font: var(--lp-font);
}

/* =========================================================================
   2. ELEMENTOR BUTTON RESET
   Every button class this widget renders MUST appear in the :not() chain
   or the kit reset flattens it invisible (refine-hints gotcha #2).
   ========================================================================= */

.elementor-kit-15048 .letter-practice-root button:not(.ss-action):not(.lp-tile):not(.lp-speaker-btn):not(.lp-nav-btn):not(.lp-retry-btn):not(.lp-speak-yes):not(.lp-keyword):not(.lp-target):not(.te-mh-gear):not(.te-mh-back):not(.te-mh-level):not(.te-rung-card):not(.te-mh-levelrow):not(.te-mh-path):not(.uf-btn),
.elementor-kit-15048 .letter-practice-container button:not(.ss-action):not(.lp-tile):not(.lp-speaker-btn):not(.lp-nav-btn):not(.lp-retry-btn):not(.lp-speak-yes):not(.lp-keyword):not(.lp-target):not(.te-mh-gear):not(.te-mh-back):not(.te-mh-level):not(.te-rung-card):not(.te-mh-levelrow):not(.te-mh-path):not(.uf-btn) {
    background-color: transparent;
    border-color: transparent;
    color: inherit;
    padding: 0;
    font-size: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    text-transform: none;
    border-radius: 0;
    box-shadow: none;
    min-height: auto;
}

/* =========================================================================
   3. BASE CONTAINER
   ========================================================================= */

.letter-practice-root {
    font-family: var(--lp-font);
    font-size: 16px;
    line-height: 1.5;
    color: var(--lp-neutral-800);
    max-width: 100%;
    margin: 0 auto;
    padding: 0;
    overflow: hidden;
    box-sizing: border-box;
}

.letter-practice-container {
    background: white;
    border-radius: var(--lp-radius-xl);
    box-shadow: var(--lp-shadow-lg);
    padding: 20px;
    min-height: 380px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

/* =========================================================================
   4. STIMULUS ZONE (fixed height — the frame never moves)
   ========================================================================= */

.letter-practice-root .lp-stimulus {
    /* Hugs the 130px target with a small, even band — was 150px, which left a
       loose gap once the target shrank (Lyda 08-11). */
    height: 138px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 24px;
}

/* Say it stacks: big letter CENTERED with the keyword card below it — a
   flex ROW pushed the letter left once the card appeared (Lyda 08-20).
   height:auto so the column never clips; the card's pre-allocated slot
   keeps the stack the same height with or without a revealed keyword. */
.letter-practice-root .lp-stimulus--speak {
    flex-direction: column;
    height: auto;
    min-height: 138px;
    gap: 4px;
    padding: 4px 0;
}

/* The big written target (L1/L2). Serif-free, maximum discriminability. */
.letter-practice-root .lp-target {
    font-size: 96px;
    font-weight: 700;
    line-height: 1;
    /* Kit-reset-excluded button: the kit `capitalize` flattens lowercase
       targets to caps (Match/Big & small alternate cases — Lyda QA 09-02). */
    text-transform: none;
    color: var(--lp-neutral-800);
    background: var(--lp-primary-light);
    border: 3px solid var(--lp-primary);
    border-radius: var(--lp-radius-xl);
    min-width: 130px;
    height: 130px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 16px;
    box-sizing: border-box;
    user-select: none;
}

/* The visual target (L1/L2 + L5) is a TAP-TO-HEAR button now — the separate 🔊
   speaker button is gone (Lyda 2026-08-18). It's exempted from the kit reset so
   it keeps the box above; here we only neutralize native button chrome and add a
   tap affordance. Lift-on-hover (not a colour flip) so a sticky :hover on touch
   never leaves the main stimulus looking "pressed". `.playing` shows the active
   state while the name plays. */
.letter-practice-root .lp-target--tappable {
    cursor: pointer;
    font-family: inherit;
    -webkit-appearance: none;
    appearance: none;
    transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease, color 0.12s ease;
}
.letter-practice-root .lp-target--tappable:hover {
    transform: translateY(-2px);
    box-shadow: var(--lp-shadow-md);
}
.letter-practice-root .lp-target--tappable:active {
    transform: scale(0.97);
}
.letter-practice-root .lp-target--tappable.playing {
    background: var(--lp-primary);
    color: #fff;
}
.letter-practice-root .lp-target--tappable:focus-visible {
    outline: 3px solid var(--lp-primary);
    outline-offset: 3px;
}

/* Review-mode chip (A2/D1) — shown in the footer's middle slot while the user
   looks back at a past answer (read-only, never re-scored). */
.letter-practice-root .lp-review-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    font-weight: 600;
    color: var(--lp-primary);
    background: var(--lp-primary-light);
    border-radius: 999px;
    padding: 4px 12px;
    white-space: nowrap;
}

/* "Review answers" summary button: styled FLEET-WIDE in shared-components.css
   (.uf-footer.uf-review-footer .uf-btn--back) — .uf-btn's kit-proofing is
   !important, so widget-side overrides silently lose. Never re-add one here. */

/* Side reveal slot + mirror spacer RETIRED 2026-08-20 (Lyda: the hint letter
   "looked funny to the right") — the Show Letter reveal now lives INSIDE the
   speaker button (.lp-speaker-btn--reveal below): one object, still tappable
   for sound, zero layout shift, and the speaker centers naturally. */

/* Speaker button (audio stimulus) — big, obvious, ≥44px many times over.
   Icon is always the full 🔊 glyph at ~56% of the circle (48px in a 110px
   button read as a tiny icon rattling in a giant ring — Lyda 08-11). */
.letter-practice-root .lp-speaker-btn {
    width: 100px;
    min-width: 0;
    padding: 0;
    height: 100px;
    border-radius: 50%;
    border: 3px solid var(--lp-primary);
    background: var(--lp-primary-light);
    color: var(--lp-primary-dark);
    font-size: 56px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--lp-shadow-md);
    transition: transform var(--lp-transition), box-shadow var(--lp-transition);
}

.letter-practice-root .lp-speaker-btn:hover {
    transform: scale(1.05);
    box-shadow: var(--lp-shadow-lg);
    background: var(--lp-primary-light);
    color: var(--lp-primary-dark);
}

.letter-practice-root .lp-speaker-btn.playing {
    background: var(--lp-primary);
    color: white;
}

.letter-practice-root .lp-speaker-btn:focus-visible {
    outline: 3px solid var(--lp-primary);
    outline-offset: 3px;
}

/* Autoplay was blocked (no gesture yet): the trial is silent until the user
   taps, so the speaker pulses as the obvious first tap. Box-shadow halo, not
   background — survives aggressive background resets (clock-pill lesson). */
.letter-practice-root .lp-speaker-btn--nudge {
    animation: lp-speaker-nudge 1.6s ease-in-out infinite;
}

@keyframes lp-speaker-nudge {
    0%, 100% { box-shadow: var(--lp-shadow-md); transform: scale(1); }
    50% { box-shadow: 0 0 0 10px rgba(59, 130, 246, 0.3), var(--lp-shadow-md); transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
    .letter-practice-root .lp-speaker-btn--nudge {
        animation: none;
        box-shadow: 0 0 0 6px rgba(59, 130, 246, 0.3), var(--lp-shadow-md);
    }
}

/* Show Letter reveal INSIDE the speaker: the circle becomes the letter,
   amber hint styling, same size (zero layout shift), still tappable for
   sound. Every state declares its colors (kit hover gotcha). */
.letter-practice-root .lp-speaker-btn--reveal {
    background: var(--lp-hint-light, #fffbeb);
    border-color: var(--lp-hint, #fbbf24);
    color: #2c1810;
    font-size: 52px;
    font-weight: 800;
    font-family: inherit;
}
.letter-practice-root .lp-speaker-btn--reveal:hover {
    background: var(--lp-hint-light, #fef3c7);
    color: #2c1810;
}
.letter-practice-root .lp-speaker-btn--reveal.playing {
    background: var(--lp-hint, #fbbf24);
    color: #2c1810;
}

/* 'See Word' reveal (First-letter mode): the spoken word, written, in the
   same slot — the circle widens to a pill so the word fits. */
.letter-practice-root .lp-speaker-btn--word {
    width: auto;
    min-width: 100px;
    padding: 0 26px;
    border-radius: 999px;
    font-size: 34px;
    font-weight: 800;
    letter-spacing: 0.01em;
    text-transform: none;
}

/* =========================================================================
   5. TILES (fixed-height zone)
   ========================================================================= */

.letter-practice-root .lp-tiles {
    min-height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 14px;
    padding: 8px 0;
}

.letter-practice-root .lp-tile {
    /* Explicit min-width/padding — the Elementor kit inflates undeclared buttons. */
    width: 92px;
    min-width: 0;
    padding: 0;
    height: 92px;
    border-radius: var(--lp-radius-lg);
    border: 3px solid var(--lp-neutral-300);
    background: white;
    color: var(--lp-neutral-800);
    font-family: var(--lp-font);
    font-size: 52px;
    font-weight: 700;
    line-height: 1;
    /* Same kit `capitalize` leak as .lp-target — lowercase tiles must render
       lowercase or Big & small mode is indistinguishable from Match. */
    text-transform: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--lp-shadow-md);
    user-select: none;
    /* State classes swap on a React-reused node — transitions would stick
       at the old colour, so none on state-swapped properties. */
    transition: none;
}

.letter-practice-root .lp-tile:hover {
    border-color: var(--lp-primary);
    background: var(--lp-primary-light);
    color: var(--lp-neutral-800);
}

.letter-practice-root .lp-tile:focus-visible {
    outline: 3px solid var(--lp-primary);
    outline-offset: 3px;
}

/* Hint 'Highlight' rung — glow the correct tile. */
.letter-practice-root .lp-tile--glow {
    border-color: var(--lp-hint);
    background: var(--lp-hint-light);
    color: var(--lp-neutral-800);
    animation: lp-glow-pulse 1.2s ease-in-out infinite;
}

.letter-practice-root .lp-tile--glow:hover {
    border-color: var(--lp-hint);
    background: var(--lp-hint-light);
    color: var(--lp-neutral-800);
}

@keyframes lp-glow-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(202, 138, 4, 0.45); }
    50% { box-shadow: 0 0 0 10px rgba(202, 138, 4, 0); }
}

/* Hint 'Eliminate' rung — errorless narrowing. Removed foils stay on screen for
   context but fade out of play: dimmed, flat, and non-interactive so the choice
   collapses to the target + one foil before the pulse lands. */
.letter-practice-root .lp-tile--eliminated,
.letter-practice-root .lp-tile--eliminated:hover {
    opacity: 0.22;
    background: white;
    border-color: var(--lp-neutral-200);
    color: var(--lp-neutral-800);
    box-shadow: none;
    cursor: default;
    pointer-events: none;
}

/* Post-answer states */
.letter-practice-root .lp-tile--correct,
.letter-practice-root .lp-tile--correct:hover {
    border-color: var(--lp-success-dark);
    background: var(--lp-success-light);
    color: var(--lp-success-dark);
}

.letter-practice-root .lp-tile--incorrect,
.letter-practice-root .lp-tile--incorrect:hover {
    border-color: var(--lp-error);
    background: var(--lp-error-light);
    color: var(--lp-error);
}

.letter-practice-root .lp-tile--dim,
.letter-practice-root .lp-tile--dim:hover {
    opacity: 0.4;
    background: white;
    border-color: var(--lp-neutral-300);
    color: var(--lp-neutral-800);
}

.letter-practice-root .lp-tile:disabled {
    cursor: default;
}

/* =========================================================================
   6. FEEDBACK STRIP (footer middle slot) + COUNTDOWN SLOT
   ========================================================================= */

/* No visible feedback strip — the green correct tile is the answer. This is a
   visually-hidden live region so screen readers still announce the outcome
   (.sr-only isn't loaded on this page, hence a local copy). */
.letter-practice-root .lp-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Fixed slot so the countdown bar appearing never shifts the footer. */
.letter-practice-root .lp-countdown-slot {
    height: 10px;
    margin: 2px 0 6px;
}

/* =========================================================================
   7. ERROR + FALLBACK STATES
   ========================================================================= */

.letter-practice-root .lp-error {
    text-align: center;
    padding: 40px 16px;
    color: var(--lp-neutral-700);
}

.letter-practice-root .lp-retry-btn,
.letter-practice-root .lp-nav-btn {
    min-height: 48px;
    min-width: 0;
    padding: 10px 20px;
    line-height: 1.2;
    border-radius: var(--lp-radius-md);
    border: 2px solid var(--lp-neutral-300);
    background: white;
    color: var(--lp-neutral-700);
    font-family: var(--lp-font);
    font-size: 17px;
    font-weight: 600;
    cursor: pointer;
}

.letter-practice-root .lp-retry-btn:hover,
.letter-practice-root .lp-nav-btn:hover {
    border-color: var(--lp-primary);
    background: var(--lp-primary-light);
    color: var(--lp-neutral-800);
}

.letter-practice-root .lp-nav-row {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    margin-top: auto;
}

.letter-practice-root .lp-nav-hint {
    background: var(--lp-hint-light);
    border-color: var(--lp-hint);
    color: var(--lp-hint);
}

.letter-practice-root .lp-complete-fallback {
    text-align: center;
    padding: 40px 16px;
}

/* =========================================================================
   8. RESPONSIVE
   ========================================================================= */

/* The shared exercise layout switches to flex-column ≤1024px but sizes its main
   column to CONTENT width (the wrapper keeps align-items:flex-start). Most widgets
   have content wide enough to fill; Letter Practice's is narrow (a few big
   letters + a short instruction), so the whole card collapsed to ~270px and
   hugged the left edge. Force the column full-width so the card is full-width and
   centered. Scoped to this widget — the shared rule is left untouched. */
@media (max-width: 1024px) {
    .letter-practice-root .te-main-col {
        width: 100%;
    }
}

@media (max-width: 768px) {
    .letter-practice-container {
        padding: 14px;
        min-height: 340px;
    }

    .letter-practice-root .lp-stimulus {
        height: 100px;
        gap: 16px;
    }

    .letter-practice-root .lp-target {
        font-size: 60px;
        min-width: 88px;
        height: 88px;
    }

    .letter-practice-root .lp-speaker-btn {
        width: 84px;
        height: 84px;
        font-size: 46px;
    }

    .letter-practice-root .lp-tiles {
        gap: 6px;
        min-height: 100px;
        flex-wrap: nowrap;
    }

    /* Size tiles to the WIDEST level (5 tiles on L4) so the bank never wraps:
       each tile = a fifth of the row minus the gaps, capped at 72px, kept square
       via aspect-ratio. Scales down smoothly on narrow phones (Lyda 08-11). */
    .letter-practice-root .lp-tile {
        width: min(72px, calc((100% - 28px) / 5));
        height: auto;
        aspect-ratio: 1 / 1;
        font-size: clamp(26px, 7.5vw, 40px);
    }
}

@media (max-width: 380px) {
    /* Tiles keep the fluid min()/aspect-ratio sizing from the ≤768 rule — it
       scales them down to fit 5-across on the smallest phones with no wrap. */

    .letter-practice-root .lp-stimulus {
        height: 88px;
    }

    .letter-practice-root .lp-target {
        font-size: 52px;
        min-width: 76px;
        height: 76px;
    }

}

/* =========================================================================
   9. ACCESSIBILITY
   ========================================================================= */

@media (prefers-reduced-motion: reduce) {
    .letter-practice-root .lp-tile--glow {
        animation: none;
        box-shadow: 0 0 0 4px rgba(202, 138, 4, 0.35);
    }

    .letter-practice-root .lp-speaker-btn {
        transition: none;
    }

    .letter-practice-root .lp-speaker-btn:hover {
        transform: none;
    }
}

/* ============================================================
   L5 "Say it" + L6 "Sight words" (2026-08-17)
   ============================================================ */

/* Word tiles: same tile language as letters, sized for 3-7 letter words.
   Lowercase on purpose — sight words are read in their normal print form. */
.letter-practice-root .lp-tiles--words {
    flex-wrap: wrap;
    gap: 10px;
}
.letter-practice-root .lp-tile--word {
    width: auto;
    min-width: 110px;
    height: 64px;
    padding: 0 22px;
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    text-transform: none;
}
@media (max-width: 500px) {
    .letter-practice-root .lp-tile--word {
        min-width: 88px;
        height: 56px;
        padding: 0 14px;
        font-size: 1.3rem;
    }
}
@media (min-width: 1025px) {
    .letter-practice-root .lp-tile--word {
        min-width: 130px;
        height: 72px;
        font-size: 1.85rem;
    }
}

/* Say-it trial: big letter + one green confirm. Every interactive state is
   declared (the class joins the kit-reset :not() chain, so the kit would
   otherwise paint hover/focus). Green = action, per the fleet color grammar. */
.letter-practice-root .lp-target--speak {
    font-size: 6rem;
}
/* Say-it keyword card ("Apple" for A) — the hint slot is pre-allocated so
   appearing never shifts the big letter or the ✓ button (zero-layout-shift
   rule). Hidden = same footprint, fully transparent, not tappable. The
   first letter gets the fleet hint amber so the letter↔word link is visible
   at a glance. In the kit-reset :not() chain (both copies) — every visual
   property is declared here on every state. */
.letter-practice-root .lp-keyword {
    display: block;
    margin: 6px auto 0;
    min-height: 52px;
    min-width: 200px;
    padding: 8px 22px;
    border: 2px solid transparent;
    border-radius: 12px;
    background: transparent;
    font-size: 1.9rem;
    font-weight: 700;
    line-height: 1.2;
    color: transparent;
    letter-spacing: 0.02em;
    /* The kit `capitalize` leaks onto excluded-from-reset buttons — it turned
       "Pen" into "PEn" (capitalizing the .lp-keyword-first span AND the rest
       span independently). Declare it dead here (Lyda QA 08-20). */
    text-transform: none;
    cursor: default;
    transition: none;
}
.letter-practice-root .lp-keyword span {
    text-transform: none;
}
.letter-practice-root .lp-keyword.visible {
    background: #fffbeb;
    border-color: #fde68a;
    color: #2c1810;
    cursor: pointer;
}
.letter-practice-root .lp-keyword.visible .lp-keyword-first {
    color: #ca8a04;
}
.letter-practice-root .lp-keyword.visible:hover,
.letter-practice-root .lp-keyword.visible:focus,
.letter-practice-root .lp-keyword.visible:active {
    background: #fef3c7;
    border-color: #fbbf24;
    color: #2c1810;
}
.letter-practice-root .lp-keyword.visible:focus-visible {
    outline: 3px solid #1a56db;
    outline-offset: 2px;
}
@media (max-width: 380px) {
    .letter-practice-root .lp-keyword {
        font-size: 1.5rem;
        min-height: 46px;
        min-width: 160px;
    }
}
.letter-practice-root .lp-speak-yes {
    min-width: 220px;
    min-height: 64px;
    padding: 12px 30px;
    border: none;
    border-radius: 14px;
    background: var(--as-primary-bg, #0F6E56);
    color: #ffffff;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.2;
    cursor: pointer;
    box-shadow: 0 3px 10px rgba(15, 23, 42, 0.22);
}
.letter-practice-root .lp-speak-yes:hover,
.letter-practice-root .lp-speak-yes:focus {
    background: var(--as-primary-bg-strong, #0B5642);
    color: #ffffff;
}
.letter-practice-root .lp-speak-yes:focus-visible {
    outline: 3px solid #1a56db;
    outline-offset: 2px;
}
.letter-practice-root .lp-speak-yes:active {
    background: var(--as-primary-bg-strong, #0B5642);
    color: #ffffff;
    transform: translateY(1px);
}
.letter-practice-root .lp-speak-yes:disabled {
    opacity: 0.55;
    cursor: default;
    transform: none;
}

/* Say-It (L5) — Naming-parity primary (Lyda 2026-09-10). Big green "Tap to
   speak" mirrors naming's .np-act-speak (3D shadow, mic + waveform); a quiet
   "✓ I said it" link underneath is the errorless self-pace path. If the mic is
   unsupported/blocked, the self-check (.lp-speak-yes) becomes the big primary. */
.letter-practice-root .lp-speak-zone {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

/* Big green action button (mirrors naming .np-action) */
.letter-practice-root .lp-action {
    width: 100%;
    max-width: 360px;
    display: flex;
    border-radius: 13px;
    overflow: hidden;
    min-height: 64px;
    box-sizing: border-box;
}
.letter-practice-root .lp-act {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-weight: 700;
    font-size: 1.2rem;
    padding: 14px;
    border: none;
    background: transparent;
    cursor: pointer;
    text-transform: none;   /* kit capitalizes buttons; keep "Tap to speak" sentence-case */
    transition: none;       /* React reuses this node across speak/listening swaps */
}
.letter-practice-root .lp-act-mic { font-size: 24px; line-height: 1; }
.letter-practice-root .lp-act-label { font-weight: 700; }
.letter-practice-root .lp-act:focus-visible {
    outline: 3px solid #1a56db;
    outline-offset: 2px;
}
/* STATE: speak — solid green */
.letter-practice-root .lp-action--speak { background: #22b573; box-shadow: 0 4px 0 #178a53; }
.letter-practice-root .lp-action--speak .lp-act,
.letter-practice-root .lp-action--speak .lp-act-label,
.letter-practice-root .lp-action--speak .lp-act-mic { color: #ffffff; }
/* STATE: listening — darker green + white waveform */
.letter-practice-root .lp-action--listening { background: #178a53; box-shadow: 0 4px 0 #106b40; }
.letter-practice-root .lp-action--listening .lp-act,
.letter-practice-root .lp-action--listening .lp-act-label,
.letter-practice-root .lp-action--listening .lp-act-mic { color: #ffffff; }
.letter-practice-root .lp-action--listening .lp-wave-bar { background: #ffffff; }

/* Waveform while live (mirrors naming .np-voice-wave) */
.letter-practice-root .lp-voice-wave {
    display: flex;
    align-items: center;
    gap: 3px;
    height: 20px;
}
.letter-practice-root .lp-wave-bar {
    display: inline-block;
    width: 4px;
    height: 8px;
    background: #ef4444;
    border-radius: 2px;
    animation: lpWaveBar 0.6s ease-in-out infinite alternate;
}
.letter-practice-root .lp-wave-bar:nth-child(1) { animation-delay: 0s; }
.letter-practice-root .lp-wave-bar:nth-child(2) { animation-delay: 0.1s; }
.letter-practice-root .lp-wave-bar:nth-child(3) { animation-delay: 0.2s; }
.letter-practice-root .lp-wave-bar:nth-child(4) { animation-delay: 0.15s; }
.letter-practice-root .lp-wave-bar:nth-child(5) { animation-delay: 0.05s; }
@keyframes lpWaveBar { 0% { height: 4px; } 100% { height: 18px; } }

/* Quiet self-check link under the mic — low-key, not a competing button */
.letter-practice-root .lp-selfcheck-link {
    margin-top: 2px;
    border: none;
    background: transparent;
    color: var(--lp-primary-dark, #2563eb);
    font-size: 0.95rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
    padding: 8px 10px;      /* ~44px tap target while staying visually light */
    min-height: 44px;
}
.letter-practice-root .lp-selfcheck-link:hover,
.letter-practice-root .lp-selfcheck-link:focus { color: #1a56db; }
.letter-practice-root .lp-selfcheck-link:focus-visible {
    outline: 3px solid #1a56db;
    outline-offset: 2px;
    border-radius: 6px;
}
.letter-practice-root .lp-selfcheck-link:disabled { opacity: 0.5; cursor: default; }

/* Mic-blocked note (browser refused the mic) */
.letter-practice-root .lp-speak-denied {
    margin-top: 2px;
    font-size: 0.95rem;
    color: var(--lp-hint, #ca8a04);
    text-align: center;
}

/* Reserved nudge line — always present (nbsp when empty) so it never shifts. */
.letter-practice-root .lp-speak-mic-hint {
    min-height: 1.4em;
    margin-top: 4px;
    padding: 0 10px;
    font-size: 1rem;
    font-weight: 600;
    color: var(--lp-hint, #ca8a04);
    text-align: center;
}
@media (prefers-reduced-motion: reduce) {
    .letter-practice-root .lp-wave-bar { animation: none; height: 12px; }
}
@media (max-width: 480px) {
    .letter-practice-root .lp-action,
    .letter-practice-root .lp-speak-yes {
        max-width: min(340px, 88vw);
        min-width: min(320px, 82vw);
    }
}

@media (min-width: 1025px) {
    .letter-practice-root .lp-target--speak {
        font-size: 7.5rem;
    }
}
