.deck-page {
    max-width: 640px;
    margin: 60px auto 0;
    padding: 0 24px;
    text-align: center;
}

.deck-page-header {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 16px;
    margin-bottom: 20px;
    flex-wrap: wrap;
}

.deck-page-header h1 {
    font-size: 22px;
    margin: 0;
}

.deck-back-link {
    font-size: 13px;
    color: #6b7280;
    text-decoration: none;
}

.deck-back-link:hover {
    color: #111827;
}

#new-deck-btn {
    padding: 8px 16px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #111827;
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.deck-new-form {
    display: flex;
    gap: 8px;
    margin-bottom: 20px;
}

.deck-new-form input {
    flex: 1;
    padding: 8px 12px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    font-size: 14px;
}

.deck-new-form button {
    padding: 8px 16px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #111827;
    color: #ffffff;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
}

.deck-logged-out,
.deck-empty-state {
    padding: 40px 24px;
    text-align: center;
    color: #6b7280;
    background: #f8fafc;
    border-radius: 12px;
    margin-top: 12px;
}

.deck-empty-title {
    font-weight: 600;
    color: #111827;
    margin: 0 0 6px;
}

/* Deck LIST page rows: radio, name, words, total, due, mastered, actions.
   This generic (unscoped) definition is also relied on by the deck
   DETAIL page's word list (#deck-words-list overrides the column count
   further down) — keep it as the flat 7-column fallback and put all
   deck-list-specific restructuring behind the #deck-list scope below,
   so the detail page's word table is not affected. */
.deck-list-header-row,
.deck-row {
    display: grid;
    grid-template-columns: 32px 1fr 60px 70px 60px 90px 120px;
    align-items: center;
    gap: 8px;
    padding: 10px 8px;
    text-align: left;
}

.deck-list-header-row {
    font-size: 12px;
    color: #94a3b8;
}

.deck-list-header-row .col-total,
.deck-list-header-row .col-due,
.deck-list-header-row .col-mastered {
    text-align: right;
    white-space: nowrap;
}

.deck-row {
    border-top: 1px solid #f1f5f9;
    font-size: 14px;
}

.deck-row-active {
    background: #f8fafc;
}

.deck-row-name {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    row-gap: 2px;
    min-height: 46px;
}

.deck-row-due {
    color: #185fa5;
    font-weight: 600;
}

.deck-row span:not(.deck-row-name) {
    text-align: right;
}

.deck-new-form[hidden],
.deck-empty-state[hidden],
.deck-logged-out[hidden],
.deck-list[hidden] {
    display: none;
}

.deck-active-badge {
    font-size: 11px;
    font-weight: 600;
    color: #185fa5;
    background: #e6f1fb;
    padding: 2px 8px;
    border-radius: 999px;
}

.deck-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%) translateY(8px);
    background: #111827;
    color: #ffffff;
    font-size: 13px;
    padding: 10px 18px;
    border-radius: 8px;
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    z-index: 100;
}

.deck-toast-visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.deck-toast[hidden] {
    display: none;
}

.deck-cell-actions {
    display: flex;
    justify-content: flex-end;
}

/* Start/Edit/Delete are grouped into a single pill so they read as one
   action cluster instead of three independently-spaced elements —
   Start is the filled primary action, Edit/Delete are compact icon
   buttons riding directly next to it inside the same container. */
.deck-action-cluster {
    display: flex;
    align-items: center;
    gap: 2px;
    background: #f8fafc;
    border-radius: 999px;
    padding: 3px;
}

.deck-action-cluster .deck-start-link {
    color: #ffffff;
    background: #185fa5;
    font-size: 12px;
    font-weight: 600;
    padding: 6px 14px;
    border-radius: 999px;
    line-height: 1.4;
    text-decoration: none;
}

.deck-action-cluster .deck-start-link:hover {
    background: #124d87;
    color: #ffffff;
}

.deck-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: #6b7280;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.deck-icon-btn:hover {
    background: #e5e7eb;
    color: #111827;
}

.deck-icon-btn-danger:hover {
    background: #fee2e2;
    color: #dc2626;
}

