/* ============================================================
   FELT — style.css
   ============================================================ */

/* --- Design Tokens --- */
:root {
    --bg:           #080f1a;
    --surface:      #0d1829;
    --surface-2:    #101c2e;
    --surface-3:    #1a2d4a;
    --border:       rgba(255,255,255,0.07);
    --border-2:     rgba(255,255,255,0.12);
    --text:         #f1f5f9;
    --text-2:       #94a3b8; /* was #64748b (4.0:1 on --bg) — now 7.5:1 */
    --text-3:       #7889a0; /* was #334155 (1.9:1 on --bg) — now 5.4:1 */
    --accent:       #4a7fb5;
    --accent-bright:#60a5fa;
    --live:         #10b981;
    --live-dim:     rgba(16,185,129,0.12);
    --live-border:  rgba(16,185,129,0.25);
    --live-text:    #34d399;
    --warn:         #f59e0b;
    --danger:       #ef4444;
    --danger-dim:   rgba(239,68,68,0.12);
    --success:      #10b981;
    --muted:        #475569;
    /* Brand gold, sampled from the wordmark. Used where Felt is selling
       itself (landing page, the sign-in wall on an invite) rather than
       across the working app, which keeps --accent. */
    --gold:         #d4ae63;
    --gold-ink:     #1a1204;
    --gold-dim:     rgba(212,174,99,0.12);
}

/* --- Reset --- */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}

body {
    background: var(--bg);
    color: var(--text);
    font-size: 0.85rem;
    -webkit-text-size-adjust: 100%;
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.container {
    max-width: 480px;
    margin: 0 auto;
}

/* --- Screen routing --- */
.screen { display: none; }
.screen.active { display: block; }

/* --- Top header --- */
header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 16px 10px;
    background: var(--bg);
    position: sticky;
    top: 0;
    z-index: 100;
    border-bottom: 1px solid var(--border);
}

.felt-wordmark {
    display: flex;
    align-items: center;
}
.felt-logo-img {
    height: 36px;
    width: auto;
    border-radius: 8px;
}

/* Back link: always the top left of a drill-down screen, on its own row
   under the logo so the logo never moves between screens. Inside the
   sticky header (which wraps for it), so it stays reachable on scroll. */
header { flex-wrap: wrap; }
.back-row { flex-basis: 100%; }
.back-link {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    margin: 8px 0 0 -4px;
    padding: 4px 6px 4px 0;
    background: none;
    border: none;
    color: var(--text-2);
    font-size: 13px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.back-link:active { color: var(--text); }
/* Drill-down headers have no logo — the back link is the top row. */
.header-sub .back-link, .gh-top-row .back-link { margin-top: 0; }
.header-sub { padding-bottom: 6px; }

.header-right {
    display: flex;
    align-items: center;
    gap: 8px;
}
.user-avatar {
    width: 30px; height: 30px;
    border-radius: 50%;
    border: 1.5px solid var(--surface-3);
    cursor: pointer;
}
.user-avatar-initials {
    width: 30px; height: 30px;
    border-radius: 50%;
    background: var(--surface-3);
    border: 1.5px solid rgba(74,127,181,0.4);
    display: flex; align-items: center; justify-content: center;
    font-size: 11px; font-weight: 500; color: var(--accent-bright);
    cursor: pointer;
}
.btn-logout {
    background: transparent;
    color: var(--text-2);
    font-size: 0.7rem;
    text-decoration: none;
    border: 1px solid var(--border-2);
    padding: 4px 8px;
    border-radius: 6px;
    cursor: pointer;
}
.admin-nav-link {
    color: #a78bfa;
    font-size: 0.7rem;
    font-weight: 500;
    text-decoration: none;
    border: 1px dashed rgba(139,92,246,0.3);
    padding: 3px 7px;
    border-radius: 6px;
    background: rgba(139,92,246,0.05);
}
/* --- End game button (inline, List view only) --- */
.btn-settle-inline {
    width: 100%;
    background: transparent;
    color: var(--live-text);
    padding: 9px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 9px;
    border: 1px solid var(--live-border);
    cursor: pointer;
    letter-spacing: 0.02em;
}
.btn-settle-inline:active { background: var(--live-dim); }

/* The bottom nav is gone — Home is the only destination, Profile and New game
   are sheets over it. This keyframe lived in that block and is still used by
   .live-dot and the pending-seat ring, so it stays. */
@keyframes pulse-yellow {
    0%   { box-shadow: 0 0 0 0 rgba(245,158,11,0.6); }
    70%  { box-shadow: 0 0 0 6px rgba(245,158,11,0); }
    100% { box-shadow: 0 0 0 0 rgba(245,158,11,0); }
}

/* --- Page padding --- */
/* Bottom padding cleared for the fixed tab bar. Every .page-body-holding
   screen gets it, including Admin/Archive where the bar is actually hidden
   (renderTabBar) — a little unused whitespace there beats conditional
   padding per screen. */
.page-body { padding: 12px 14px 84px; }

.ss-value.pos { color: var(--live-text); }

/* --- Feed: live hero --- */
/* The only element in the feed with full elevation. Exactly one live game
   ever gets it — see liveAttendanceRank(). */
.feed-hero {
    background: var(--live-dim);
    border: 1px solid var(--live-border);
    border-radius: 12px;
    padding: 13px 14px 14px;
    margin: 10px 0 12px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.hero-live {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11px;
    color: var(--live-text);
    letter-spacing: 0.04em;
    margin-bottom: 8px;
}
.hero-mid {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}
/* Groups title + cardroom tag as one flex item so space-between still puts
   all the free space between this group and .hero-bank, not between the
   title and its own tag. */
.hero-title-wrap {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
    overflow: hidden;
}
.hero-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.hero-bank {
    font-size: 20px;
    font-weight: 600;
    color: var(--live-text);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}
.hero-people {
    display: flex;
    align-items: center;
    gap: 9px;
    margin: 11px 0 12px;
}
.hero-avatars { display: flex; }
.hero-av {
    width: 24px; height: 24px;
    border-radius: 50%;
    border: 1.5px solid var(--bg);
    background: var(--surface-3);
    object-fit: cover;
    flex-shrink: 0;
}
.hero-av + .hero-av { margin-left: -6px; }
.hero-av.initials, .hero-av.more {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
    color: var(--text-2);
}
.hero-count { font-size: 11px; color: var(--text-2); }
.hero-cta {
    background: var(--live);
    color: #04342c;
    border-radius: 9px;
    text-align: center;
    padding: 9px;
    font-size: 13px;
    font-weight: 500;
}

/* --- Feed: flat rows --- */
/* History, and live games you aren't at. Deliberately no border and no raised
   background — elevation is reserved for things you can act on. */
.feed-row {
    display: flex;
    align-items: center;
    gap: 11px;
    padding: 9px 2px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.feed-row:active { background: var(--surface-2); }
.fr-date {
    width: 30px;
    flex-shrink: 0;
    text-align: center;
}
.fr-mon { display: block; font-size: 11px; color: var(--text-3); letter-spacing: 0.04em; }
.fr-day { display: block; font-size: 13px; color: var(--text-2); }
.fr-title {
    flex: 1;
    min-width: 0;
    font-size: 13px;
    color: var(--text-2);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fr-live {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--live-text);
    flex-shrink: 0;
}
.fr-amount {
    font-size: 12px;
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
    flex-shrink: 0;
}

/* --- Signed-out welcome --- */
.welcome-card {
    text-align: center;
    padding: 34px 20px 26px;
}
.welcome-icon { font-size: 30px; opacity: 0.25; margin-bottom: 14px; }
.welcome-title {
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -0.3px;
    color: var(--text);
    margin-bottom: 9px;
}
.welcome-body {
    font-size: 13px;
    color: var(--text-2);
    line-height: 1.55;
    max-width: 300px;
    margin: 0 auto 20px;
}
.welcome-card .signin-btn { max-width: 260px; margin: 0 auto; }
.welcome-foot { font-size: 12px; color: var(--text-3); margin-top: 16px; }

/* --- Sign-in gates --- */
/* The view stays open to anyone with the link; these replace the controls
   that write. */
.btn-rsvp-signin {
    flex: 1;
    min-height: 40px;
    background: var(--gold);
    color: var(--gold-ink);
    border: none;
    border-radius: 9px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}

.field-optional {
    font-size: 11px;
    color: var(--text-3);
    font-weight: 400;
    margin-left: 5px;
}
.field-hint {
    font-size: 11px;
    color: var(--text-3);
    line-height: 1.45;
    margin-top: 5px;
}

.feed-month {
    font-size: 11px;
    color: var(--text-3);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 18px 2px 4px;
}

/* The Live now / Upcoming / History section headers are gone with the feed
   rewrite — one surface, no labelled sections. Month dividers (.feed-month)
   are the only heading left. */

/* --- Session cards --- */
.session-card {
    border-radius: 12px;
    margin-bottom: 8px;
    overflow: hidden;
    border: 1px solid var(--border);
    background: var(--surface);
}
.session-card.live-game {
    background: var(--live-dim);
    border-color: var(--live-border);
}
/* Completed cards previously also got opacity:0.6 on top of the title's
   already-muted color — double-dimming that fought the contrast fix.
   Color alone (.row-title.dimmed) now carries the "this is history" signal. */

.card-click-zone {
    padding: 12px 14px 10px;
    cursor: pointer;
    display: block;
}
.card-action-zone {
    padding: 0 14px 12px;
}
.card-action-zone.with-border {
    padding-top: 8px;
    border-top: 1px solid var(--border);
}

.card-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 5px;
    gap: 8px;
}
.card-title {
    font-size: 13px;
    font-weight: 500;
    color: var(--text);
    letter-spacing: -0.1px;
    flex: 1;
    min-width: 0;
}
.card-title.dimmed { color: var(--text-2); }

.state-pill {
    font-size: 9px;
    padding: 3px 8px;
    border-radius: 20px;
    font-weight: 500;
    letter-spacing: 0.03em;
    white-space: nowrap;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 4px;
}
.pill-live    { background: var(--live-dim); color: var(--live-text); border: 1px solid var(--live-border); }

.live-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--warn);
    display: inline-block;
    flex-shrink: 0;
    box-shadow: 0 0 0 0 rgba(245,158,11,0.6);
    animation: pulse-yellow 1.8s ease-out infinite;
}

.card-meta {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--text-2);
    margin-bottom: 8px;
}
.card-meta i { font-size: 12px; }

.card-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.card-stat {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: var(--text);
}
.card-stat i { font-size: 12px; }
.card-bank { font-size: 12px; font-weight: 500; color: var(--live-text); }
.card-bank.neutral { color: var(--text-2); }

.live-elapsed { font-size: 10px; color: var(--live-text); }

.row-chevron { font-size: 15px; color: var(--text-3); flex-shrink: 0; line-height: 1; }

