:root {
    --bg: #f4f1ea;
    --surface: #ffffff;
    --text: #1d1d1b;
    --muted: #5f5e5a;
    --accent: #14532d;
    --link: #14532d; /* green used for text (the accent stays for buttons and borders) */
    --accent-text: #ffffff;
    --border: #d9d5cb;
    --selected: #dcefe2;
    --red: #b42318;
    --diamond: #c25400;
    --club: #15803d;
    --vul: #fde2df;
    --dd-head: #dbeafe; /* the double dummy table's header row and seat column: blue, not a colour that reads as vulnerable */
    --warn: #9a3412;
    color-scheme: light;
}

@media (prefers-color-scheme: dark) {
    :root {
        --bg: #121412;
        --surface: #1c1f1c;
        --text: #ecebe6;
        --muted: #b4b3ad;
        --accent: #3f9c62;
        --link: #5cc184;
        --accent-text: #08130c;
        --border: #343832;
        --selected: #23412e;
        --red: #ff8f84;
        --diamond: #ffa04d;
        --club: #4ade80;
        --vul: #4a2420;
        --dd-head: #1e3a5f;
        --warn: #fdba74;
        color-scheme: dark;
    }
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 17px;
    line-height: 1.4;
    -webkit-text-size-adjust: 100%;
}

.shell { max-width: 560px; margin: 0 auto; padding: 16px 16px 48px; }

h1 { font-size: 1.7rem; margin: 0.2rem 0 0.6rem; }
h2 { font-size: 1.15rem; margin: 1.2rem 0 0.5rem; }
h3 { font-size: 0.95rem; margin: 0 0 0.3rem; }
h1:focus { outline: none; }

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 16px;
    margin-bottom: 14px;
}

.muted { color: var(--muted); }
.small { font-size: 0.85rem; }
.label { margin: 0.9rem 0 0.3rem; font-weight: 600; }
.eyebrow { text-transform: uppercase; letter-spacing: 0.06em; font-size: 0.75rem; color: var(--muted); margin: 0; }
.error { color: var(--red); }
.red { color: var(--red); }

button {
    font: inherit;
    color: var(--text);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 10px 14px;
    min-height: 44px;
    cursor: pointer;
}
button.selected { background: var(--selected); border-color: var(--accent); font-weight: 600; }
button.primary { background: var(--accent); color: var(--accent-text); border-color: var(--accent); width: 100%; margin-top: 12px; font-weight: 600; }
button.primary:disabled { opacity: 0.4; cursor: default; }
button.danger { color: var(--red); }
button.link { border: none; background: none; color: var(--link); padding: 6px 0; min-height: auto; font-weight: 600; }
button.down { color: var(--red); }
button small { color: var(--muted); }

input {
    font: inherit;
    color: var(--text);
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 8px 10px;
    min-width: 0;
}
input[type=number] { width: 5em; }

.seats { display: grid; gap: 8px; }
.deal-count { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: 8px 12px; margin: 12px 0 4px; }
.deal-count input[type=number] { width: 4em; }
.deal-count label { display: flex; align-items: center; gap: 10px; font-weight: 600; white-space: nowrap; }
.play-time { margin: 6px 0 0; text-align: left; font-weight: 600; color: var(--link); }
.board-total { background: var(--selected); border: 1px solid var(--accent); border-radius: 10px; padding: 6px 12px; white-space: nowrap; }
.board-total strong { font-size: 1.6rem; color: var(--link); }
.seats label { display: grid; grid-template-columns: 4.5em 1fr; align-items: center; }
.row { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin: 10px 0; }
.row.check { justify-content: flex-start; }
.row.check input { width: 22px; height: 22px; flex-shrink: 0; }

.choices { display: flex; flex-wrap: wrap; gap: 6px; }
.choices button { flex: 1 1 auto; }
.levels, .outcomes { display: grid; grid-template-columns: repeat(7, 1fr); }
.levels button, .outcomes button { padding: 10px 0; min-width: 0; }
.suit-btn { font-size: 1.4rem; }
button.wide { width: 100%; margin-top: 8px; }
.dealing { text-align: center; }
.deal-group { list-style: none; padding: 0; margin: 16px 0 4px; display: grid; gap: 8px; text-align: left; }
.deal-group li { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; }
.deal-group .dir { font-size: 1.6rem; font-weight: 700; color: var(--link); }
.deal-group .dir { white-space: nowrap; }
.deal-group .who { font-size: 1.1rem; color: var(--muted); min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* one line, so long names can't push Next down */
.deal-group.with-cards li { display: grid; grid-template-columns: 8.6rem 3.4rem minmax(0, 1fr); align-items: baseline; gap: 6px; }
.deal-group.with-cards .dir { font-size: 1.3rem; white-space: nowrap; }
.deal-group.with-cards .test-card { text-align: left; }
.deal-group.with-cards .who { text-align: right; }
.deal-group.single.with-cards li { display: flex; }
.deal-group.single li { flex-direction: column; align-items: center; border: none; padding: 20px 0 8px; }
.deal-group.single .dir { font-size: 2.4rem; }
.ranks { display: grid; grid-template-columns: repeat(7, 1fr); margin-bottom: 6px; }
.ranks button { padding: 10px 0; min-width: 0; }
.link-row { display: flex; justify-content: space-between; margin-top: 6px; }
.pile-tops { list-style: none; padding: 0; margin: 12px 0; display: grid; gap: 8px; text-align: left; }
.pile-tops li { display: flex; justify-content: space-between; align-items: center; border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; }
.pile-tops .top-card { font-size: 1.4rem; font-weight: 700; }
button.next { min-height: 88px; font-size: 1.4rem; }
.summary { list-style: none; padding: 0; margin: 8px 0 4px; display: grid; gap: 6px; font-size: 1.15rem; }
.summary li strong { display: inline-block; min-width: 1.6em; text-align: right; margin-right: 8px; font-size: 1.4rem; }
.summary li.points { font-size: 1.25rem; margin-bottom: 4px; }
.summary li.points strong { font-size: 2rem; }
.how-to { border: 1px solid var(--border); border-radius: 10px; padding: 8px 12px; margin: 8px 0; }
.how-to summary { cursor: pointer; font-weight: 600; color: var(--link); }
.how-to ol { padding-left: 1.3rem; margin: 8px 0 4px; display: grid; gap: 6px; }
.dealing .hand { text-align: left; }
.table-hands { display: grid; grid-template-columns: minmax(0, auto) 4rem minmax(0, auto); grid-template-areas: "n n n" "w t e" "s s s"; gap: 8px; align-items: center; margin: 10px 0; text-align: left; }
.table-hands .th-north { grid-area: n; justify-self: center; }
.table-hands .th-south { grid-area: s; justify-self: center; }
/* North and South as wide as West and East (one side column: 1fr of 2.45fr, after the gaps). */
.table-hands .th-north, .table-hands .th-south { width: max-content; min-width: calc((100% - 16px) / 2.45); max-width: 100%; }
.table-hands .th-north .hand, .table-hands .th-south .hand { box-sizing: border-box; width: 100%; }
.table-hands .th-west { grid-area: w; }
.table-hands .th-east { grid-area: e; }
.table-hands .th-table { grid-area: t; aspect-ratio: 1; border: 2px solid var(--accent); border-radius: 6px; background: var(--selected); }
.table-hands .hand { padding: 6px 8px; font-size: 0.85rem; }
.table-hands .hand h3 { font-size: 0.8rem; }
.pack-check { background: var(--selected); border-radius: 10px; padding: 8px 12px; font-weight: 600; }
.deal-picker { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; margin: 6px 0; }
.deal-picker button { padding: 8px 0; min-width: 0; min-height: 38px; font-size: 0.9rem; }
.deal-picker.suit-row { grid-template-columns: 1.2em repeat(auto-fit, minmax(0, 1fr)); align-items: center; gap: 3px; }
.deal-picker.suit-row button { font-size: 0.75rem; padding: 6px 0; }
.deal-reveal { font-size: 1.3rem; font-weight: 700; color: var(--link); margin: 8px 0; }
.how-to-play ul, .how-to-play ol { padding-left: 1.3rem; display: grid; gap: 6px; }
.next-card { font-size: 1.05rem; background: var(--selected); border-radius: 10px; padding: 10px 12px; }
.declarers { display: grid; grid-template-columns: 1fr 1fr; }
.card > h2:first-child { margin-top: 0; }

.bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; color: var(--muted); }

.handover { text-align: center; padding: 32px 16px; }
.handover h1 { font-size: 2.4rem; }

.private { border: 2px solid var(--accent); }
.big { font-size: 1.4rem; font-weight: 700; margin: 0.3rem 0; }
.warn { color: var(--warn); }
.arrow-map { list-style: none; padding: 0; margin: 12px 0; display: grid; gap: 8px; }
.arrow-map li { display: flex; align-items: center; gap: 12px; font-size: 1.1rem; }
.arrow-map .arrow { font-size: 1.8rem; width: 1.4em; text-align: center; color: var(--link); }

