/* Centering: flex-body + width:100%. Shared .app-container base
   (max-width/background/border-radius/box-shadow) lives in shared.css. */
body {
    display: flex;
    justify-content: center;
}
.app-container {
    width: 100%;
    /* body is a flex row with this as its only item — without this, a flex
       item's default min-width:auto is its content's min-content size, so
       any wide unwrapped content deep inside (e.g. a tile row before it
       wraps) can stop this from shrinking to the viewport at all, which
       stops every wrap rule further down from ever engaging. */
    min-width: 0;
    padding: clamp(12px, 4vw, 20px);
}

/* Same approach as singleplayer/style.css: the page scrolls normally (no
   fixed/internally-scrolling container), and only .results below freezes
   via plain position:sticky — the header itself (icon/title/settings/
   Seat+Round Wind/Winner) scrolls away like ordinary content. Overrides
   shared.css's .header to drop flex-wrap/margin-bottom, which this page
   never had. */
.header {
    flex-wrap: nowrap;
    margin-bottom: 0;
}

/* The responsive header-dropdown grid (Ruleset/Seat Wind/Round Wind/Winner)
   now lives in shared.css as the opt-in .hdr-grid layout, shared with
   singleplayer — this page just adds .hdr-container/.hdr-grid to its markup. */

.meta-group {
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* See shared/shared.css's .meta-group for why this is needed — this
       file's local copy of the rule predates that fix and must carry it
       too, since it loads after shared.css and overrides it at equal
       specificity. */
    min-width: 0;
}

.meta-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-width: 0;
}
.meta-item span { white-space: nowrap; }

/* Same rule as the other 3 pages' .meta-checkbox-label (settings-panel
   checkboxes only, base shared in shared.css) — keep this one identical
   to those when making layout changes here; just the 2 extra properties
   below are visual-builder-only. Win Conditions/Special Hands checkboxes
   are a separate concern and use their own .win-condition-label instead
   of overloading this shared class with different behavior. */
.meta-checkbox-label {
    font-size: 14px;
}
.meta-checkbox-label:has(input:disabled) {
    color: #aaa;
    cursor: default;
}
/* Win Conditions/Special Hands checkboxes: checkbox and label packed
   tightly together (no space-between), unlike .meta-checkbox-label. */
.win-condition-label {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
    padding: 4px 0;
    font-size: 14px;
    font-weight: normal;
}
.win-condition-label:has(input:disabled) {
    color: #aaa;
    cursor: default;
}
/* Freezes at the top once scrolled past, same as singleplayer/style.css's
   .results — background:#fff means it simply paints over whatever's
   scrolled up beneath it, no separate opaque layer needed since the page
   itself (not a custom container) is what's scrolling. */
.results {
    position: sticky;
    top: 0;
    z-index: 10;
    background: #fff;
    padding: clamp(10px, 3vw, 16px) 0;
    border-bottom: 2px solid #b32424;
    margin-bottom: 16px;
    display: flex;
    flex-direction: column;
    gap: clamp(10px, 3vw, 16px);
}
/* .total-row is .results' only child now — the Mini Points/Doubles
   summary boxes that used to sit above it (and drove the padding-top/
   border-top here) moved inside Scoring Details' own column titles
   instead, so there's nothing left above this row to divide from. */
.total-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
}
/* Clear stays fixed-size and on the same line as Point Total at every
   width — .point-total's own flex-wrap (below) is what absorbs overflow
   on narrow screens by wrapping its own contents, not by pushing Clear
   onto its own row. */