.rsvp-strip {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0 14px 12px;
}
.rsvp-my-status {
    font-size: 12px;
    font-weight: 700;
    flex: 1;
    color: var(--text-2);
}
.rsvp-my-status.in  { color: var(--live); }
.rsvp-my-status.out { color: #f87171; }
.rsvp-my-status.wait { color: var(--warn); }

/* --- Schedule panel --- */
.collapse-trigger {
    background: var(--surface);
    padding: 11px 14px;
    border-radius: 10px;
    margin-bottom: 8px;
    cursor: pointer;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 500;
    font-size: 13px;
    user-select: none;
    border: 1px solid var(--border);
    color: var(--text);
}
.collapse-icon { font-size: 10px; color: var(--text-3); }
.collapse-content {
    display: none;
    background: var(--surface);
    padding: 12px 14px;
    border-radius: 0 0 10px 10px;
    margin-top: -10px;
    margin-bottom: 8px;
    border: 1px solid var(--border);
    border-top: none;
}
.collapse-content.open { display: block; }

.input-stack { display: flex; flex-direction: column; gap: 7px; }
.input-row { display: flex; gap: 6px; }
.input-row input, .input-row select { flex: 1; min-width: 0; }

input, select {
    background: var(--bg);
    border: 1px solid var(--surface-3);
    color: var(--text);
    padding: 7px 9px;
    border-radius: 7px;
    font-size: 16px; /* iOS zooms on focus if font-size < 16px */
}
input::placeholder { color: var(--text-3); }
input[type="text"], input[type="email"] { flex: 2; min-width: 0; }
input[type="number"], input[type="date"], input[type="time"], select { flex: 1; min-width: 0; }

/* Any select left in a compact inline row (the list-view add-player form)
   keeps its native behaviour but must never again be mistaken for a filled-in
   text field sitting next to it. Explicit caret, since iOS Safari draws none
   once a select is styled at all. */
select {
    -webkit-appearance: none;
    appearance: none;
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    padding-right: 26px;
}

/* --- Payment method chips ---
   Replaced the <select> in the money modals. Six options, all visible, one
   tap each — the select they replaced was indistinguishable from the amount
   input above it and everyone submitted its first option without noticing. */
.method-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    border-radius: 9px;
}
.method-chip {
    flex: 1 1 auto;
    min-width: 72px;
    padding: 11px 10px;
    border-radius: 8px;
    background: var(--surface-2);
    border: 1px solid var(--border-2);
    color: var(--text-2);
    font-size: 13px;
    font-weight: 500;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.method-chip:active { background: var(--surface-3); }
.method-chip.selected {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
    font-weight: 600;
}
/* Submitted without picking one — same nudge the amount field gets. */
.method-chips.needs-pick {
    animation: chip-nudge 0.4s ease;
    box-shadow: 0 0 0 2px var(--danger);
}
@keyframes chip-nudge {
    0%, 100% { transform: translateX(0); }
    25%      { transform: translateX(-4px); }
    75%      { transform: translateX(4px); }
}
@media (prefers-reduced-motion: reduce) {
    .method-chips.needs-pick { animation: none; }
}

button { cursor: pointer; font-weight: 500; border: none; border-radius: 6px; }
.btn-primary {
    background: var(--accent);
    color: white;
    padding: 9px 14px;
    font-size: 0.82rem;
    border-radius: 8px;
    width: 100%;
}

/* --- Status buttons (Start now / Propose) --- */
.status-btn-group {
    display: flex;
    gap: 6px;
}
.status-btn {
    flex: 1;
    padding: 8px 0;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    background: var(--surface-2);
    color: var(--text-2);
    border: 1px solid var(--surface-3);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.status-btn.active {
    background: var(--accent);
    color: #fff;
    border-color: var(--accent);
}

/* --- New Game sheet: labels, hints, stakes picker --- */
.field-label {
    font-size: 10px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-top: 4px;
}
.field-hint { font-size: 11.5px; color: var(--text-3); min-height: 0; }
.field-hint:empty { display: none; }
.status-btn-group.needs-pick {
    animation: chip-nudge 0.4s ease;
    box-shadow: 0 0 0 2px var(--danger);
    border-radius: 9px;
}
@media (prefers-reduced-motion: reduce) {
    .status-btn-group.needs-pick { animation: none; }
}
.stakes-picker { display: flex; flex-direction: column; gap: 7px; }
/* Blinds dropdown and buy-in side by side, equal halves. */
.stakes-row { gap: 8px; }
.stakes-col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.stakes-select { width: 100%; font-variant-numeric: tabular-nums; }
.stakes-row { align-items: flex-start; }
.stakes-other { display: flex; gap: 6px; margin-top: 2px; }
.stakes-blind { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
/* Seats: a few digits wide, hint beside it rather than under it. */
.seats-row { display: flex; align-items: center; gap: 10px; margin-top: 4px; }
/* .seats-row prefix outranks the global input[type="text"] { flex: 2 }. */
.seats-row .seats-input { flex: 0 0 92px; width: 92px; box-sizing: border-box; }
/* Fixed "$" inside the box — the host types the number only. */
.money-input { position: relative; display: flex; flex: 1; min-width: 0; }
.money-input > span {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--text-3);
    font-size: 15px;
    pointer-events: none;
}
.money-input input { flex: 1; width: 100%; padding-left: 22px; }

/* Notes: multi-line box in the form/modal, read-only block on the game
   screen, two-line teaser on a proposal card. */
.notes-input {
    width: 100%;
    box-sizing: border-box;
    background: var(--bg);
    border: 1px solid var(--surface-3);
    color: var(--text);
    padding: 7px 9px;
    border-radius: 7px;
    font: inherit;
    font-size: 16px; /* iOS zooms on focus below 16px */
    resize: vertical;
}
.notes-input::placeholder { color: var(--text-3); }
.game-notes {
    margin: 0 14px 10px;
    padding: 9px 12px;
    background: var(--surface-2);
    border-radius: 9px;
    font-size: 12.5px;
    color: var(--text-2);
    overflow-wrap: anywhere;
}
/* pre-wrap on the text only — on the box it would also render the markup's
   own indentation as blank lines around the label. */
#game-notes-text { white-space: pre-wrap; }
#game-notes-text.clamped {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.game-notes-more {
    background: none; border: none; padding: 4px 0 0;
    font-size: 12px; font-weight: 500; color: var(--accent);
    cursor: pointer;
}
/* The one line under the game title: countdown / stakes / date, an
   optional lock, then Details. JS sets .with-sep on all but the first
   visible item. */
.gh-meta-row {
    display: flex; align-items: center; flex-wrap: wrap; gap: 0 6px;
    padding-top: 2px;
    font-size: 12px; color: var(--text-2);
    font-variant-numeric: tabular-nums;
}
.gh-meta-row > .with-sep::before { content: '·'; color: var(--text-3); margin-right: 6px; }
.gh-lock { display: inline-flex; align-items: center; color: var(--text-2); }
.gh-lock svg { display: block; }
.gh-details-link {
    background: none; border: none; padding: 0;
    font-size: 12px; color: var(--accent); cursor: pointer;
}
/* Details sheet */
.details-sheet-body { padding: 0 4px 12px; max-height: 65vh; overflow-y: auto; }
.details-row { padding: 9px 0; border-bottom: 1px solid var(--border); }
.details-row:last-child { border-bottom: none; }
.details-label {
    font-size: 10px; color: var(--text-3);
    text-transform: uppercase; letter-spacing: 0.06em; font-weight: 500;
    margin-bottom: 3px;
}
.details-value { font-size: 14px; color: var(--text); line-height: 1.45; }
.details-notes { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-2); }
.game-notes-label {
    font-size: 10px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 500;
    margin-bottom: 4px;
}
/* "James invited you to" — above the title, for invitees on a Scheduled game. */
.gh-invited-by { font-size: 12px; color: var(--text-2); margin: 2px 0 2px; }


/* --- Other method text input --- */
.other-label-input {
    background: var(--bg);
    border: 1px solid var(--surface-3);
    color: var(--text);
    border-radius: 6px;
    padding: 5px 8px;
    font-size: 16px;
}

/* --- Sort / dash controls --- */
.sort-action-btn {
    background: var(--surface);
    border: 1px solid var(--surface-3);
    color: var(--text-2);
    font-size: 10px;
    padding: 3px 8px;
    border-radius: 6px;
    cursor: pointer;
}

/* --- Empty states --- */
.empty-state {
    text-align: center;
    padding: 28px 16px;
    color: var(--text-3);
    font-size: 12px;
    line-height: 1.6;
}
.empty-icon { font-size: 26px; opacity: 0.3; margin-bottom: 8px; display: block; }

/* --- Archive --- */
.archive-item-controls { display: flex; gap: 4px; }
/* Archive rows reuse the history-row layout (.settings-row + .fr-date);
   the buttons follow the roster's .action-btn look. */
.archive-row { cursor: default; gap: 11px; }
.archive-row-main { flex: 1; min-width: 0; }
.archive-row-main .fr-title { display: block; }
.archive-row-meta { font-size: 11px; color: var(--text-3); margin-top: 2px; }
.archive-item-controls { display: flex; gap: 6px; flex-shrink: 0; }
.btn-restore, .btn-purge {
    padding: 7px 12px;
    border-radius: 8px;
    border: none;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}
.btn-restore { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
.btn-purge   { background: var(--danger-dim); color: var(--danger); }

/* ── Game screen ──────────────────────────────────────────── */
.game-header {
    padding: 14px 16px 10px; /* matches header, so the logo doesn't shift */
    background: var(--bg);
    border-bottom: 1px solid var(--border);
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    flex-direction: column;
}
.gh-top-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
}
.gh-left { display: flex; flex-direction: column; }
.gh-delete-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--text-3);
    cursor: pointer;
    padding: 6px;
    margin: -6px 0;
}
.gh-delete-icon:active { color: var(--danger); }
.gh-title {
    font-size: 16px;
    font-weight: 500;
    letter-spacing: -0.3px;
    color: var(--text);
    margin-bottom: 4px;
}

/* Edit game sheet */
.edit-section-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text);
    margin: 18px 0 6px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}
.modal-title + .edit-section-title { margin-top: 4px; padding-top: 0; border-top: none; }
.settings-row.edit-toggle-row { margin: 8px 0 0; padding: 10px 0 4px; cursor: default; border-bottom: none; }
.edit-locked-note { color: var(--warn); margin-top: 2px; }
.toggle-pill:disabled,
#stakes-modal input:disabled,
#stakes-modal select:disabled { opacity: 0.45; cursor: not-allowed; }

/* Progress tracker — informational only */
.progress-track {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 10px;
}
.prog-step { display: flex; align-items: center; gap: 6px; }
.prog-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}
.prog-dot.done   { background: var(--live); }
.prog-dot.active { background: var(--accent); }
.prog-dot.future { background: var(--surface-3); }
.prog-label { font-size: 10px; color: var(--text-3); }
.prog-label.active { color: var(--text); font-weight: 600; }
.prog-line { flex: 1; height: 1px; background: var(--border); }
.prog-line.done { background: var(--live); opacity: 0.4; }

/* Ledger stats */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    margin-bottom: 8px;
    padding: 10px 14px 0;
}
.stat-card {
    background: var(--surface);
    padding: 8px 6px;
    border-radius: 10px;
    text-align: center;
    border: 1px solid var(--border);
}
.stat-label { font-size: 10px; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.05em; }
.stat-value { font-size: 16px; font-weight: 600; margin-top: 3px; font-variant-numeric: tabular-nums; }
.status-match    { color: var(--live); }
.status-mismatch { color: var(--warn); }

/* Warning box */
.warning-box {
    background: rgba(245,158,11,0.07);
    border: 1px solid rgba(245,158,11,0.2);
    border-radius: 10px;
    padding: 10px 12px;
    margin: 0 14px 8px;
}
.warning-box .warn-head {
    font-size: 12px;
    color: var(--warn);
    font-weight: 500;
    margin-bottom: 3px;
}
.warning-box .warn-body { font-size: 11px; color: var(--text-2); }

/* Payment breakdown */
.payment-breakdown {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    row-gap: 4px;
    padding: 6px 14px;
    font-size: 11px;
    color: var(--text-2);
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    margin-bottom: 8px;
}
.payment-breakdown { font-size: 12px; color: var(--text-2); }
.payment-breakdown span { color: var(--accent-bright); font-weight: 600; }

/* RSVP summary */
.rsvp-summary-box {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 12px;
    margin: 10px 14px 8px;
}
.rsvp-summary-title {
    font-size: 10px;
    color: var(--text-3);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 500;
    margin-bottom: 6px;
}
.rsvp-summary-list { display: grid; grid-auto-columns: minmax(0, 1fr); grid-auto-flow: column; gap: 8px; }
.rsvp-col { display: flex; flex-direction: column; gap: 4px; }
.rsvp-col-header { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 2px; }
.rsvp-col-header.in  { color: var(--live); }
.rsvp-col-header.out { color: var(--danger); }
.rsvp-col-header.wait { color: var(--warn); }
.rsvp-col-name { font-size: 12px; color: var(--text); background: var(--bg); padding: 5px 8px; border-radius: 6px; }

/* Add player */
.form-card {
    background: var(--surface);
    padding: 8px 10px;
    border-radius: 10px;
    margin: 0 14px 10px;
    border: 1px solid var(--border);
}
.form-group {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    align-items: center;
}
.form-group input[type="text"] { flex: 1 1 120px; min-width: 0; }
.form-group input[type="number"] { width: 60px; flex-shrink: 0; }
.form-group select { flex: 1 1 80px; min-width: 0; }
.form-group .name-typeahead-wrap { position: relative; flex: 1 1 120px; min-width: 0; }
.form-group .name-typeahead-wrap input[type="text"] { width: 100%; }