/* Delete requires a second tap to confirm — the button itself flips
   to a solid red state (rather than swapping to a "Delete?" text
   label, which the icon-only button no longer has room for) so the
   confirm state is still unmistakable. */
.deck-icon-btn-armed {
    background: #dc2626;
    color: #ffffff;
}

.deck-icon-btn-armed:hover {
    background: #b91c1c;
    color: #ffffff;
}

.deck-rename-input {
    flex: 1;
    padding: 4px 8px;
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    font-size: 14px;
    font-family: inherit;
}

/* =========================================================
   DECK LIST PAGE — restructured to 4 grid areas (radio / name /
   stats / actions) instead of 7 flat columns. The "stats" area is a
   single flex child holding Words/Cards/Due/Mastered together, so on
   mobile it can drop to its own row as one unit instead of the whole
   grid being forced to fit 7 fixed-width columns into a narrow
   viewport (that fixed-column overflow was the cause of the
   horizontal scroll).

   Scoped to #deck-list so the deck DETAIL page's word-list table
   (#deck-words-list, further below) — which reuses .deck-row with a
   different column count — is completely unaffected by this.
   ========================================================= */

#deck-list .deck-list-header-row,
#deck-list .deck-row {
    /* Stats and actions are fixed widths, not auto — each row here is
       an independent CSS Grid instance (not shared rows of one table),
       so "auto" sizes a column based on THAT row's own content. The
       header row's actions column is empty (no Start/Edit/Delete),
       while every data row's is ~150px+ wide; with auto, that mismatch
       made the header's 1fr name column compute a different width than
       the data rows', shifting the Words/Total/Due/Mastered labels out
       of alignment with the numbers beneath them. Fixed widths force
       identical column boundaries across every row regardless of what
       each one actually contains. 272px comfortably fits the stats
       column's content ("Mastered" is the widest label, ~8 chars at
       12px); 172px fits the Start/Edit/Delete action cluster.
     */
    grid-template-columns: 28px 1fr 272px 172px;
    grid-template-areas: "radio name stats actions";
    gap: 8px 14px;
}

.deck-cell-radio { grid-area: radio; }
.deck-cell-name {
    grid-area: name;
    min-width: 0;
}
.deck-cell-actions { grid-area: actions; }

.deck-cell-stats {
    grid-area: stats;
    display: flex;
    justify-content: flex-end;
    gap: 14px;
    width: 100%;
}

.deck-stat {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    text-align: right;
}

.deck-stat-words { min-width: 50px; }
.deck-stat-cards { min-width: 60px; }
.deck-stat-due { min-width: 50px; }
.deck-stat-mastered { min-width: 70px; }

/* Header row's stat spans are plain text labels (no value/label split),
   so they just need the same widths + right alignment to line up with
   the data row's numbers underneath. */
#deck-list .deck-list-header-row .deck-stat {
    display: block;
    text-align: right;
    white-space: nowrap;
}

/* Data-row stat labels are mobile-only — hidden on desktop where the
   header row already supplies "Words / Cards / Due / Mastered". */
.deck-stat-label {
    display: none;
}

.deck-row .deck-stat-due .deck-stat-value {
    color: #185fa5;
    font-weight: 600;
}

/* =========================================================
   DECK DETAIL PAGE — word list (5 columns: word, translation,
   total, mastered, remove) — scoped so it doesn't affect the
   deck LIST page's rows above.
   ========================================================= */

#deck-words-list .deck-list-header-row,
#deck-words-list .deck-row {
    grid-template-columns: 1fr 1fr 60px 90px 80px;
}

#deck-detail-name {
    font-size: 22px;
    margin: 0 0 20px;
}

/* =========================================================
   LANE BREAKDOWN PILLS (deck list page)
   ========================================================= */

.deck-lane-breakdown {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 0 8px 10px 40px;
}

.deck-lane-pill {
    font-size: 10px;
    font-weight: 600;
    color: #6b7280;
    background: #f1f5f9;
    padding: 3px 10px;
    border-radius: 999px;
    border: 1px solid transparent;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.1s;
}

.deck-lane-pill:hover {
    background: #e5e7eb;
    color: #111827;
}