.total-row .btn {
    flex-shrink: 0;
}
.point-total {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 6px 10px;
}
.point-total-label {
    font-size: 12px;
    font-weight: bold;
    text-transform: uppercase;
    color: #b32424;
    letter-spacing: 0.3px;
    /* Otherwise wraps into two lines ("POINT"/"TOTAL") the moment this flex
       item gets squeezed, which reads worse than everything else after it
       wrapping instead — that's what .point-total's own flex-wrap is for. */
    white-space: nowrap;
}
.point-total strong { font-size: 24px; color: #222; }
.point-total strong.capped { color: #b32424; }
.point-total strong.below-min-faan { color: #b36b00; }
/* .status-badge/.east-badge/.limit-badge/.base-total/.stat-count bases now
   live in shared.css — this page just adds its own extra badge color. */
.instant-payout-badge { background: #2e7d32; }

.section-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: #b32424;
    /* No padding-top here — unlike .total-row (a child inside .results,
       whose own padding-top is the only gap above it), this section is a
       separate sibling outside .results, so .results' margin-bottom:16px
       already provides that gap on its own; adding padding-top here would
       stack on top of it instead of matching it. */
}
/* .fold-all-btn and .collapsible-body now live in shared.css. */
.scoring-details-columns {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
@media (min-width: 650px) {
    .scoring-details-columns { flex-direction: row; }
}
.scoring-details-column {
    flex: 1;
    min-width: 0;
}
.scoring-details-column-title {
    font-size: 13px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    color: #888;
    /* Fixed, not the default font-metric-derived `normal` — HKOS's blank
       second-column title (visual/index.js) relies on this box being
       exactly as tall as the first column's real text title so both
       columns' rows start on the same line; a metric-derived line-height
       is one glyph-rendering quirk away from disagreeing with itself
       between an empty/nbsp-only title and a real word, even holding the
       font/size/weight constant. */
    line-height: 16px;
    padding-top: 8px;
    /* Matches a row's own 6px top padding (below) — flexbox paddings don't
       collapse between siblings, so row-to-row gap is already 6+6=12px;
       without this, title-to-first-row was only 6px, half that. */
    padding-bottom: 6px;
}
.scoring-details-list {
    display: flex;
    flex-direction: column;
}
.scoring-details-row {
    display: flex;
    justify-content: space-between;
    padding: 6px 0;
    font-size: 13px;
}
.scoring-details-row span:last-child {
    color: #888;
}
.scoring-details-empty {
    font-size: 13px;
    color: #999;
    padding: 8px 0;
}

.board-section {
    margin-bottom: 20px;
}
.scoring-details-section {
    padding-bottom: 16px;
    border-bottom: 2px solid #b32424;
}
.board-section-title {
    font-size: 12px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    color: #b32424;
    margin-bottom: 8px;
}

.hand-status {
    font-size: 12px;
    font-weight: normal;
    text-transform: none;
    letter-spacing: normal;
    color: #a35b00;
}
.hand-status.complete {
    color: #2e7d32;
    font-weight: bold;
}

.group-list {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 8px;
}
.group-list-empty {
    font-size: 13px;
    color: #999;
    padding: 12px;
    text-align: center;
    border: 1px dashed #ddd;
    border-radius: 8px;
}
.group-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    background: #f8f8f8;
    border-radius: 8px;
    padding: 8px 10px;
    min-width: 0;
    max-width: 100%;
}
/* A normal meld/pair only ever has 2-4 tiles (never needs to wrap), but the
   Thirteen Orphans/Nine Gates special-hand card (see renderSpecialHandCard
   in index.js) shows 13-14 at once — needs to wrap onto multiple lines
   rather than overflow past the card's edge. */
.group-card-tiles {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    max-width: 100%;
}
.group-card-tiles img {
    width: 44px;
    height: auto;
}
/* Flower/season tiles in "Your Hand" are individually removable (unlike a
   real meld, which is removed as a whole group) — a plain button reset so
   each tile still looks like the static tiles beside it, just clickable. */
.group-card-tile-btn {
    border: none;
    background: none;
    padding: 0;
    cursor: pointer;
    display: flex;
}
.group-card-tile-btn:active img { opacity: 0.6; }
.group-card-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
}
.group-type-label {
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    color: #555;
    background: #eee;
    padding: 2px 6px;
    border-radius: 4px;
}
.group-remove-btn {
    width: 28px;
    height: 28px;
    border: none;
    border-radius: 6px;
    background: #f0d0d0;
    color: #911d1d;
    font-weight: bold;
    cursor: pointer;
    flex-shrink: 0;
}
.group-remove-btn:active { background: #e0b0b0; }

.add-group-controls {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 20px;
    margin-bottom: 12px;
}
.concealed-toggle {
    flex: 0 0 auto;
}
/* Checkbox styling itself now lives on the unscoped input[type="checkbox"]
   rule above — every checkbox on the page matches it, so .picker-label
   only needs its own layout. */
.picker-label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}
/* Each .group-type-picker is its own nowrap unit (4 normal buttons, or the
   2 special-hand buttons) — .add-group-controls' own flex-wrap is what
   moves a whole unit onto a new line, rather than letting individual
   buttons split off from their group. */
.group-type-picker {
    display: flex;
    flex-wrap: nowrap;
    flex: 0 0 auto;
    gap: 6px;
}
.group-type-btn {
    /* Fixed width (not flex-grow/shrink-to-content) so every button is the
       same size regardless of its label length ("Chow" vs "13 Orphans") —
       sized to comfortably fit the longest label. */
    width: 104px;
    padding: 10px 6px;
    border: 1px solid #ccc;
    border-radius: 8px;
    background: #f8f8f8;
    color: #555;
    font-weight: bold;
    font-size: 13px;
    text-align: center;
    white-space: nowrap;
    cursor: pointer;
}
/* On mobile, the 4 main buttons (Chow/Pung/Kong/Pair) switch from fixed
   104px to an even 4-column grid so they span the full row width — still
   uniform sizing (all 4 share the row equally), just not the same fixed
   pixel width as the wider layout above. */
@media (max-width: 700px) {
    #group-type-picker {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        width: 100%;
    }
    #group-type-picker .group-type-btn {
        width: auto;
    }
}
.group-type-btn.active {
    background: #b32424;
    border-color: #b32424;
    color: #fff;
}
.group-type-btn:disabled {
    opacity: 0.3;
    cursor: default;
}