/* Player name typeahead — suggests people you've hosted before */
.name-typeahead-wrap { position: relative; }
.name-suggest-list {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 20;
    background: var(--surface-2);
    border: 1px solid var(--surface-3);
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 4px 14px rgba(0,0,0,0.35);
}
.name-suggest-list.open { display: block; }
.name-suggest-item {
    padding: 8px 10px;
    font-size: 13px;
    color: var(--text);
    cursor: pointer;
}
.name-suggest-item:hover, .name-suggest-item.active { background: var(--surface-3); }
.name-suggest-item + .name-suggest-item { border-top: 1px solid var(--border); }
.form-group .btn-add { flex-shrink: 0; }
.btn-add {
    background: var(--accent);
    color: white;
    padding: 7px 12px;
    font-size: 12px;
    border-radius: 7px;
    white-space: nowrap;
}

/* Player list */
.player-list { display: flex; flex-direction: column; gap: 4px; padding: 0 14px; margin-bottom: 10px; }
.player-block {
    background: var(--surface);
    border-radius: 10px;
    overflow: hidden;
    border-left: 3px solid var(--accent);
}
.player-block.busted-out { border-left-color: var(--text-3); opacity: 0.55; }
/* RSVP'd In, hasn't bought in yet: muted, but not dimmed like a cash-out. */
.player-block.not-seated { border-left-color: var(--text-3); }
.player-row {
    padding: 10px 10px 0;
    display: flex;
    flex-direction: column;
    gap: 0;
}
.player-row-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    cursor: pointer;
    padding-bottom: 8px;
}

.p-identity { display: flex; flex-direction: column; min-width: 0; gap: 3px; flex: 1; }
.p-name { font-weight: 600; font-size: 14px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.p-status-dot { font-size: 11px; color: var(--text-2); display: flex; align-items: center; gap: 5px; }

.p-action-row {
    display: flex;
    gap: 6px;
    padding: 4px 0 10px;
}

.action-btn {
    flex: 1;
    padding: 8px 4px;
    border-radius: 8px;
    border: none;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    text-align: center;
}
.action-btn.rebuy  { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
.action-btn.toggle { background: rgba(100,116,139,0.15); color: var(--text-2); }
.action-btn.toggle.out { background: rgba(16,185,129,0.12); color: var(--live); }
.action-btn.manager { background: rgba(100,116,139,0.15); color: var(--text-2); }
.action-btn.manager.on { background: rgba(96,165,250,0.15); color: var(--accent-bright); }
.action-btn.remove { background: var(--danger-dim); color: var(--danger); }
.action-btn.remove.small {
    flex: 0 0 36px;
    padding: 8px 0;
    font-size: 11px;
    opacity: 0.6;
}

.active-pulse {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--live);
    flex-shrink: 0;
    box-shadow: 0 0 0 0 rgba(16,185,129,0.6);
    animation: pulse-green 1.8s ease-out infinite;
}
@keyframes pulse-green {
    0%   { box-shadow: 0 0 0 0 rgba(16,185,129,0.6); }
    70%  { box-shadow: 0 0 0 6px rgba(16,185,129,0); }
    100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); }
}
.stood-up-dot, .out-dot {
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--danger);
    flex-shrink: 0;
}
.status-active-label { color: var(--live-text); font-weight: 500; }
.status-out-label    { color: var(--danger); font-weight: 500; }
.status-waiting-label { color: var(--text-2); font-weight: 500; }
.history-hint        { color: var(--text-2); font-size: 10px; margin-left: 2px; }

.p-finances { display: flex; align-items: center; gap: 10px; margin-left: auto; flex-shrink: 0; }
.fin-inline { display: flex; flex-direction: column; align-items: flex-end; gap: 1px; }
.fin-label { font-size: 10px; color: var(--text-2); text-transform: uppercase; letter-spacing: 0.04em; white-space: nowrap; }
.fin-val { font-weight: 700; font-size: 20px; font-variant-numeric: tabular-nums; color: var(--text); }
.fin-sep { color: var(--border); font-size: 20px; font-weight: 300; align-self: center; }

.mini-cash-wrapper {
    display: flex;
    align-items: center;
    background: var(--bg);
    border: 1px solid var(--surface-3);
    border-radius: 5px;
    padding: 2px 4px;
    width: 76px;
}
.mini-cash-wrapper > span { color: var(--text-3); font-size: 13px; }
.mini-cash-wrapper input {
    background: transparent;
    border: none;
    padding: 0;
    color: var(--text);
    font-size: 15px;
    font-weight: 700;
    width: 100%;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
input[type=number] { -moz-appearance: textfield; }

.cashout-method-select {
    background: var(--bg);
    border: 1px solid var(--surface-3);
    color: var(--text-2);
    font-size: 11px;
    padding: 2px 4px;
    border-radius: 5px;
    margin-left: 4px;
    flex-shrink: 0;
}
.p-profit { font-weight: 700; font-size: 16px; flex-shrink: 0; font-variant-numeric: tabular-nums; }
.profit-pos { color: var(--live); }
.profit-neg { color: var(--danger); }

.p-actions { display: flex; gap: 5px; align-items: center; flex-shrink: 0; }
.icon-btn {
    width: 32px; height: 32px;
    border-radius: 7px;
    display: flex; align-items: center; justify-content: center;
    font-size: 15px;
    border: none;
    cursor: pointer;
}
.icon-btn.rebuy         { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
.icon-btn.toggle        { background: rgba(100,116,139,0.15); color: var(--text-2); }
.icon-btn.toggle.busted { background: rgba(16,185,129,0.15); color: var(--live); }
.icon-btn.remove        { background: var(--danger-dim); color: var(--danger); }

.player-drawer {
    background: var(--bg);
    border-top: 1px solid var(--border);
    padding: 6px 10px;
}
.tx-history-list { display: flex; flex-direction: column; gap: 3px; }
.tx-item { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-2); }
.tx-method-badge {
    font-size: 9px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    padding: 1px 5px;
    border-radius: 4px;
    color: var(--text-3);
}

/* Host ledger corrections — the pencil on each drawer row, the amended /
   removed markers everyone sees, and the "add a missing entry" affordance.
   .tx-item is a flex row, so the controls sit inside its right-hand group. */
.tx-item { align-items: center; gap: 8px; min-height: 20px; }
.tx-item > div { display: flex; align-items: center; gap: 4px; }

.tx-edit-btn {
    background: none;
    border: none;
    color: var(--text-3);
    font-size: 11px;
    line-height: 1;
    padding: 2px 4px;
    margin-left: 2px;
    cursor: pointer;
    border-radius: 4px;
}
.tx-edit-btn:hover { color: var(--accent-bright); background: var(--surface-2); }

/* Reads as a quiet annotation on the line it belongs to, never as a number
   that could be mistaken for part of the amount. */
.tx-amended {
    font-size: 9px;
    font-style: italic;
    color: var(--text-3);
    margin-left: 6px;
}

.tx-removed { opacity: 0.55; }
.tx-removed > span:first-child,
.tx-removed > div { text-decoration: line-through; }
.tx-removed .tx-amended { text-decoration: none; }

.tx-add-row { justify-content: flex-start; margin-top: 4px; }
.tx-add-btn {
    background: none;
    border: 1px dashed var(--border);
    color: var(--text-3);
    font-size: 10px;
    padding: 3px 8px;
    border-radius: 5px;
    cursor: pointer;
}
.tx-add-btn:hover { color: var(--accent-bright); border-color: var(--accent); }
/* Outstanding-credit repayment — deliberately warmer than the neutral "add a
   missing entry" dashed button, since this one represents real money still
   owed rather than a routine correction. */
.tx-repay-btn { border-style: solid; border-color: rgba(245,158,11,0.4); color: #fcd34d; }
.tx-repay-btn:hover { color: #fcd34d; border-color: #fcd34d; }

/* Sits under the Cancel/Save pair as a deliberately secondary, destructive
   action — not a third peer button competing with them. */
.btn-ledger-delete {
    display: block;
    width: 100%;
    margin-top: 10px;
    background: none;
    border: none;
    color: var(--danger);
    font-size: 12px;
    padding: 6px;
    cursor: pointer;
    border-radius: 6px;
}
.btn-ledger-delete:hover { background: rgba(239,68,68,0.08); }

.modal-sub {
    font-size: 12px;
    color: var(--text-2);
    margin: -6px 0 12px;
}

/* Proposal banner */
#host-lock-banner {
    background: rgba(245,158,11,0.07);
    border: 1px solid rgba(245,158,11,0.2);
    border-radius: 10px;
    padding: 9px 12px;
    margin: 10px 14px 8px;
    display: none;
}
.lock-banner-inner {
    display: flex;
    flex-direction: column;
    gap: 9px;
}
.lock-banner-text { color: var(--warn); font-weight: 500; font-size: 12px; }
.lock-banner-actions { display: flex; gap: 8px; }
.btn-share-proposal, .btn-lock-date {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 10px;
    font-size: 12px;
    border-radius: 7px;
    cursor: pointer;
    font-weight: 600;
}
.btn-share-proposal {
    background: transparent;
    color: var(--warn);
    border: 1px solid rgba(245,158,11,0.4);
}
.btn-lock-date {
    background: var(--warn);
    color: #422006;
    border: none;
}
.btn-cancel-proposal {
    background: none;
    border: none;
    color: var(--text-3);
    font-size: 11px;
    text-align: center;
    padding: 2px;
    cursor: pointer;
    text-decoration: underline;
    text-decoration-color: transparent;
}
.btn-cancel-proposal:active { color: var(--danger); text-decoration-color: var(--danger); }

/* Pending requests banner (host) */
#requests-banner {
    background: rgba(245,158,11,0.07);
    border: 1px solid rgba(245,158,11,0.2);
    border-radius: 10px;
    margin: 10px 14px 8px;
    overflow: hidden;
}
.requests-banner-toggle {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: none;
    border: none;
    padding: 10px 12px;
    color: var(--warn);
    font-weight: 500;
    font-size: 12px;
    cursor: pointer;
}
/* The gap here sits between the bell and the label text, and nothing else —
   the phrase must stay a single child, or the gap lands inside the sentence. */
.requests-banner-label { display: flex; align-items: center; gap: 7px; }
.requests-banner-label svg { flex-shrink: 0; }
#requests-banner-chevron { transition: transform 0.15s ease; flex-shrink: 0; }
#requests-banner.expanded #requests-banner-chevron { transform: rotate(180deg); }
#requests-banner-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 10px 10px;
}
.request-card {
    background: var(--surface);
    border: 1px solid var(--surface-3);
    border-radius: 10px;
    padding: 10px 12px;
}
.request-card-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; }
.request-card-name { font-size: 13px; font-weight: 600; color: var(--text); }
.request-card-sub { font-size: 11px; color: var(--text-2); margin-top: 2px; }
.request-card-amount { font-size: 16px; font-weight: 700; color: var(--text); }
.request-card-actions { display: flex; gap: 8px; margin-top: 10px; }
.request-card-actions button { flex: 1; padding: 8px; font-size: 12px; border-radius: 7px; }
.btn-request-decline { background: var(--surface-2); color: var(--danger); border: 1px solid rgba(239,68,68,0.3); }
.btn-request-confirm { background: var(--live); color: #022c22; font-weight: 700; border: none; }

/* You tab */
.you-status-card {
    background: var(--surface);
    border: 1px solid var(--surface-3);
    border-radius: 12px;
    padding: 18px 16px;
    margin: 4px 14px 12px;
    text-align: center;
}
.you-status-card .you-hint { font-size: 12px; color: var(--text-2); margin-bottom: 12px; }
.you-stack-label { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; }
.you-stack-value { font-size: 28px; font-weight: 700; margin: 4px 0; }
.you-status-pill { font-size: 12px; font-weight: 500; }
.you-status-pill.pending { color: var(--warn); }
.you-status-pill.confirmed { color: var(--live-text); }
.you-action-row { display: flex; gap: 8px; margin: 12px 14px; }
.you-action-row button { flex: 1; padding: 11px; font-size: 13px; font-weight: 500; border-radius: 8px; background: var(--surface); border: 1px solid var(--surface-3); color: var(--text); }
.you-history-title { font-size: 11px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; margin: 4px 14px 6px; }

/* Settlement */
.game-settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    margin: 0 14px 8px;
    background: var(--surface);
    border-radius: 10px;
    border: 1px solid var(--surface-3);
}
.settings-label { font-size: 13px; color: var(--text-2); }

