/* hax-lexigon.css — Lexigon play surface styling per LexigonDesign/docs/design.md §11.
   Loaded via @Assets cache-busting from App.razor.

   v1 chunk D.4.a — view-only board, rack, score panel, move history. Interactive layer (drag,
   click-to-place, blank-tile picker) lands in chunk D.4.b/c with additional .lexigon-board-cell
   modifier classes (.is-selectable, .is-target, .is-invalid).

   Mobile-first per design.md §11.1: ~380px portrait baseline, each board cell ~50px so the
   accessible-target threshold is met without zoom. The 7×7 grid + 5-tile rack + score panel
   stack vertically and don't need media queries to scale up — the board centers within its
   container's max-width and the rack inherits the same width.

   Premium-square cues use both background color and a glyph hint (2L / 3L / 2W / 3W) per
   §11.1's "color cue + glyph hint (not relying on color alone)" — survives colorblind viewers
   and the operator preference [[feedback-color-never-sole-indicator]]. */

.lexigon-play {
    display: flex;
    flex-direction: column;
    gap: 16px;
    max-width: 460px;
    margin: 0 auto;
    padding: 12px 8px;
}

.lexigon-play-pregame,
.lexigon-play-terminal,
.lexigon-play-game {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Pre-accept event banner (operator request 2026-06-08) — discipline glyph + title/subtitle,
   mirroring the cross-module banner pattern (ClueMaster / Chess / Bowling / Cubing + Haxopoly)
   so the awaiting surface makes the event unmistakable. No margin-bottom — the
   .lexigon-play-pregame parent's flex gap handles spacing. */
.lexigon-event-banner {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: var(--mud-palette-text-primary);
    font-weight: 600;
}

.lexigon-event-banner::before {
    content: '';
    flex-shrink: 0;
    width: 52px;
    height: 52px;
    background-image: url('/icons/disciplines/icon-lexigon-default.png');
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

.lexigon-event-banner-text {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    min-width: 0;
}

.lexigon-event-banner-title {
    font-size: 1.25rem;
    font-weight: 600;
}

.lexigon-event-banner-subtitle {
    font-size: 0.9rem;
    font-weight: 500;
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-pregame-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.lexigon-play-header {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.lexigon-play-scores {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}

.lexigon-play-score-tile {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-radius: 8px;
    padding: 8px 12px;
    text-align: center;
}

.lexigon-play-score-tile.is-active {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 2px var(--mud-palette-primary-hover);
}

.lexigon-play-score-name {
    font-size: 0.85rem;
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-score-value {
    font-size: 1.6rem;
    font-weight: 700;
    line-height: 1.2;
}

.lexigon-play-status {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
}

.lexigon-play-status-badge {
    font-weight: 600;
    padding: 4px 10px;
    border-radius: 999px;
    font-size: 0.9rem;
}

.lexigon-play-status-badge.turn-you {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
}

.lexigon-play-status-badge.turn-opp {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-status-badge.win {
    background: var(--mud-palette-success);
    color: var(--mud-palette-success-text);
}

.lexigon-play-status-badge.loss {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-meta {
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-decisive {
    font-style: italic;
    color: var(--mud-palette-text-secondary);
}

/* 7×7 board grid. */
.lexigon-board {
    display: flex;
    flex-direction: column;
    gap: 2px;
    background: var(--mud-palette-divider);
    padding: 2px;
    border-radius: 6px;
}

.lexigon-board-row {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 2px;
    /* clip any subpixel overflow — defense-in-depth against the 2026-06-01 row-2
       overflow bug where webkit let min-content from premium-square glyphs push a
       row past the board frame on narrow iPhone viewports. */
    overflow: hidden;
}

.lexigon-board-cell {
    /* box-sizing: border-box so .has-tile's padding lives INSIDE the grid track instead of
       expanding the cell's rendered size — without this, the 1px padding extends the cell
       2px wider than its track and eats both grid gaps on adjacent placed-tile cells, so
       consecutive tiles visually touch (UAT regression noticed 2026-05-31 after the 05-30
       tan-empty-cell palette change made the gap visible). */
    box-sizing: border-box;
    /* min-width:0 / min-height:0 overrides the grid-item default of min-width:auto
       (== min-content). Without this, premium-square glyph cells ("3L"/"3W") can demand
       more space than their 1fr track allocates, and webkit lets the row overflow rather
       than shrinking the cells — caused the 2026-06-01 row-2-overflow bug on narrow iPhone
       viewports after orientation change. */
    min-width: 0;
    min-height: 0;
    aspect-ratio: 1 / 1;
    background: #e8d5a8;                /* light tan empty-cell field — operator palette 2026-05-30 */
    border-radius: 3px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    font-weight: 700;
    color: #4a3823;                     /* warm brown for any text against tan */
    user-select: none;
    position: relative;
    /* Container queries — the placed tile's letter + point sizing scales off THIS cell's
       inline size (cqi) instead of a fixed rem, so mobile (~50px cells) and desktop (~65px
       cells) both render the letter at the same proportion. Operator 2026-05-30 squish fix. */
    container-type: inline-size;
}

/* Premium palette — all shades of green per operator design 2026-05-30. Intensity ladder
   preserved: DL (lightest) → TL (deeper letter) and DW (light) → TW (deepest). */
.lexigon-board-cell.is-dl { background: #c8e6c9; color: #1b5e20; }   /* pale sage */
.lexigon-board-cell.is-tl { background: #2e7d32; color: #fff; }      /* medium emerald */
.lexigon-board-cell.is-dw { background: #a5d6a7; color: #1b5e20; }   /* spring green */
.lexigon-board-cell.is-tw { background: #1b5e20; color: #fff; }      /* deep forest */

.lexigon-board-cell.is-start {
    background: linear-gradient(135deg, #a5d6a7, #81c784);
    color: #1b5e20;
}

.lexigon-board-cell.is-last-move {
    outline: 2px solid var(--mud-palette-warning);
    outline-offset: -2px;
}

.lexigon-board-cell.has-tile {
    background: transparent;
    color: inherit;
    padding: 1px;
}

.lexigon-board-cell.is-click-target {
    cursor: pointer;
}

.lexigon-board-cell.is-click-target:hover {
    outline: 2px dashed var(--mud-palette-primary);
    outline-offset: -2px;
}

.lexigon-board-cell.is-staged {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.lexigon-board-cell.is-staged .lexigon-tile {
    background: linear-gradient(180deg, #fff8e0, #f0e0a8);
    border-color: var(--mud-palette-primary);
}

.lexigon-board-start-mark {
    font-size: 1.4rem;
    opacity: 0.6;
}

.lexigon-board-premium-glyph {
    font-size: 0.65rem;
    letter-spacing: 0.5px;
}

/* Tile glyph — used both on the board (placed tiles) and in the rack. The width:100% on .lexigon-tile
   inside a board cell makes it fill the cell; in the rack the .lexigon-rack-tile wrapper sizes it. */
.lexigon-tile {
    /* box-sizing: border-box so the 1px border is included in the 100% width/height — without
       it the tile renders 2px larger than its parent cell's content area, contributing to the
       2026-05-31 board-gap eating regression (see .lexigon-board-cell note). */
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    background: linear-gradient(180deg, #fdf6e3, #f5ecd3);
    border: 1px solid #c9b89a;
    border-radius: 3px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: #2a2a2a;
    font-family: "Segoe UI", system-ui, sans-serif;
    position: relative;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.08);
}

.lexigon-tile.is-blank {
    background: linear-gradient(180deg, #fffefa, #f4eed8);
    font-style: italic;
}

.lexigon-tile-letter {
    /* 55% of the containing cell's inline size — scales naturally between mobile + desktop.
       The rack-scoped override below uses an explicit rem since rack tiles are uniform. */
    font-size: 55cqi;
    font-weight: 700;
    line-height: 1;
}

.lexigon-tile-points {
    font-size: 20cqi;                   /* ~22% of cell — keeps the subscript readable but not crowding the letter */
    font-weight: 700;
    position: absolute;
    bottom: 2px;
    right: 3px;
    color: #000;                        /* black — operator 2026-05-30; was mud-palette-text-secondary which renders near-invisible on the cream tile */
}

/* Rack — 5 fixed slots whether filled or not so the layout doesn't reflow as the rack drains.
   width:100% added 2026-05-30 — without it the grid shrink-wraps to its inner content (button
   intrinsic size), collapsing rack tiles to ~25px squares. The max-width caps things on desktop;
   tightened from 320px → 240px per operator 2026-05-30 (rack tiles read about one size smaller
   than board-placed tiles, mirroring real Scrabble-tile-in-rack proportions). */
.lexigon-rack {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 4px;
    width: 100%;
    max-width: 240px;
    margin: 0 auto;
}

/* Scope the letter + point-value font sizes inside the rack to the smaller rack-tile footprint.
   Board-placed tiles use container-query sizing (55cqi / 20cqi) off their cell; the rack uses
   absolute rems because rack tiles share one rack-wide width and don't need to scale per-tile. */
.lexigon-rack .lexigon-tile-letter {
    font-size: 1.6rem;
}

.lexigon-rack .lexigon-tile-points {
    font-size: 0.55rem;
}

.lexigon-rack-tile {
    aspect-ratio: 1 / 1;
    border-radius: 4px;
    padding: 0;
    border: none;
    background: none;
    /* Container — the rack-tile itself is the sizing base when the tile lives outside .lexigon-rack
       (e.g. the Exchange overlay's tile picker). Without this, the base .lexigon-tile-letter cqi
       falls back to viewport units and renders the letter ~3x the tile size. Operator 2026-05-30. */
    container-type: inline-size;
}

.lexigon-rack-tile.is-empty {
    background: var(--mud-palette-divider);
    opacity: 0.4;
}

.lexigon-rack-tile.is-view-only .lexigon-tile {
    opacity: 0.85;
}

.lexigon-rack-tile.is-clickable {
    cursor: pointer;
}

.lexigon-rack-tile.is-clickable[disabled] {
    cursor: default;
    opacity: 0.4;
}

.lexigon-rack-tile.is-clickable .lexigon-tile {
    transition: transform 80ms ease-out, box-shadow 80ms ease-out;
}

.lexigon-rack-tile.is-clickable:hover:not([disabled]) .lexigon-tile {
    transform: translateY(-2px);
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.15);
}

.lexigon-rack-tile.is-selected .lexigon-tile {
    /* Strong "this tile is armed" signal — operator 2026-05-30. Was a 3px lift + thin primary
       ring that read as a subtle hover state, not a selection. Now: bigger lift, mint-green
       tint replacing the cream face, thicker primary ring + deeper shadow. The letter (#2a2a2a)
       stays readable against the tint. */
    transform: translateY(-6px);
    background: linear-gradient(180deg, #b8ecc8, #8fdca0);
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 3px var(--mud-palette-primary), 0 6px 10px rgba(0, 0, 0, 0.3);
}

.lexigon-rack-tile.is-staged .lexigon-tile {
    opacity: 0.35;
}

.lexigon-play-submit-error {
    grid-column: 1 / -1;
    width: 100%;
}

/* Actions strip + history. */
.lexigon-play-actions {
    display: flex;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
}

.lexigon-play-history {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 8px 12px;
}

.lexigon-play-history-empty {
    text-align: center;
    color: var(--mud-palette-text-secondary);
    font-style: italic;
}

.lexigon-play-history > summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.lexigon-play-history-list {
    margin: 8px 0 0 0;
    padding: 0;
    list-style: none;
    max-height: 200px;
    overflow-y: auto;
}

.lexigon-play-history-entry {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    gap: 8px;
    padding: 4px 0;
    border-bottom: 1px solid var(--mud-palette-divider);
    font-size: 0.85rem;
}

.lexigon-play-history-entry:last-child {
    border-bottom: none;
}

.lexigon-play-history-num {
    color: var(--mud-palette-text-secondary);
}

.lexigon-play-history-who {
    font-weight: 600;
}

.lexigon-play-history-score {
    color: var(--mud-palette-primary);
    font-weight: 600;
}

/* Action-menu overlays — blank-tile picker, exchange picker, pass + resign confirms.
   Full-viewport backdrop centered over the play surface; the inner card stops click
   propagation so taps inside don't dismiss. Bottom-sheet style on small viewports for
   thumb-reach finger affordance per design.md §11.1. */

.lexigon-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: 16px;
}

.lexigon-overlay-card {
    background: var(--mud-palette-background);
    color: var(--mud-palette-text-primary);
    border-radius: 10px;
    padding: 16px;
    max-width: 360px;
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

.lexigon-overlay-hint {
    color: var(--mud-palette-text-secondary);
}

.lexigon-overlay-actions {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 8px;
}

.lexigon-blank-picker-grid {
    display: grid;
    grid-template-columns: repeat(7, 1fr);
    gap: 6px;
    margin-top: 8px;
}

.lexigon-blank-picker-letter {
    aspect-ratio: 1 / 1;
    border: 1px solid var(--mud-palette-divider);
    background: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
    font-size: 1.1rem;
    font-weight: 700;
    border-radius: 4px;
    cursor: pointer;
}

.lexigon-blank-picker-letter:hover {
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    border-color: var(--mud-palette-primary);
}

.lexigon-exchange-row {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 6px;
    margin-top: 8px;
}

/* Force End panel — Dev/Staging-only per design.md §14.1. Visually fenced from the live play
   controls so the operator's eye reads the pipeline-test affordance separately from real-play
   actions and never confuses it with a regular Resign. */

.lexigon-force-end-panel {
    margin-top: 12px;
    padding: 12px;
    background: var(--mud-palette-surface);
    border: 1px dashed var(--mud-palette-warning);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.lexigon-force-end-header {
    display: flex;
    align-items: center;
    gap: 8px;
}

.lexigon-force-end-pill {
    background: var(--mud-palette-warning);
    color: var(--mud-palette-warning-text);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 2px 8px;
    border-radius: 999px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.lexigon-force-end-title {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.lexigon-force-end-hint,
.lexigon-force-end-followup {
    margin: 0;
    font-size: 0.8rem;
    color: var(--mud-palette-text-secondary);
}

.lexigon-force-end-buttons {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Stats cards CSS — used by LexigonStatsComponent. */
.lexigon-stats {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.lexigon-stats-grid {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.lexigon-stats-event-title {
    margin: 0 0 8px 0;
    font-size: 1.05rem;
    font-weight: 600;
}

.lexigon-stats-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 8px;
    margin: 0 0 12px 0;
    padding: 0;
}

.lexigon-stats-stats > div {
    background: var(--mud-palette-surface);
    border: 1px solid var(--mud-palette-divider);
    border-radius: 6px;
    padding: 8px 12px;
}

.lexigon-stats-stats dt {
    margin: 0;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.lexigon-stats-stats dd {
    margin: 2px 0 0 0;
    font-size: 1.3rem;
    font-weight: 700;
}

.lexigon-stats-scoring dd {
    color: var(--mud-palette-primary);
}

.lexigon-stats-empty {
    color: var(--mud-palette-text-secondary);
    font-style: italic;
    text-align: center;
}
