/* ==========================================================================
   Utility
   ========================================================================== */

.hidden {
    display: none !important;
}

/* ==========================================================================
   Intro tagline
   ========================================================================== */

.game-tagline {
    font-size: 14px;
    font-style: italic;
    font-weight: 600;
    color: var(--color-primary);
    margin-bottom: 14px;
}

/* Shows searchable category tags as metadata without adding filtering behavior. */
.game-tags {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px;
    margin: -4px 0 14px;
    padding: 0;
    list-style: none;
}

.game-tags li {
    padding: 4px 10px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-primary-soft);
    color: var(--color-primary-dark);
    font-size: 12px;
    font-weight: 700;
}

/* Confetti layer shown when a game is finished (js/components/celebration.js). It never blocks clicks. */
.celebration {
    position: fixed;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: calc(var(--z-modal) + 1);   /* above the answer modal and the bottom bar */
}

.celebration-piece {
    position: absolute;
    top: -2em;
    left: var(--x);
    font-size: var(--size);
    line-height: 1;
}

/* Level tags inside a game: pastel version of the level colour (the other tags keep the blue chip). */
.game-tags li[data-tag="basic"] { background: var(--level-a-soft); border-color: var(--level-a-soft); color: var(--level-a-text); }
.game-tags li[data-tag="intermediate"] { background: var(--level-b-soft); border-color: var(--level-b-soft); color: var(--level-b-text); }
.game-tags li[data-tag="advanced"] { background: var(--level-c-soft); border-color: var(--level-c-soft); color: var(--level-c-text); }

/* ==========================================================================
   Stats bar
   ========================================================================== */

.game-stats {
    display: flex;
    align-items: center;
    justify-content: flex-start;   /* the round on the left; mistakes and the sound button on the right */

    font-size: 13px;
    font-weight: 600;
    color: var(--color-subtle);

    margin-bottom: 14px;
}

.game-round {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: auto;
}

.game-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--color-accent);
    animation: gamePulse 1.6s ease-in-out infinite;
}

@keyframes gamePulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.35; }
}

.game-stat {
    display: flex;
    align-items: center;
    gap: 5px;
    color: var(--color-heading);
    font-weight: 700;
}

/* ==========================================================================
   Instruction box
   ========================================================================== */

.game-instruction {
    display: flex;
    align-items: center;
    gap: 14px;

    background: var(--color-page-bg);
    border-radius: var(--radius-md);
    padding: 16px 18px;

    margin-bottom: 20px;
}

.game-instruction-icon {
    flex-shrink: 0;
    width: 42px;
    height: 42px;

    display: flex;
    align-items: center;
    justify-content: center;

    background: var(--color-highlight);
    border-radius: var(--radius-md);

    font-size: 20px;
    font-weight: 700;
    color: var(--color-text);
}

.game-instruction-label {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-subtle);
    margin-bottom: 2px;
}

.game-instruction-body {
    font-size: 15px;
    font-weight: 700;
    color: var(--color-heading);
    line-height: 1.4;
}

/* Shake used by the wrong-answer tile of any game */
@keyframes gameShake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}

/* ==========================================================================
   Footer row
   ========================================================================== */

.game-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;

    font-size: 13px;
    color: var(--color-subtle);
}

.game-footer .quiz-btn {
    flex: none;
    padding: 10px 16px;
}

/* ==========================================================================
   Completion modal
   ========================================================================== */

.game-modal-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal);   /* above the bottom bar */

    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;

    background: rgba(23, 32, 51, 0.55);

    opacity: 0;
    transition: opacity 0.25s ease;
}

.game-modal-overlay.visible {
    opacity: 1;
}

.game-modal-card {
    width: 100%;
    max-width: 380px;

    background: var(--color-bg);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);

    padding: 28px 24px;
    text-align: center;

    transform: scale(0.95);
    transition: transform 0.25s ease;
}

.game-modal-overlay.visible .game-modal-card {
    transform: scale(1);
}

.game-modal-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 16px;

    display: flex;
    align-items: center;
    justify-content: center;

    background: var(--color-success-soft);
    border-radius: 50%;

    font-size: 28px;
    color: var(--color-success);
}

.game-modal-icon .ti {
    margin-right: 0; /* centered standalone icon, no trailing text */
}

.game-modal-card h2 {
    font-size: 21px;
    color: var(--color-heading);
    margin-bottom: 6px;
}