.toggle-pill {
    position: relative;
    width: 40px; height: 22px;
    border-radius: 11px;
    border: none;
    background: var(--surface-3);
    cursor: pointer;
    transition: background 0.2s;
    flex-shrink: 0;
    padding: 0;
}
.toggle-pill.on { background: var(--live); }
.toggle-thumb {
    position: absolute;
    top: 3px; left: 3px;
    width: 16px; height: 16px;
    border-radius: 50%;
    background: #fff;
    transition: transform 0.2s;
    display: block;
}
.toggle-pill.on .toggle-thumb { transform: translateX(18px); }

.settle-card {
    background: var(--surface);
    padding: 12px 14px;
    border-radius: 12px;
    border: 1px solid var(--surface-3);
    margin: 0 14px 10px;
}

/* ── Settled-game results card ── */
.results-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    overflow: hidden;
    /* No own margin — #roster (.player-list) already pads 14px, matching
       the stats grid; doubling it squeezed the money columns. */
    margin: 0;
}
.results-head {
    padding: 10px 14px 8px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-3);
}
.results-colhead, .results-row {
    display: grid;
    /* Header and rows are separate grids, so they only align if every one
       uses the same fixed tracks — sized to fit a 4-digit amount with
       decimals (−$1100.00) at these font sizes without wrapping. */
    grid-template-columns: minmax(0, 1fr) 70px 74px 82px;
    gap: 6px;
    align-items: center;
    padding: 0 14px;
}
.results-colhead {
    padding-top: 8px;
    padding-bottom: 6px;
    border-top: 1px solid var(--border);
}
.results-colhead span {
    font-size: 8.5px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-3);
    text-align: right;
}
.results-colhead span:first-child { text-align: left; }
.results-row {
    padding-top: 11px;
    padding-bottom: 11px;
    border-top: 1px solid var(--border);
    cursor: pointer;
}
.results-row:active { background: var(--surface-2); }
.results-row.me {
    background: rgba(96,165,250,0.06);
    border-top-color: rgba(96,165,250,0.3);
    box-shadow: inset 2px 0 0 var(--accent-bright);
}
/* flex-wrap so the credit-owed badge (forced to its own line below, see
   .results-name-cell .role-badge) never competes with the name for width —
   it used to sit inline and, once wrapped, its floor width could crush the
   name down to a couple of characters on a narrow screen. */
.results-name-cell { min-width: 0; display: flex; align-items: center; flex-wrap: wrap; row-gap: 2px; }
.results-name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.results-name-cell .role-badge { flex-basis: 100%; margin-left: 0; }
.results-youtag {
    font-size: 8px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--accent-bright);
    background: rgba(96,165,250,0.14);
    border-radius: 4px;
    padding: 1px 5px;
    margin-left: 6px;
    flex-shrink: 0;
}
.results-num {
    font-size: 12.5px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: var(--text-2);
    white-space: nowrap;
}
.results-num.out { color: var(--text); }
.results-net {
    font-size: 14.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}
.results-net.pos  { color: var(--live-text); }
.results-net.neg  { color: #f87171; }
.results-net.even { color: var(--text-2); }
.results-drawer {
    background: var(--bg);
    border-top: 1px solid var(--border);
    padding: 6px 14px 9px;
}
.results-hint {
    text-align: center;
    font-size: 10px;
    color: var(--text-3);
    margin-top: 10px;
}
.settle-title {
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-3);
    margin-bottom: 8px;
}
.payout-instruction {
    background: var(--bg);
    padding: 8px 10px;
    border-radius: 7px;
    margin-bottom: 5px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 12px;
    border-left: 2px solid var(--live);
}
.payout-amount { font-weight: 500; color: var(--live); font-variant-numeric: tabular-nums; }
.btn-calc {
    width: 100%;
    background: var(--live);
    color: #022c22;
    padding: 11px;
    font-size: 13px;
    font-weight: 700;
    margin-top: 10px;
    border-radius: 9px;
    border: none;
    cursor: pointer;
    letter-spacing: 0.02em;
}