.hands { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.hand { border: 1px solid var(--border); border-radius: 10px; padding: 8px; }
.suit { font-variant-numeric: tabular-nums; }
.suit span { display: inline-block; width: 1.1em; }

.table-grid {
    display: grid;
    grid-template-areas: ". n ." "w c e" ". s .";
    grid-template-columns: 1fr 1.1fr 1fr;
    gap: 6px;
    text-align: center;
}
.table-grid .seat { border: 1px solid var(--border); border-radius: 10px; padding: 8px 4px; display: flex; flex-direction: column; overflow-wrap: anywhere; }
.table-grid .seat span { font-size: 0.75rem; color: var(--muted); }
.auction-dealer { text-align: center; font-size: 1.25rem; margin: 0 0 12px; }
.auction-dealer strong { color: var(--link); }
.auction-dealer span { color: var(--muted); font-size: 1rem; }
.table-grid .seat.dealer { border-width: 2px; border-color: var(--accent); }
.table-grid .badges { display: flex; gap: 4px; justify-content: center; flex-wrap: wrap; }
.table-grid .seat.you { border-width: 2px; }
.you-badge { background: var(--text); color: var(--surface) !important; }
.dealer-badge { align-self: center; background: var(--accent); color: var(--accent-text) !important; font-size: 0.7rem !important; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; border-radius: 6px; padding: 1px 6px; margin-bottom: 2px; }
.deal-banner { text-align: center; font-size: 1.2rem; margin: 0 0 10px; }
.arrow-glyph { display: inline-block; min-width: 1.1em; text-align: center; font-weight: 700; }
.deal-group .arrow-glyph { font-size: 1.15em; }
.steps { padding-left: 1.3rem; margin: 8px 0 12px; display: grid; gap: 6px; }
.pass-to { font-size: 1.1rem; display: flex; align-items: center; gap: 12px; margin: 8px 0 4px; }
.pass-to .arrow-glyph { font-size: 2rem; color: var(--link); vertical-align: middle; margin-right: 6px; }
.menu { display: grid; gap: 8px; }
.menu button.wide { margin-top: 0; }
.menu button:disabled { opacity: 0.4; cursor: default; }
/* The menu's groups: a small heading over each, and a line between them. */
.menu-group { display: grid; gap: 8px; }
.menu-group + .menu-group { border-top: 1px solid var(--border); padding-top: 10px; }
.menu-label { margin: 0 2px -2px; font-size: 0.72rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.confirm-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.confirm-row button { margin-top: 0; } /* a pair side by side: the same size and level, whichever is the primary */
.pile-counts-label { margin: 10px 0 0; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); text-align: center; }
.pile-counts { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 4px 0 0; font-size: 0.8rem; color: var(--muted); }
.pile-counts div { border: 1px solid var(--border); border-radius: 8px; padding: 6px 2px; display: flex; flex-direction: column; align-items: center; }
.pile-counts strong { font-size: 1.3rem; color: var(--text); }
.deal-toggles { display: flex; justify-content: space-between; align-items: center; margin-top: 14px; }
.deal-toggles .row { margin: 0; }
.speed-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px; margin-top: 8px; }
.speed-row span { font-weight: 600; min-width: 5em; text-align: center; }
.speed-row button:disabled { opacity: 0.4; }
.recorded { text-align: center; font-weight: 600; color: var(--link); margin: 0 0 8px; }
.scores tr.just-played td { background: var(--selected); font-weight: 600; }
.show-cards { justify-content: center; margin-top: 14px; font-size: 0.85rem; color: var(--muted); }
.test-card { font-size: 1.3rem; font-weight: 700; }
.table-grid .seat { border-width: 3px; border-color: #1f9d55; }
.table-grid .seat.vul { background: var(--vul); border-color: #c4161c; }
.table-grid .north { grid-area: n; }
.table-grid .east { grid-area: e; }
.table-grid .south { grid-area: s; }
.table-grid .west { grid-area: w; }
.table-grid .centre { grid-area: c; align-self: center; font-size: 0.8rem; font-weight: 600; }

.preview { margin: 14px 0 0; }

.totals { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.totals div { border: 1px solid var(--border); border-radius: 10px; padding: 10px; display: flex; flex-direction: column; }
.totals span { font-size: 0.85rem; color: var(--muted); }
.totals strong { font-size: 1.6rem; }

table.scores { width: 100%; border-collapse: collapse; margin-top: 10px; font-size: 0.92rem; }
.scores th, .scores td { text-align: left; padding: 6px 4px; border-bottom: 1px solid var(--border); }
.scores th { white-space: nowrap; }
.scores td:not(:nth-child(2)) { white-space: nowrap; }
.scores tr.result-row td { border-bottom: none; padding-bottom: 0; }
.scores tr.result-row.no-detail td { border-bottom: 1px solid var(--border); padding-bottom: 6px; }
.scores tr.detail-row td { padding-top: 0; text-align: left; }
.scores td:not(:nth-child(2)), .scores th:not(:nth-child(2)) { text-align: right; font-variant-numeric: tabular-nums; }
.total-line { font-weight: 600; text-align: center; margin: 8px 0; }
.totals .leading { border-color: var(--accent); background: var(--selected); }
.scores td.primary-col { font-weight: 700; }
.scores tr.selectable { cursor: pointer; }
.result-detail { font-size: 0.8rem; color: var(--muted); }
.scores td { vertical-align: top; }

.actions { display: grid; gap: 8px; }
.actions button.primary { margin-top: 0; }

.version { text-align: center; color: var(--muted); font-size: 0.75rem; margin-top: 24px; }

#back-hint { position: fixed; left: 50%; bottom: 72px; transform: translateX(-50%); z-index: 950; background: var(--text); color: var(--bg); padding: 10px 16px; border-radius: 999px; font-size: 0.9rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25); }
#back-hint[hidden] { display: none; }
/* 6 Nov (00n6): the update prompt at the top of the page, in the flow (it was fixed over the bottom of the screen, under taps). */
#update-banner { position: static; display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 8px 16px; background: var(--accent); color: var(--accent-text); font-weight: 600; font-size: 0.95rem; }
#update-banner[hidden] { display: none; }
#update-banner button { background: var(--accent-text); color: var(--link); border: none; font-weight: 700; white-space: nowrap; }

/* Blazor template plumbing */
#blazor-error-ui { color-scheme: light only; background: lightyellow; bottom: 0; box-shadow: 0 -1px 2px rgba(0,0,0,.2); box-sizing: border-box; display: none; left: 0; padding: .6rem 1.25rem .7rem; position: fixed; width: 100%; z-index: 1000; }
#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: .75rem; top: .5rem; }
.loading-progress { position: absolute; display: block; width: 8rem; height: 8rem; inset: 20vh 0 auto 0; margin: 0 auto; }
.loading-progress circle { fill: none; stroke: var(--border); stroke-width: .6rem; transform-origin: 50% 50%; transform: rotate(-90deg); }
.loading-progress circle:last-child { stroke: var(--accent); stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%; transition: stroke-dasharray .05s ease-in-out; }
.loading-progress-text { position: absolute; text-align: center; font-weight: bold; inset: calc(20vh + 3.25rem) 0 auto .2rem; }
.loading-progress-text:after { content: var(--blazor-load-percentage-text, "Loading"); }

/* Reading deals from a file */
.file-pick { display: inline-block; position: relative; margin: 0.25rem 0 0.5rem; }
.file-pick input[type=file] { position: absolute; inset: 0; opacity: 0; width: 100%; cursor: pointer; }
.file-button { display: inline-block; padding: 0.6rem 1rem; border: 1px solid var(--accent); color: var(--link); border-radius: 8px; font-weight: 600; }
.deal-picker sup.pick-order { font-size: 0.65em; margin-left: 2px; font-weight: 700; }
.auction { margin-top: 0.75rem; }
.auction-grid { border-collapse: collapse; width: 100%; max-width: 20rem; text-align: center; }
.auction-grid th, .auction-grid td { padding: 0.15rem 0.3rem; width: 25%; }
.auction-grid th { border-bottom: 1px solid currentColor; }

/* Sharing a game */
.share .qr { background: #fff; padding: 0.5rem; border-radius: 8px; max-width: 22rem; margin: 0.75rem auto; }
.share .qr svg { display: block; width: 100%; height: auto; }
.share .summary { padding-left: 1.2rem; margin: 0.5rem 0; }
.share .summary li { margin: 0.2rem 0; }
/* Share with other tables: the warning stands out; the game's settings are a small list (not the score sheet's big summary style). */
.share-warn { border-left: 4px solid var(--warn); padding: 0.4rem 0.6rem; background: var(--selected); border-radius: 6px; }
.share .share-summary { font-size: 0.9rem; color: var(--muted); padding-left: 1.1rem; }
.share .share-summary-label { font-size: 0.9rem; }
.share-link { word-break: break-all; font-size: 0.7rem; }
.code-banner { border-left: 4px solid var(--accent); padding: 0.5rem 0.75rem; background: var(--selected); border-radius: 6px; margin: 0.75rem 0; }
.code-banner ul { padding-left: 1.2rem; margin: 0.4rem 0 0; }
#error-detail { font-size: 0.75rem; margin-top: 0.3rem; word-break: break-word; color: #555; }
.slow-load { position: absolute; inset: calc(20vh + 10rem) 1rem auto 1rem; text-align: center; }
/* The video fills the box by absolute positioning (a percentage height inside an aspect-ratio box, and rounded corners with
   overflow hidden around a video, both leave Safari on iPhone and iPad showing a black box), with its own rounded corners. */
.scan-view { position: relative; background: #000; border-radius: 8px; aspect-ratio: 1; max-width: 22rem; margin: 0.75rem auto; }
.scan-view video.scan-source { position: absolute; top: 0; left: 0; width: 2px; height: 2px; opacity: 0.01; pointer-events: none; }
.scan-view canvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 8px; background: #000; }

/* Confirmation dialog */
.dialog-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; padding: 1rem; z-index: 900; }
.dialog { width: 100%; max-width: 24rem; max-height: 90vh; overflow-y: auto; margin: 0; text-align: left; }
.dialog h2 { text-align: center; margin-top: 0.25rem; }
.dialog ul { padding-left: 1.2rem; }
.dialog button.primary { width: 100%; }
.dialog-tick { width: 3.5rem; height: 3.5rem; margin: 0 auto; border-radius: 50%; background: var(--accent); color: var(--accent-text); font-size: 2rem; line-height: 3.5rem; text-align: center; font-weight: 700; }

/* Device lying in the middle of the table (Show hands): each hand faces its player. All four
   boxes are the same size (--hand-w by --hand-h); West and East are turned a quarter turn, so
   their cells swap width and height, and North is upside down. */
.table-hands.facing { --hand-w: 10rem; --hand-h: 7.5rem; grid-template-columns: var(--hand-h) minmax(4rem, 1fr) var(--hand-h); justify-content: center; }
.table-hands.facing .hand { box-sizing: border-box; width: var(--hand-w); min-height: var(--hand-h); }
.table-hands.facing .th-north, .table-hands.facing .th-south { width: auto; }
.table-hands.facing .th-north .hand { transform: rotate(180deg); }
.table-hands.facing .th-west, .table-hands.facing .th-east { position: relative; width: var(--hand-h); height: var(--hand-w); }
.table-hands.facing .th-west .hand, .table-hands.facing .th-east .hand { position: absolute; left: 50%; top: 50%; }
.table-hands.facing .th-west .hand { transform: translate(-50%, -50%) rotate(90deg); }
.table-hands.facing .th-east .hand { transform: translate(-50%, -50%) rotate(-90deg); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.bottom-edge { text-align: center; text-wrap: balance; font-weight: 600; color: var(--link); margin: 0.25rem 0 0.25rem; letter-spacing: 0.01em; }
/* A long suit wraps inside its box rather than running off the screen; the cards that wrap
   line up after the suit symbol. */
.table-hands .suit { display: flex; }
.table-hands .suit span { flex: none; }
/* The table in the middle: the same small square in every layout. */
.table-hands .th-table { display: flex; align-items: center; justify-content: center; width: 4rem; height: 4rem; aspect-ratio: auto; justify-self: center; align-self: center; box-sizing: border-box; }
.facing-toggle { justify-content: center; margin: 0.25rem 0 0.5rem; flex-wrap: nowrap; }
.facing-toggle button { flex: 0 1 auto; padding: 0.35rem 0.7rem; font-size: 0.85rem; min-height: 0; }
/* Back is always centred, just below the screen's card. */
/* Back looks like a button: outlined, centred just below the card. */
button.link.back { display: block; margin: 0.5rem auto 0; padding: 0.55rem 1.6rem; min-width: 8rem; min-height: 44px;
    border: 1.5px solid var(--accent); border-radius: 10px; background: var(--surface); color: var(--link); font-weight: 600; }

/* Double dummy table */
.double-dummy { margin-top: 0.75rem; }
.dd-table { border-collapse: collapse; margin: 0.25rem 0; }
.dd-table th, .dd-table td { border: 1px solid var(--border); width: 2.6rem; height: 2rem; text-align: center; padding: 0; }
.dd-table thead th { background: var(--dd-head); }
.dd-table tbody th { background: var(--dd-head); width: 2rem; }
.dd-table td.makes { font-weight: 700; }
button.link.centred { display: block; margin: 0.5rem auto 0; padding: 8px 16px; }
.dd-later { text-align: center; }
.menu-btn { border: none; background: none; color: var(--link); font-size: 1.6rem; line-height: 1; padding: 4px 8px; min-height: 44px; min-width: 44px; cursor: pointer; }
button.primary.next:disabled { opacity: 0.55; }

/* Four-colour suits (Settings, on by default): diamonds orange and clubs green. */
.four-colour .suit-d { color: var(--diamond); }
.four-colour .suit-c { color: var(--club); }

/* Names round the table (setup) */
.seat-table { display: grid; grid-template-columns: 1fr 4.2rem 1fr; grid-template-areas: "n n n" "w m e" "s s s"; gap: 8px; align-items: center; }
.seat-table input { width: 100%; box-sizing: border-box; min-width: 0; }
.seat-table .seat-north { grid-area: n; justify-self: center; width: min(12rem, 60%); }
.seat-table .seat-south { grid-area: s; justify-self: center; width: min(12rem, 60%); }
.seat-table .seat-west { grid-area: w; }
.seat-table .seat-east { grid-area: e; }
.seat-table .seat-mid { grid-area: m; position: relative; aspect-ratio: 1; border: 2px solid var(--accent); border-radius: 6px;
    background: var(--selected); color: var(--link); font-weight: 700; font-size: 0.8rem; }
.seat-mid span, .th-table span { position: absolute; line-height: 1; }
.seat-mid .cn, .th-table .cn { top: 4px; left: 50%; transform: translateX(-50%); }
.seat-mid .cs, .th-table .cs { bottom: 4px; left: 50%; transform: translateX(-50%); }
.seat-mid .cw, .th-table .cw { left: 5px; top: 50%; transform: translateY(-50%); }
.seat-mid .ce, .th-table .ce { right: 5px; top: 50%; transform: translateY(-50%); }
.mode-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 1rem; }
.mode-row .choices { flex: 0 0 auto; }
.mode-row .choices button { padding: 0.35rem 0.8rem; min-height: 0; font-size: 0.85rem; }
.suit-sample { margin-left: auto; font-size: 1.1rem; letter-spacing: 0.15em; }
.row.practise input { max-width: 8rem; }
.practise-right { color: var(--link); font-weight: 700; }
/* Deal type buttons: name with a padlock rating below */
button.source { display: flex; flex-direction: column; align-items: center; gap: 2px; }
button.source .sub { font-size: 0.75rem; font-weight: 400; color: var(--muted); }
.centred-text { text-align: center; }
/* Interest analysis and deal statistics */
details.interest { margin-top: 0.75rem; }
details.interest summary { cursor: pointer; font-weight: 600; color: var(--link); }
.interest-total .accept { color: var(--link); font-weight: 700; }
.interest-total .reject { color: var(--red); font-weight: 700; }
.interest-hand p { margin: 0.4rem 0 0.1rem; font-size: 0.9rem; }
.interest-hand ul, ul.stats { margin: 0 0 0.3rem; padding-left: 1.2rem; font-size: 0.85rem; }
.preview-board .eyebrow .accept { color: var(--link); font-weight: 700; }
.preview-board .eyebrow .reject { color: var(--red); font-weight: 700; }
.table-hands .th-table { position: relative; color: var(--link); font-weight: 700; font-size: 0.8rem; }
.score-breakdown table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.score-breakdown td { padding: 3px 0; border-bottom: 1px solid var(--border); }
.score-breakdown td.pts { text-align: right; white-space: nowrap; padding-left: 8px; }
.score-breakdown tr.total td { font-weight: 700; border-bottom: none; }
.practise-row { display: flex; gap: 8px; align-items: stretch; }
.practise-row .sign { flex: 0 0 auto; flex-wrap: nowrap; }
.practise-row .sign button { min-width: 2.8rem; font-size: 1.2rem; font-weight: 700; padding: 0 0.6rem; }
.practise-row input { flex: 1 1 auto; min-width: 0; }

/* Short screens (small devices with the browser's bars showing): tighten the dealing card just
   enough that Next and Back show without scrolling. */
@media (max-height: 640px) {
    .deal-banner { margin-bottom: 6px; font-size: 1.1rem; }
    .deal-group { margin-top: 10px; gap: 6px; }
    .deal-group li { padding: 5px 14px; }
    button.next { min-height: 64px; font-size: 1.25rem; }
    .card.dealing > .eyebrow { letter-spacing: 0.02em; font-size: 0.7rem; }
}

/* Players' own devices */
.seat-choices { display: grid; grid-template-columns: 1fr 1fr; }
.seat-choices button { display: flex; flex-direction: column; align-items: center; line-height: 1.2; }
.seat-choices button small { font-size: 0.8rem; color: var(--muted); font-weight: 400; }
.player-board { text-align: center; }
.player-board .board-number { font-size: 2.6rem; margin: 0.1em 0 0.3em; }
.player-board .board-number span { font-size: 1.1rem; color: var(--muted); font-weight: 600; }
.player-footer { margin: 0.5rem 0 1rem; }
.player-footer .confirm-row .link { text-align: center; }
.table-hands .hand.elsewhere { display: flex; flex-direction: column; justify-content: center; text-align: center; opacity: 0.65; border-style: dashed; }
.table-hands .hand.elsewhere p { margin: 0; }
/* Offline: an own-device hand the host has shown, with the offer to show it on this device from now on. */
.own-device-off { text-align: center; margin: 0.4rem auto 0; max-width: 40rem; }

.solver-link { margin: 12px 0; }
.solver-btn { display: block; box-sizing: border-box; width: 100%; text-align: center; text-decoration: none; font: inherit; font-weight: 600;
    color: var(--link); background: var(--surface); border: 1px solid var(--border); border-radius: 10px; padding: 10px 14px; min-height: 44px; line-height: 24px; }
.solver-link p { margin: 6px 0 0; }

/* Deal options: stacked one above the other at any width, each with its description under it when selected. */
.source-list { display: flex; flex-direction: column; gap: 8px; }
.source-list button.source { width: 100%; }
.source-list .source-help { margin: 0 0 6px; }
.source-detail { margin: 0 0 6px; padding: 0 0 0 4px; border-left: 3px solid var(--selected); padding-left: 10px; }
.source-detail .label { margin-top: 10px; }

/* A tappable hand: tap to hide it ("Tap to show") or show it again. */
.hand.tappable { cursor: pointer; -webkit-tap-highlight-color: transparent; user-select: none; }
.hand.tappable:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.hand.hidden-hand { display: flex; flex-direction: column; background: var(--selected); min-height: 7rem; }
.hand.hidden-hand h3 { margin-bottom: auto; }
.hand .tap-hint { margin: 0; align-self: center; margin-bottom: auto; font-weight: 600; color: var(--link); }
.table-hands .th-table.tappable-table { cursor: pointer; }
/* A hand on a player's own device, tappable here only to sort out a problem: blue, to tell it from the others. */
.hand.own-device { background: #dbeafe; border-color: #2563eb; }
.hand.own-device .tap-hint, .hand.own-device .own-note { color: #1d4ed8; }
.hand.own-device .own-note { margin: 0 0 .25rem; align-self: center; font-weight: 600; }
.hand.own-device h3 { margin-bottom: .25rem; }
@media (prefers-color-scheme: dark) {
  .hand.own-device { background: #1e3a5f; border-color: #60a5fa; }
  .hand.own-device .tap-hint, .hand.own-device .own-note { color: #93c5fd; }
}

/* The connection to the online service, at the bottom of every page. */
.sync-status { display: flex; align-items: center; justify-content: center; gap: .4rem; margin: 20px 0 0; font-size: 0.8rem; color: var(--muted); }
.sync-status .dot { width: .6rem; height: .6rem; border-radius: 50%; background: #9ca3af; }
.sync-status.online .dot { background: #16a34a; }
.sync-status.connecting .dot { background: #f59e0b; }
.sync-status.reachable .dot { background: #2563eb; } /* offline game, the service can be seen but isn't used */
.sync-status.online { color: #166534; }
@media (prefers-color-scheme: dark) { .sync-status.online { color: #86efac; } }
.follow-note { margin: 0 0 .5rem; color: var(--link); font-weight: 600; font-size: 0.9rem; }
.agree-list { list-style: none; padding: 0; margin: .5rem 0; }
.agree-list li { display: flex; justify-content: space-between; gap: .5rem; padding: .4rem 0; border-bottom: 1px solid var(--border, #ddd); }
.agree-list li.agrees .status { color: var(--link); font-weight: 600; }
.agree-list li.disagrees .status { color: var(--red); font-weight: 600; }
.agree-list li.waiting .status { color: var(--muted); }

/* The setup steps. */
.step-line { margin: 0 0 .25rem; }
.quick-start { padding: .75rem; border: 1px dashed var(--accent); border-radius: 8px; margin-bottom: .5rem; }
.quick-start p { margin: .4rem 0 0; }
.step-buttons { display: flex; flex-direction: column; gap: .25rem; margin-top: .75rem; }
.summary-list { padding-left: 1.1rem; margin: .5rem 0; }
.summary-list li { margin: .15rem 0; }
.back-step { align-self: center; }

.voice-details { font-size: 0.8rem; color: var(--muted); margin: .25rem 0 .5rem; }
.voice-details ul { padding-left: 1rem; margin: .25rem 0; word-break: break-all; }


/* Teacher's console */
.board-strip { display: flex; flex-wrap: wrap; gap: 6px; margin: 0.5rem 0; }
.board-strip button { min-width: 2.6rem; }
.board-strip button small { display: block; font-size: 0.65rem; color: var(--muted); }
.teacher-nav { display: flex; gap: 8px; align-items: center; justify-content: space-between; margin: 0.5rem 0; }
.teacher-nav button { flex: 1; }
.hcp-line { text-align: center; margin: 0.25rem 0 0.75rem; }
.hcp-line span { margin: 0 0.5rem; white-space: nowrap; }
/* Projector view: larger text and the whole width of the screen. */
html.projector, html.projector body { font-size: clamp(19px, 2vw, 26px); }
html.projector .shell { max-width: 1200px; }
html.projector .teacher-tools, html.projector .bar { display: none; }
html.projector .table-hands { max-width: 760px; margin-left: auto; margin-right: auto; }
html.projector .table-hands .hand { font-size: 1.1rem; }
html.projector .table-hands .hand h3 { font-size: 1rem; }
html.projector .projector-exit.bottom { top: auto; bottom: 12px; }
html.projector .projector-exit { position: fixed; right: 12px; top: 12px; z-index: 50; font-size: 0.8rem; padding: 8px 14px; background: var(--accent); color: var(--accent-text); border: 0; border-radius: 8px; }
html.projector .shell { padding-top: 3.2rem; }

/* Teacher's overview of the tables */
.tabs { margin-bottom: 0.5rem; }
.class-bar .message-row { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-top: 0.5rem; }
.class-bar .message-row input { flex: 1 1 12rem; min-width: 0; }
/* Every table is at least the same height (room for the bidding, the result and the lead). A table opened with More takes two
   rows, and if it needs more the rows below move down, so nothing overlaps. Other tables keep their size: they don't stretch. */
.tables-grid { --tz: 1; --tile-row: calc(30rem - 9rem * var(--tz)); display: grid; grid-template-columns: repeat(auto-fill, minmax(calc(11.5rem * var(--tz)), 1fr)); grid-auto-rows: minmax(var(--tile-row), auto); gap: 10px; align-items: start; }
.tables-grid > .table-tile { min-height: var(--tile-row); }
.tables-grid > .table-tile.open { grid-row: span 2; }
html.wide-console .shell { max-width: 1500px; }
.table-tile { border-left: 8px solid var(--border); margin-bottom: 0; padding: calc(10px * var(--tz)); font-size: calc(1rem * var(--tz)); }
.table-tile p { margin: 0.2em 0; }
.table-tile h3 { display: flex; justify-content: space-between; margin: 0 0 0.2em; }
.table-tile .tile-online { color: var(--link); }
.table-tile.away .tile-online { color: var(--muted); }
.table-tile .tile-stage { font-weight: 600; }
.slip { color: var(--red); font-weight: 700; }
.slip-note { color: var(--red); font-size: 0.8em; margin: 0; }
.table-tile .tile-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 0.4em; }
.table-tile button { font-size: inherit; padding: 0.35em 0.7em; }
.zoom-buttons { display: inline-flex; gap: 4px; margin-left: auto; }
.zoom-buttons button { min-width: 2.4rem; white-space: nowrap; }
.table-tile.away { opacity: 0.6; }
.table-tile h3 { font-size: 1.05rem; }
/* Two colours only: green when the table can get on with it, red when it needs something from the teacher */
.table-tile.stage-dealing, .table-tile.stage-bidding, .table-tile.stage-playing, .table-tile.stage-confirming, .table-tile.stage-scored { border-left-color: #16a34a; }
.table-tile.stage-contract, .table-tile.stage-waiting { border-left-color: #dc2626; background: var(--vul); }
.table-tile.stage-finished { border-left-color: #6b7280; }
.class-hold { text-align: center; }
.class-hold h1 { font-size: clamp(1.05rem, 5.2vw, 1.35rem); display: flex; align-items: center; justify-content: center; gap: 0.4em; }
.class-hold h1, .class-hold p { text-wrap: balance; }
.class-hold .big { font-size: 1.25rem; }
.class-hold .nowrap { white-space: nowrap; }
.pause-icon { width: 0.9em; height: 0.9em; fill: currentColor; flex: none; }
.class-code-block { display: flex; flex-direction: column; align-items: center; margin: 0.25rem 0 0.5rem; }
.class-code-label { font-size: 0.8rem; color: var(--muted); line-height: 1.2; }
.class-code-line { text-align: center; font-size: 1.1rem; margin: 0 0 0.25rem; }
.table-tile .tile-host { font-size: 0.9em; color: var(--muted); margin: 0 0 0.2em; }
.class-switches { gap: 14px; }
.class-switches .row { margin: 0; }
.sync-row { margin-top: 0.3rem; }
.sync-row input { width: 4rem; }
.class-code { font-size: 2.2rem; letter-spacing: 0.25em; }

/* The class bar stays compact so more tables fit on screen */
.class-bar { padding: 10px 12px; }
.class-bar p { margin: 0.2em 0; }
.class-bar .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.class-bar .actions button { width: auto; flex: 0 0 auto; margin: 0; }
.class-bar .message-row { margin-top: 0.4rem; }

.share.class-page .class-title { margin: 0 0 0.15rem; }
.share.class-page .qr { margin-top: 0.15rem; margin-bottom: 0.15rem; }
.class-qr-col .class-code { font-size: 2.4rem; line-height: 1.1; }

.scores tfoot .total-row th, .scores tfoot .total-row td { border-top: 2px solid var(--accent); font-weight: 700; }

/* A played board as a tappable pair of lines: the contract and result, then the lead and score */
.result-link { display: block; width: 100%; text-align: left; background: none; border: 0; padding: 0.15em 0; font: inherit; color: inherit; cursor: pointer; }
.result-link .rl-main { display: block; font-size: 1.25em; font-weight: 700; }
.result-link .rl-sub { display: block; font-size: 0.95em; }
.result-link:hover .rl-main, .result-link:focus-visible .rl-main { text-decoration: underline; }
.done-list { display: block; margin-top: 0.4em; }
.done-item { display: grid; grid-template-columns: 1.6em 1fr; column-gap: 0.4em; padding: 0.3em 0; border-top: 1px solid var(--border); }
.done-item .di-board { color: var(--muted); padding-top: 0.15em; }
.done-item .result-link .rl-main { font-size: 1.05em; }
.done-item .di-slips { grid-column: 2; display: block; }
.done-item .slip-note { display: block; }
.focus-banner { border-left: 8px solid var(--accent); }
.focus-banner p { margin: 0.2em 0; }
.focus-banner .rl-main { font-size: 1.3em; font-weight: 700; }

/* On the contract page there is no "Contract" label, so a blank line separates Passed out from the numbers */
.choices.levels.after-passed-out { margin-top: 1.6rem; }

.row.compact { justify-content: flex-start; }
input[type=number].table-number { width: 4em; }
.code-banner .link { padding: 0.2rem 0; }

/* Wide screens (an iPad in landscape): the teacher's class code page and boards use the width */
@media (min-width: 900px) {
    .share.class-page { display: grid; grid-template-columns: minmax(300px, 460px) 1fr; column-gap: 2.5rem; align-items: start; }
    .share.class-page > * { grid-column: 2; }
    .share.class-page > .class-qr-col { grid-column: 1; grid-row: 1 / span 6; }
    .share.class-page > .class-title { grid-column: 2; }
    .share.class-page .qr { max-width: 460px; margin: 0; }
    .class-qr-col .class-code { font-size: 3.4rem; }
    .share.class-page .summary { display: block; column-count: 2; column-gap: 1.5rem; padding-left: 0; margin: 0.5rem 0; list-style: none; }
    .share.class-page .summary li { break-inside: avoid; margin: 0 0 0.5rem; font-size: 0.95rem; }
    .board-card { display: grid; grid-template-columns: minmax(320px, 1fr) minmax(300px, 1fr); column-gap: 2rem; align-items: start; grid-template-areas: "head nav" "strip side" "meta side" "hands side" "rest side"; grid-template-rows: auto auto auto auto 1fr; align-content: start; }
    .board-card > .board-head { grid-area: head; }
    .board-card > .teacher-nav { grid-area: nav; margin: 0 0 12px; }
    .board-card > .board-strip { grid-area: strip; }
    .board-card > .board-meta { grid-area: meta; }
    .board-card > .board-hands { grid-area: hands; }
    .board-card > .board-side { grid-area: side; display: flex; flex-direction: column; gap: 12px; align-self: start; }
    .board-side > .class-bidding { margin: 0; }
}

/* One style of Back everywhere (setup steps too), and a 44px touch height for links and two-way toggles */
button.link.back-step { display: block; margin: 0.25rem auto 0; padding: 0.55rem 1.6rem; min-width: 8rem; min-height: 44px;
    border: 1.5px solid var(--accent); border-radius: 10px; background: var(--surface); color: var(--link); font-weight: 600; }
button.link { min-height: 44px; display: inline-flex; align-items: center; justify-content: center; }
.facing-toggle button, .mode-row .choices button { min-height: 44px; }
.table-tile button { min-height: max(30px, calc(44px * var(--tz, 1))); }

/* First screen: two groups, every option with its own line of explanation */
.role-group { margin: 1.1rem 0 0.3rem; font-weight: 700; color: var(--muted); text-transform: uppercase; font-size: 0.75rem; letter-spacing: 0.06em; }
.role-hint { margin: 0.25rem 0 0.6rem; }

/* Names: slightly smaller text in the table diagram's boxes */
.seat-table input { font-size: 0.9rem; }

/* Advanced one-page setup on a wide screen: two columns */
@media (min-width: 900px) {
    .shell:has(.setup-cols.one-page) { max-width: 1100px; }
    .setup-cols.one-page { column-count: 2; column-gap: 2.5rem; }
    .setup-cols.one-page .setup-sec { break-inside: avoid; }
}

/* Projector view: the whole board on one screen, nothing but the board */
html.projector .focus-banner, html.projector .board-meta .muted, html.projector .board-strip { display: none; }
html.projector .board-card { row-gap: 0; padding-top: 8px; padding-bottom: 8px; }
html.projector .board-card .table-hands { margin-top: 2px; margin-bottom: 2px; }
html.projector .shell { padding-top: 3.4rem; }
html.projector .board-card > .board-head { margin: 0.2rem 0; }
html.projector .board-card > .board-meta p { margin: 0 0 0.4rem; }
html.projector .projector-exit-bottom { display: block; margin: 1rem auto 0; }

/* Class access: passwords and the staff devices in a class */
.access-grid { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.4rem 0.75rem; align-items: center; margin: 0.5rem 0; }
.access-grid .row { margin: 0; min-width: 0; }
.access-grid input { min-width: 0; }
/* On a phone the label sits above its box, so the box and the Generate button next to it both fit */
@media (max-width: 520px) {
    .access-grid .row { flex-direction: column; align-items: stretch; gap: 4px; }
    .access-grid input { width: 100%; box-sizing: border-box; }
    .access-grid > button { align-self: end; }
}
.access-grid input { text-transform: uppercase; letter-spacing: 0.08em; }
.access-list { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 1rem; margin: 0.5rem 0; }
.access-list dt { font-weight: 600; }
.access-list dd { margin: 0; letter-spacing: 0.12em; font-variant-numeric: tabular-nums; }
.device-list { list-style: none; padding: 0; margin: 0.25rem 0; }
.device-list li { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; padding: 0.3rem 0; border-bottom: 1px solid var(--line, rgba(128,128,128,.3)); }
.class-access { margin-top: 1rem; }
.teacher-link-note { margin-top: 0.75rem; }

/* Support */
.support-list { list-style: none; padding: 0; margin: 0.5rem 0; }
.support-list li { display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line, rgba(128,128,128,.3)); }

/* Scores QR and checking scores */
.scores-pickup .all-match { font-size: 1.15rem; font-weight: 600; color: var(--link); }
.pickup-list { list-style: none; padding: 0; margin: 0.5rem 0; }
.pickup-list li { display: flex; flex-direction: column; gap: 0.25rem; padding: 0.5rem 0; border-bottom: 1px solid var(--line, rgba(128,128,128,.3)); }
.takeover-card { border-left: 6px solid var(--red); }


/* The hands laid out for the device lying in the middle of the table (the pick-your-cards page, and Show all four hands).
   The diagram grows with the screen so the cards can be read from across the table: --u is one unit (1rem on a small
   phone, up to 2.8rem on a big landscape screen). Ranks are bold. */
.shell:has(.table-hands.facing) { max-width: 1400px; --u: clamp(1rem, min(calc((100vw - 3rem) / 19.5), calc((100vh - 17rem) / 26)), 2.3rem); }
.table-hands.facing {
    --hand-w: calc(10 * var(--u)); --hand-h: calc(7.5 * var(--u));
    grid-template-columns: var(--hand-h) minmax(calc(4 * var(--u)), 1fr) var(--hand-h);
    gap: calc(0.5 * var(--u));
    width: calc(19.5 * var(--u)); max-width: 100%; margin-left: auto; margin-right: auto;
}
.table-hands.facing .hand { font-size: calc(0.9 * var(--u)); padding: calc(0.4 * var(--u)) calc(0.55 * var(--u)); border-width: 2px; }
.table-hands.facing .hand h3 { font-size: calc(0.85 * var(--u)); margin: 0 0 calc(0.2 * var(--u)); }
.table-hands.facing .suit { font-weight: 700; letter-spacing: 0.06em; line-height: 1.35; }
.table-hands.facing .suit span { width: 1.3em; font-size: 1.1em; }
.table-hands.facing .th-table { width: calc(4 * var(--u)); height: calc(4 * var(--u)); font-size: calc(0.8 * var(--u)); border-radius: calc(0.4 * var(--u)); }
.shell:has(.table-hands.facing) .bottom-edge { font-size: clamp(1rem, calc(0.9 * var(--u)), 1.8rem); }
.card:has(> .table-hands.facing) > button.primary { display: block; width: auto; max-width: 100%; margin: 0.6rem auto; padding-left: 2.5rem; padding-right: 2.5rem; }
/* A wide, short screen (an iPad on its side): West and East run down both sides of North, the table and South, so the diagram is
   about 20 units tall instead of 25 and can be bigger. The edge line, the toggle and the button stay under South. */
@media (min-aspect-ratio: 4/3) {
    .shell:has(.table-hands.facing) { --u: clamp(1rem, min(calc((100vw - 3rem) / 26.5), calc((100vh - 17rem) / 20.5)), 2.8rem); }
    .table-hands.facing { width: calc(26.5 * var(--u)); grid-template-columns: var(--hand-h) calc(10.5 * var(--u)) var(--hand-h); grid-template-areas: "w n e" "w t e" "w s e"; }
    .table-hands.facing .th-west, .table-hands.facing .th-east { align-self: center; }
    .card:has(> .table-hands.facing) > p.muted { max-width: 60rem; margin-left: auto; margin-right: auto; }
}

/* "Your hand" (one player looking at their own cards): bigger and bold on a tablet, a little bolder on a phone. */
.shell:has(.card.private > .hand) { max-width: min(760px, 100%); }
.card.private > .hand { font-size: clamp(1.05rem, calc(0.7rem + 1.6vmin), 2.1rem); padding: 0.6em 0.8em; border-width: 2px; }
.card.private > .hand h3 { font-size: 1em; }
.card.private > .hand .suit { font-weight: 700; letter-spacing: 0.06em; line-height: 1.45; }
.card.private > .hand .suit span { width: 1.3em; font-size: 1.1em; }

/* The same larger, bolder hands when everyone faces South (the hands upright, as in a bridge diagram): 24.5 units wide, about 20 tall. */
.shell:has(.table-hands.picking) { max-width: 1400px; --u: clamp(0.95rem, min(calc((100vw - 3rem) / 25), calc((100vh - 18rem) / 22)), 2.3rem); }
.table-hands.picking { grid-template-columns: minmax(0, calc(10 * var(--u))) minmax(0, calc(4 * var(--u))) minmax(0, calc(10 * var(--u))); gap: calc(0.5 * var(--u)); width: calc(24.5 * var(--u)); max-width: 100%; margin-left: auto; margin-right: auto; }
.table-hands.picking .th-north, .table-hands.picking .th-south { width: calc(10 * var(--u)); min-width: 0; max-width: 100%; }
.table-hands.picking .hand { box-sizing: border-box; width: 100%; font-size: calc(0.9 * var(--u)); padding: calc(0.4 * var(--u)) calc(0.55 * var(--u)); border-width: 2px; }
.table-hands.picking .hand h3 { font-size: calc(0.85 * var(--u)); margin: 0 0 calc(0.2 * var(--u)); }
.table-hands.picking .suit { font-weight: 700; letter-spacing: 0.06em; line-height: 1.35; }
.table-hands.picking .suit span { width: 1.3em; font-size: 1.1em; }
.table-hands.picking .th-table { width: calc(4 * var(--u)); height: calc(4 * var(--u)); font-size: calc(0.8 * var(--u)); border-radius: calc(0.4 * var(--u)); }
.shell:has(.table-hands.picking) .bottom-edge { font-size: clamp(1rem, calc(0.9 * var(--u)), 1.8rem); }
.card:has(> .table-hands.picking) > button.primary { display: block; width: auto; max-width: 100%; margin: 0.6rem auto; padding-left: 2.5rem; padding-right: 2.5rem; }
.card:has(> .table-hands.picking) > p.muted { max-width: 60rem; margin-left: auto; margin-right: auto; }

/* Every seat the same size, on every screen that shows the four seats round a table. */
.table-grid { grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); }
.table-grid .seat { justify-content: center; }
.seat-table .seat-north, .seat-table .seat-south { width: calc((100% - 4.2rem - 16px) / 2); }
.table-hands.picking { grid-template-rows: repeat(3, 1fr); }
.table-hands:not(.facing) .hand { box-sizing: border-box; height: 100%; }
/* The usual four-suit hand is this tall, so the four hands look the same size unless one has to wrap */
html:not(.projector) .table-hands:not(.facing):not(.picking) .hand { min-height: 8.6em; }
.table-hands:not(.facing):not(.picking) { grid-template-columns: minmax(0, 1fr) 4rem minmax(0, 1fr); }
.table-hands:not(.facing):not(.picking) .th-north, .table-hands:not(.facing):not(.picking) .th-south { width: calc((100% - 4rem - 16px) / 2); min-width: 0; }

.preview .pv-main, .preview .pv-sub { display: block; }

/* The teacher playing at a table: a bar back to the class console (red when a table needs them) */
.sit-bar { position: sticky; top: 0; z-index: 30; display: flex; justify-content: space-between; align-items: center; gap: 0.75rem; background: var(--accent); color: var(--accent-text); padding: 0.45rem 0.75rem; border-radius: 10px; margin-bottom: 10px; font-weight: 600; }
.sit-bar.attention { background: #b42318; color: #fff; }
.sit-bar button { background: #fff; color: #14532d; border: 0; border-radius: 8px; padding: 0.4rem 0.8rem; font-weight: 700; min-height: 0; }
.tabs button.table-tab { background: var(--accent); color: var(--accent-text); border-color: var(--accent); font-weight: 700; }
.tabs button.table-tab.attention { background: #b42318; border-color: #b42318; color: #fff; }

/* A table calling the teacher */
.table-tile.calling { border-left-color: #dc2626; box-shadow: 0 0 0 2px #dc2626; }
.tile-calling { margin: 0; color: var(--red); font-weight: 700; }
button.tile-calling { background: none; border: 0; padding: 0.35rem 0; min-height: 44px; text-align: left; cursor: pointer; text-decoration: underline; }

/* How the class did */
.class-badge { display: block; color: var(--link); font-weight: 600; font-size: 0.85rem; }
.class-rows { width: 100%; border-collapse: collapse; margin: 0.5rem 0; }
.class-rows td { padding: 0.45rem 0.4rem; border-bottom: 1px solid var(--line, rgba(128,128,128,.3)); vertical-align: baseline; }
.class-rows tr.mine td { background: var(--selected); font-weight: 700; }
.class-rows tr.mine td:first-child { border-radius: 6px 0 0 6px; }
.class-rows tr.mine td:last-child { border-radius: 0 6px 6px 0; }
.class-rows .cr-score { text-align: right; white-space: nowrap; }
.class-rows .cr-table, .class-rows .cr-main, .class-rows .cr-lead, .class-rows .cr-pos { white-space: nowrap; }
.class-rows th { text-align: left; font-size: 0.8rem; font-weight: 600; color: var(--muted, inherit); padding: 0.2rem 0.4rem; border-bottom: 2px solid var(--line, rgba(128,128,128,.4)); white-space: nowrap; }
.class-rows th.cr-score { text-align: right; }
.class-rows .cr-pos { width: 1.5rem; }

/* Boards tab: the cards are the point, so the hands are bigger and bolder */
.board-hands .table-hands .hand { font-size: 1.05rem; font-weight: 600; padding: 10px 12px; }
.board-hands .table-hands .hand h3 { font-size: 1rem; }
@media (min-width: 900px) { .board-hands .table-hands .hand { font-size: 1.2rem; } .board-hands .table-hands .hand h3 { font-size: 1.1rem; } }
.board-info .class-results { margin-top: 0; }

/* The play screen's instruction: what to do now, before the table and the result. */
.play-step { text-align: center; margin-bottom: 0.75rem; padding-bottom: 0.75rem; border-bottom: 1px solid var(--border); }
.play-step h1 { margin: 0 0 0.25rem; font-size: 1.45rem; }
.play-step p { margin: 0; }

/* Settings: the spoken directions folded away (most people never use a Guided deal). */
.settings-more { margin-top: 1rem; }
.settings-more summary { cursor: pointer; font-weight: 600; padding: 6px 0; }
/* Where results are entered: scoring practice on or off. */
.practise-switch { margin-bottom: 0.5rem; }

/* Hints (explanations): shown in full unless hints are off. Then each shows its first line, ending "…", with an ⓘ that
   opens the rest; one that fits on its line shows whole, with no ⓘ (marked one-line by dupliUi.fitHints). */
.hint .hint-i { display: none; }
html.hints-off .hint { min-height: 0; display: flex; align-items: flex-start; gap: 2px; }
html.hints-off .hint .hint-text { flex: 1; min-width: 0; }
html.hints-off .hint:not(.open) .hint-text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; }
html.hints-off .hint .hint-i { display: inline-flex; flex: none; align-items: center; justify-content: center; border: none; background: none; padding: 0 6px;
    min-height: 0; min-width: 28px; margin: 0 0 0 -6px; color: var(--link); font-size: 1.05rem; line-height: inherit; cursor: pointer; }
html.hints-off .hint.one-line:not(.open) .hint-i { display: none; }
html.hints-off .hint.one-line:not(.open) .hint-text { cursor: auto; }
.hints-choice { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; margin-top: 1.25rem; }
.hints-choice .choices { margin: 0; }
.hints-choice .choices button { min-width: 3.5rem; }
/* Information beside the choices on the first screens: normal size, set apart from the button and its hint. */
.role-info { margin: 1rem 0 0; }

/* ---- The auction round the table: each player's calls at their seat, the bidding box (or the contract) in the middle ---- */
/* --call scales the call cards: a little smaller on a phone (to leave room for the box), 1.2 times on a short tablet
   (an iPad on its side, under the browser's bars), twice as big on a taller one. */
.auction-table { --call: 0.85; display: grid; grid-template-columns: auto minmax(6rem, 1fr) auto; grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: ". n ." "w m e" ". s ."; align-items: center; justify-items: center; gap: 0.35rem; margin: 0.25rem 0 0.75rem; }
/* A very narrow phone (a folded Galaxy Fold): smaller calls and less padding, to leave the box room. */
@media (max-width: 340px) { .auction-table { --call: 0.6; } .card.bidding-card { padding-left: 0.2rem; padding-right: 0.2rem; } .shell:has(.auction-table.with-box) { padding-left: 4px; padding-right: 4px; } }
/* A tablet: less room needed above the table than a phone's wrapped heading. */
@media (min-width: 700px) { .auction-table.with-box.with-box { height: clamp(20rem, calc(100vh - 9.5rem), 64rem); height: clamp(20rem, calc(100svh - 9.5rem), 64rem); } }
@media (min-width: 700px) and (min-height: 520px) { .auction-table { --call: 1.2; } }
@media (min-width: 700px) and (min-height: 760px) { .auction-table:not(.with-box) { --call: 2; } } /* 6 Nov (00p4): while bidding the calls stay 1.2, leaving the box room */
/* The whole table, during and just after the bidding: as tall as the screen allows. The small viewport height (svh) does
   not change as the browser's address bar slides in and out, so scrolling never resizes the box (or flips it to compact). */
/* On a phone the box is limited by the width, so the table is only as tall as that needs (South stays on screen). */
.auction-table.with-box { height: clamp(20rem, min(calc(100vh - 10.5rem), calc(100vw + 7rem)), 64rem); height: clamp(20rem, min(calc(100svh - 10.5rem), calc(100vw + 7rem)), 64rem); }
/* At the opening lead: about half the screen, so the lead can be entered below it. */
.auction-table.whole { height: clamp(18rem, 55vh, 34rem); height: clamp(18rem, 55svh, 34rem); }
.auction-table.with-box { align-items: stretch; justify-items: stretch; }
/* A small copy (See the bidding, the class pause): normal-size calls on any screen. */
.auction-table.small { --call: 0.85; }
.at-north { grid-area: n; } .at-south { grid-area: s; } .at-west { grid-area: w; } .at-east { grid-area: e; }
.at-north, .at-south { justify-self: center; }
.at-west, .at-east { align-self: center; }
/* From the middle out: the calls, then the name (nearest the player). */
.at-seat { display: flex; flex-direction: column; align-items: center; gap: calc(0.2rem * var(--call)); }
.at-name { margin: 0; font-size: calc(0.8rem + 0.3rem * (var(--call) - 1)); color: var(--muted); white-space: nowrap; }
.at-next .at-name { color: var(--accent); font-weight: 700; }
.at-calls { display: flex; justify-content: center; min-height: calc(2.4rem * var(--call)); }
.at-call { display: inline-flex; align-items: center; justify-content: flex-start; box-sizing: border-box; width: calc(3.2rem * var(--call)); height: calc(2.4rem * var(--call));
    padding: 0 calc(0.2rem * var(--call)); border-radius: calc(0.3rem * var(--call)); font-weight: 700; font-size: calc(0.95rem * var(--call));
    background: #fbfaf6; color: #1d1d1b; border: 1px solid #c9c4b8; box-shadow: -1px 0 2px rgba(0,0,0,0.15); }
/* The next call covers the right of the last, as on a real table; the text is at the left. */
.at-call + .at-call { margin-left: calc(-1.05rem * var(--call)); }
.at-call .suit-h, .at-call .suit-d { color: #c8102e; } .at-call .suit-s, .at-call .suit-c { color: #1d1d1b; }
.at-pass { background: #1f9d55; color: #fff; border-color: #1f9d55; font-size: calc(0.72rem * var(--call)); }
.at-x { background: #d4322c; color: #fff; border-color: #d4322c; }
.at-xx { background: #1e2a78; color: #fff; border-color: #1e2a78; }
.at-waiting { justify-content: center; background: none; border: 2px dashed var(--accent); color: var(--accent); box-shadow: none; }
/* 6 Nov (00o8, 00o7): the "?" (the next call) reads upright for the player it faces (the calls themselves face the middle), and stands clear of that
   player's earlier call instead of lying on it. */
.auction-table.facing .at-waiting { transform: rotate(180deg); }
.auction-table .at-calls .at-call.at-waiting { margin-left: calc(0.3rem * var(--call)); }
.auction-table:not(.facing) .at-west .at-calls .at-call.at-waiting, .auction-table:not(.facing) .at-east .at-calls .at-call.at-waiting { margin-left: 0; margin-top: calc(0.3rem * var(--call)); }
/* Facing each player: each seat turned to its player (North's upside down, West's and East's sideways, in a column as wide
   as the seat is deep), and the calls turned round again to read from the middle of the table. */
.auction-table.facing .at-north .at-seat { transform: rotate(180deg); }
.auction-table.facing .at-calls { transform: rotate(180deg); }
.auction-table.facing .at-west, .auction-table.facing .at-east { position: relative; width: calc(2.6rem * var(--call) + 1.1rem); height: 100%; min-height: 9rem; align-self: stretch; }
.auction-table.facing .at-west .at-seat, .auction-table.facing .at-east .at-seat { position: absolute; left: 50%; top: 50%; white-space: nowrap; }
.auction-table.facing .at-west .at-seat { transform: translate(-50%, -50%) rotate(90deg); }
.auction-table.facing .at-east .at-seat { transform: translate(-50%, -50%) rotate(-90deg); }
/* All upright: North's name at the top edge; West and East in columns of a set width (so the box never changes size as
   calls are added), the name above the calls, which go down the column, each overlapping the last with its text at the top. */
.auction-table:not(.facing) .at-north .at-seat { flex-direction: column-reverse; }
.auction-table:not(.facing) .at-west, .auction-table:not(.facing) .at-east { width: calc(3.4rem * var(--call) + 0.7rem); } /* 7 Nov (00p9): a little wider, so a name usually fits on one line */
/* Where the screen is wide (a phone on its side, a tablet) the name has the room it needs, up to 9rem. */
@media (min-width: 600px) { .auction-table:not(.facing) .at-west, .auction-table:not(.facing) .at-east { width: auto; min-width: calc(3.4rem * var(--call) + 0.7rem); max-width: 9rem; } }
.auction-table:not(.facing) .at-west .at-seat, .auction-table:not(.facing) .at-east .at-seat { flex-direction: column-reverse; }
.auction-table:not(.facing) .at-west .at-name, .auction-table:not(.facing) .at-east .at-name { white-space: normal; text-align: center; }
.auction-table:not(.facing) .at-west .at-calls, .auction-table:not(.facing) .at-east .at-calls { flex-direction: column; }
.auction-table:not(.facing) .at-west .at-call, .auction-table:not(.facing) .at-east .at-call { align-items: flex-start; padding-top: calc(0.3rem * var(--call)); }
.auction-table:not(.facing) .at-west .at-call + .at-call, .auction-table:not(.facing) .at-east .at-call + .at-call { margin-left: 0; margin-top: calc(-0.7rem * var(--call)); }
.at-middle { grid-area: m; display: flex; align-items: center; justify-content: center; min-width: 0; min-height: 0; }
.with-box .at-middle { position: relative; container-type: size; }
.at-contract { min-width: calc(3.6rem * var(--call)); min-height: calc(3rem * var(--call)); display: flex; align-items: center; justify-content: center; border-radius: 0.5rem; background: var(--accent);
    color: var(--accent-text); font-weight: 700; font-size: calc(1.15rem * var(--call)); padding: 0.3rem 0.5rem; text-align: center; white-space: nowrap; }
.at-contract .suit-h, .at-contract .suit-d, .at-contract .suit-s, .at-contract .suit-c { color: inherit; }
.bidding-head { margin: 0 0 0.25rem; font-size: 0.9rem; }
.card.bidding-card { padding-left: 0.5rem; padding-right: 0.5rem; }
.auction-table.facing .at-west .at-name, .auction-table.facing .at-east .at-name { font-size: calc(0.72rem + 0.35rem * (var(--call) - 0.85)); }
.bidding-links { display: flex; flex-direction: column; align-items: center; }
.see-bidding { margin: 0 0 0.75rem; }
.see-bidding summary { cursor: pointer; color: var(--link); }

/* ---- The bidding box: a square in the middle of the table (as big as fits), turning in place to face the caller, so it
   looks the same from every seat. The full box (every bid) needs a square of at least 245 px inside; smaller (a phone),
   it is the compact box (the level, then the strain) for everyone. ---- */
.bb-room { position: absolute; inset: 0; }
.own-lead { position: relative; width: 100%; max-width: 24rem; aspect-ratio: 1 / 0.85; margin: 0.5rem auto; }
.bb-face { position: absolute; left: 50%; top: 50%; box-sizing: border-box; width: min(100cqw, 160cqh); height: min(100cqh, 160cqw); padding: 0.3rem;
    display: flex; flex-direction: column; gap: 0.3rem; transform: translate(-50%, -50%); container: bbox / size;
    background: var(--surface); border: 1px solid var(--border); border-radius: 0.6rem; }
/* Turned a quarter, the box's own width runs along the middle's height: it fills the middle that way round. */
.bb-turn-90, .bb-turn-270 { width: min(100cqh, 160cqw); height: min(100cqw, 160cqh); }
.bb-turn-90 { transform: translate(-50%, -50%) rotate(90deg); }
.bb-turn-180 { transform: translate(-50%, -50%) rotate(180deg); }
.bb-turn-270 { transform: translate(-50%, -50%) rotate(-90deg); }
.bb-who { margin: 0; text-align: center; font-weight: 700; font-size: clamp(0.7rem, 6cqmin, 1rem); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bb-full { display: none; flex: 1 1 auto; flex-direction: column; gap: 0.3rem; min-height: 0; }
.bb-compact { display: flex; flex: 1 1 auto; flex-direction: column; gap: 0.3rem; min-height: 0; }
/* The full box: wherever the box is at least 245 px each way (tablets), and on phones from the iPhone 11 / standard 12-17 width
   up (385 px or wider; not the minis or the SE) once it is at least 195 by 300 px, either way round. It fills the middle of the
   table, taller or wider than square; laid out wide (turned to West or East), the levels run across and the strains down. */
/* 6 Nov (00k9): the full box (a level per row, seven rows) only where its buttons are big enough to tap; otherwise the compact box.
   Upright (South, North) it needs about 195 x 290 inside its padding (a standard 390 px iPhone just fits, rows about 25 px); turned to East or West (facing each player) the same room the other way round,
   so every seat gets the same box. Not on the minis or the SE (under 385 px). */
@media (min-width: 385px) {
    @container bbox (min-width: 195px) and (min-height: 290px) {
        .bb-turn-0 .bb-full, .bb-turn-180 .bb-full { display: flex; }
        .bb-turn-0 .bb-compact, .bb-turn-180 .bb-compact { display: none; }
    }
    @container bbox (min-width: 290px) and (min-height: 195px) {
        .bb-turn-90 .bb-full, .bb-turn-270 .bb-full { display: flex; }
        .bb-turn-90 .bb-compact, .bb-turn-270 .bb-compact { display: none; }
    }
    /* Turned to East or West and wide: the seven rows on the left, Pass / X / XX / STOP and the confirm in a column on the right. */
    @container bbox (orientation: landscape) and (min-width: 290px) and (min-height: 195px) {
        .bb-facing.bb-turn-90 .bb-full, .bb-facing.bb-turn-270 .bb-full { display: grid; grid-template-columns: 1fr 5.5rem; grid-template-rows: 4fr 1fr; gap: 0.25rem; margin-bottom: 0; }
        .bb-facing .bb-full .bb-bids { grid-column: 1; grid-row: 1 / 3; }
        .bb-facing .bb-full .bb-other { grid-column: 2; grid-row: 1; height: auto; grid-template-columns: 1fr; grid-auto-rows: 1fr; grid-template-rows: none; }
        /* The confirm (one button, below the box elsewhere) sits in the side column's last place, under STOP. */
        .bb-facing.bb-turn-90 > .bb-confirm-row, .bb-facing.bb-turn-270 > .bb-confirm-row { position: absolute; right: 0.3rem; bottom: 0.3rem; width: 5.5rem; height: calc((100% - 0.85rem) / 5); }
        .bb-facing.bb-turn-90 > .bb-confirm-row > *, .bb-facing.bb-turn-270 > .bb-confirm-row > * { width: 100%; height: 100%; font-size: clamp(0.85rem, 5cqmin, 1.2rem); }
    }
}
.bb-confirm-row { flex: 0 0 auto; display: flex; justify-content: center; }
/* Facing each player, the box doesn't say who is calling: the seat's own label shows it. */
.bb-facing .bb-who { display: none; }
/* This device's choice (menu): always the compact box. */
.force-compact .bb-full { display: none !important; }
.force-compact .bb-compact { display: flex !important; }
/* The menu's compact-box choice is only offered on screens narrower than an iPhone 17. */
@media (min-width: 402px) { .narrow-only { display: none !important; } }
/* A call picked and waiting for its confirm. */
.bb-face .bb-bid.selected, .bb-face .bb-strain.selected, .bb-face .bb-other button.selected { outline: 3px solid var(--accent); outline-offset: -1px; box-shadow: 0 0 0 2px var(--surface) inset; }
/* 5 Nov: the call's confirm is below the box, as the lead's is, in the same style (.pick-confirm); the space is kept while it isn't this player's turn. */
.bb-face .bb-confirm, .bb-face .bb-confirm-space { flex: 0 0 auto; width: 70%; height: max(2.8rem, 15%); margin: 0; font-size: clamp(1rem, 8cqmin, 1.6rem); }
.bb-face .bb-confirm:disabled { opacity: 0.35; }
.bb-bids { flex: 1 1 auto; display: grid; grid-template-columns: repeat(5, 1fr); grid-auto-rows: 1fr; gap: 0.25rem; min-height: 0; }
.bb-levels, .bb-strains { flex: 1 1 0; display: grid; gap: 0.25rem; min-height: 0; }
.bb-levels { flex-grow: 2; grid-template-columns: repeat(4, 1fr); } /* 1–4 and 5–7: wider buttons on a narrow phone */
.bb-strains { grid-template-columns: repeat(5, 1fr); }
.bb-face button { margin: 0; padding: 0; min-height: 0; min-width: 0; font-weight: 700; border-radius: 0.4rem; font-size: clamp(0.8rem, 6cqmin, 1.5rem);
    background: #fbfaf6; color: #1d1d1b; border: 1px solid #c9c4b8; }
.bb-face button .suit-h, .bb-face button .suit-d { color: #c8102e; }
.bb-face button .suit-s, .bb-face button .suit-c { color: #1d1d1b; }
.bb-face button:disabled { opacity: 0.25; }
.bb-face .bb-level.selected { background: var(--accent); color: var(--accent-text); border-color: var(--accent); }
.bb-other { flex: 0 0 auto; height: max(2.6rem, 14%); display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 0.25rem; }
.bb-compact .bb-other { flex: 1 1 0; height: auto; }
.bb-other.with-stop { grid-template-columns: 2fr 1fr 1fr 1.4fr; }
.bb-face .bb-pass { background: #1f9d55; color: #fff; border-color: #1f9d55; }
.bb-face .bb-x { background: #d4322c; color: #fff; border-color: #d4322c; }
.bb-face .bb-xx { background: #1e2a78; color: #fff; border-color: #1e2a78; }
.bb-face .bb-stop-btn { background: #fff; color: #d4322c; border: 2px solid #d4322c; font-weight: 800; }
/* ---- 6 Nov (00o7): the bidding box in a few FIXED sizes, never growing or shrinking with the room. The middle of the table (the
   container, .at-middle) is measured as Wm x Hm; a box turned to East / West sees it the other way round. Versions (own size):
     P1  the 35 calls, a level a row, Pass / X / Alert / STOP under them     228 x 356   (tablet: 1.18 times, 269 x 420)
     SC  the 35 calls with Pass / X / Alert / STOP and the confirm in a side column  340 x 204   (phones and short windows only)
     C   the compact box (level, then strain)                                  180 x 192   (SE, minis, small landscape phones)
   In Facing each player every seat gets a 35 box, or every seat gets the compact box (never a mix); a device smaller than an
   iPhone 11 (the SE, minis) always gets the compact box. The page's own rules are set by
   custom properties here, so each version is described once. ---- */
.bb-face.bbx { container-type: normal; padding: calc(6px * var(--s)); gap: calc(4px * var(--s)); --s: 1; --bfs: calc(14px * var(--s));
    width: var(--bw, 100cqw); height: var(--bh, 100cqh); }
.bb-face.bbx.bb-turn-90, .bb-face.bbx.bb-turn-270 { width: var(--bw, 100cqh); height: var(--bh, 100cqw); }
.bb-face.bbx .bb-full { display: var(--show-full, none); flex: 1 1 auto; grid-template-columns: 1fr calc(88px * var(--s)); grid-template-rows: repeat(5, 1fr); gap: calc(4px * var(--s)); }
.bb-face.bbx .bb-compact { display: var(--show-compact, flex); }
.bb-face.bbx .bb-full .bb-bids { grid-column: var(--bc, auto); grid-row: var(--br, auto); gap: calc(4px * var(--s)); }
.bb-face.bbx .bb-full .bb-other { grid-column: var(--oc, auto); grid-row: var(--or, auto); height: var(--oh, calc(34px * var(--s))); }
.bb-face.bbx .bb-other { grid-template-columns: var(--otc, 2fr 1fr 1.2fr); gap: calc(4px * var(--s)); }
.bb-face.bbx .bb-other.with-stop { grid-template-columns: var(--otc, 2fr 1fr 1.2fr 1.4fr); }
.bb-face.bbx .bb-compact .bb-other { flex: 1 1 0; height: auto; }
.bb-face.bbx .bb-levels, .bb-face.bbx .bb-strains { gap: calc(4px * var(--s)); }
.bb-face.bbx button { font-size: var(--bfs); }
.bb-face.bbx .bb-other button { font-size: calc(var(--bfs) * 0.86); }
.bb-face.bbx .bb-other .bb-pass { font-size: var(--bfs); }
/* The space under the box, always kept: who is to call (or the confirm once a call is picked). In the side column it is one place of five. */
.bb-face.bbx .bb-confirm-row { display: grid; grid-template-areas: "x"; flex: 0 0 var(--ch, 30px); position: var(--cpos, static); right: calc(6px * var(--s)); bottom: calc(6px * var(--s));
    width: var(--cw, auto); height: var(--ch, 30px); align-items: stretch; justify-items: center; }
.bb-face.bbx .bb-confirm-row { grid-template-columns: 100%; }
.bb-face.bbx .bb-confirm-row > * { grid-area: x; }
.bb-face.bbx .bb-confirm, .bb-face.bbx .bb-confirm-space { width: var(--cbw, 70%); height: 100%; margin: 0; font-size: calc(16px * var(--s)); }
.bb-face.bbx .bb-wait { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 0 0.4rem; min-width: 0; overflow: hidden; line-height: 1.15; }
.bb-face.bbx .bb-wait { width: 100%; }
.bb-face.bbx .bb-who { font-size: var(--whofs, calc(13px * var(--s))); margin: 0; white-space: normal; text-align: center; min-width: 0; }
.bb-face.bbx .bb-instead { font-size: calc(12px * var(--s)); padding: 0; min-height: 0; }
.bb-face.bbx .bb-confirm-row:has(.bb-confirm) .bb-wait { display: none; }
.bb-face .bb-alert { background: #1f6fe0; color: #fff; border-color: #1f6fe0; }
/* C: the compact box, where it fits (also its own size when the player chose the compact box in the menu). */
@container (min-width: 176px) and (min-height: 186px) { .bb-face.bbx:is(.bb-turn-0, .bb-turn-180) { --bw: 180px; --bh: 192px; --ch: 34px; } }
@container (min-width: 180px) and (min-height: 176px) { .bb-face.bbx:is(.bb-turn-90, .bb-turn-270) { --bw: 180px; --bh: 192px; --ch: 34px; } }
/* The 35-call boxes, only on a "roomy" device (iPhone 11 and up, tablets, computers: index.html). Every rule below has the same
   weight (6 Nov, 00p6: a heavier rule had forced the side-column box on every tablet), so the later one wins where both fit:
   the side-column box, then the portrait-style box, then the tablet size of it. (No comma lists in @container: browsers drop them.)
   SC: a seat that sees a wide, short space. Facing each player: only where the seats turned the other way have a 35 box too. */
@container (min-width: 352px) and (min-height: 222px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-0, .bb-turn-180) { --s: 1; --bw: 340px; --bh: 204px; --show-full: grid; --show-compact: none; --bfs: calc(12px * var(--s)); --bc: 1; --br: 1 / 6; --oc: 2; --or: 1 / 5; --oh: auto; --otc: 1fr; --cpos: absolute; --cw: calc(88px * var(--s)); --cbw: 100%; --ch: calc((100% - 28px * var(--s)) / 5); --whofs: 11px; } }
@container (min-width: 222px) and (min-height: 352px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-90, .bb-turn-270) { --s: 1; --bw: 340px; --bh: 204px; --show-full: grid; --show-compact: none; --bfs: calc(12px * var(--s)); --bc: 1; --br: 1 / 6; --oc: 2; --or: 1 / 5; --oh: auto; --otc: 1fr; --cpos: absolute; --cw: calc(88px * var(--s)); --cbw: 100%; --ch: calc((100% - 28px * var(--s)) / 5); --whofs: 11px; } }
@container (min-width: 340px) and (min-height: 200px) { :root.roomy .bb-face.bbx:not(.bb-facing):is(.bb-turn-0, .bb-turn-180) { --s: 1; --bw: 340px; --bh: 204px; --show-full: grid; --show-compact: none; --bfs: calc(12px * var(--s)); --bc: 1; --br: 1 / 6; --oc: 2; --or: 1 / 5; --oh: auto; --otc: 1fr; --cpos: absolute; --cw: calc(88px * var(--s)); --cbw: 100%; --ch: calc((100% - 28px * var(--s)) / 5); --whofs: 11px; } }
/* P1: a seat that sees a tall space - the 35 calls, Pass / X / Alert / STOP under them, the confirm under that. */
@container (min-width: 222px) and (min-height: 352px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-0, .bb-turn-180), :root.roomy .bb-face.bbx:not(.bb-facing):is(.bb-turn-0, .bb-turn-180) { --s: 1; --bw: 228px; --bh: 356px; --show-full: flex; --show-compact: none; --bfs: calc(14px * var(--s)); --bc: auto; --br: auto; --oc: auto; --or: auto; --oh: calc(34px * var(--s)); --otc: initial; --cpos: static; --cw: auto; --cbw: 70%; --ch: calc(38px * var(--s)); --whofs: initial; } }
@container (min-width: 352px) and (min-height: 222px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-90, .bb-turn-270) { --s: 1; --bw: 228px; --bh: 356px; --show-full: flex; --show-compact: none; --bfs: calc(14px * var(--s)); --bc: auto; --br: auto; --oc: auto; --or: auto; --oh: calc(34px * var(--s)); --otc: initial; --cpos: static; --cw: auto; --cbw: 70%; --ch: calc(38px * var(--s)); --whofs: initial; } }
/* Tablets: the portrait-style box at 1.18 times, Pass at the bottom, for every seat that has room (upright, and turned to East / West). */
@container (min-width: 264px) and (min-height: 416px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-0, .bb-turn-180), :root.roomy .bb-face.bbx:not(.bb-facing):is(.bb-turn-0, .bb-turn-180) { --s: 1.18; --bw: 269px; --bh: 420px; --show-full: flex; --show-compact: none; --bfs: calc(14px * var(--s)); --bc: auto; --br: auto; --oc: auto; --or: auto; --oh: calc(34px * var(--s)); --otc: initial; --cpos: static; --cw: auto; --cbw: 70%; --ch: calc(38px * var(--s)); --whofs: initial; } }
@container (min-width: 416px) and (min-height: 264px) { :root.roomy .bb-face.bbx.bb-facing:is(.bb-turn-90, .bb-turn-270) { --s: 1.18; --bw: 269px; --bh: 420px; --show-full: flex; --show-compact: none; --bfs: calc(14px * var(--s)); --bc: auto; --br: auto; --oc: auto; --or: auto; --oh: calc(34px * var(--s)); --otc: initial; --cpos: static; --cw: auto; --cbw: 70%; --ch: calc(38px * var(--s)); --whofs: initial; } }
/* The player's own menu choice: always the compact box, at its own size. */
.force-compact .bb-face.bbx { --bw: 180px !important; --bh: 192px !important; --s: 1 !important; --show-full: none !important; --show-compact: flex !important; --bfs: 14px !important;
    --cpos: static !important; --cw: auto !important; --cbw: 70% !important; --ch: 34px !important; --oh: auto !important; }
/* The Stop card over the box until the wait is over. */
.bb-stop { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0.5rem;
    background: color-mix(in srgb, var(--surface) 80%, transparent); border-radius: 0.6rem; }
.bb-stop-card { display: inline-block; background: #d4322c; color: #fff; font-weight: 800; font-size: 2.4rem; letter-spacing: 0.08em; padding: 0.5rem 1.4rem; border-radius: 0.6rem; box-shadow: 0 2px 6px rgba(0,0,0,0.3); }
.bb-stop-left { font-size: 2rem; font-weight: 700; }
/* Bidding on a tablet: the table (and box) can use the width. */
.shell:has(.auction-table.with-box), .shell:has(.auction-table.whole) { max-width: 1000px; }
/* The opening lead in the middle of the table, in the bidding box's place: suit, card, then Lead. */
.lead-box .lb-suits { flex: 1.2 1 0; display: grid; grid-template-columns: repeat(4, 1fr); gap: 0.25rem; min-height: 0; }
.lead-box .lb-ranks { flex: 2 1 0; display: grid; grid-template-columns: repeat(7, 1fr); grid-template-rows: 1fr 1fr; gap: 0.25rem; min-height: 0; }
.lead-box .lb-actions { flex: 1 1 0; display: grid; grid-template-columns: 1fr 2fr; gap: 0.25rem; min-height: 0; }
.lead-box .selected { background: var(--accent) !important; color: var(--accent-text) !important; border-color: var(--accent) !important; }
.lead-box .lb-rank.selected .suit-h, .lead-box .lb-rank.selected .suit-d, .lead-box .lb-rank.selected .suit-s, .lead-box .lb-rank.selected .suit-c { color: inherit; }
.lead-box .lb-suit.selected { background: var(--selected) !important; color: inherit !important; border: 4px solid var(--accent) !important; }
.lead-box .lb-suit { font-size: clamp(1rem, 10cqmin, 2.4rem) !important; }
.lead-box .lb-actions .lb-made, .lead-box .lb-actions .lb-made-space { grid-column: 1 / -1; justify-self: center; width: 70%; }
.lead-box .lb-made { background: #1f9d55 !important; color: #fff !important; border-color: #1f9d55 !important; }
.lead-box .lb-made:disabled { opacity: 0.35; }
.centred-text { text-align: center; margin: 0; }
.bb-who.bb-warn { color: #b3261e; }

/* ---- Layout polish (audit, 29 Oct) ---- */
/* The table-layout choice: three equal buttons of one height, the same on every screen. */
.facing-toggle { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; }
.facing-toggle button { padding: .3rem .4rem; min-height: 52px; line-height: 1.15; font-size: .85rem; }
.facing-toggle.next-seat-actions { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* Three short choices (Total points, Matchpoints, IMPs) fit on one row of a phone. */
@media (max-width: 520px) { .choices button { padding-left: .5rem; padding-right: .5rem; } }
/* A wide screen (a tablet on its side, a laptop): the menu in two columns instead of one long list. */
@media (min-width: 900px) {
    .shell:has(.card.menu) { max-width: 900px; }
    .card.menu { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 28px; align-items: start; }
    .card.menu > .menu-group + .menu-group { border-top: none; padding-top: 0; }
}

/* The teacher's view of the bidding: the latest calls on a table's tile, and how the whole class bid a board. */
.tile-calls { margin: .15rem 0; }
.tile-calls .bidgrid { font-size: .85rem; margin: 0; max-width: none; }
.tile-calls .bidgrid th { padding: .1rem 0; font-size: .75rem; }
.tile-calls .bidgrid td { padding: .1rem 0; }
.table-tile button.tile-bids { padding: 0; min-height: 26px; font-size: clamp(.62rem, calc(.78rem * var(--tz, 1)), .78rem); white-space: nowrap; }
.class-bidding .bid-group { margin: .8rem 0 .2rem; }
.class-bidding .bid-odd { color: var(--red); font-size: .8rem; font-weight: 600; }
.class-bidding button.bid-row { display: flex; gap: .7rem; width: 100%; margin-top: .25rem; text-align: left; align-items: center; min-height: 40px; padding: .35rem .6rem; font-size: .9rem; }
.class-bidding .bid-t { font-weight: 600; min-width: 4.8rem; }

/* No button spans a wide screen: the full-width buttons are a comfortable width, centred. (On a phone they still fill the card.) */
@media (min-width: 700px) {
    button.primary, button.wide, .actions > button, .step-buttons > button { width: min(100%, 26rem); margin-left: auto; margin-right: auto; display: block; }
    .actions { justify-items: center; }
    .step-buttons { align-items: center; }
}
/* Choosing a button doesn't change its weight (and so its width): the colour and border show it. */
button.selected { font-weight: inherit; }
@media (min-width: 700px) {
    button.source { width: min(100%, 30rem); margin-left: auto; margin-right: auto; display: flex; } /* flex column (as on a phone): the sub-line stays on its own line */
    .facing-toggle { max-width: 42rem; margin-left: auto; margin-right: auto; }
    .choices button:only-child { flex: 0 1 26rem; }
    .choices:has(> button:only-child) { justify-content: center; }
}

/* Bidding as on a club's bidding sheet (teacher's pages). */
.bidgrid { border-collapse: collapse; width: 100%; max-width: 26rem; margin: .5rem auto 0; text-align: center; font-size: 1.05rem; }
.bidgrid th { background: #c4161c; color: #fff; padding: .25rem .3rem; }
.bidgrid .bg-cols th { width: 25%; border-top: 1px solid #fff; }
.bidgrid .bg-cols th.vul { background: #c4161c; color: #fff; }
.bidgrid .bg-cols th.nonvul { background: #fff; color: #1d1d1b; border-bottom: 1px solid #c4161c; }
.bidgrid td { padding: .2rem .3rem; width: 25%; }
.bidgrid .bg-band td { background: var(--text); color: var(--bg); font-weight: 700; text-align: left; padding: .25rem .5rem; }
.bidgrid .bg-block.bg-0 { background: rgba(127, 127, 127, .16); }
.bidgrid .bg-block.bg-1 { background: transparent; }
.bidgrid .bg-block.bg-hot { background: #ffef3a; color: #000; }
.bidgrid .bg-tag td { text-align: left; font-size: .75rem; color: var(--muted); padding: .15rem .5rem 0; }
.bidgrid .bg-hot .bg-tag td { color: #444; }
.bidgrid td.bg-diff { background: #ffef3a; color: #000; font-weight: 700; }
.bid-view { display: flex; gap: .5rem; justify-content: center; margin: .4rem 0; }
.bid-view button { min-width: 7rem; }
.bidgrid .bg-hot [class*="suit-"], .bidgrid td.bg-diff [class*="suit-"] { filter: none; } .bidgrid .bg-hot .red, .bidgrid td.bg-diff .red { color: #b42318; }

/* Each table's bidding beside its result (How the class did): a compact sheet. */
.class-rows td.cr-bid, .class-rows th.cr-bid { padding: .1rem .2rem; }
.class-rows .cr-bid .bidgrid { font-size: .72rem; margin: 0; max-width: none; }
.class-rows .cr-bid .bidgrid th { padding: .05rem 0; font-size: .65rem; }
.class-rows .cr-bid .bidgrid td { padding: .05rem 0; }
.class-rows .cr-bid .bidgrid.bare .bg-block, .class-rows .cr-bid .bidgrid.bare .bg-block.bg-0 { background: transparent; }
.class-rows .cr-letters { display: grid; grid-template-columns: repeat(4, minmax(1.6rem, 1fr)); text-align: center; font-size: .7rem; margin: 0 .2rem; }
.class-rows .cr-letters span { padding: .05rem 0; font-weight: 700; }
.class-rows .cr-letters span.vul { background: #c4161c; color: #fff; }
.class-rows .cr-letters span.nonvul { background: #fff; color: #1d1d1b; }

/* The host's name beside the table number in How the class did. */
.class-rows .cr-host { font-size: .85em; color: var(--muted); font-weight: 400; }

.table-tile .tile-ask { margin: .25rem 0; color: var(--warn); }
.table-tile button.tile-allow { min-height: 30px; }
.reset-card .agree-list { list-style: none; padding: 0; }

/* A player's device: what they are waiting for, in plain sight. */
p.stage-status { text-align: center; font-weight: 600; margin: .75rem 0; }
.player-board { padding-top: .6rem; padding-bottom: .6rem; }

/* "Show my hand" during bidding and play: a button, not a divider. */
button.show-hand { min-height: 48px; border: 1.5px solid var(--accent); border-radius: 10px; background: var(--surface); color: var(--link); font-weight: 600; margin: 0 0 .5rem; }
.time-slider input[type=range] { width: 100%; margin: 0.25rem 0 0; }
.time-scale { position: relative; height: 1.2rem; font-size: 0.8rem; color: var(--muted, #666); margin-bottom: 0.25rem; }
.time-scale span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
.time-scale span:last-child { transform: translateX(-100%); }
.view-hint-all p { margin: 0.25rem 0; } .view-hint-all .view-current { color: var(--text, inherit); }
/* A player on their own device, on the bidding and lead table: blue, as on the take-your-cards page. */
.auction-table .at-name.at-own { background: #dbeafe; color: #1d4ed8; border-radius: 0.4rem; padding: 0 0.35rem; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .auction-table .at-name.at-own { background: #1e3a5f; color: #93c5fd; } }
/* The heading and the result are one card: the host's heading card joins the result card that follows it, and the player's result sits flat inside its card. */
.card.merge-next { display: flow-root; margin-bottom: 0; border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; padding-bottom: 0; }
/* 7 Nov (00q0): also with the page mark (a hidden span) between the two cards. */
.card.merge-next + .card, .card.merge-next + .page-mark + .card { display: flow-root; margin-top: 0; border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; padding-top: 0; }
.play-card > .card { border: none; box-shadow: none; background: none; padding: 0; margin: 0; }
/* Time per board: tappable marks under the slider, each with the time it gives for this game. */
.time-scale { height: 2.7rem; }
.time-mark { position: absolute; transform: translateX(-50%); white-space: nowrap; background: none; border: none; padding: 0; min-height: 0; font-size: 0.8rem; color: var(--link); display: flex; flex-direction: column; align-items: center; line-height: 1.2; }
.time-mark small { font-size: 0.75rem; color: var(--muted, #666); }
.time-mark-end { transform: translateX(-100%); align-items: flex-end; }
/* The Lead button: light, so the suit shows in its own colour. */
.lead-box .lb-made { background: var(--card, #fff) !important; color: #1d1d1b !important; border: 3px solid #1f9d55 !important; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .lead-box .lb-made { background: #1c1f1d !important; color: #f2f2f0 !important; } }
.lead-box .lb-made .suit-s, .lead-box .lb-made .suit-c { color: inherit; }
/* Vulnerability round each name on the bidding, lead and result tables: red heavier border for vulnerable, green for not (traditional colours). */
.auction-table .at-name { border-radius: 0.4rem; padding: 0 0.35rem; }
.auction-table .at-name.at-vul { border: 3px solid #c4161c; }
.auction-table .at-name.at-nonvul { border: 2px solid #8fcaa6; background: #eef8f1; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .auction-table .at-name.at-nonvul { background: #1d2e24; border-color: #3f8f5f; } }
.auction-table .at-name.at-own { background: #dbeafe; }
.own-key { background: #dbeafe; color: #1d4ed8; border-radius: 0.3rem; padding: 0 0.35rem; }
/* The teacher's pages: green for not vulnerable, as on the tables. */
.bidgrid .bg-cols th.nonvul { background: #1f9d55; color: #fff; border-bottom: none; }
.class-rows .cr-letters span.nonvul { background: #1f9d55; color: #fff; }
/* Once the lead is confirmed the contract is locked: the choices stay as they were, just not tappable. */
fieldset.entry-locked { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.entry-locked button:disabled { opacity: 1; cursor: default; }
fieldset.entry-locked button:disabled:not(.selected) { opacity: 0.45; }
/* Vulnerability beside a result's score is plain text, in the usual words. */
/* Offline, the opponents confirm on the host's device: who taps is said plainly, in bold, so the host doesn't just tap again. */
.confirm-who { font-weight: 700; margin: 0.6rem 0; }
/* Who still has to accept a result (host's waiting page and the players' agree page); a sleeping device is listed as Not connected. */
.agree-needed { font-weight: 600; margin: 0.5rem 0; }
.agree-list li.not-connected .status { color: var(--muted); font-style: italic; }
/* Joining: "Where are you sitting?" as a table; a seat already taken is greyed and says who has it. */
/* Equal side columns that may shrink below their text (minmax 0), a fixed square in the middle, so N, the square and S share the
   centre and W and E mirror each other. Each seat's state has its own colour: free plain, taken greyed, the host's tinted, yours green. */
.seat-table.seat-choices { grid-template-columns: minmax(0, 1fr) 4.6rem minmax(0, 1fr); }
.seat-table.seat-choices .seat-mid { width: 4.6rem; height: 4.6rem; aspect-ratio: auto; justify-self: center; }
.seat-table.seat-choices button { min-height: 3.4rem; width: 100%; margin: 0; padding: 0.3rem 0.4rem; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow-wrap: anywhere; }
.seat-table.seat-choices .seat-north, .seat-table.seat-choices .seat-south { width: min(12rem, 70%); }
.seat-table.seat-choices button small { display: block; font-size: 0.75rem; font-weight: 400; }
.seat-table.seat-choices button.seat-free { background: var(--surface); border-color: var(--accent); color: var(--link); font-weight: 600; }
.seat-table.seat-choices button.seat-taken { background: var(--bg); color: var(--muted); opacity: 1; }
.seat-table.seat-choices button.seat-host { background: #dbeafe; color: #1d4ed8; border-color: #93c5fd; opacity: 1; }
.seat-table.seat-choices button.seat-mine, .seat-table.seat-choices button.seat-mine:disabled { background: var(--accent); color: var(--accent-text); border-color: var(--accent); opacity: 1; font-weight: 700; }
.seat-table.seat-choices button.seat-mine small { color: var(--accent-text); opacity: 0.9; }
.seat-wait-note { margin-top: 0.9rem; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .seat-table.seat-choices button.seat-host { background: #1e3a5f; color: #93c5fd; border-color: #2c5282; } }
/* With a physical box or spoken bidding: a line saying how the bidding is done. */
.bidding-method { margin: 0 0 0.3rem; color: var(--muted); }
/* The host's small in-step code (offline), at the start of the top bar: about 2.5 cm, so a phone's camera reads it from the table. */
/* 5 Nov: the mini in-step code - 44 pt (the smallest tap target), black on white in both themes (contrast is what scans; it is kept quiet by size). */
/* 00h0: clear of the iPhone's status bar (safe area) and a little below the top edge. */
.instep-wrap { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 0.25rem; margin-top: calc(env(safe-area-inset-top, 0px) + 4px); }
.instep-small { box-sizing: border-box; flex: 0 0 auto; padding: 0; margin: 0; min-height: 0; background: #fff; border: 1px solid var(--border); border-radius: 3px; }
.instep-info { flex: 0 0 auto; width: 1.6rem; height: 1.6rem; min-height: 0; padding: 0; margin: 0 0.5rem 0 0; border-radius: 50%; font: italic 700 0.85rem Georgia, serif; color: var(--muted, #666); background: none; border: 1px solid var(--border); }
.instep-small svg { display: block; width: 100%; height: 100%; }
.bar .instep-wrap + span { flex: 1 1 auto; }
.instep-full .qr { background: #fff; padding: 0.5rem; border-radius: 8px; max-width: 22rem; margin: 0.75rem auto; }
.instep-full .qr svg { display: block; width: 100%; height: auto; }
/* The 4-character codes (games, shared games, classes): large, spaced, easy to read out. */
.game-code { font-size: 1.6rem; letter-spacing: 0.15em; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.game-code-line, .share-code { text-align: center; }
.menu-note { margin: 0.4rem 0; text-align: center; color: var(--muted); }
/* The end-of-game card and the Home Screen steps. */
.end-card h2 { margin-top: 0; }
.install-steps { margin: 0.4rem 0 0.6rem; padding-left: 1.3rem; }
.install-steps li { margin: 0.2rem 0; }

/* One style for every "confirm what I picked" button (5 Nov, Nick): the Lead button's - light, a heavy green border, the suits in their own colours. */
.pick-confirm, .bb-face button.pick-confirm { background: var(--card, #fff); color: #1d1d1b; border: 3px solid #1f9d55; font-weight: 800; border-radius: 0.5rem; }
button.pick-confirm.contract-confirm, button.pick-confirm.lead-confirm { display: block; width: 70%; margin: 0.6rem auto; min-height: 3.2rem; font-size: 1.15rem; }
.pick-confirm .suit-h, .pick-confirm .suit-d { color: #c8102e; }
.pick-confirm .suit-s, .pick-confirm .suit-c { color: inherit; }
.pick-confirm:disabled { opacity: 0.35; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .pick-confirm, :root:not([data-theme="light"]) .bb-face button.pick-confirm { background: #1c1f1d; color: #f2f2f0; } }
:root[data-theme="dark"] .pick-confirm, :root[data-theme="dark"] .bb-face button.pick-confirm { background: #1c1f1d; color: #f2f2f0; }

/* Play the hand (5 Nov): the bidding's middle is the compass; the contract and lead, just above the tricks, centred and prominent. */
.at-middle .at-compass { position: relative; width: 4.4rem; height: 4.4rem; font-size: 0.95rem; aspect-ratio: auto; border: 2px solid var(--accent); border-radius: 6px;
    background: var(--selected, #dcefe2); color: var(--accent); font-weight: 700; }
.preview.contract-saved { text-align: center; margin: 0.9rem 0 0.6rem; }
.preview.contract-saved .pv-main { font-size: 1.45rem; font-weight: 800; line-height: 1.25; }
.preview.contract-saved .pv-sub { font-size: 1.15rem; font-weight: 700; margin-top: 0.15rem; }
.seat-wait-lead { margin: 0.2rem 0 0.8rem; }

/* Every "waiting for…" line on a player's device looks the same and stands out (5 Nov): a tinted band, larger text, a slow pulsing dot. */
p.wait-line, button.wait-line { display: block; width: 100%; text-align: center; font-size: 1.05rem; font-weight: 700; color: var(--accent); background: var(--selected, #dcefe2);
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); border-radius: 0.6rem; padding: 0.7rem 0.9rem; margin: 0.9rem 0; line-height: 1.35; }
/* 00h5: no pulsing dot. */
p.wait-line.agree-ok::before { display: none; }
@keyframes wait-pulse { 0%, 100% { opacity: 0.25; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { p.wait-line::before { animation: none; } }
/* The QR test page (5 Nov): the test code fixed in the top corner, where the in-step code sits. */
.qrtest-code { position: fixed; top: 6px; left: 6px; z-index: 50; padding: 0; margin: 0; min-height: 0; background: #fff; border: 1px solid var(--border); border-radius: 3px; box-sizing: border-box; }
.qrtest-code svg { display: block; }
.qrtest .qrtest-sizes button { min-width: 3rem; }
.qrtest-now { margin-top: 1rem; }

/* 5 Nov (00g6): the contract on the opening lead page, as prominent as on Play the hand. */
.lead-contract { text-align: center; font-size: 1.45rem; font-weight: 800; line-height: 1.25; margin: 0.8rem 0 0.4rem; }
/* The lead box sized to its content (ranks, suits, Lead), about the bidding box's proportions, not the whole tall middle. */

/* 00i8: the layout line centred in its panel (hands and bidding pages). */
.view-hint { text-align: center; }
.hand .own-use { margin-bottom: 0; }
.hand .own-or { margin-top: 0.1rem; font-size: 0.9em; }

/* 00i7: the lead box like Enter contract's lead entry - limited width, the result form's button heights, centred, room round it for the calls. */
.bb-face.lead-box { width: min(100cqw, 24rem); height: auto; max-height: 100cqh; gap: 0.35rem; padding: 0.45rem; container-type: inline-size; }
.bb-turn-90.lead-box, .bb-turn-270.lead-box { width: min(100cqh, 24rem); height: auto; max-height: 100cqw; }
.lead-box .lb-ranks, .lead-box .lb-suits, .lead-box .lb-actions { flex: 0 0 auto; }
.lead-box .lb-ranks { grid-template-rows: auto auto; }
.lead-box .lb-ranks button, .lead-box .lb-suits button { height: 2.5rem; font-size: 1.05rem !important; }
.lead-box .lb-suits button { font-size: 1.35rem !important; }
.lead-box .lb-actions .lb-made, .lead-box .lb-actions .lb-made-space { height: 2.8rem; font-size: 1.15rem; }
/* 00i6: on wide screens the bidding table is no taller than it needs (it filled the window, leaving empty bands round the box). */
@media (min-width: 1300px) { .auction-table.with-box.with-box { height: clamp(20rem, min(calc(100vh - 9.5rem), 40rem), 64rem); height: clamp(20rem, min(calc(100svh - 9.5rem), 40rem), 64rem); } }
/* 00i5: on wide screens the mini code sits fixed in the margin beside the page, so the top bar keeps its height. */
@media (min-width: 1300px) { .bar .instep-wrap { position: fixed; top: 12px; left: 12px; margin: 0; z-index: 40; } }
/* Pages with the usual narrow column (560 px) have room in the margin from about 840 px wide (the bidding and lead pages widen it, so 1300 px there). */
@media (min-width: 840px) { .shell:not(:has(.auction-table.with-box, .auction-table.whole, .table-hands)) .bar .instep-wrap { position: fixed; top: 12px; left: 12px; margin: 0; z-index: 40; } }

/* 00j3: a table's options under More all one width (the widest's), in a tidy grid; a confirm's question spans it. */
/* 6 Nov (00n7): a table's rare actions are a quiet list of links with a divider above (each asks first); Yes / No buttons still fill the width. */
.table-tile .tile-more-actions { display: flex; flex-direction: column; align-items: stretch; gap: 0; border-top: 1px solid var(--border); margin-top: 8px; padding-top: 4px; }
.table-tile .tile-more-actions > button { width: 100%; margin: 4px 0 0; }
.table-tile .tile-more-actions > p { margin: 6px 0 0; }
.table-tile button.tile-act { width: 100%; min-height: 40px; padding: 8px 4px; text-align: center; font-weight: 600; margin: 0; }
.table-tile button.tile-act:disabled { opacity: 0.45; }
.table-tile button.tile-close { color: var(--red); }

/* 00j6: four-colour suits in the bidding box, the lead box and the confirm buttons too (their own rules were more specific). */
.four-colour .bb-face button .suit-d, .four-colour .lead-box .suit-d { color: #c25400; }
.four-colour .bb-face button .suit-c, .four-colour .lead-box .suit-c { color: #15803d; }
.four-colour .pick-confirm .suit-d { color: var(--diamond); }
.four-colour .pick-confirm .suit-c { color: var(--club); }
.four-colour .at-call .suit-d { color: #c25400; }
.four-colour .at-call .suit-c { color: #15803d; }

/* 5 Nov (00a8): Buy me a coffee - a quiet line on the final scores, and a menu entry that is a link styled as the menu's buttons. */
.coffee-line { text-align: center; margin: 14px 0 4px; }
.coffee-line .link.small { display: block; margin: 4px auto 0; }
a.button { display: block; box-sizing: border-box; text-align: center; text-decoration: none; color: inherit; font: inherit; padding: 10px 14px;
    border: 1px solid var(--border); border-radius: 10px; background: var(--surface); color: var(--text); min-height: 44px; width: 100%; }

/* 5 Nov: a short box keeps its call buttons big enough to tap - the confirm (and the space kept for it) and Pass / X / XX are slimmer. */
@container bbox (max-height: 280px) or (max-width: 240px) {
    .bb-face .bb-confirm, .bb-face .bb-confirm-space { height: 2rem; font-size: 0.95rem; }
    .bb-other { height: 2rem; }
}

/* 6 Nov (00k9): suits on a dark surface in dark mode (the confirm buttons) - light colours, so ♠ and ♣ show. The bidding and lead boxes'
   own buttons stay light cards with dark ink. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .pick-confirm .suit-s, :root:not([data-theme="light"]) .pick-confirm .suit-c { color: #ecebe6; }
    :root:not([data-theme="light"]) .pick-confirm .suit-h, :root:not([data-theme="light"]) .pick-confirm .suit-d { color: #ff6b6b; }
    :root:not([data-theme="light"]) .four-colour .pick-confirm .suit-d { color: #ffa04d; }
    :root:not([data-theme="light"]) .four-colour .pick-confirm .suit-c { color: #4ade80; }
}
:root[data-theme="dark"] .pick-confirm .suit-s, :root[data-theme="dark"] .pick-confirm .suit-c { color: #ecebe6; }
:root[data-theme="dark"] .pick-confirm .suit-h, :root[data-theme="dark"] .pick-confirm .suit-d { color: #ff6b6b; }
:root[data-theme="dark"] .four-colour .pick-confirm .suit-d { color: #ffa04d; }
:root[data-theme="dark"] .four-colour .pick-confirm .suit-c { color: #4ade80; }

/* 6 Nov (00m4): the names on the players' setup, round the table as on the game setup. */
.names-table { margin-bottom: 8px; }
.names-table .name-north { grid-area: n; justify-self: center; width: min(12rem, 60%); }
.names-table .name-south { grid-area: s; justify-self: center; width: min(12rem, 60%); }
.names-table .name-west { grid-area: w; }
.names-table .name-east { grid-area: e; }

/* 6 Nov (00n0): Same cards, both pairs - each deal's two boards one under the other, in columns, the NS scores right-aligned. */
.both-boards { display: grid; grid-template-columns: auto auto auto 1fr; column-gap: 0.8rem; row-gap: 0.1rem; margin: 0.1rem 0 0 0.5rem; font-variant-numeric: tabular-nums; }
.both-boards .bb-deal { grid-column: 1 / -1; font-size: 0.85em; }
.both-boards .bb-score { text-align: right; }

/* 6 Nov (00n6): the setup's number choices are dropdowns (only valid values). */
select { font: inherit; color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 8px 10px; min-height: 40px; }
select.table-number, .deal-count select, select.stop-delay { width: auto; min-width: 4em; padding-right: 4px; }

/* 6 Nov (00n6): Settings - what the app noted on this device. */
.app-trail pre { white-space: pre-wrap; font-size: 0.8rem; max-height: 16rem; overflow: auto; background: var(--bg); border: 1px solid var(--border); border-radius: 8px; padding: 8px; }

/* 6 Nov (00o3, 00o4, 00o5): the white New game button on Game over, the PBN hint under its button, the thanks line. */
button.new-game-end { background: var(--surface); }
.pbn-hint { margin: 2px 0 8px; }
.coffee-thanks { margin-top: 10px; }

/* 6 Nov (00p2): while bidding on a phone, less margin beside the table, so the middle has room for the 35-call box (228 px) on every
   iPhone from the 11 up. */
@media (max-width: 699px) {
    .shell:has(.auction-table.with-box) { padding-left: 10px; padding-right: 10px; }
    .card.bidding-card:has(.auction-table.with-box) { padding-left: 6px; padding-right: 6px; }
}
/* 6 Nov (00p3): a phone on its side - the whole table fits the screen's height: smaller calls, North and South each one row (name beside
   the calls), no heading line, and the table as tall as what is left of the screen. */
@media (orientation: landscape) and (max-height: 500px) {
    .card.bidding-card:has(.auction-table.with-box) { padding-top: 4px; padding-bottom: 4px; }
    /* The heading goes (the board is in the header; the dealer and who is vulnerable show at the seats); the dealer's "shuffles and
       deals" stays, on one small line. */
    .bidding-card:has(.auction-table.with-box) { position: relative; }
    /* 7 Nov (00p9): the heading in the top-left corner on two lines, beside North (not over it), taking no height of its own. */
    .bidding-card:has(.auction-table.with-box) .bidding-head { position: absolute; left: 10px; top: 4px; z-index: 1; max-width: calc(50% - 4.5rem); margin: 0;
        font-size: 0.78rem; line-height: 1.15; color: var(--muted); }
    .bidding-card:has(.auction-table.with-box) .bidding-head .bh-sep { display: none; }
    .bidding-card:has(.auction-table.with-box) .bidding-head .bh-rest { display: block; }
    .bidding-card:has(.auction-table.with-box) .deal-note { margin: 0 0 0 50%; text-align: right; font-size: 0.8rem; line-height: 1.2rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } /* clear of the heading in the corner */
    .auction-table.with-box.with-box.with-box { --call: 0.7; height: calc(100svh - var(--table-top, 76px)); min-height: 0; margin-top: 0; margin-bottom: 0; row-gap: 0; }
    .bidding-card:has(.deal-note) .auction-table.with-box.with-box.with-box { --table-top: 96px; }
    .auction-table.with-box .at-north .at-seat, .auction-table.with-box .at-south .at-seat { flex-direction: row; }
    .auction-table.with-box:not(.facing) .at-north .at-seat { flex-direction: row-reverse; }
}

/* ---- 7 Nov (00q6-00q9): the host's page (26) and the game settings on one page (20) ---- */
.quick-line { margin: -0.25rem 0 0.75rem; }
.names-optional { margin: 0.25rem 0 0.5rem; }
.quick-time { margin: 0.4rem 0 0.1rem; }
.more-boards { margin: 0.1rem 0 0.9rem; }
.device-line { margin: 0 0 0.75rem; }
.setup .show-code { margin: 0 auto 0.75rem; }
.setup .change-settings { margin-top: 0.75rem; }
/* Page 20: the sections in the order Deals, Type of deal, Players' devices, Bidding and scoring, each with a number and its own ⓘ. */
.setup-cols.long { display: flex; flex-direction: column; }
.setup-cols.long .sec-deals { order: 1; }
.setup-cols.long .sec-dealtype { order: 2; }
.setup-cols.long .sec-players { order: 3; }
.setup-cols.long .sec-options { order: 4; }
.setup-cols.long .setup-sec + .setup-sec { border-top: 1px solid var(--border); margin-top: 1rem; padding-top: 0.5rem; }
.sec-head { display: flex; align-items: center; gap: 0.5rem; }
.sec-head .sec-no { display: inline-flex; align-items: center; justify-content: center; width: 1.6rem; height: 1.6rem; border-radius: 50%;
    background: var(--accent); color: var(--accent-text, #fff); font-size: 0.9rem; flex: none; }
.sec-head .sec-hint { display: inline-flex; align-items: center; justify-content: center; border: none; background: none; padding: 0 6px;
    min-height: 0; min-width: 28px; color: var(--link); font-size: 1.15rem; line-height: 1; cursor: pointer; margin: 0; }
/* Each section's explanations show only when its ⓘ is tapped (whatever the Hints setting), then in full. */
.setup-cols.long .setup-sec:not(.show-hints) :is(.hint, .source-help) { display: none; }
.setup-cols.long .setup-sec.show-hints .hint { display: block; }
.setup-cols.long .setup-sec.show-hints .hint .hint-i { display: none; }
.setup-cols.long .setup-sec.show-hints .hint .hint-text { white-space: normal; }
.setup .long-done { margin-top: 1.25rem; }
/* 7 Nov (00q8): the boards box the height of the deals dropdown, its number not enlarged (page 26 and page 20 alike). */
.setup .deal-count .board-total { display: flex; align-items: center; gap: 5px; height: 2.4rem; box-sizing: border-box; padding: 0 10px; border-radius: 8px; }
.setup .deal-count .board-total strong { font-size: 1.15rem; }

/* 7 Nov (00r8): ☰ → What device is this? */
.device-table { width: 100%; border-collapse: collapse; margin: 0.5rem 0; font-size: 0.9rem; }
.device-table th { text-align: left; font-weight: 600; padding: 4px 8px 4px 0; vertical-align: top; width: 42%; }
.device-table td { padding: 4px 0; word-break: break-word; }
.device-table tr + tr { border-top: 1px solid var(--border); }
.device-log { margin: 0.25rem 0 0.75rem; padding-left: 1.1rem; font-size: 0.85rem; }