.game-modal-sub {
    font-size: 13px;
    color: var(--color-subtle);
    margin-bottom: 22px;
}

.game-modal-card .quiz-btn {
    width: 100%;
}

/* Secondary action in the brand accent (pink), e.g. "More Games".
   White text on --color-accent is 4.9:1; on hover it is darker still. */
.game-btn-accent {
    --btn-shadow: var(--color-accent-dark);
    background: var(--color-accent);
    color: var(--color-bg);
}

/* ==========================================================================
   Game frame (drawn by js/games/game-kit.js, shared by every round-based game)
   ========================================================================== */

.game-card {
    max-width: 700px;
    margin-inline: auto;
}

/* The "try again" message floats over the top of the instruction box: the slot has no height, so an empty message takes
   no space (no gap between the progress bar and the instruction on a phone) and a message never pushes the tiles down. */
.game-feedback-slot {
    position: relative;
    height: 0;
    margin-bottom: var(--space-sm);
}

.game-feedback {
    position: absolute;
    top: 6px;
    left: 0;
    right: 0;
    z-index: 2;
    margin: 0;
    color: var(--color-subtle);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.5;
    text-align: center;
}

.game-feedback:not(:empty) {
    padding: 10px 14px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}

.game-feedback.incorrect {
    color: var(--color-error-dark);
    background: var(--color-error-soft);
    border-color: var(--color-error-border);
}

/* Elements that only receive the focus from the script (tabindex="-1": "Round 2 / 3", the title of the final screen):
   no ring after a tap or a click; the keyboard still shows it. */
#game-round:focus:not(:focus-visible),
#game-complete-title:focus:not(:focus-visible) { outline: none; }

/* Sound effects on/off, at the end of the round bar (speaker; crossed out when off). */
.game-sound-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin: -8px -8px -8px 4px;   /* a 40px touch target without making the round bar taller */
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-heading);
    font-size: 20px;
    cursor: pointer;
    touch-action: manipulation;
}

.game-sound-btn[aria-pressed="false"] { color: var(--color-subtle); }

.game-sound-btn:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

@media (hover: hover) {
    .game-sound-btn:hover { background: var(--color-primary-soft); }
}

/* "Correct!" modal */
.game-correct-card .game-modal-icon {
    background: var(--color-success-soft);
    color: var(--color-success);
}

.game-correct-card h2,
.game-correct-card .game-explanation {
    color: var(--color-success);
}

.game-correct-card .game-explanation {
    font-size: 15px;
    line-height: 1.5;
    white-space: pre-line;   /* a dialogue (Order the Conversation) keeps one line per turn */
}

.game-correct-card .quiz-btn {
    display: inline-block;
    width: auto;
    margin-top: 8px;
}

/* Games without explanation: give the button the room the explanation would take */
.game-correct-card .game-explanation.hidden + .quiz-btn {
    margin-top: 22px;
}

/* Reading aloud: speaker button + "read automatically" switch (js/core/speech.js) */
.game-speech {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin: 4px 0 14px;
}

.game-speech.hidden { display: none; }

.game-speak-btn {
    width: 52px;
    height: 52px;
    display: inline-flex;
    align-items: center;
    justify-content: center;

    background: var(--color-success-soft);
    color: var(--color-success);
    border: 2px solid var(--color-success);
    border-radius: 50%;

    font-size: 26px;
    cursor: pointer;
}

.game-speak-btn .ti { margin-right: 0; }

.game-speak-btn:hover,
.game-speak-btn.is-speaking {
    background: var(--color-success);
    color: var(--color-bg);
}

.game-speak-btn:focus-visible {
    outline: 3px solid var(--color-success);
    outline-offset: 3px;
}

.game-auto-read {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 13px;
    color: var(--color-subtle);
    cursor: pointer;
}

/* Completion screen */
.game-complete { text-align: center; }
.game-complete h2 { margin-bottom: 8px; color: var(--color-heading); }
.game-complete p { margin-bottom: 16px; color: var(--color-subtle); }
.game-final-mistakes strong { color: var(--color-heading); }
.game-complete .quiz-btn { margin: 6px; }

/* "Next game on the list": its own card under the finish card. The whole card is the link. */
.game-next-card {
    position: relative;
    display: block;
    max-width: 700px;
    margin: var(--space-sm) auto 0;
    padding: 18px 56px 18px 24px;
    background: var(--color-bg);
    border: 1px solid var(--color-border-light);
    border-radius: var(--radius-lg);
    color: var(--color-subtle);
    text-decoration: none;
    transition: transform 0.2s var(--ease-out), border-color 0.2s;
}