/* Admin */
.admin-page-card {
    background: var(--surface);
    border-radius: 10px;
    padding: 10px;
    overflow-x: auto;
    margin: 12px 14px;
    border: 1px solid var(--border);
}
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.75rem; }
.admin-table th {
    text-align: left;
    color: var(--text-3);
    padding: 4px;
    border-bottom: 1px solid var(--surface-3);
    text-transform: uppercase;
    font-size: 0.65rem;
    letter-spacing: 0.05em;
}
.admin-table td { padding: 8px 4px; border-bottom: 1px solid var(--border); }
.role-badge { font-size: 0.6rem; padding: 2px 6px; border-radius: 10px; font-weight: 500; text-transform: uppercase; white-space: nowrap; flex-shrink: 0; }
.role-badge.admin  { background: rgba(139,92,246,0.15); color: #c4b5fd; }
.role-badge.host   { background: rgba(245,158,11,0.15); color: #fcd34d; }
.role-badge.player { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
/* Cardroom: Manager chip is deliberately a different hue from Host's amber
   so the two read as distinct roles at a glance wherever they sit together. */
.role-badge.manager    { background: rgba(96,165,250,0.15);  color: var(--accent-bright); }
/* Attendance badge tiers — climb on games played alone, never on results. */
.role-badge.tier-railbird { background: rgba(100,116,139,0.15); color: var(--text-2); }
.role-badge.tier-rec      { background: rgba(74,127,181,0.15);  color: var(--accent-bright); }
.role-badge.tier-reg      { background: rgba(16,185,129,0.15);  color: var(--live-text); }
.role-badge.tier-semipro  { background: rgba(245,158,11,0.15);  color: #fcd34d; }
.role-badge.tier-pro      { background: rgba(239,68,68,0.15);   color: #f87171; }
/* Outstanding Credit balance still owed to the host — red reads as "needs
   attention" and is distinct from every other badge hue used alongside it. */
/* Cardroom owner. Solid brand gold, unlike every other badge's translucent
   tint, so it can't be mistaken for Semi-Pro's amber or a game's Private chip. */
.role-badge.owner {
    display: inline-flex; align-items: center; gap: 3px;
    background: var(--gold); color: var(--gold-ink); font-weight: 600;
}
.role-badge.owner svg { flex-shrink: 0; }
/* Member list: the owner's pinned row sits where a heading would, so it
   gets the same top gap the first tier heading would have had. */
.cr-owner-list { margin-top: 12px; }
.cr-tier-heading { display: flex; align-items: center; gap: 6px; }
/* Same hues as the tier badges' text, which now only appear where a
   player shows up alone (no heading around them). */
.cr-tier-dot { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; background: var(--text-3); }
.cr-tier-dot.tier-pro      { background: #f87171; }
.cr-tier-dot.tier-semipro  { background: #fcd34d; }
.cr-tier-dot.tier-reg      { background: var(--live-text); }
.cr-tier-dot.tier-rec      { background: var(--accent-bright); }
.cr-tier-dot.tier-railbird { background: var(--text-2); }
/* "You" beside your own name in a member list. Outline only, so it reads
   as a marker rather than competing with the filled status badges. */
.cr-you {
    font-size: 0.6rem; font-weight: 500; line-height: 1.3; white-space: nowrap; flex-shrink: 0;
    padding: 1px 6px; border-radius: 10px;
    border: 1px solid var(--text-3); color: var(--text-2); background: transparent;
}
.role-badge.credit-owed   { background: rgba(239,68,68,0.15);   color: #f87171; }
.role-badge.status-scheduled { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
.role-badge.status-live      { background: var(--live-dim);        color: var(--live-text); }

/* Cardroom roster screen */
.cr-row-left { display: flex; align-items: center; gap: 10px; min-width: 0; }
.cr-row-name { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cr-name-line { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 500; color: var(--text); }
.cr-row-meta { font-size: 11px; color: var(--text-3); }
.role-select-box {
    background: var(--bg);
    border: 1px solid var(--surface-3);
    color: var(--text);
    font-size: 0.7rem;
    padding: 3px 5px;
    border-radius: 5px;
}

/* Modal */
.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0; top: 0;
    width: 100%; height: 100%;
    background: rgba(0,0,0,0.75);
    align-items: center;
    justify-content: center;
}
.modal-content {
    background: var(--surface);
    padding: 16px;
    border-radius: 14px;
    width: 280px;
    border: 1px solid var(--surface-3);
}
.modal-title { font-weight: 500; font-size: 14px; margin-bottom: 10px; color: var(--text); }
.modal-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 8px; }
.modal-field label { font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.05em; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 4px; }
.btn-modal-cancel  { background: var(--surface-2); color: var(--text-2); padding: 7px 12px; font-size: 12px; border-radius: 7px; border: none; cursor: pointer; }
.btn-modal-confirm { background: var(--live); color: #022c22; padding: 7px 12px; font-size: 12px; border-radius: 7px; border: none; cursor: pointer; font-weight: 700; }
.btn-modal-confirm.danger { background: var(--danger); color: #fff; }
.confirm-remove-body { font-size: 13px; color: var(--text-2); margin: 4px 0 16px; }
.modal-close-btn {
    position: absolute; top: 12px; right: 12px;
    background: transparent; border: none; color: var(--text-3);
    font-size: 16px; cursor: pointer; padding: 4px;
}
.modal-content { position: relative; }
.buyin-method-options { display: flex; flex-direction: column; gap: 8px; margin: 4px 0 4px; }
.buyin-method-btn {
    display: flex; flex-direction: column; gap: 4px;
    background: var(--surface-2); border: 1px solid var(--surface-3);
    border-radius: 10px; padding: 14px; cursor: pointer; text-align: left;
    color: var(--text); transition: border-color 0.15s, background 0.15s;
}
.buyin-method-btn:hover { border-color: var(--accent); background: rgba(96,165,250,0.06); }
.buyin-method-btn strong { font-size: 13px; color: var(--text); }
.buyin-method-icon { font-size: 20px; margin-bottom: 2px; }
.buyin-method-desc { font-size: 11px; color: var(--text-2); line-height: 1.4; }

/* Sheet headings — New game and Profile are sheets now, not screens, so they
   no longer carry their own card container or page heading. */
.sheet-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}
.sheet-title {
    font-size: 19px;
    font-weight: 600;
    letter-spacing: -0.3px;
    color: var(--text);
}

/* Profile */
/* No horizontal padding — the sheet supplies it. */
.profile-body { padding: 0 0 8px; }
.profile-hero {
    text-align: center;
    padding: 20px 0 24px;
}
.profile-avatar-wrap {
    width: 56px; height: 56px;
    border-radius: 50%;
    margin: 0 auto 10px;
    border: 2px solid var(--surface-3);
    overflow: hidden;
}
.profile-avatar-wrap img { width: 100%; height: 100%; object-fit: cover; }
.profile-avatar-initials {
    width: 56px; height: 56px;
    border-radius: 50%;
    background: var(--surface-3);
    margin: 0 auto 10px;
    display: flex; align-items: center; justify-content: center;
    font-size: 18px; font-weight: 500; color: var(--accent-bright);
    border: 2px solid rgba(74,127,181,0.3);
}
/* --- Profile photo upload ---
   The avatar IS the control. The file input covers it invisibly rather than
   sitting beside it as a separate button, so the whole circle is the tap
   target; the pencil badge is what makes it read as one. */
.profile-photo-control { position: relative; }
.profile-photo-tap {
    position: relative;
    display: block;
    width: 56px;
    margin: 0 auto;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.profile-photo-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    width: 100%;
    height: 100%;
    cursor: pointer;
}
.profile-photo-badge {
    position: absolute;
    right: -2px;
    bottom: 8px;
    width: 22px; height: 22px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    border: 2px solid var(--surface);
    display: flex; align-items: center; justify-content: center;
    pointer-events: none;
}
.profile-photo-tap:active .profile-avatar-wrap,
.profile-photo-tap:active .profile-avatar-initials { opacity: 0.7; }
/* Mid-upload: the resize and write are fast, but on a cold connection this is
   the difference between "saving" and "did my tap register?" */
.profile-photo-control.busy .profile-photo-tap { opacity: 0.5; pointer-events: none; }
.profile-photo-control.busy .profile-photo-badge { animation: photo-pulse 1s ease-in-out infinite; }
@keyframes photo-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.profile-photo-remove {
    display: block;
    margin: 0 auto 10px;
    background: none;
    border: none;
    font-size: 11.5px;
    color: var(--text-3);
    text-decoration: underline;
    text-underline-offset: 2px;
    -webkit-tap-highlight-color: transparent;
}
.profile-photo-remove:active { color: var(--text-2); }
@media (prefers-reduced-motion: reduce) {
    .profile-photo-control.busy .profile-photo-badge { animation: none; }
}

.profile-name { font-size: 15px; font-weight: 500; color: var(--text); margin-bottom: 4px; }
.profile-role {
    display: inline-block;
    font-size: 10px;
    color: var(--accent-bright);
    background: rgba(74,127,181,0.1);
    padding: 3px 10px;
    border-radius: 20px;
    border: 1px solid rgba(74,127,181,0.2);
    font-weight: 500;
}

.settings-list {
    background: var(--surface);
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid var(--border);
    margin-bottom: 10px;
}
.settings-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 13px 14px;
    border-bottom: 1px solid var(--border);
    cursor: pointer;
}
.settings-row:last-child { border-bottom: none; }

/* Home-feed "you owe money" banner — deliberately warmer than a plain
   .settings-list row so it doesn't blend into the rest of the feed; the
   amber-tinted border echoes .role-badge.credit-owed used inside it. */
.credit-prompt-card {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    background: rgba(239,68,68,0.08);
    border: 1px solid rgba(239,68,68,0.3);
    border-radius: 12px;
    padding: 12px 14px;
    margin-bottom: 12px;
    cursor: pointer;
}
/* Host nudge for a game left live past a day — amber (--warn), a step
   softer than the red credit banner: nothing's owed, just unfinished. Navy
   --surface underneath, amber only on the border and heading: an amber
   tint over the navy page muddies to brown-gray. */
.stale-live-card {
    background: var(--surface);
    border: 1px solid rgba(245,158,11,0.3);
    border-radius: 12px;
    padding: 12px 14px 4px;
    margin-bottom: 12px;
}
.stale-live-heading { font-size: 13px; font-weight: 500; color: var(--warn); }
.stale-live-sub { font-size: 11px; color: var(--text-3); margin-top: 2px; }
.stale-live-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border-top: 1px solid rgba(245,158,11,0.15);
    margin-top: 8px;
    cursor: pointer;
    color: var(--text-3);
}
.stale-live-row + .stale-live-row { margin-top: 0; }
.settings-row-left {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: var(--text-2);
}
.settings-row-left i { font-size: 17px; color: var(--text-3); }
.settings-row-right i { font-size: 14px; color: var(--text-3); }
.btn-signout {
    width: 100%;
    background: transparent;
    border: 1px solid var(--border-2);
    border-radius: 10px;
    padding: 11px;
    font-size: 12px;
    color: var(--text-3);
    cursor: pointer;
}

/* Toast */
#_felt_toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    padding: 9px 16px;
    border-radius: 8px;
    font-size: 12px;
    z-index: 9999;
    white-space: nowrap;
    pointer-events: none;
}

/* Lobby interactive */
.lobby-interactive-drawer { display: flex; flex-direction: column; gap: 6px; }

/* ── View toggle row (below stats grid) ── */
.gh-right {
    display: flex;
    align-items: center;
    gap: 8px;
}
.view-toggle-row {
    display: flex;
    gap: 3px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    border-radius: 9px;
    padding: 3px;
    margin: 8px 14px 0;
}
.vt-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    padding: 7px 0;
    border-radius: 7px;
    font-size: 12px;
    font-weight: 600;
    border: none;
    cursor: pointer;
    color: var(--text-2);
    background: transparent;
    transition: all 0.18s;
    white-space: nowrap;
}
.vt-btn.active {
    background: var(--surface-3);
    color: var(--text);
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
}

/* ── Header status row: title (left) · Live pulse (center) · List (right) ── */
.gh-status-row {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px 0 0;
    gap: 8px;
}
.gh-title-group {
    display: flex; align-items: center; gap: 5px;
    min-width: 0;
    /* "Live" moved out of this row (now lives in the table view's own
       corner) so the title just needs to yield to the List button, not
       stop at a hard 50% -- fills whatever space is left, ellipsizes
       past that via .gh-title below. */
    flex: 1 1 auto;
}
.gh-title-group .gh-title {
    margin-bottom: 0; text-align: left;
    min-width: 0; overflow: hidden;
    white-space: nowrap; text-overflow: ellipsis;
}

/* ── Table arena ── */
.table-arena {
    position: relative;
    width: 100%;
    max-width: 820px;
    margin: 0 auto;
    height: 560px;
}

/* Lifted out of an inline style attribute so the padding can be reclaimed
   below. `display` stays inline — JS toggles it. The top padding is there to
   clear the absolutely-positioned Live pill. */
#table-arena-wrapper { position: relative; padding-top: 40px; }

/* Sit down (or a pending sit-down request) under the table. */
.table-ctas { padding: 2px 14px 10px; }

/* Home (feed, history) and the sheets stay in the 480px column on every screen
   size — desktop is that same column, centered. The GAME screen widens as a
   unit instead: back nav, title row and table all share one width, because a
   header narrower than the table sitting under it reads as broken. Gated above
   the column width so phone layout is bit-for-bit unchanged.

   Negative margin rather than translateX: .game-header is position:sticky, and
   a transformed ancestor becomes its containing block, which browsers handle
   inconsistently for sticky children. */
@media (min-width: 481px) {
    #game-main-col {
        width: min(100vw - 32px, 820px);
        margin-left: calc(-1 * (min(100vw - 32px, 820px) - 100%) / 2);
    }
}

/* Landscape phone: the chrome above the table (back nav, title, Live pill)
   already eats a big share of ~430px, and every pixel returned here goes
   straight into the arena's height, which is what the ring is starved of. */
@media (max-height: 500px) {
    #table-arena-wrapper { padding-top: 28px; }
}

/* Lifted out of an inline style attribute so .compact can override the
   padding — see computeTableGeom, which collapses it when height is scarce. */
.table-hint {
    text-align: center;
    font-size: 10px;
    color: var(--text-3);
    padding: 18px 0 14px;
    letter-spacing: 0.03em;
}
.table-hint.compact { padding: 2px 0 4px; }
.table-hint:empty { padding: 0; }
/* The rail, felt and outer glow are all painted into this by renderRailVisual
   (app.js) as one SVG — replaces the old .felt-oval, which was a flat CSS
   ellipse (gradient + border-radius) and can't express a tilted, shaded 3D
   rail. Fills the arena; seats are separate DOM siblings appended after it,
   so plain DOM order — not z-index — puts them on top. */
#table-rail-visual {
    position: absolute;
    inset: 0;
}
.felt-bank-wrap {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 4px;
    pointer-events: none;
}
.felt-bank { font-size: 24px; font-weight: 700; color: rgba(255,255,255,0.92); font-variant-numeric: tabular-nums; animation: bank-glow 3s ease-in-out infinite; }
.felt-bank.bank-pulse { animation: bank-glow 3s ease-in-out infinite, bank-pulse-flash 0.5s ease-out; }
@keyframes bank-pulse-flash {
    0% { transform: scale(1.22); color: #7be3ad; }
    100% { transform: scale(1); color: rgba(255,255,255,0.92); }
}
@keyframes bank-glow {
    0%, 100% { text-shadow: 0 0 6px rgba(16,185,129,0.15); }
    50%      { text-shadow: 0 0 16px rgba(16,185,129,0.55); }
}
.felt-bank-label { font-size: 9px; color: rgba(255,255,255,0.55); text-transform: uppercase; letter-spacing: 0.08em; }
/* "On the [Felt logo]" — the wordmark stands in for the word "felt". */
.felt-bank-label { display: flex; align-items: center; gap: 5px; }
.felt-bank-label:has(.felt-bank-logo) { font-size: 10px; }
.felt-bank-logo { height: 16px; width: auto; display: block; }
.dealer-btn {
    position: absolute; bottom: 28px; right: 28px;
    width: 22px; height: 22px; border-radius: 50%;
    background: #fff; color: #000; font-size: 8px; font-weight: 900;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 1px 3px rgba(0,0,0,0.5);
}

/* ── Seat chips ── */
.seat {
    position: absolute;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
    transition: transform 0.1s;
    touch-action: manipulation;
}
.seat:active { transform: scale(0.93); }
.seat.dragging { opacity: 0.4; }
.seat-chip.moving-seat {
    border-color: var(--warn) !important;
    box-shadow: 0 0 0 3px rgba(245,158,11,0.4), 0 2px 8px rgba(0,0,0,0.4) !important;
    animation: pulse-yellow 1.2s ease-out infinite;
}
/* Everyone who isn't the player being moved recedes and stops taking taps —
   the gaps between seats are the only targets in move mode. */
.seat-chip.move-inert {
    opacity: 0.45;
    border-color: var(--border);
}
.seat.inert { pointer-events: none; }

/* Slide the ring into its new arrangement when a move is committed. Applied
   only for that transition, so ordinary re-renders still paint instantly. */
.seat.seat-sliding {
    transition: left 0.28s cubic-bezier(0.4, 0, 0.2, 1),
                top  0.28s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Insertion points between seats, shown only in move mode. Sized to the 44px
   touch minimum even though the visible dot is smaller. */
.seat-gap {
    position: absolute;
    width: 44px; height: 44px;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    -webkit-user-select: none; user-select: none;
    touch-action: manipulation;
    z-index: 3;
}
.seat-gap-mark {
    width: 26px; height: 26px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-2);
    border: 2px dashed var(--warn);
    color: var(--warn);
    font-size: 15px; font-weight: 700; line-height: 1;
    animation: pulse-yellow 1.6s ease-out infinite;
}
.seat-gap:active .seat-gap-mark { transform: scale(0.9); background: var(--warn); color: var(--bg); }
.seat-chip {
    /* computeTableGeom publishes --seat-size on the arena; the fallback is the
       full-size chip, which is what every portrait viewport resolves to. */
    width: var(--seat-size, 72px); height: var(--seat-size, 72px);
    border-radius: 50%;
    background: var(--surface-2);
    border: 2px solid var(--border-2);
    display: flex; align-items: center; justify-content: center;
    flex-direction: column; gap: 1px;
    position: relative;
    transition: border-color 0.15s, box-shadow 0.15s;
    box-shadow: 0 2px 8px rgba(0,0,0,0.4);
}
.seat-chip.active-seat {
    border-color: var(--live-border);
    box-shadow: 0 0 0 2px var(--live-border), 0 2px 8px rgba(0,0,0,0.4);
    padding: 0;
    overflow: hidden;
}
.seat-chip.drag-over {
    border-color: var(--warn);
    box-shadow: 0 0 0 3px rgba(245,158,11,0.4), 0 2px 8px rgba(0,0,0,0.4);
}
/* Own pill now (was bare text) — James: "the names should be in their own
   pill." Background needed since it sits directly on the rail/felt rather
   than a flat background, same reasoning as .seat-amount-badge already had. */
.seat-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--text);
    background: rgba(11,18,32,0.85);
    border: 0.5px solid var(--border-2);
    border-radius: 999px;
    padding: 2px 9px;
    white-space: nowrap;
}
/* ── Your own seat: highlight ring, full-circle photo, inline actions ── */
.seat-chip-wrap { position: relative; }
.seat-chip.mine {
    border-color: var(--accent-bright);
    box-shadow: 0 0 0 2px rgba(96,165,250,0.35), 0 2px 8px rgba(0,0,0,0.4);
    animation: pulse-accent 1.8s ease-out infinite;
}
.seat-chip.mine.pending {
    border-color: var(--warn);
    box-shadow: 0 0 0 2px rgba(245,158,11,0.35), 0 2px 8px rgba(0,0,0,0.4);
    animation: pulse-yellow 1.8s ease-out infinite;
}
@keyframes pulse-accent {
    0%   { box-shadow: 0 0 0 0 rgba(96,165,250,0.5); }
    70%  { box-shadow: 0 0 0 8px rgba(96,165,250,0); }
    100% { box-shadow: 0 0 0 0 rgba(96,165,250,0); }
}
.seat-photo-fill { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; }
/* calc() off --seat-size (chip diameter) rather than a fixed px, so the
   initial scales with the chip instead of drifting out of proportion when
   SEAT_CHIP_R/SEAT_CHIP_R_MINE change in app.js. */
.seat-chip-initial { font-size: calc(var(--seat-size, 72px) * 0.42); font-weight: 700; color: var(--accent-bright); }
.seat-amount-badge {
    position: absolute;
    top: -10px; left: 50%; transform: translateX(-50%);
    background: var(--live);
    color: #022c22;
    font-size: 12px; font-weight: 700;
    border-radius: 10px;
    padding: 2px 8px;
    white-space: nowrap;
    z-index: 2;
}
/* Tap cue on your own seat. Replaced the two satellite buttons that used to
   sit at the chip's bottom corners — the whole circle is the control now, so
   this only has to say "this opens something". pointer-events:none is
   load-bearing: it overlaps the chip, and a tap landing on it must still
   reach the seat's click handler. */
.seat-tap-cue {
    position: absolute;
    bottom: -5px; left: 50%; transform: translateX(-50%);
    width: 26px; height: 16px;
    border-radius: 8px;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-bright);
    color: #04121f;
    border: 1.5px solid var(--surface);
    pointer-events: none;
    z-index: 2;
}
.seat-tap-cue svg { width: 11px; height: 11px; }
/* Press feedback — the clearest available signal that a circle is a button. */
.seat-mine { cursor: pointer; }
.seat-mine .seat-chip-wrap { transition: transform 0.1s ease-out; }
.seat-mine:active .seat-chip-wrap { transform: scale(0.94); }

/* ── Sit-down CTA (shown when you're not seated) ── */
.btn-sit-down {
    width: 100%;
    background: var(--live);
    color: #022c22;
    padding: 11px;
    font-size: 13px;
    font-weight: 700;
    border-radius: 9px;
    border: none;
    cursor: pointer;
    letter-spacing: 0.02em;
}
.btn-sit-down:active { opacity: 0.85; }
.sit-cta-pending {
    background: rgba(245,158,11,0.1);
    border: 1px solid rgba(245,158,11,0.25);
    border-radius: 9px;
    padding: 9px 12px;
}
.sit-cta-pending-text {
    font-size: 12px; font-weight: 600; color: var(--warn);
    text-align: center; margin-bottom: 7px;
}
.sit-cta-pending-actions { display: flex; gap: 7px; }
.sit-cta-pending-actions button {
    flex: 1;
    background: var(--surface-2);
    color: var(--text-2);
    border: 1px solid var(--surface-3);
    border-radius: 7px;
    padding: 7px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}

/* ── Table action sheet ── */
.action-sheet-backdrop {
    display: none;
    position: fixed; inset: 0; z-index: 300;
    background: rgba(0,0,0,0.5);
}
.action-sheet-backdrop.open { display: block; }
.action-sheet {
    position: fixed; bottom: 0; left: 50%;
    transform: translateX(-50%) translateY(100%);
    width: 100%; max-width: 480px;
    background: var(--surface);
    border-radius: 16px 16px 0 0;
    border-top: 1px solid var(--border-2);
    padding: 0 16px 36px;
    z-index: 301;
    transition: transform 0.25s cubic-bezier(0.32, 0.72, 0, 1);
}
.action-sheet.open { transform: translateX(-50%) translateY(0); }
/* Profile and New game carry a lot more than a player action sheet, so they
   scroll internally rather than growing past the top of the screen. */
.action-sheet.tall {
    max-height: 88vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    /* Stops a scroll that runs off the end of the sheet from chaining into
       the page behind it. */
    overscroll-behavior: contain;
}
/* Landscape phone: ~350px of height total. Every sheet becomes internally
   scrollable, not just .tall — a short sheet that fits in portrait can run off
   the top here, stranding its buttons out of reach — and the generous bottom
   padding gives its space back. */
@media (max-height: 500px) {
    .action-sheet {
        max-height: 92vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding-bottom: 16px;
    }
}
/* The visible grip is the ::before bar; the element itself is a full-width
   strip so there's something big enough to actually grab. touch-action:none
   hands the drag to our pointer handlers instead of the scroller. */
.sheet-handle {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 28px;
    margin-bottom: 6px;
    touch-action: none;
    cursor: grab;
    -webkit-tap-highlight-color: transparent;
}
.sheet-handle:active { cursor: grabbing; }
.sheet-handle::before {
    content: '';
    display: block;
    width: 36px; height: 4px; border-radius: 2px;
    background: var(--surface-3);
}

/* --- Sign-in sheet --- */
/* Google and email link are peers, not a primary and a fallback — there's no
   Apple Sign-In, so email carries everyone without a usable Google account. */
.btn-signin-header {
    background: var(--surface-2);
    border: 1px solid var(--border-2);
    color: var(--text);
    border-radius: 20px;
    padding: 7px 15px;
    font-size: 12px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.btn-signin-header:active { background: var(--surface-3); }

.signin-btn {
    width: 100%;
    min-height: 46px;
    border-radius: 10px;
    font-size: 14px;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    cursor: pointer;
    margin-bottom: 8px;
    border: 1px solid transparent;
    -webkit-tap-highlight-color: transparent;
}
.signin-btn:disabled { opacity: 0.55; cursor: default; }
.signin-btn.google  { background: #f1f5f9; color: #0f172a; }
.signin-btn.email   { background: var(--surface-2); border-color: var(--border-2); color: var(--text); }
.signin-btn.primary { background: var(--accent); color: #fff; }
.signin-btn.ghost   { background: transparent; color: var(--text-2); font-weight: 400; }
.signin-btn.ghost:active { background: var(--surface-2); }

.signin-note {
    text-align: center;
    font-size: 11.5px;
    color: var(--text-3);
    padding: 4px 0 2px;
    line-height: 1.5;
}
/* The email fallback. Deliberately a text link, not a button — it sits below
   Google as the exception ("no Google account?"), not as an equal choice. */
.signin-link {
    background: none;
    border: none;
    padding: 0;
    font: inherit;
    color: var(--text-2);
    text-decoration: underline;
    text-underline-offset: 2px;
    -webkit-tap-highlight-color: transparent;
}
.signin-link:active { color: var(--text); }
.signin-error {
    background: var(--danger-dim);
    color: #f87171;
    border-radius: 8px;
    padding: 9px 12px;
    font-size: 12px;
    line-height: 1.45;
    margin-bottom: 10px;
}
.signin-sent { margin-bottom: 12px; }
.signin-sent-title { font-size: 15px; color: var(--text); margin-bottom: 5px; }
.signin-sent-body { font-size: 12.5px; color: var(--text-2); line-height: 1.5; }
.signin-sent-body strong { color: var(--text); font-weight: 500; word-break: break-all; }
.sheet-player-header {
    display: flex; align-items: center; justify-content: space-between;
    margin-bottom: 12px;
}
.sheet-player-name { font-size: 16px; font-weight: 600; color: var(--text); }
.sheet-player-meta { font-size: 12px; color: var(--text-2); margin-top: 1px; }
.sheet-close {
    background: var(--surface-2); border: none;
    width: 28px; height: 28px; border-radius: 50%;
    color: var(--text-3); font-size: 14px; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
}
.sheet-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.sheet-action-btn {
    padding: 14px 8px; border-radius: 12px; border: none; cursor: pointer;
    font-size: 13px; font-weight: 700;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    transition: opacity 0.1s;
}
.sheet-action-btn:active { opacity: 0.7; }
.sa-icon { font-size: 22px; }
.sheet-action-btn.addon  { background: rgba(74,127,181,0.15); color: var(--accent-bright); }
.sheet-action-btn.out    { background: rgba(239,68,68,0.1); color: #f87171; border: 1px solid rgba(239,68,68,0.2); }
.sheet-action-btn.backin { background: rgba(16,185,129,0.12); color: var(--live); border: 1px solid var(--live-border); }
.sheet-action-btn.remove { background: transparent; border: 1px solid var(--border-2); color: var(--text-3); }
/* The .you-* status blocks were authored for the old full-bleed modal, so
   they carry their own 14px side margins and sit on var(--surface) — which is
   the sheet's own background, leaving the card invisible here. Re-inset to the
   sheet's padding and lift the fill one step. */
#my-player-sheet .you-status-card {
    margin: 0 0 12px;
    background: var(--surface-2);
    padding: 16px 14px;
}
#my-player-sheet .you-action-row { margin: 0 0 12px; }
#my-player-sheet .you-action-row button { background: var(--surface-2); }

/* ── History drawer (your own player card) ── */
.history-drawer { margin-top: 14px; border-top: 1px solid var(--border-2); }
.history-drawer-toggle {
    width: 100%;
    display: flex; align-items: center; justify-content: space-between;
    background: none; border: none; cursor: pointer;
    padding: 12px 2px;
    font-size: 13px; font-weight: 500; color: var(--text-2);
    -webkit-tap-highlight-color: transparent;
}
.history-drawer-toggle:active { color: var(--text); }
.history-drawer-caret {
    font-size: 15px; line-height: 1; color: var(--text-3);
    transition: transform 0.2s ease-out;
}
.history-drawer-toggle.open .history-drawer-caret { transform: rotate(180deg); }
/* Collapsed by default; capped and internally scrollable when open so a long
   ledger can't push the sheet's actions off the top of a short screen. */
.history-drawer-body { display: none; }
.history-drawer-body.open {
    display: block;
    max-height: 40vh;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
    padding-bottom: 4px;
}

.sheet-cashout-row {
    margin-top: 10px; display: flex; align-items: center;
    background: var(--surface-2); border: 1px solid var(--border-2);
    border-radius: 10px; padding: 10px 14px; gap: 10px;
}
.sheet-cashout-label { font-size: 12px; color: var(--text-2); flex: 1; }
.sheet-cashout-input-wrap {
    display: flex; align-items: center; gap: 2px;
    background: var(--bg); border: 1px solid var(--surface-3);
    border-radius: 7px; padding: 4px 8px; width: 80px;
}
.sheet-cashout-input-wrap span { color: var(--text-3); font-size: 14px; }
.sheet-cashout-input {
    background: transparent; border: none; padding: 0;
    color: var(--text); font-size: 16px; font-weight: 700;
    width: 100%; text-align: right; font-variant-numeric: tabular-nums; outline: none;
}

/* --- Profile stats --- */
.profile-stats-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-bottom: 8px;
}
.profile-stats-grid .stat-card,
.stat-wide {
    text-align: left;
    padding: 11px 12px;
}
.stat-wide { margin-bottom: 8px; }
.stat-wide:last-child { margin-bottom: 0; }
.profile-stats-grid .stat-value,
.stat-wide .stat-value { font-size: 20px; margin-top: 4px; }
.stat-value.pos { color: var(--live-text); }
.stat-sub { font-size: 12px; font-weight: 400; color: var(--text-2); }
.stat-meta { font-size: 11px; color: var(--text-3); margin-top: 3px; }

/* ── Bottom tab bar — Games / Cardroom / Stats ──────────────────
   Chrome for the three root "browsing" screens only. JS (renderTabBar)
   toggles `display` between 'none' and 'flex' rather than relying on
   opacity/visibility — game-screen's table view was deliberately built with
   zero dependency on any reserved nav-height (a `--nav-h` variable existed
   for this once and was removed on purpose), so a hidden tab bar must
   contribute exactly zero layout footprint, not just sit invisibly in the
   flow. Default `none` here so a slow first paint never flashes it before
   JS decides. */
#tab-bar {
    display: none;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    max-width: 480px;
    margin: 0 auto;
    background: var(--surface);
    border-top: 1px solid var(--border);
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom, 0px));
    z-index: 150;
    justify-content: space-around;
    align-items: center;
}
.tab-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    flex: 1;
    background: transparent;
    border: none;
    color: var(--text-3);
    font-size: 10px;
    padding: 4px 0;
}
.tab-btn.active { color: var(--accent-bright); }
.tab-btn svg { display: block; }