.tile-picker {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
/* Pung/Kong/Pair's 4 groups (Bamboo/Characters/Circles/Winds & Dragons) —
   plain stacked column by default, same as everything else in
   #tile-picker; switches to a 2x2 grid once the viewport is wide enough
   that 2 side-by-side 9-tile rows (~450px each) comfortably fit. */
.pkp-grid {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
@media (min-width: 1000px) {
    .pkp-grid {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 16px 24px;
    }
}
/* Flowers & Seasons (and Animals, Singaporean only) — now its own
   board-section instead of living inside #tile-picker, so it needs the
   same column layout that section relied on there. */
#bonus-tile-picker {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}
.tile-picker-row-label {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    color: #888;
    letter-spacing: 0.3px;
    margin-bottom: 6px;
}
/* Grid instead of flex-wrap so rows of 9 (numeric suits) or 7 (chow start
   picks) wrap at a predictable 5-per-row point, rather than however many
   tiles happen to fit at the current container width (which left a lone
   9th tile stranded on its own line at in-between widths). */
.tile-picker-row {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    min-width: 0;
    max-width: 100%;
}
/* On phones, wrap the numeric suit rows (1-9) at a clean 5-then-4 split
   instead of however many happen to fit at that width (which left a lone
   9th tile stranded on its own line). Wider screens keep the single-row
   flex layout above. */
@media (max-width: 700px) {
    .tile-picker-row {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        max-width: 320px;
        /* Otherwise sits flush left against the wider column beneath it —
           center the grid itself now that it's narrower than its
           container. */
        margin: 0 auto;
    }
    .tile-picker-honors-row {
        justify-content: center;
    }
}
/* Chow picker: only the 7 tiles that can actually start a run are shown
   (8/9 are omitted entirely, not greyed out — see renderTilePicker), each
   as its own cell showing all three tiles of the run plus its "1-2-3"
   label. auto-fit lets as many columns fit as the container allows (no
   fixed column count to tune per breakpoint) — the 140px minimum is the
   actual floor a cell can shrink to without its own 3 tile images (44px
   each = 132px, plus 4px+4px button padding) overflowing the column and
   visually spilling into the next one — a smaller minimum (100px was
   tried first) lets auto-fit fit one extra column at in-between widths,
   but every cell in that row then overflows and adjacent buttons' tiles
   blend into what looks like one continuous strip instead of 7 distinct
   options. */
.chow-picker-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 8px;
}
.chow-tile-btn {
    border: none;
    border-radius: 6px;
    background: #fff;
    padding: 4px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.chow-tile-btn:active { background: #f0f0f0; }
.chow-tile-btn:disabled {
    opacity: 0.3;
    cursor: default;
}
.chow-tile-images {
    display: flex;
    gap: 0;
}
.chow-tile-btn img {
    width: 44px;
    height: auto;
}
.chow-tile-btn span {
    font-size: 14px;
    color: #888;
}

/* Winds + dragons share one row that only wraps if it runs out of room —
   plain flex-wrap, not the fixed grid above. */
.tile-picker-honors-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
    max-width: 100%;
}
/* The 3 dragons move to the next line as a single unit if the row wraps,
   rather than splitting mid-group. */
.dragon-group {
    display: flex;
    flex-wrap: nowrap;
    gap: 6px;
}
/* Flowers & seasons: plain flex-wrap, same as .tile-picker-honors-row, so
   all 8 sit on one line whenever there's room. Only below 700px (where
   there generally isn't) does it switch to a 4-column grid, landing
   cleanly on 2 rows of 4 instead of wherever flex-wrap happens to break
   (which could strand an uneven split like 5+3 or 6+2). */
.tile-picker-flower-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
    max-width: 100%;
}
@media (max-width: 700px) {
    .tile-picker-flower-row {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        max-width: 260px;
        margin: 0 auto;
    }
}
.tile-picker-btn {
    border: none;
    border-radius: 6px;
    background: #fff;
    padding: 4px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}
.tile-picker-btn:active { background: #f0f0f0; }
.tile-picker-btn:disabled {
    opacity: 0.3;
    cursor: default;
}
/* A selected flower/season looks the same as a disabled tile, but stays
   clickable — clicking it again removes it from the hand. */
.tile-picker-btn-selected {
    opacity: 0.3;
}
.tile-picker-btn img {
    width: 44px;
    height: auto;
}
.tile-picker-btn span {
    font-size: 14px;
    color: #888;
}
/* "Animals" row heading matches Flowers & Seasons' own .board-section-title
   styling (red, 12px, bold) instead of the plain grey/11px every other
   .tile-picker-row-label uses — needs to be at least as specific as that
   base rule to actually win. Each individual tile's own label (Cat/Mouse/
   Rooster/Centipede) stays the same plain grey every other tile label
   uses (F1/S1, chow ranks, etc.) — only the section heading is red. */
.tile-picker-row-label.animal-row-label {
    font-size: 12px;
    font-weight: 800;
    color: #b32424;
}
/* Animal names are full words (Cat/Mouse/Rooster/Centipede), noticeably
   wider than every other tile's 1-2 character label — a plain flex row
   would let them shrink/overlap instead of wrapping to a new line once
   they run out of room, which is what was actually clipping them.
   flex-shrink: 0 keeps each button at its natural (image-or-label,
   whichever is wider) width so the row wraps instead of squeezing text;
   white-space: nowrap keeps each label on one line rather than breaking
   mid-word. The row's own flex-wrap (inherited from .tile-picker-honors-row)
   handles moving tiles to the next line once a row is full — the larger
   gap here just gives each label breathing room from its neighbor. */
.tile-picker-honors-row.animal-tile-row {
    gap: 14px;
}
.animal-tile-row .tile-picker-btn {
    flex-shrink: 0;
}
.animal-tile-row .tile-picker-btn span {
    white-space: nowrap;
}

.win-conditions-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 6px 24px;
}
@media (min-width: 480px) {
    .win-conditions-list { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 650px) {
    .win-conditions-list { grid-template-columns: repeat(3, 1fr); }
}

/* .btn now lives in shared.css. */