.game-next-card.hidden { display: none; }

.game-next-label {
    margin-bottom: 4px;
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-subtle);
}

.game-next-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0 0 2px;
    font-size: 20px;
    color: var(--color-heading);
}

.game-next-text {
    margin: 4px 0 0;
    font-size: 14px;
    line-height: 1.5;
}

.game-next-arrow {
    position: absolute;
    top: 50%;
    right: 20px;
    font-size: 24px;
    color: var(--color-primary);
    transform: translateY(-50%);
    transition: transform 0.2s var(--ease-out);
}

.game-next-card:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

@media (hover: hover) {
    .game-next-card:hover {
        border-color: var(--color-primary);
        transform: translateY(-2px);
    }

    .game-next-card:hover .game-next-arrow {
        transform: translate(4px, -50%);
    }
}

/* Eggs earned (final screen): regular weight and small, so it stays short on phones. */
.game-complete .game-eggs {
    margin-bottom: 4px;
    font-size: 17px;
    font-weight: 600;
    color: var(--color-heading);
}
.game-complete .game-eggs-hint {
    font-size: 14px;
}

/* "Add to favorites" on the final screen: outlined in the accent color, heart filled when saved. */
.game-btn-favorite {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    --btn-shadow: var(--color-accent-soft);
    border: 1px solid var(--color-accent);
    background: var(--color-bg);
    color: var(--color-accent-dark);
}

.game-btn-favorite svg {
    width: 20px;
    height: 20px;
    transition: fill 0.2s ease;
}

.game-btn-favorite[aria-pressed="true"] { background: var(--color-accent-soft); }
.game-btn-favorite[aria-pressed="true"] svg { fill: currentColor; }

/* ==========================================================================
   Choice tiles (shared board: the learner taps one tile among several)
   Used by Odd One Out and Number Sums. The kit adds .is-correct / .is-incorrect
   to the tile the learner chose. A game with a different board adds its own section.
   ========================================================================== */

.game-choices {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
    margin: 20px 0;
}

.game-choice {
    min-height: 88px;
    padding: 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-primary-soft);
    color: var(--color-heading-alt);
    font: inherit;
    font-size: clamp(17px, 3vw, 22px);
    font-weight: 700;
    overflow-wrap: break-word;   /* safety net: a very long word wraps instead of leaving its tile */
    cursor: pointer;
    box-shadow: 0 4px 0 var(--color-border);   /* chunky bottom edge */
    transition: var(--transition);
}

/* hover only where a real pointer exists (no sticky hover on touch) */
@media (hover: hover) {
    .game-choice:hover:not(:disabled) {
        background: var(--color-border-light);
        transform: translateY(-2px);
    }
}


.game-choice:active:not(:disabled) {
    transform: translateY(3px);
    box-shadow: 0 1px 0 var(--color-border);
}

.game-choice:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

.game-choice:disabled { cursor: default; }
.game-choice.is-correct { background: var(--color-success-soft); border-color: var(--color-success-bright); color: var(--color-success); box-shadow: 0 4px 0 var(--color-success-bright); }
.game-choice.is-incorrect { background: var(--color-error-soft); border-color: var(--color-error-border); color: var(--color-error); box-shadow: 0 4px 0 var(--color-error-border); animation: gameShake 0.4s ease-in-out; }

/* ==========================================================================
   Prompt (optional): the challenge shown above the tiles, e.g. "2 + 4 = ?"
   ========================================================================== */

.game-prompt {
    padding: 20px 18px;
    background: var(--color-page-bg);
    border-radius: var(--radius-md);
    color: var(--color-heading);
    font-size: clamp(30px, 7vw, 42px);
    font-weight: 700;
    letter-spacing: 0.04em;
    text-align: center;
}

/* ==========================================================================
   Person cards (Meet the Person, js/games/person-card.js): one or three short introductions and the question.
   The tiles are the shared .game-choices; with three people there are three tiles (--three).
   ========================================================================== */

.game-prompt--person {
    text-align: left;
    font-size: 16px;
    font-weight: 400;
    letter-spacing: 0;
}

.person-cards {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.person-card {
    display: flex;
    align-items: center;
    gap: 12px;
}

.person-avatar {
    flex: none;
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--color-bg);
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
    font-size: 28px;
    line-height: 1;
}