/* ── Cardroom tab ── */
.cardroom-hero {
    margin: 4px 14px 10px;
    padding: 14px;
    background: var(--surface);
    border: 1px solid var(--surface-3);
    border-radius: 12px;
}
.cardroom-hero-empty { text-align: center; }
.cardroom-hero-name { font-size: 15px; font-weight: 600; color: var(--text); }
.cardroom-hero-tagline { font-size: 12px; color: var(--text-2); margin-top: 3px; }
/* Plain inline flow, not flex — this line mixes bare text ("N players ·")
   with .role-badge spans, and a flex gap would land between every anonymous
   text-node box too, not just between the badges (the exact "stranded gap"
   trap documented on requests-banner-label). Line-height instead keeps
   multi-line wrapping from feeling cramped. */
.cardroom-hero-meta { font-size: 11px; color: var(--text-3); margin-top: 8px; line-height: 1.9; }
.cardroom-hero-meta .role-badge { margin-right: 4px; }

/* ── Cardroom-name tag on a Games-tab feed card ── */
.feed-cardroom-tag {
    font-size: 10px;
    color: var(--text-3);
    background: var(--surface-2);
    border-radius: 6px;
    padding: 1px 6px;
    margin-left: 6px;
    white-space: nowrap;
}

/* Ledger save waiting on the connection — see setSavingNotice in app.js.
   Sits above the toast position so a toast doesn't cover it. */