.deck-lane-pill:active {
    transform: scale(0.94);
}

/* JS already adds this class when a lane has cards (deck_list.html's
   renderRows()) — it just had no matching style before, so an active
   lane and an "off, click to enable" lane looked identical. Reusing
   the same blue used for the Active deck badge and Due count keeps it
   consistent with the rest of the page's accent color. */
.deck-lane-pill-on {
    background: #e6f1fb;
    color: #185fa5;
    border-color: #b9d9f0;
}

/* =========================================================
   PUBLIC DECK PAGE — read-only word list, no auth, own scoped
   classes (deliberately not reusing .deck-row/#deck-words-list —
   this table has fewer columns and no per-row actions).
   ========================================================= */

#deck-public-words {
    max-width: 480px;
    margin: 24px auto 0;
    background: #ffffff;
    border: 1px solid #e5e7eb;
    border-radius: 12px;
    padding: 8px 20px;
}

.deck-public-header-row,
.deck-public-row {
    display: grid;
    grid-template-columns: 1fr 1fr 1.5fr;
    gap: 12px;
    padding: 10px 0;
    text-align: left;
}

.deck-public-header-row {
    font-size: 12px;
    color: #94a3b8;
    border-bottom: 1px solid #f1f5f9;
}

.deck-public-row {
    border-top: 1px solid #f1f5f9;
    font-size: 14px;
}

.deck-public-word {
    font-weight: 600;
    color: #111827;
}

.deck-public-pinyin {
    color: #6b7280;
}

.deck-public-translation {
    color: #374151;
}

/* =========================================================
   SHARE TOGGLE + PUBLIC BADGE (deck list page)
   ========================================================= */

/* =========================================================
   SHARE — two permanently-reserved rows below the lane pills, for
   every deck regardless of is_public. The link row's height is fixed
   and always rendered; only its contents' visibility toggles (not
   display), so toggling a deck's share state never changes any row's
   height — which was the actual cause of the list jumping/reflowing on
   every click.
   ========================================================= */

.deck-share-checkbox-row {
    padding: 0 8px 4px 40px;
}

.deck-share-checkbox-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    color: #6b7280;
    cursor: pointer;
}

.deck-share-checkbox-label input[type="checkbox"] {
    cursor: pointer;
}

.deck-share-link-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 8px 12px 40px;
    min-height: 24px;
}

.deck-share-link {
    flex: 1;
    min-width: 0;
    font-size: 12px;
    color: #6b7280;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.deck-copy-link-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    flex-shrink: 0;
    color: #6b7280;
    background: transparent;
    font-size: 12px;
    font-weight: 600;
    padding: 5px 12px;
    border: 1px solid #e5e7eb;
    border-radius: 999px;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}

.deck-copy-link-btn:hover {
    background: #e5e7eb;
    color: #111827;
}

.deck-public-badge {
    font-size: 11px;
    font-weight: 600;
    color: #16a34a;
    background: #dcfce7;
    padding: 2px 8px;
    border-radius: 999px;
}

/* =========================================================
   MOBILE — deck list page only. Drops the stats block (Words/
   Cards/Due/Mastered) to its own row below name+actions instead of
   forcing everything into one horizontally-scrolling row. Header row
   is hidden since its labels move inline next to each value instead.
   ========================================================= */
@media (max-width: 640px) {
    .deck-page {
        padding: 0 12px;
        margin-top: 32px;
    }

    #deck-list .deck-list-header-row {
        display: none;
    }

    #deck-list .deck-row {
        grid-template-columns: 24px 1fr auto;
        grid-template-areas:
            "radio name actions"
            "stats stats stats";
        row-gap: 6px;
        padding: 12px 6px;
    }

    .deck-cell-stats {
        flex-wrap: wrap;
        gap: 6px 16px;
        padding-left: 32px;
    }

    .deck-stat {
        flex-direction: row;
        align-items: baseline;
        gap: 4px;
        min-width: 0;
        text-align: left;
    }

    .deck-stat-label {
        display: inline;
        font-size: 11px;
        color: #94a3b8;
    }

    .deck-lane-breakdown {
        padding-left: 32px;
    }
}