.person-text {
    margin: 0;
    font-size: clamp(16px, 3.6vw, 19px);
    font-weight: 600;
    line-height: 1.5;
    color: var(--color-heading);
}

.person-question {
    margin: 14px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
    font-size: clamp(18px, 4vw, 22px);
    font-weight: 700;
    color: var(--color-heading);
}

.game-choices--three {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* ==========================================================================
   Conversation (Order the Conversation, js/games/conversation-order.js):
   the lines already placed as chat bubbles, and below them the lines still to place.
   ========================================================================== */

.game-conversation {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin: 20px 0;
}

.conversation-built {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.conversation-bubble {
    max-width: 88%;
    padding: 10px 14px;
    border-radius: 16px;
    font-size: clamp(15px, 3.4vw, 18px);
    font-weight: 600;
    line-height: 1.4;
    color: var(--color-heading);
    animation: pop-in 0.3s var(--ease-bounce);
}

.conversation-bubble--left {
    align-self: flex-start;
    border-bottom-left-radius: 4px;
    background: var(--color-primary-soft);
}

.conversation-bubble--right {
    align-self: flex-end;
    border-bottom-right-radius: 4px;
    background: var(--color-accent-soft);
}

.conversation-pool {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.conversation-line {
    min-height: 0;
    text-align: left;
    font-size: clamp(15px, 3.4vw, 18px);
    font-weight: 600;
}

.conversation-line[hidden] {
    display: none;
}

.game-conversation .game-translate {
    align-self: flex-start;
    margin-top: 0;
}

.game-conversation .game-translation {
    margin-top: 0;
}

/* ==========================================================================
   Word search (js/games/word-search.js): a counter, the grid of letters and a tip.
   Cells are buttons; the grid keeps a square shape and never wider than 420px.
   ========================================================================== */

.game-wordsearch {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin: 16px 0;
}

.wordsearch-status {
    margin: 0;
    font-size: 16px;
    color: var(--color-subtle);
}

.wordsearch-status strong { color: var(--color-heading); }

.wordsearch-grid {
    display: grid;
    grid-template-columns: repeat(var(--cols, 7), minmax(0, 1fr));
    gap: 4px;
    width: min(100%, 420px);
}

.wordsearch-cell {
    aspect-ratio: 1;
    min-width: 0;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    font: inherit;
    font-size: clamp(16px, 4.8vw, 24px);
    font-weight: 700;
    line-height: 1;
    color: var(--color-heading);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;   /* two quick taps (first and last letter) must not zoom the page */
    user-select: none;
    transition: background 0.15s, border-color 0.15s, transform 0.15s;
}

/* Syllable cells (Syllable Search): smaller text so a syllable of up to 5 letters fits a cell on a phone. */
.wordsearch-grid--syllables { gap: 4px; }
.wordsearch-grid--syllables .wordsearch-cell {
    min-height: 44px;
    padding: 0 2px;
    overflow: hidden;
    font-size: clamp(11px, 3.4vw, 17px);
    letter-spacing: 0;
}

.wordsearch-cell.is-selected {
    border-color: var(--color-primary);
    background: var(--color-primary-soft);
}

.wordsearch-cell.is-start { transform: scale(1.08); }

.wordsearch-cell.is-found { cursor: default; }
.wordsearch-cell.found-0 { background: #d9f2e1; border-color: var(--color-success-bright); }
.wordsearch-cell.found-1 { background: #fde9c9; border-color: #f0a73a; }
.wordsearch-cell.found-2 { background: #dbe8fb; border-color: #5b8fe0; }
.wordsearch-cell.found-3 { background: #f6dcec; border-color: #d36aa6; }

.wordsearch-cell.is-wrong {
    border-color: var(--color-error);
    animation: wordsearch-shake 0.35s;
}

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

@media (prefers-reduced-motion: reduce) {
    .wordsearch-cell.is-wrong { animation: none; }
}

.wordsearch-cell:disabled { opacity: 1; cursor: default; }

.wordsearch-tip {
    margin: 0;
    font-size: 14px;
    text-align: center;
    color: var(--color-subtle);
}

.game-wordsearch .game-translate { margin-top: 0; }

/* ==========================================================================
   Triplicate find (js/games/triplicate-find.js): a counter, a grid of emojis and a tip.
   Reuses the counter and tip of the word search; the grid is square and never wider than 420px.
   ========================================================================== */

.game-triplicate {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    margin: 16px 0;
}

.triplicate-grid {
    display: grid;
    grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
    gap: 4px;
    width: min(100%, 420px);
}

.triplicate-tile {
    aspect-ratio: 1;
    min-width: 0;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-bg);
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
    font-size: clamp(22px, calc(40vw / var(--cols, 4)), 44px);
    line-height: 1;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    user-select: none;
    transition: background 0.15s, border-color 0.15s;
}

.triplicate-tile.is-found { background: #d9f2e1; border-color: var(--color-success-bright); cursor: default; }
.triplicate-tile.is-wrong { border-color: var(--color-error); animation: wordsearch-shake 0.35s; }
.triplicate-tile:disabled { opacity: 1; cursor: default; }

@media (prefers-reduced-motion: reduce) {
    .triplicate-tile.is-wrong { animation: none; }
}

.game-triplicate .game-translate { margin-top: 0; }

/* "Translate" under a clue: small, regular weight, so the clue stays the main thing. */
.game-translate {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 12px;
    padding: 6px 12px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg);
    color: var(--color-label);
    font: inherit;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0;
    cursor: pointer;
}
.game-translate[aria-expanded="true"] {
    background: var(--color-primary-soft);
    border-color: var(--color-primary);
}
.game-translation {
    margin-top: 10px;
    font-size: 15px;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--color-subtle);
}
.game-translation p { margin: 2px 0; }
.game-translation span { white-space: pre-line; }   /* several lines of a dialogue or a card stay as lines */
.game-translation b { color: var(--color-heading); margin-right: 4px; }

/* ==========================================================================
   Emoji tiles (Body Parts): larger symbols, and denser grids for 6 or 8 tiles.
   Combine with .game-choices; the game toggles --dense / --many per puzzle.
   ========================================================================== */

.game-choices--emoji .game-choice {
    font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
    font-size: clamp(36px, 9vw, 52px);
    line-height: 1;
}

/* Sentence with a gap (js/games/gap-fill.js): longer than a word, so smaller type; the gap is a line */
.game-prompt--sentence {
    font-size: clamp(22px, 5.5vw, 32px);
    line-height: 1.5;
    letter-spacing: 0;
}

.game-gap {
    display: inline-block;
    min-width: 2.4em;
    margin: 0 4px;
    border-bottom: 3px solid currentColor;
}

/* "Not available for this learning language" screen: the alternative game and "More games" stacked */
.game-unavailable-actions {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.game-unavailable-actions .quiz-description { margin-bottom: 0; }

/* Note on the intro screen about one learning language (string "note-<language>" of a game) */
.game-note {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 12px 0;
    padding: 10px 12px;
    background: var(--color-primary-soft);
    border-radius: 10px;
    color: var(--color-heading-alt);
    font-size: 14px;
    line-height: 1.5;
    text-align: left;
}

.game-note .ti {
    flex-shrink: 0;
    margin-right: 0;
    color: var(--color-primary);
    font-size: 18px;
    line-height: 1.4;
}

/* Introductory lesson on the first screen of a game (`lesson` in vocab-<language>.js, lessonHtml in game-kit.js):
   a short list of forms and two examples, before the Start button. Left-aligned, like a note. */
.game-lesson {
    margin: var(--space-sm) 0;
    padding: var(--space-sm);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    text-align: left;
    font-size: 15px;
    line-height: 1.5;
}

.game-lesson-title {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 0 6px;
    font-size: 17px;
    color: var(--color-heading-alt);
}

.game-lesson-title .ti {
    margin-right: 0;
    color: var(--color-primary);
}

.game-lesson-intro {
    margin: 0 0 10px;
    color: var(--color-text);
}

.game-lesson-group {
    margin: 0 0 8px;
}

.game-lesson-name {
    margin: 8px 0 2px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-label);
}

.game-lesson-words {
    margin: 0;
    font-weight: 700;
    color: var(--color-primary-dark);
}

.game-lesson-examples {
    margin: 0;
    padding: 0;
    list-style: none;
}

.game-lesson-examples li {
    margin: 4px 0;
    padding: 6px 10px;
    background: var(--color-page-bg);
    border-left: 3px solid var(--color-accent);
    border-radius: 6px;
}

.game-lesson-example {
    display: block;
    font-weight: 600;
    color: var(--color-heading-alt);
}

.game-lesson-translation {
    display: block;
    font-size: 13px;
    color: var(--color-label);
}

/* Shape tiles (Shape Sequence): Tabler outline icons, big and slightly thickened so the thin
   line stays readable. No color is set here: the tile keeps --color-heading-alt (about 11:1 on its
   background) and the correct / incorrect states recolor the icons through currentColor. */
.game-choices--shapes .game-choice {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(8px, 3vw, 18px);
    min-height: 96px;
}

.game-choices--shapes .game-choice .ti {
    margin-right: 0;
    vertical-align: baseline;
    font-size: clamp(34px, 9vw, 46px);
    line-height: 1;
    -webkit-text-stroke: 0.5px currentColor;   /* thickens the outline a little */
}

.game-choices--shapes.game-choices--dense .game-choice {
    gap: 6px;
    padding: 10px 6px;
}

.game-choices--shapes.game-choices--dense .game-choice .ti {
    font-size: clamp(26px, 7vw, 40px);
}

/* The sequence in words is longer than "2 + 4 = ?": smaller type and a normal letter spacing */
.game-prompt--sequence {
    font-size: clamp(24px, 6vw, 34px);
    letter-spacing: 0.01em;
}

.game-choices--dense { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.game-choices--many { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.game-choices--many .game-choice {
    min-height: 72px;
    padding: 10px;
    font-size: clamp(30px, 7vw, 44px);
}

/* Ink Colors / Ink Words (Stroop): text painted with the ink of a color (the prompt, or a word tile). Fixed hex values on purpose,
   they are the colors being tested, not part of the site palette. Yellow is a deep gold and white is
   not used, so every ink stays readable on the light prompt. */
.game-prompt[data-ink="red"],
.game-choice[data-ink="red"] { color: #d62828; }
.game-prompt[data-ink="orange"],
.game-choice[data-ink="orange"] { color: #f07f13; }
.game-prompt[data-ink="yellow"],
.game-choice[data-ink="yellow"] { color: #b88a00; }
.game-prompt[data-ink="green"],
.game-choice[data-ink="green"] { color: #2e9e3e; }
.game-prompt[data-ink="blue"],
.game-choice[data-ink="blue"] { color: #1e6fe0; }
.game-prompt[data-ink="purple"],
.game-choice[data-ink="purple"] { color: #8b3fd1; }
.game-prompt[data-ink="brown"],
.game-choice[data-ink="brown"] { color: #7b4b26; }
.game-prompt[data-ink="black"],
.game-choice[data-ink="black"] { color: #1a1a1a; }

/* Ink Words: tiles that hold a color word, not a symbol. Smaller type so the longest word fits in
   the 3 and 4 column grids. Keep it AFTER .game-choices--many (same specificity, the later rule wins). */
.game-choices--words .game-choice {
    min-height: 64px;
    padding: 8px 4px;
    font-size: clamp(14px, 4vw, 22px);
    overflow-wrap: anywhere;
}

/* A clue is a sentence, so it needs a smaller type than a single word. */
.game-prompt--clue {
    font-size: clamp(20px, 5vw, 28px);
    letter-spacing: 0;
}

/* ==========================================================================
   Tag filter (home page): one toggle button per tag.
   The state lives in aria-pressed, so the look and the screen-reader
   announcement can never disagree.
   ========================================================================== */

.tag-filter {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: var(--space-md);
}

/* Space for the buttons while js/pages/home.js has not drawn them yet (no layout shift; see "Reserved space" in
   css/styles.css): one row on wide screens, two on a phone. */
.tag-filter:empty { min-height: 40px; }

@media (max-width: 600px) {
    .tag-filter:empty { min-height: 88px; }
}

/* While the search box has text the buttons are paused (and disabled), but keep their on/off look. */
.tag-filter.is-paused { opacity: 0.45; }

.tag-filter-btn:disabled { cursor: not-allowed; }

/* Search box: first thing inside the games block (.content-card) of the home page */
.game-search {
    position: relative;
    max-width: 280px;
    margin-bottom: var(--space-md);
}

.game-search input {
    width: 100%;
    min-height: 40px;
    padding: 6px 40px 6px 14px;   /* right padding leaves room for the icon (and the browser's clear button) */
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-bg);
    color: var(--color-text);
    font: inherit;
    font-size: 15px;
}

.game-search input::placeholder { color: var(--color-label); opacity: 1; }

.game-search input:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

.game-search .ti {
    position: absolute;
    top: 50%;
    right: 14px;
    margin-right: 0;
    transform: translateY(-50%);
    color: var(--color-primary);
    font-size: 18px;
    pointer-events: none;
}

.tag-filter-btn {
    min-height: 40px;   /* comfortable touch target */
    padding: 6px 14px;
    border: 1px solid var(--color-primary);
    border-radius: 999px;
    background: var(--color-primary);
    color: var(--color-bg);
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: var(--transition);
}

/* ON state of the level tags: green / yellow / pink (the other tags stay blue). */
.tag-filter-btn[data-tag="basic"][aria-pressed="true"] { border-color: var(--level-a); background: var(--level-a); }
.tag-filter-btn[data-tag="intermediate"][aria-pressed="true"] { border-color: var(--level-b); background: var(--level-b); color: var(--color-text); }
.tag-filter-btn[data-tag="advanced"][aria-pressed="true"] { border-color: var(--level-c); background: var(--level-c); }

/* Off: outlined and dashed, so the state is not conveyed by colour alone. */
.tag-filter-btn[aria-pressed="false"] {
    border-style: dashed;
    border-color: var(--color-border);
    background: transparent;
    color: var(--color-label);
}

/* hover only where a real pointer exists (no sticky hover on touch) */
@media (hover: hover) {
    .tag-filter-btn[aria-pressed="false"]:hover {
        border-color: var(--color-primary-light);
        background: var(--color-primary-soft);
        color: var(--color-primary);
    }
}


.tag-filter-btn:focus-visible {
    outline: 3px solid var(--color-primary);
    outline-offset: 2px;
}

/* ==========================================================================
   Game cards (home and Favorites), with their favourite (heart) button
   The heart is a sibling of the card link, not inside it: a button cannot
   live inside a link. It sits in the top-right corner of the card.
   ========================================================================== */

.game-item {
    position: relative;
}

.game-item .grid-card-title {
    padding-right: 36px;   /* keeps the name clear of the heart */
}

.grid-card .game-tagline {
    margin: 0;   /* the card spaces its lines itself */
}

/* "Played" badge (js/components/game-card.js). It must not look like a #tag, so it differs in four ways:
   position (bottom-right corner, not next to the tags), fill (transparent with a border, the tags are
   pastel blocks), shape (small corners, the tags are round pills) and a check icon. Green text on the
   white card is AA (5:1+).
   margin-top: auto pushes it to the bottom: the card link is a column with equal heights in a row.
   Louder variant: background var(--color-success) + color var(--color-bg), no border. */
.game-played {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    align-self: flex-end;
    margin-top: auto;
    padding: 2px 9px 2px 6px;

    background: transparent;
    border: 1.5px solid var(--color-success);
    border-radius: 6px;
    color: var(--color-success);

    font-size: 12px;
    font-weight: 700;
    line-height: 1.3;
}

.game-played .ti {
    margin-right: 0;
    vertical-align: baseline;
    font-size: 15px;
}

.favorite-btn {
    position: absolute;
    top: 4px;
    right: 4px;

    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;   /* Android recommends at least 48 */
    height: 48px;
    padding: 0;

    border: 0;
    border-radius: 50%;
    background: transparent;
    color: var(--color-subtle);
    cursor: pointer;
    transition: var(--transition);
}

.favorite-btn svg {
    width: 24px;
    height: 24px;
    transition: fill 0.2s ease;
}

/* On: the heart is filled with the accent color. The state lives in aria-pressed. */
.favorite-btn[aria-pressed="true"] {
    color: var(--color-accent);
}

.favorite-btn[aria-pressed="true"] svg {
    fill: currentColor;
}

.favorite-btn:active {
    transform: scale(0.9);
}

.favorite-btn:focus-visible {
    outline: 3px solid var(--color-accent);
    outline-offset: 2px;
}

/* hover only where a real pointer exists (no sticky hover on touch) */
@media (hover: hover) {
    .favorite-btn:hover {
        background: var(--color-accent-soft);
        color: var(--color-accent);
    }
}

/* ==========================================================================
   Favorites page
   ========================================================================== */

/* A card whose heart was switched off on this page: dimmed, but still there so the tap can be undone. */
.game-item.is-unfavorited .grid-card {
    opacity: 0.55;
}

.favorites-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-md);
    padding: var(--space-lg) var(--space-md);
    text-align: center;
    color: var(--color-subtle);
}

.favorites-empty-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: var(--color-accent-soft);
    color: var(--color-accent);
    font-size: 36px;
}

.favorites-empty p {
    max-width: 34ch;
    font-size: 15px;
}

/* ==========================================================================
   "Games for kids" page (list.html?list=for-kids; js/pages/list.js sets body[data-list]): yellow page, navy ink,
   white cards with a thick outline, a hard shadow and a colored band on top. The #tags keep their usual colors.
   Colors: --kids-* in css/styles.css.
   ========================================================================== */
body[data-list="for-kids"] {
    background-color: var(--kids-page-bg);
}

body[data-list="for-kids"] main > .header h1 {
    color: var(--kids-ink);
}

body[data-list="for-kids"] main > .header p {
    color: var(--kids-ink);
    font-weight: 600;
}

body[data-list="for-kids"] main > .content-card {
    padding-left: 0;
    padding-right: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
}

body[data-list="for-kids"] .card-grid .grid-card {
    background: var(--color-bg);
    border: 3px solid var(--kids-ink);
    border-radius: 18px;
    box-shadow: 5px 5px 0 var(--kids-ink);
}

body[data-list="for-kids"] .card-grid .game-item:nth-child(4n+1) .grid-card { border-top: 12px solid var(--kids-band-1); }
body[data-list="for-kids"] .card-grid .game-item:nth-child(4n+2) .grid-card { border-top: 12px solid var(--kids-band-2); }
body[data-list="for-kids"] .card-grid .game-item:nth-child(4n+3) .grid-card { border-top: 12px solid var(--kids-band-3); }
body[data-list="for-kids"] .card-grid .game-item:nth-child(4n+4) .grid-card { border-top: 12px solid var(--kids-band-4); }

body[data-list="for-kids"] .card-grid .grid-card-title {
    color: var(--kids-ink);
    font-weight: 800;
}

/* ==========================================================================
   Vocabulary page (vocabulary.html, js/pages/vocabulary.js): one table per topic, speaker | word | translation.
   ========================================================================== */
/* Every topic is an accordion item: a full-width button (icon, name, number of words, chevron) over its table. */
.vocab-topic + .vocab-topic {
    border-top: 1px solid var(--color-border-light);
}

.vocab-topic-heading {
    margin: 0;
    font-size: inherit;
}

.vocab-topic-trigger {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    min-height: 48px;
    padding: 12px 4px;
    border: 0;
    background: none;
    color: var(--color-heading-alt);
    font: inherit;
    font-size: 18px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.vocab-topic-trigger > .ti:first-child {
    color: var(--color-primary);
}

.vocab-topic-name {
    flex: 1;
    min-width: 0;
}

.vocab-topic-count {
    flex: none;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-label);
}

.vocab-topic-icon {
    flex: none;
    color: var(--color-primary);
    transition: transform 0.25s ease;
}

.vocab-topic-trigger[aria-expanded="true"] .vocab-topic-icon {
    transform: rotate(180deg);
}

.vocab-topic-trigger:focus-visible {
    outline: 3px solid var(--color-accent);
    outline-offset: 2px;
    border-radius: var(--radius-md);
}

@media (hover: hover) {
    .vocab-topic-trigger:hover .vocab-topic-name {
        color: var(--color-primary);
    }
}

.vocab-topic-panel {
    padding-bottom: var(--space-sm);
}

.vocab-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 15px;
}

.vocab-table th {
    padding: 6px 8px;
    border-bottom: 2px solid var(--color-border);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-align: left;
    text-transform: uppercase;
    color: var(--color-label);
}

.vocab-table td {
    padding: 6px 8px;
    border-bottom: 1px solid var(--color-border-light);
    vertical-align: middle;
}

.vocab-col-speak {
    width: 44px;
}

.vocab-word {
    font-weight: 700;
    color: var(--color-heading-alt);
}

.vocab-translation {
    color: var(--color-label);
}

.vocab-speak {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1.5px solid var(--color-primary-light);
    border-radius: 50%;
    background: var(--color-primary-soft);
    color: var(--color-primary);
    font-size: 18px;
    cursor: pointer;
    transition: var(--transition);
}

.vocab-speak .ti { margin-right: 0; }

.vocab-speak:hover,
.vocab-speak.is-speaking {
    background: var(--color-primary);
    color: #ffffff;
}

.vocab-speak:focus-visible {
    outline: 3px solid var(--color-accent);
    outline-offset: 2px;
}