.saving-notice {
    position: fixed;
    bottom: 64px;
    left: 50%;
    transform: translateX(-50%);
    max-width: calc(100vw - 32px);
    box-sizing: border-box;
    background: #2a1f06;
    border: 1px solid rgba(245, 158, 11, 0.35);
    color: #fcd34d;
    padding: 9px 16px;
    border-radius: 8px;
    font-size: 0.75rem;
    text-align: center;
    z-index: 9999;
    pointer-events: none;
}

/* ── Header "+ New game" — every tab, everyone signed in ── */
.btn-new-game-header {
    background: var(--accent);
    color: #fff;
    border: none;
    border-radius: 20px;
    padding: 7px 14px;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    -webkit-tap-highlight-color: transparent;
}
.btn-new-game-header:active { filter: brightness(0.9); }

/* ── Scheduled card (Home) ──
   The whole card opens the game; only the In/Out buttons don't. */
.sched-card { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.sched-top {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 12px 14px 0;
}
.sched-title {
    flex: 1;
    min-width: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sched-when {
    padding: 3px 14px 0;
    font-size: 13px;
    font-weight: 500;
    color: var(--accent-bright);
    font-variant-numeric: tabular-nums;
}
.sched-meta, .sched-sub {
    padding: 4px 14px 0;
    font-size: 12px;
    color: var(--text-2);
    font-variant-numeric: tabular-nums;
}
.sched-sub { padding-top: 2px; color: var(--text-3); }
.sched-card .lobby-interactive-drawer { margin-top: 12px; }

/* In/Out answer — your current answer is the lit one. */
.rsvp-toggle {
    display: flex;
    background: var(--surface-2);
    border: 1px solid var(--border-2);
    border-radius: 9px;
    padding: 2px;
    gap: 2px;
    flex-shrink: 0;
}
.rsvp-opt {
    min-width: 64px;
    min-height: 34px;
    padding: 0 14px;
    background: transparent;
    border: none;
    border-radius: 7px;
    color: var(--text-2);
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.rsvp-opt.in.on  { background: var(--live); color: #022c22; cursor: default; }
.rsvp-opt.out.on { background: var(--danger-dim); color: #fca5a5; cursor: default; }

/* ── History rows: total on the felt over player count ── */
.fr-figures {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    flex-shrink: 0;
    line-height: 1.3;
}
.fr-count { font-size: 11px; color: var(--text-3); }
.feed-more {
    display: block;
    width: 100%;
    margin: 8px 0 0;
    padding: 10px;
    background: none;
    border: none;
    color: var(--accent-bright);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
}

/* ── Game screen: when + calendar ── */
/* Sits inside .gh-meta-row. The countdown stays accent-colored; a settled
   game's plain date inherits the row's quieter color. */
.gh-when[data-countdown] {
    font-weight: 500;
    color: var(--accent-bright);
}
.btn-calendar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 8px 10px;
    background: transparent;
    color: var(--text-2);
    border: 1px solid var(--border-2);
    border-radius: 7px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
}
#game-rsvp-slot { margin: 2px 0 8px; }
#game-rsvp-slot .rsvp-strip { padding: 0 14px; }

/* Room stat under the tagline */
.cardroom-stat { font-size: 12px; color: var(--text-2); margin-top: 4px; }
.cardroom-stat strong { color: var(--text); font-weight: 600; }


/* ── Signed-out landing page ─────────────────────────────── */
.landing { padding: 8px 18px 28px; line-height: 1.5; }
.landing-hero { text-align: center; padding: 26px 0 8px; }
.landing-title {
    font-size: 28px;
    font-weight: 600;
    letter-spacing: -0.5px;
    line-height: 1.2;
    color: var(--text);
}
.landing-title span { color: var(--gold); }
.landing-lede { font-size: 14px; color: var(--text-2); max-width: 340px; margin: 12px auto 20px; }
.landing-cta {
    display: block;
    width: 100%;
    max-width: 320px;
    margin: 0 auto;
    min-height: 46px;
    background: var(--gold);
    color: var(--gold-ink);
    border: none;
    border-radius: 11px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
.landing-cta:active { opacity: 0.85; }
.landing-fine { font-size: 11.5px; color: var(--text-3); margin-top: 9px; }
.landing-signin { font-size: 12.5px; color: var(--text-2); margin-top: 14px; }
.landing-signin button {
    background: none; border: none; padding: 0;
    color: var(--gold); font-size: inherit; cursor: pointer;
}
.landing-sec { border-top: 1px solid var(--border); margin-top: 26px; padding-top: 24px; }
.landing-kicker { font-size: 10.5px; color: var(--text-3); letter-spacing: 0.08em; text-transform: uppercase; font-weight: 500; }
.landing-h { font-size: 19px; font-weight: 600; letter-spacing: -0.3px; color: var(--text); margin: 4px 0 14px; }
.landing-p { font-size: 13px; color: var(--text-2); }
.landing-vs {
    display: grid;
    grid-template-columns: 1fr 1fr;
    border: 1px solid var(--border-2);
    border-radius: 11px;
    overflow: hidden;
    font-size: 12.5px;
}
.landing-vs > div { padding: 9px 11px; border-top: 1px solid var(--border); }
.landing-vs .vs-old { background: var(--bg); color: var(--text-3); }
.landing-vs .vs-new { background: var(--surface); color: var(--text); }
.landing-vs .vs-head { border-top: none; font-size: 10.5px; letter-spacing: 0.08em; font-weight: 600; text-transform: uppercase; }
.landing-vs .vs-new.vs-head { color: var(--gold); }
.landing-feat { display: flex; gap: 12px; margin-top: 16px; }
.landing-feat svg { flex-shrink: 0; color: var(--gold); margin-top: 2px; }
.landing-feat-t { font-size: 13.5px; font-weight: 600; color: var(--text); }
.landing-feat-d { font-size: 13px; color: var(--text-2); }
.landing-step-n {
    width: 22px; height: 22px; flex-shrink: 0; margin-top: 1px;
    border-radius: 50%;
    border: 1px solid var(--gold);
    color: var(--gold);
    font-size: 11px;
    display: flex; align-items: center; justify-content: center;
}
.landing-perk {
    margin-top: 16px;
    padding: 11px 13px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    font-size: 12.5px;
    color: var(--text-2);
}
.landing-perk strong { color: var(--gold); font-weight: 600; }
.landing-close { text-align: center; }
.landing-close .landing-h { margin-bottom: 6px; }
.landing-close .landing-p { margin-bottom: 18px; }

/* ── Sit a player: QR first, manual entry as the fallback ── */
.btn-sit-qr {
    width: 100%;
    min-height: 40px;
    background: var(--surface-2);
    color: var(--text);
    border: 1px solid var(--border-2);
    border-radius: 9px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center; gap: 7px;
}
.btn-sit-qr svg { color: var(--gold); }
/* renderGameScreen shows this card as display:flex, which defaults to a row —
   that put the QR button beside the manual form and stretched it to the
   form's full height. Stack them so the form gets the card's whole width. */
#ledger-add-player-card { flex-direction: column; gap: 8px; }
/* Fixed basis: the global `input[type="number"] { flex: 1 }` otherwise wins
   over width and squeezes the buy-in to ~34px, clipping "100". */
#new-buyin { flex: 0 0 76px; }
/* Two deliberate rows at every width — name + $, then method + Seat — rather
   than letting wrap strand the Seat button alone on a line at ~375px. */
#manual-sit-form .name-typeahead-wrap { flex: 1 1 calc(100% - 81px); }
.manual-sit-head {
    display: flex; justify-content: space-between; align-items: center;
    font-size: 11px; color: var(--text-3); margin-bottom: 6px;
}
.manual-sit-head button { background: none; border: none; color: var(--text-2); font-size: 11px; cursor: pointer; padding: 2px 0; }
.sit-qr-body { text-align: center; padding: 2px 4px 8px; }
.sit-qr-lede { font-size: 13px; color: var(--text-2); line-height: 1.5; margin: 0 auto 16px; max-width: 290px; }
.sit-qr-code {
    width: 220px; height: 220px;
    margin: 0 auto;
    padding: 12px;
    background: #fff;
    border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
}
.sit-qr-code img, .sit-qr-code svg { width: 100%; height: 100%; display: block; image-rendering: pixelated; }
.sit-qr-code .sit-qr-fallback { font-size: 12px; color: #334155; line-height: 1.4; }
.sit-qr-actions { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }
.sit-qr-actions button {
    background: var(--surface-2); color: var(--text);
    border: 1px solid var(--border-2); border-radius: 9px;
    padding: 9px 14px; font-size: 12.5px; cursor: pointer;
}
.sit-qr-manual {
    margin-top: 18px; padding-top: 14px;
    border-top: 1px solid var(--border);
    font-size: 12.5px; color: var(--text-3);
}
.sit-qr-manual button { background: none; border: none; padding: 0; color: var(--gold); font-size: inherit; cursor: pointer; }

/* Who's coming, when the host has hidden the names. */
.rsvp-hidden-count { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text); }
.rsvp-hidden-count svg { color: var(--gold); flex-shrink: 0; }
.rsvp-hidden-sub { font-size: 11.5px; color: var(--text-3); }
.rsvp-hidden-note { font-size: 11px; color: var(--text-3); margin-top: 8px; }

/* ── Guests: walk-ups with no Felt account ── */
.role-badge.guest { background: rgba(100,116,139,0.18); color: var(--text-2); }
.user-avatar-initials.guest { border-color: var(--border); color: var(--text-2); }

/* Seat-a-player suggestions: who each person is, not just a bare name, so
   the list can't be mistaken for the browser's own autofill. */
.suggest-heading { padding: 6px 10px 4px; font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: 0.04em; }
.name-suggest-item:not(.suggest-new) { display: flex; align-items: center; gap: 10px; }
.suggest-avatar {
    width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0; object-fit: cover;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-3); color: var(--accent-bright); font-size: 11px; font-weight: 500;
}
.suggest-avatar.guest { color: var(--text-2); }
.suggest-text { min-width: 0; }
.suggest-name { display: flex; align-items: center; gap: 6px; }
.suggest-meta { font-size: 11px; color: var(--text-3); margin-top: 1px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.name-suggest-item.suggest-new { color: var(--live-text); }

/* Expected: RSVP'd in, no buy-in yet. Host and Managers only. */
.expected-card { border: 1px solid var(--border); border-radius: 10px; margin-bottom: 10px; background: var(--surface); }
.expected-head {
    width: 100%; display: flex; justify-content: space-between; align-items: center;
    padding: 10px 12px; background: none; border: none; color: var(--text-2);
    font-size: 12px; font-weight: 500; cursor: pointer;
}
.expected-chev { font-size: 10px; }
.expected-list { border-top: 1px solid var(--border); }
.expected-row { display: flex; justify-content: space-between; align-items: center; padding: 8px 12px; gap: 10px; }
.expected-row + .expected-row { border-top: 1px solid var(--border); }
.expected-name { font-size: 13px; color: var(--text); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* --- How Felt works: guide screen + chapter cards --- */
/* Fixed min-height so the centered card doesn't jump as steps change length. */
.tour-content { width: min(340px, calc(100vw - 32px)); padding: 18px; }
#guide-body { min-height: 430px; display: flex; flex-direction: column; }
.tour-visual {
    background: var(--bg);
    border: 1px solid var(--border-2);
    border-radius: 10px;
    padding: 14px 12px;
    margin-bottom: 14px;
    display: flex; flex-direction: column; gap: 8px;
    pointer-events: none;
}
.tour-visual .status-btn { text-align: center; }
.tour-visual .field-label { margin-top: 0; }
.tour-visual .toggle-pill { display: inline-block; }
.tour-hl { box-shadow: 0 0 0 2px var(--gold); border-radius: 9px; }
.tour-row {
    display: flex; align-items: center; justify-content: space-between;
    font-size: 13px; color: var(--text); padding: 4px 6px;
}
.tour-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; align-items: center; }
.tour-cols > div { display: flex; flex-direction: column; gap: 4px; }
.tour-input {
    background: var(--surface-2);
    border: 1px solid var(--surface-3);
    border-radius: 8px;
    padding: 8px 10px;
    font-size: 13px; color: var(--text);
}
.tour-placeholder { color: var(--text-3); }
.tour-chip {
    text-transform: none; letter-spacing: 0;
    background: var(--gold-dim); color: var(--gold);
    border-radius: 6px; padding: 1px 6px; margin-left: 6px;
}
.tour-tag {
    display: inline-block;
    font-size: 10px; text-transform: uppercase; letter-spacing: 0.05em;
    color: var(--gold); margin-bottom: 4px;
}
.tour-text { font-size: 13px; color: var(--text-2); line-height: 1.45; display: flex; flex-direction: column; gap: 8px; }
.tour-text b { color: var(--text); font-weight: 600; }
.tour-footer { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; padding-top: 16px; }
.tour-skip { background: none; border: none; color: var(--text-3); font-size: 12px; cursor: pointer; padding: 7px 0; }
.tour-count { font-size: 11px; color: var(--text-3); font-variant-numeric: tabular-nums; }
.tour-nav { display: flex; gap: 6px; }

/* Undo / View links inside a toast (showToast's actions) */
.toast-action {
    background: none; border: none; color: #fff;
    font-size: inherit; font-weight: 700; cursor: pointer;
    margin-left: 14px; padding: 0;
}
.expected-row .action-btn { flex: 0 0 auto; padding-left: 16px; padding-right: 16px; }

/* ── Seat links ── */
.seat-link-actions { display: flex; gap: 8px; justify-content: center; margin-top: 14px; }
.seat-link-actions button {
    background: var(--surface-2); color: var(--text);
    border: 1px solid var(--border-2); border-radius: 9px;
    padding: 9px 16px; font-size: 12.5px; cursor: pointer;
}
.seat-link-actions .seat-link-share { background: var(--live); color: #04241a; border-color: var(--live); font-weight: 600; }
.seat-link-foot { margin-top: 12px; font-size: 11px; color: var(--text-3); }
.seat-link-note { color: var(--warn); margin-bottom: 6px; font-size: 12px; }
.seat-link-new { background: none; border: none; color: var(--text-2); text-decoration: underline; font-size: 11px; cursor: pointer; padding: 0; }
.seat-link-row-btn {
    display: block; width: 100%; margin: 8px 0 4px; padding: 9px;
    background: var(--live-dim); color: var(--live-text);
    border: 1px solid var(--live-border); border-radius: 9px; font-size: 12.5px; cursor: pointer;
}
.seat-link-row-btn.subtle { background: none; color: var(--text-2); border-color: var(--border-2); }

/* Landing a guest sees from their link */
.claim-body { padding-top: 12px; }
.claim-loading { text-align: center; color: var(--text-3); font-size: 12px; padding: 30px 0; }
.claim-heading { font-size: 20px; font-weight: 600; color: var(--text); margin: 8px 0 6px; line-height: 1.3; }
.claim-heading.center, .claim-sub.center { text-align: center; }
.claim-sub { font-size: 13px; color: var(--text-2); line-height: 1.5; margin: 0 0 16px; }
.claim-card { background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px; padding: 12px 14px; margin-bottom: 18px; }
.claim-card-title { font-size: 14px; font-weight: 600; color: var(--text); }
.claim-card-sub { font-size: 12px; color: var(--text-2); margin-top: 2px; }
.claim-card-seat { font-size: 12px; color: var(--text-2); margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--border); }
.claim-card-seat strong { color: var(--text); font-weight: 500; }
.claim-btn {
    display: block; width: 100%; margin-top: 8px; padding: 12px;
    border-radius: 10px; font-size: 14px; cursor: pointer;
    background: none; color: var(--text); border: 1px solid var(--border-2);
}
.claim-btn.primary { background: var(--live); color: #04241a; border-color: var(--live); font-weight: 600; }
.claim-icon { text-align: center; font-size: 34px; color: var(--text-3); margin: 40px 0 10px; }
.claim-icon.ok { color: var(--live-text); }

/* Seat-link cards on the Games feed: the host's join requests and the
   guest's own pending / linked / declined notes. */
.claim-feed-card { background: var(--surface); border: 1px solid var(--border-2); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; }
.claim-feed-card.pending { border-left: 3px solid var(--warn); border-radius: 0 12px 12px 0; }
.claim-feed-card.ok { border-color: var(--live-border); background: var(--live-dim); }
.claim-feed-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.claim-feed-title { font-size: 13.5px; font-weight: 600; color: var(--text); }
.claim-feed-sub { font-size: 12px; color: var(--text-2); margin-top: 2px; }
.claim-pill { background: rgba(245,158,11,0.14); color: #fcd34d; font-size: 10.5px; padding: 2px 8px; border-radius: 999px; white-space: nowrap; }
.claim-feed-foot { display: flex; justify-content: space-between; align-items: center; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--border); font-size: 12px; color: var(--text-2); }
.claim-feed-foot strong { color: var(--text); font-weight: 500; }
.claim-feed-foot button, .claim-x { background: none; border: none; color: var(--text-2); font-size: 12px; cursor: pointer; text-decoration: underline; padding: 0; }
.claim-x { text-decoration: none; font-size: 13px; }
.claim-feed-link { margin-top: 8px; background: none; border: none; color: var(--live-text); font-size: 12.5px; cursor: pointer; padding: 0; }
.claim-request-who { display: flex; gap: 10px; align-items: center; }
.claim-email { font-weight: 400; color: var(--text-3); font-size: 11.5px; }
.claim-request-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 12px; }
.claim-request-actions button { padding: 9px; border-radius: 9px; font-size: 12.5px; cursor: pointer; background: none; color: var(--text); border: 1px solid var(--border-2); }
.claim-request-actions .primary { background: var(--live); color: #04241a; border-color: var(--live); font-weight: 600; }

/* Guide card visuals — drawn with app classes where they exist */
.tour-btn { text-align: center; padding: 7px 8px; border-radius: 8px; font-size: 12px; font-weight: 600; }
.tour-btn.blue  { background: var(--accent); color: #fff; }
.tour-btn.green { background: var(--live); color: #022c22; }
.tour-btn.ghost { background: var(--surface-2); color: var(--text-2); border: 1px solid var(--surface-3); }
.tour-visual .request-card { margin: 0; }
.tour-rsvp { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 11.5px; color: var(--text); line-height: 1.5; }
.tour-rsvp .k { font-size: 9.5px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-3); margin-bottom: 2px; }
.tour-rsvp .k.in { color: var(--live-text); }
.tour-gh { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; }
.tour-gh em { font-style: normal; font-size: 10px; font-weight: 600; color: var(--live-text); margin-left: 6px; }
.tour-icon { width: 28px; height: 28px; border-radius: 8px; background: var(--surface-2); color: var(--text-2); display: inline-flex; align-items: center; justify-content: center; }
.tour-toggle { display: inline-flex; gap: 4px; }
.tour-toggle b, .tour-toggle i { font-style: normal; font-size: 11.5px; font-weight: 600; padding: 4px 12px; border-radius: 7px; }
.tour-toggle b { background: var(--live); color: #022c22; }
.tour-toggle i { background: var(--surface-2); color: var(--text-2); }
.tour-caption { font-size: 11px; color: var(--text-3); text-align: center; }
.tour-qr {
    width: 72px; height: 72px; margin: 0 auto; border-radius: 8px; background-color: #fff;
    background-image: conic-gradient(#000 25%, #fff 0 50%, #000 0 75%, #fff 0);
    background-size: 14px 14px; border: 6px solid #fff;
}
.tour-table { position: relative; height: 118px; margin: 4px 16px; }
.tour-felt {
    position: absolute; inset: 12px 18px; border-radius: 999px;
    background: radial-gradient(ellipse at center, #136b47, #0b4a31);
    border: 7px solid #161618; box-shadow: 0 0 14px rgba(16,185,129,0.22);
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.tour-felt b { font-size: 14px; }
.tour-felt span { font-size: 9px; color: rgba(255,255,255,0.7); }
.tour-seat {
    position: absolute; width: 26px; height: 26px; border-radius: 50%; transform: translate(-50%, -50%);
    background: var(--surface-3); border: 2px solid var(--bg);
    display: flex; align-items: center; justify-content: center; font-size: 10.5px; font-weight: 600;
}
.tour-seat.tour-hl { border-radius: 50%; }
.tour-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.tour-stat { background: var(--surface); border-radius: 8px; padding: 7px 4px; text-align: center; }
.tour-stat .k { font-size: 9.5px; color: var(--text-3); }
.tour-stat .v { font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tour-stat .v.ok { color: var(--live-text); }
.tour-line { display: flex; justify-content: space-between; gap: 8px; font-size: 12px; padding: 5px 4px; color: var(--text); font-variant-numeric: tabular-nums; }
.tour-line > span:last-child { color: var(--text-2); }
.tour-line.boxed { background: var(--surface); border-radius: 8px; padding: 7px 10px; }
.tour-line.ok > span:last-child { color: var(--live-text); font-weight: 600; }
.tour-owes { font-size: 9.5px; font-weight: 700; color: var(--warn); background: rgba(245,158,11,0.12); padding: 1px 5px; border-radius: 4px; margin-left: 4px; }
.tour-toast { align-self: center; background: #0d2d19; border: 1px solid rgba(16,185,129,0.3); color: #34d399; border-radius: 8px; padding: 7px 12px; font-size: 11.5px; white-space: nowrap; }
.tour-toast b { color: #fff; margin-left: 12px; }

.guide-title { font-size: 20px; font-weight: 600; letter-spacing: -0.3px; margin: 2px 0 4px; }
.guide-chapter { gap: 12px; }
.guide-num {
    width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
    background: var(--gold-dim); color: var(--gold);
    display: inline-flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700;
}
.guide-name { display: block; font-size: 13.5px; font-weight: 600; color: var(--text); }
.guide-desc { display: block; font-size: 11.5px; color: var(--text-3); }
.guide-foot { text-align: center; font-size: 12px; color: var(--text-3); margin-top: 16px; }
.guide-foot button { background: none; border: none; color: var(--text-2); text-decoration: underline; font-size: 12px; cursor: pointer; padding: 0; }
.guide-link { background: none; border: none; color: var(--gold); font-size: 12.5px; font-weight: 600; cursor: pointer; padding: 0; margin-top: 12px; }
.guide-link-row { text-align: center; font-size: 12.5px; color: var(--text-3); margin-top: 2px; }
.guide-link-row .guide-link { margin-top: 0; }
.new-badge { font-size: 9.5px; font-weight: 700; background: var(--gold); color: var(--gold-ink); border-radius: 5px; padding: 1px 6px; margin-left: 8px; letter-spacing: 0.03em; text-transform: uppercase; }

/* One-time tips, pinned under the control they explain */
.tip-slot { margin: 0 14px; }
.tip-slot:empty, #tip-share-slot:empty { display: none; }
.coach-tip {
    position: relative; display: flex; align-items: center; gap: 10px;
    background: var(--gold); color: var(--gold-ink);
    border-radius: 10px; padding: 9px 10px 9px 12px; margin: 8px 0;
    font-size: 12.5px; line-height: 1.4; letter-spacing: 0; text-align: left;
}
.coach-tip::before {
    content: ""; position: absolute; top: -6px; left: 26px;
    border: 6px solid transparent; border-top: none; border-bottom-color: var(--gold);
}
.coach-tip b { font-weight: 700; }
.coach-tip.arrow-right::before { left: auto; right: 22px; }
.coach-tip-text { flex: 1; }
.coach-tip button {
    flex-shrink: 0; background: var(--gold-ink); color: var(--gold);
    border: none; border-radius: 6px; padding: 5px 10px; font-size: 12px; font-weight: 700; cursor: pointer;
}
#tip-share-slot .coach-tip { margin: 0; }
.table-hint .coach-tip { margin: 0 14px; }
