/* ==========================================================================
   Tarok - table, hand and CSS cards
   ==========================================================================
   Cards are drawn entirely in CSS. No images, so nothing to load, nothing to
   licence, and they scale to any size. Every card face comes from one place in
   the JS (cardFace) so real artwork can be swapped in later without touching
   layout.

   Theme: uses the platform's semantic tokens from variables.css, so the table
   follows light/dark automatically.
   ========================================================================== */

.tk {
    /* Two layers on purpose. The -base pair is the size the reader picked; --tk-card-w/h is what
       cards actually use, so a descendant can restate it as a fraction of the base and rescale
       itself AND everything inside it (pips, numerals, figures are all shares of --tk-card-w).
       That is how .tk-card--mini shrinks with one rule instead of a second set of numbers.
       It has to be done with a separate base variable rather than a scale factor: var() inside
       a custom property is substituted where the property is DECLARED, so a scale set further
       down the tree would never reach a --tk-card-w declared up here. */
    --tk-card-w-base: 4.5rem;
    --tk-card-h-base: 6.6rem;
    --tk-card-w: var(--tk-card-w-base);
    --tk-card-h: var(--tk-card-h-base);
    --tk-radius: 0.5rem;
    --tk-felt: #1f6b4a;
    --tk-felt-edge: #17543a;
    /* Traditional two colours: clubs and spades black, hearts and diamonds red. */
    --tk-black: #1a1a1a;
    --tk-red: #c0392b;
    --tk-tarok: #8a6d1f;
    --tk-tarok-bg: #fdf6e3;
    /* Card face sizes, all expressed as a share of the card width so the reader's S/M/L control
       rescales them for free - no media queries, no second set of numbers.
       Face sizes are unitless RATIOS of the card width, multiplied at the point of use. They
       cannot be pre-multiplied lengths: var() inside a custom property is substituted where the
       property is declared, so a --tk-pip-size computed here would keep the full card's width
       and refuse to shrink inside .tk-card--mini. A bare number has no var() to bake. */
    --tk-pip-ratio: 0.26;
    /* The tarok numeral is the whole face of the card, so it gets room: 0.3 of the card width
       puts XIX at ~22px at size S and ~33px at size L. It also has to be this big for the font
       to work at all - see the note by .tk-card--tarok .tk-card__corner. */
    --tk-numeral-ratio: 0.3;
}

[data-theme="dark"] .tk {
    --tk-felt: #17402f;
    --tk-felt-edge: #0f2c20;
    --tk-tarok: #d9b551;
    --tk-tarok-bg: #2a2618;
    /* Cards stay white in both themes, so the suit colours barely change; the felt and
       the gold accents are what the theme drives. */
}

/* Reader-chosen card size (S/M/L header control). Each just rescales the two card
   variables, so every card - hand, trick, talon - follows. S is the comfortable baseline;
   M and L step up for anyone who finds the default hard to read. */
.tk[data-card-size="s"] {
    --tk-card-w-base: 4.5rem;
    --tk-card-h-base: 6.6rem;
}

.tk[data-card-size="m"] {
    --tk-card-w-base: 5.7rem;
    --tk-card-h-base: 8.35rem;
}

.tk[data-card-size="l"] {
    --tk-card-w-base: 6.9rem;
    --tk-card-h-base: 10.15rem;
}

.tk-size-btn.active {
    background: var(--tk-tarok);
    border-color: var(--tk-tarok);
    color: #1a1a1a;
}

/* --------------------------------------------------------------- the table */

.tk-table {
    background: radial-gradient(ellipse at 50% 40%, var(--tk-felt) 0%, var(--tk-felt-edge) 100%);
    border-radius: 1rem;
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    position: relative;
    container-type: inline-size;
}

/* The watch strip: a spectator ribbon and/or a live "N watching" count, sitting at the
   very top of the felt above the contract banner. */
.tk-watch {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.75);
}

.tk-watch--spectator {
    color: #fff;
    background: rgba(0, 0, 0, 0.28);
    border: 1px solid var(--tk-tarok);
    border-radius: 999px;
    padding: 0.3rem 0.9rem;
    align-self: center;
}

.tk-watch__eye {
    font-size: 1rem;
    line-height: 1;
}

.tk-watch__label {
    font-weight: 600;
    letter-spacing: 0.02em;
}

.tk-watch__count {
    opacity: 0.85;
}

.tk-watch--spectator .tk-watch__count::before {
    content: "·";
    margin-right: 0.5rem;
    opacity: 0.6;
}

.tk-hand--empty {
    display: none;
}

/* A seat's radelci - open information at a real table, so shown on the seat. */
.tk-seat__radelc {
    display: block;
    color: var(--tk-tarok);
    font-size: 0.7rem;
    letter-spacing: 0.12em;
    line-height: 1;
    margin-top: 0.15rem;
    cursor: help;
}

/* Table chat. A drawer pinned to the right edge, sliding in over the page rather than
   beside it in the flow - so opening it never reflows the felt mid-trick, and the same
   rules give a phone a near-full-width panel.

   Lives outside the game container so a game re-render never wipes a half-typed message.

   `hidden` is reserved for "there is nobody to talk to". Open/closed is the --open class,
   because display:none would kill the transition it is supposed to animate. */
.tk-chat {
    position: fixed;
    top: 0;
    right: 0;
    /* Above .floating-widgets-stack (site.css, z-index 9998), which is emitted after this
       element in the layout and would otherwise win a tie. */
    z-index: 10000;
    width: min(23rem, 92vw);
    height: 100dvh;
    background: var(--bs-body-bg, #fff);
    border-left: 1px solid rgba(128, 128, 128, 0.3);
    box-shadow: -0.5rem 0 1.5rem rgba(0, 0, 0, 0.18);
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.28s ease, visibility 0.28s;
}

.tk-chat--open {
    transform: none;
    visibility: visible;
}

.tk-chat[hidden] {
    display: none;
}

@media (prefers-reduced-motion: reduce) {
    .tk-chat {
        transition: none;
    }
}

/* Title row: the heading plus a close button. The drawer covers the header button that
   opened it on a narrow screen, so it needs its own way out. */
.tk-chat__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.tk-chat__title {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--tk-tarok);
}

.tk-chat__close {
    flex: 0 0 auto;
    border: 0;
    background: none;
    color: inherit;
    opacity: 0.6;
    font-size: 1.1rem;
    line-height: 1;
    padding: 0.2rem 0.4rem;
    cursor: pointer;
}

.tk-chat__close:hover,
.tk-chat__close:focus-visible {
    opacity: 1;
}

/* Full height inside the drawer, unlike the old below-the-table panel which was capped. */
.tk-chat__list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-size: 0.85rem;
    scroll-behavior: smooth;
}

/* A short conversation sits at the BOTTOM of the tall drawer, next to the input, rather
   than stranded at the top. A flexible spacer does it; justify-content: flex-end would
   make the overflowing case unscrollable at the top in several browsers. Being a pseudo
   element it stays out of childNodes, so the DOM-trimming loop never sees it. */
.tk-chat__list::before {
    content: '';
    flex: 1 1 auto;
    min-height: 0;
}

/* Header toggle: the way into the drawer, with an unread count riding on it. */
.tk-chat-toggle {
    position: relative;
}

.tk-chat-toggle__badge {
    position: absolute;
    top: -0.35rem;
    right: -0.35rem;
    min-width: 1.05rem;
    padding: 0 0.25rem;
    border-radius: 999px;
    background: var(--bs-danger, #dc3545);
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 1.05rem;
    text-align: center;
}

.tk-chat-toggle__badge[hidden] {
    display: none;
}

.tk-chat__empty {
    opacity: 0.6;
    font-style: italic;
}

.tk-chat__msg {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    line-height: 1.35;
}

.tk-chat__who {
    font-weight: 600;
    white-space: nowrap;
}

.tk-chat__who::after {
    content: ":";
}

.tk-chat__msg--mine .tk-chat__who {
    color: var(--tk-tarok);
}

/* Messages that landed while the drawer was shut. The badge says how many; this says
   which. Cleared when the drawer closes again, so the mark never goes stale. */
.tk-chat__msg--new {
    background: rgba(217, 181, 81, 0.14);
    border-left: 2px solid var(--tk-tarok);
    border-radius: 0 var(--tk-radius) var(--tk-radius) 0;
    margin-left: -0.4rem;
    padding: 0.15rem 0.35rem 0.15rem 0.4rem;
}

/* The rule drawn above the first of them: "------ NEW ------". */
.tk-chat__newline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.2rem 0;
    color: var(--tk-tarok);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
}

.tk-chat__newline::before,
.tk-chat__newline::after {
    content: '';
    flex: 1 1 auto;
    height: 1px;
    background: currentColor;
    opacity: 0.45;
}

/* Sits inside the name span, before its colon, so a watcher reads as "Ana (watching):". */
.tk-chat__tag {
    font-weight: 400;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.65;
    margin-left: 0.3rem;
}

.tk-chat__tag::before {
    content: "(";
}

.tk-chat__tag::after {
    content: ")";
}

.tk-chat__body {
    overflow-wrap: anywhere;
    flex: 1 1 8rem;
}

.tk-chat__form {
    display: flex;
    gap: 0.5rem;
}

.tk-chat__input {
    flex: 1 1 auto;
}

/* Send is drawn as a tarok card: white face, gold bar along the top edge, and the same
   lift-on-hover as a playable card. Mirrors .tk-card / .tk-card--tarok deliberately - the
   deck is this feature's whole visual identity, and a stock Bootstrap pill looked pasted on.
   Cards stay white in both themes (see the note by .tk-card--tarok), so does this. */
.tk-chat__send {
    flex: 0 0 auto;
    position: relative;
    padding: 0.55rem 0.9rem 0.45rem;
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: var(--tk-radius);
    background: #fff;
    color: #1a1a1a;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.02em;
    user-select: none;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.tk-chat__send::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--tk-tarok), #e3c273);
    border-radius: var(--tk-radius) var(--tk-radius) 0 0;
}

.tk-chat__send:hover,
.tk-chat__send:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
    outline: none;
}

.tk-chat__send:active {
    transform: translateY(0);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

@media (prefers-reduced-motion: reduce) {
    .tk-chat__send {
        transition: none;
    }

    .tk-chat__send:hover,
    .tk-chat__send:focus-visible {
        transform: none;
    }
}

.tk-chat__note {
    font-size: 0.8rem;
    opacity: 0.7;
}

/* Leaving the table gives up your seat, so it reads as neutral until you reach for it
   and turns red under the cursor - the one destructive control in the header. */
.tk-leave:hover,
.tk-leave:focus-visible {
    background-color: var(--bs-danger, #dc3545);
    border-color: var(--bs-danger, #dc3545);
    color: #fff;
}

/* ------------------------------------------------------------- fullscreen */

/* The website builder's expand mode, borrowed wholesale: a body class hides the site
   chrome and lifts the centered container's width cap so the felt gets the whole viewport.
   Body-scoped, and this stylesheet is only registered by the three tarok views, so nothing
   here can reach another page. The tarok view nests its own .container inside the layout's
   (views/layouts/main.php), hence both selectors. */
body.tk-fullscreen header,
body.tk-fullscreen footer,
body.tk-fullscreen .breadcrumb,
body.tk-fullscreen .language-switcher-floating,
body.tk-fullscreen #section-nav,
body.tk-fullscreen #mascot-container,
body.tk-fullscreen .floating-widgets-stack {
    display: none !important;
}

body.tk-fullscreen main {
    /* body.has-sticky-header pads main to clear the now-hidden header. */
    padding-top: 0 !important;
}

body.tk-fullscreen main > .container,
body.tk-fullscreen .tk.container {
    max-width: 100% !important;
}

.tk-seats {
    display: flex;
    justify-content: space-around;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.tk-seat {
    color: #fff;
    text-align: center;
    padding: 0.4rem 0.7rem;
    border-radius: 0.5rem;
    background: rgba(0, 0, 0, 0.25);
    min-width: 6rem;
    font-size: 0.85rem;
    line-height: 1.3;
    transition: box-shadow 0.2s ease, background 0.2s ease;
}

.tk-seat--turn {
    background: rgba(255, 255, 255, 0.18);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.55);
}

.tk-seat--you {
    font-weight: 600;
}

/* The seat playing the game, against everyone else at the table. */
.tk-seat--declarer {
    border: 1px solid var(--tk-tarok);
}

.tk-seat--declarer .tk-seat__name::before {
    content: '★ ';
    color: var(--tk-tarok);
}

/* The declarer's silent partner (4 players). Only ever styled once the engine has
   revealed the partnership - for opponents that is when the called king is played. */
.tk-seat--partner {
    border: 1px solid rgba(227, 194, 115, 0.6);
}

.tk-seat--partner .tk-seat__name::before {
    content: '🤝 ';
}

.tk-seat__name {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tk-seat__meta {
    display: block;
    opacity: 0.75;
    font-size: 0.75rem;
}

/* What this seat called during the auction. */
.tk-seat__bid {
    display: inline-block;
    margin-top: 0.35rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1.4;
}

/* A live bid - somebody has taken a game. */
.tk-seat__bid--bid {
    background: rgba(227, 194, 115, 0.2);
    color: var(--tk-tarok);
    border: 1px solid rgba(227, 194, 115, 0.45);
}

/* The current high bidder - the one everyone else has to beat. */
.tk-seat__bid--holder {
    background: var(--tk-tarok);
    color: #2a2205;
    border: 1px solid transparent;
}

/* Out of the auction. */
.tk-seat__bid--pass {
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

/* Who took the game. In tarok the declarer plays alone against the rest, so this is
   the first thing you need to know when you look at the table. */
.tk-contract {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    color: #fff;
}

.tk-contract__game {
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: 0.02em;
}

.tk-contract__who {
    font-size: 0.8rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.3);
    color: var(--tk-tarok);
    border: 1px solid rgba(227, 194, 115, 0.5);
}

.tk-contract__who--you {
    background: rgba(227, 194, 115, 0.9);
    color: #2a2205;
    border-color: transparent;
    font-weight: 600;
}

/* The called king (4 players): a small label + the king's face, so everyone can see
   which king was named and watch for the partnership reveal. */
.tk-contract__king {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.tk-contract__king-label {
    font-size: 0.75rem;
    color: var(--tk-tarok);
    text-transform: lowercase;
}

.tk-contract__side {
    font-size: 0.8rem;
    color: rgba(255, 255, 255, 0.85);
    font-style: italic;
}

/* --------------------------------------------- announcements + kontra chips */

/* A running read-out of what has been called and doubled, both on the felt banner and
   above the acting player's own controls. Public information, kept in view all hand. */
.tk-ann-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    align-items: center;
}

.tk-contract__ann {
    margin-left: 0.25rem;
}

.tk-ann-chip {
    font-size: 0.72rem;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
    white-space: nowrap;
    border: 1px solid transparent;
}

.tk-ann-chip--bonus {
    background: rgba(227, 194, 115, 0.9);
    color: #2a2205;
    font-weight: 600;
}

.tk-ann-chip--kontra {
    background: rgba(192, 57, 43, 0.85);
    color: #fff;
    text-transform: lowercase;
}

/* Declare step: the bonus toggles, select-then-confirm like the discard picker. */
.tk-ann-options {
    justify-content: center;
}

.tk-ann-opt--on {
    background: var(--tk-tarok);
    border-color: var(--tk-tarok);
    color: #2a2205;
    font-weight: 600;
}

/* The trick: a single centred row, cards in the order they were played. */
.tk-trick {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    gap: 0.6rem;
    min-height: calc(var(--tk-card-h) + 1.5rem);
    flex-wrap: wrap;
}

.tk-trick--past .tk-card {
    opacity: 0.85;
}

.tk-trick__slot {
    text-align: center;
}

.tk-trick__seat {
    color: rgba(255, 255, 255, 0.85);
    font-size: 0.72rem;
    margin-bottom: 0.25rem;
    white-space: nowrap;
}

.tk-trick__empty {
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.9rem;
    padding: 1rem;
}

/* --------------------------------------------------------------- the cards */

.tk-card {
    width: var(--tk-card-w);
    height: var(--tk-card-h);
    border-radius: var(--tk-radius);
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.25);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    display: inline-flex;
    flex-direction: column;
    justify-content: space-between;
    align-items: center;
    padding: 0.3rem 0.25rem;
    font-weight: 600;
    line-height: 1;
    user-select: none;
    position: relative;
    flex: 0 0 auto;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.tk-card__corner {
    align-self: flex-start;
    font-size: 0.8rem;
    /* The fan shows only the left strip of a card, so the corner must never wrap or
       spill - it is the only part of an overlapped card you can actually read. */
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
}

.tk-card__corner--bottom {
    align-self: flex-end;
    transform: rotate(180deg);
}

.tk-card__pip {
    font-size: 1.6rem;
}

/* An empty middle. A tarok carries its numeral only in the corners, so this is the spacer that
   keeps them pinned top and bottom - and the slot future tarok artwork drops into. */
.tk-card__mid {
    flex: 1 1 auto;
    align-self: stretch;
}

/* The pip field - the middle of a number card. It is the flex box's stretchy middle child,
   so it fills exactly the space between the two corner indices and a pip can never land
   under one. Positions come from PIP_LAYOUT in the JS and are percentages of THIS box, not
   of the card. */
.tk-card__pips {
    position: relative;
    flex: 1 1 auto;
    align-self: stretch;
    width: 100%;
}

.tk-card__pip-mark {
    position: absolute;
    transform: translate(-50%, -50%);
    font-size: calc(var(--tk-card-w) * var(--tk-pip-ratio));
    line-height: 1;
}

/* A real deck stands its lower-half pips on their heads - the reference photo of the 9 of
   clubs shows it plainly, stems down on top and stems up below. We can only honour that for
   clubs and diamonds. Unicode's heart and spade are very nearly each other's inverse: an
   upside-down spade has a heart's silhouette and an upside-down heart has a spade's, so
   rotating them would fill half of every spade card with black hearts and half of every
   heart card with red spades. In a game about following suit that is not cosmetic.
   Diamonds are symmetric, so the rotation there is free and costs nothing to keep uniform. */
.tk-card--clubs .tk-card__pip-mark--lower,
.tk-card--diamonds .tk-card__pip-mark--lower {
    transform: translate(-50%, -50%) rotate(180deg);
}

/* The red 1 is a single pip with the whole card to itself, and a real deck draws it large.
   Without this it would be the one rank that got SMALLER than the glyph it replaced. */
.tk-card__pips--single .tk-card__pip-mark {
    font-size: calc(var(--tk-card-w) * 0.44);
}

/* Figure cards. Font Awesome's chess set is already loaded by the layout and happens to be the
   tarok hierarchy exactly - King, Dame, Cavalier on horseback, Fant on foot - and Tabler's
   joker is the Skis, a jester's cap and bells. Being font glyphs they inherit colour, so one
   set of icons covers all sixteen courts: black for clubs and spades, red for hearts and
   diamonds, grey when muted, with no per-suit rules at all. The small pip below a court keeps
   clubs telling apart from spades; the Skis has no suit and so goes solo. */
.tk-card__figure {
    flex: 1 1 auto;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.05rem;
}

.tk-card__fig {
    font-size: calc(var(--tk-card-w) * 0.46);
    line-height: 1;
}

/* No suit pip underneath, so the figure can take the room it saves. */
.tk-card__figure--solo .tk-card__fig {
    font-size: calc(var(--tk-card-w) * 0.56);
}

.tk-card__figure-suit {
    font-size: calc(var(--tk-card-w) * 0.2);
    line-height: 1;
}

/* Two-colour deck: black suits and red suits. */
.tk-card--spades,
.tk-card--clubs { color: var(--tk-black); }

.tk-card--hearts,
.tk-card--diamonds { color: var(--tk-red); }

/* Taroks are white with black numerals like every other card - a real deck does not
   tint its trumps. They are marked instead by a gold bar along the top edge, which
   stays visible when the hand is fanned and the rest of the card is covered. */
.tk-card--tarok {
    background: #fff;
    color: #1a1a1a;
    border-color: rgba(0, 0, 0, 0.25);
}

.tk-card--tarok::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--tk-tarok), #e3c273);
    border-radius: var(--tk-radius) var(--tk-radius) 0 0;
}

/* Tarok numerals are the card. Bodoni Moda 700 is a true Didone - one thick stroke, one
   hairline, flat unbracketed serifs - which is what the real Industrie und Glueck deck uses
   and why its numerals read as straight letters rather than as decoration.
   The numeral lives in the corners only; the middle is left empty for artwork. */
.tk-card--tarok .tk-card__corner {
    font-family: var(--font-family-bodoni-moda);
    font-weight: 700;
    font-size: calc(var(--tk-card-w) * var(--tk-numeral-ratio));
    /* Optical sizing is left on AUTO deliberately, and it is doing real work here. Bodoni's
       opsz axis is its stroke-contrast dial, and contrast is a trap at small sizes: a hairline
       narrower than one device pixel antialiases to pale grey or vanishes, which is exactly how
       XIX ends up looking like X|X. `auto` sets opsz from the rendered size (~16 at card size S,
       ~25 at size L), so each card size gets as much contrast as its pixels can actually carry.
       Do NOT pin this with font-variation-settings: 'opsz' - a fixed high value looks right in a
       mockup and breaks the thin strokes on the real table. */
    font-optical-sizing: auto;
    /* Bodoni gives its I generous side bearings, which is right for words and wrong for Roman
       numerals: III came out as three separate strokes with air between them rather than one
       numeral. Pulled in until the strokes group without touching. */
    letter-spacing: -0.06em;
}

/* Long numerals step down so they never clip. VIII, XIII and XVII are four glyphs; XVIII is
   five, and Bodoni is a wide face. The tighter tracking above bought enough room to keep these
   close to full size, which matters: a smaller numeral has fewer pixels to render a hairline in. */
.tk-card--num4 .tk-card__corner { font-size: calc(var(--tk-card-w) * var(--tk-numeral-ratio) * 0.9); }
.tk-card--num5 .tk-card__corner { font-size: calc(var(--tk-card-w) * var(--tk-numeral-ratio) * 0.8); }

/* Skis, Mond and Pagat - the trula. Worth 5 each and worth spotting. */
.tk-card--honour {
    box-shadow: 0 0 0 2px var(--tk-tarok), 0 1px 4px rgba(0, 0, 0, 0.4);
}

/* A slightly reduced card for reference displays like the talon strip. It renders exactly the
   same content as a full card - pip field, court figure, corner numeral - so it stays readable;
   0.55 was small enough that a card became a suit glyph and nothing else. Every size inside it
   is a share of --tk-card-w, so scaling the box scales the contents with it. */
.tk-card--mini {
    --tk-card-w: calc(var(--tk-card-w-base) * 0.82);
    --tk-card-h: calc(var(--tk-card-h-base) * 0.82);
    padding: 0.2rem 0.2rem;
    border-radius: 0.4rem;
}

.tk-card--mini .tk-card__corner--bottom { display: none; }

/* -------------------------------------------------- the talon on the table */

/* A slim reference strip pinned at the top of the felt. Stays put whatever the trick
   area does below it. */
.tk-talon-strip {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding-bottom: 0.6rem;
    margin-bottom: 0.2rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.tk-talon-strip__label {
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.75rem;
    font-weight: 600;
}

.tk-talon-strip__group {
    display: flex;
    align-items: center;
    gap: 0.15rem;
    padding: 0.25rem;
    border-radius: 0.45rem;
    position: relative;
}

/* The group the declarer picked up - highlighted, and labelled with who took it. */
.tk-talon-strip__group--taken {
    background: rgba(227, 194, 115, 0.18);
    border: 1px solid rgba(227, 194, 115, 0.55);
}

/* The rest went to the opponents. */
.tk-talon-strip__group--rejected {
    opacity: 0.55;
    border: 1px solid transparent;
}

.tk-talon-strip__who {
    color: var(--tk-tarok);
    font-size: 0.65rem;
    font-weight: 600;
    white-space: nowrap;
    margin-left: 0.15rem;
}

/* --------------------------------------------------- trick -> winner animation */

/* A completed trick is held on screen, then the cards fly to the seat that won it.
   Without this the bots resolve a whole trick inside one request and you never see
   what was played. The transform is set inline in JS from the winning seat's real
   position, so it works whatever the layout does. */
.tk-card--flying {
    /* Duration must match FLIGHT_MS in web/js/tarok/table.js. The fade is held back so
       the cards stay readable for most of the journey instead of vanishing at once. */
    transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.7s ease-in 0.2s;
    opacity: 0;
    z-index: 20;
}

.tk-trick__slot--winner .tk-card {
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.85), 0 4px 10px rgba(0, 0, 0, 0.45);
}

/* --------------------------------------------------- card drop-in (a card played) */

/* When a card lands in the centre pile it drops onto the felt rather than teleporting
   in. Direction reads who played it: your own card rises from your hand below the felt;
   every opponent's falls in from the seat row above. Duration ~360ms - long enough to
   register, short enough to keep play brisk even when a solo table's bot replies cascade
   in (each later card gets an inline animation-delay from JS). */
.tk-card--drop {
    animation-duration: 0.42s;
    animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1);
    animation-fill-mode: both;
    z-index: 15;
}

.tk-card--drop-self {
    animation-name: tk-drop-self;
}

.tk-card--drop-other {
    animation-name: tk-drop-other;
}

/* Your card travels a long way up from the hand at the bottom of the screen, so the rise
   is generous - it should clearly read as coming from your own cards. */
@keyframes tk-drop-self {
    from {
        opacity: 0;
        transform: translateY(90px) scale(1.18);
    }
    55% {
        opacity: 1;
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

/* Opponents' cards fall in from the seat row above the felt. */
@keyframes tk-drop-other {
    from {
        opacity: 0;
        transform: translateY(-80px) scale(1.18) rotate(-6deg);
    }
    55% {
        opacity: 1;
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1) rotate(0);
    }
}

/* Reduced motion: keep the reveal, drop the travel. The card still fades up in place so
   a new play is not silent, but nothing slides across the felt. */
@media (prefers-reduced-motion: reduce) {
    .tk-card--drop {
        animation-name: tk-drop-fade;
        animation-duration: 0.2s;
    }
}

@keyframes tk-drop-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

.tk-seat--collecting {
    background: rgba(255, 255, 255, 0.3);
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8);
}

/* Skis is the one tarok that prints a WORD rather than a numeral (a real Skis carries no
   number), and a word needs to be small enough to fit. Deliberately scoped to --named and
   not --honour: Pagat and Mond are in the trula too, and they now print I and XXI, which
   must keep the full numeral size. */
.tk-card--named .tk-card__corner {
    font-size: calc(var(--tk-card-w) * var(--tk-numeral-ratio) * 0.62);
    letter-spacing: -0.02em;
}

/* --------------------------------------------------------------- your hand */

.tk-hand {
    display: flex;
    justify-content: center;
    padding: 0.75rem 0.5rem 1.25rem;
    min-height: calc(var(--tk-card-h) + 2rem);
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    /* Break the hand out of the centred content column to the full viewport width, so the
       fanned cards (and their scroll room on a phone) get the whole screen. Standard
       full-bleed: 100vw wide, pulled back by half the gap between the column and the
       viewport edge on each side. */
    width: 100vw;
    max-width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
}

/* Fan the hand. 16 cards will not fit side by side on a phone, so they overlap
   and the hovered/focused card lifts clear.
   The overlap is 32%, not more, and that number is load-bearing: number cards carry no corner
   index any more, so the only way to read your own hand is to count pips. The left column sits
   at 25% of the card and the centre column at 50%, and it is the centre column that separates
   7 from 8 and 9 from 10 - hide it and half your hand becomes ambiguous. Showing 68% of each
   card clears the centre column with room to spare. */
.tk-hand .tk-card {
    margin-right: calc(var(--tk-card-w) * -0.32);
}

.tk-hand .tk-card:last-child {
    margin-right: 0;
}

/* No cards left: collapse rather than leaving a card-height hole between the table and
   the score sheet. */
.tk-hand:empty {
    min-height: 0;
    padding: 0;
}

.tk-card--playable {
    cursor: pointer;
}

.tk-card--playable:hover,
.tk-card--playable:focus-visible {
    transform: translateY(-0.9rem);
    box-shadow: 0 6px 14px rgba(0, 0, 0, 0.4);
    z-index: 5;
    outline: none;
}

.tk-card--playable:focus-visible {
    box-shadow: 0 0 0 3px var(--color-primary-500), 0 6px 14px rgba(0, 0, 0, 0.4);
}

/* Not legal this trick: still readable, clearly not available. Showing them rather
   than hiding them is what lets a player learn the rules.
   Deliberately NOT opacity - a white card at 40% opacity over a dark page turns dark
   grey and becomes unreadable, and after a suit lead that is most of your hand. Dim
   the card's own colours instead so it stays a card. */
.tk-card--muted {
    background: #c8c8c8;
    border-color: rgba(0, 0, 0, 0.2);
    box-shadow: none;
    cursor: not-allowed;
}

/* Dimmed but still legible as black or red against the grey card. */
.tk-card--muted.tk-card--spades,
.tk-card--muted.tk-card--clubs { color: #4a4a4a; }

.tk-card--muted.tk-card--hearts,
.tk-card--muted.tk-card--diamonds { color: #9a6660; }

.tk-card--muted::before {
    opacity: 0.3;
}

.tk-card--muted.tk-card--honour {
    box-shadow: 0 0 0 2px rgba(138, 109, 31, 0.45);
}

/* --------------------------------------------------------------- prompts */

.tk-prompt {
    background: var(--bg-secondary);
    border: 1px solid var(--border-default);
    border-radius: 0.75rem;
    padding: 1rem;
}

.tk-prompt__title {
    font-weight: 600;
    margin-bottom: 0.15rem;
}

.tk-prompt__hint {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin-bottom: 0.75rem;
}

/* The 3-vs-4 players picker: two selectable cards (icon + title + description). The real
   radio is visually hidden; the label is the card, and :has(:checked) paints the choice. */
.tk-choice {
    display: flex;
    gap: 0.75rem;
}

/* Space-filler mode: the row grows to eat the leftover height in a shorter form, and its
   cards stretch with it (default align-items: stretch), so two side-by-side forms line up
   at the same bottom edge. */
.tk-choice--grow {
    flex: 1 1 auto;
}

.tk-choice__card {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.85rem 1rem;
    border: 1px solid var(--border-default);
    border-radius: 0.75rem;
    background: var(--bg-primary);
    cursor: pointer;
    transition: transform 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}

.tk-choice__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.tk-choice__icon {
    flex: 0 0 auto;
    width: 2.5rem;
    height: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 0.6rem;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 1.1rem;
    transition: background 0.15s ease, color 0.15s ease, transform 0.2s ease;
}

.tk-choice__body {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.tk-choice__title {
    font-weight: 600;
    line-height: 1.2;
}

.tk-choice__desc {
    font-size: 0.8rem;
    color: var(--text-secondary);
    line-height: 1.25;
}

.tk-choice__card:hover {
    border-color: var(--tk-tarok);
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
}

.tk-choice__card:hover .tk-choice__icon {
    transform: scale(1.08);
}

.tk-choice__card:has(.tk-choice__input:checked) {
    border-color: var(--tk-tarok);
    background: var(--tk-tarok-bg);
    box-shadow: inset 0 0 0 2px var(--tk-tarok);
}

.tk-choice__card:has(.tk-choice__input:checked) .tk-choice__icon {
    background: var(--tk-tarok);
    color: #fff;
}

/* The native radio is hidden, so surface keyboard focus on the card itself. */
.tk-choice__card:focus-within {
    outline: 2px solid var(--tk-tarok);
    outline-offset: 2px;
}

@media (max-width: 420px) {
    .tk-choice {
        flex-direction: column;
    }
}

.tk-choices {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Picked for the discard but not yet committed. Deliberately loud - these cards are
   about to leave your hand, and the points you bury count toward your own pile. */
.tk-card--selected {
    transform: translateY(-0.75rem);
    box-shadow: 0 0 0 3px var(--color-primary-500), 0 8px 16px rgba(0, 0, 0, 0.45);
    z-index: 6;
}

.tk-card--selected::after {
    content: '✓';
    position: absolute;
    top: -0.55rem;
    right: -0.55rem;
    width: 1.4rem;
    height: 1.4rem;
    border-radius: 50%;
    background: var(--color-primary-500);
    color: #fff;
    font-size: 0.85rem;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
}

.tk-card--playable.tk-card--selected:hover {
    transform: translateY(-1.1rem);
}

.tk-confirm {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-top: 1rem;
    padding-top: 0.85rem;
    border-top: 1px solid var(--border-default);
}

.tk-confirm__count {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text-secondary);
}

.tk-confirm .btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* The discard grid wraps, so cards need breathing room for the lift and the tick. */
.tk-prompt .tk-choices .tk-card {
    margin: 0.6rem 0.15rem 0.2rem;
}

.tk-talon-group {
    display: flex;
    gap: 0.25rem;
    padding: 0.5rem;
    border: 2px solid var(--border-default);
    border-radius: 0.6rem;
    background: var(--bg-primary);
    cursor: pointer;
    transition: border-color 0.15s ease, transform 0.15s ease;
}

/* Talon-take: all groups on a single row whatever their size, so the whole talon reads
   at a glance. Cards are a touch larger than the default mini for readability; the row
   scrolls sideways rather than wrapping if a very narrow screen cannot hold all six. */
.tk-talon-take {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.85rem;
    padding: 0.35rem 0.1rem;
}

.tk-talon-take .tk-talon-group {
    flex: 0 0 auto;
    padding: 0.4rem;
}

.tk-talon-group:hover {
    border-color: var(--color-primary-500);
    transform: translateY(-2px);
}

/* --------------------------------------------------------------- log + score */

.tk-log {
    max-height: 12rem;
    overflow-y: auto;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.tk-log__line {
    padding: 0.15rem 0;
    border-bottom: 1px solid var(--border-muted);
}

/* --------------------------------------------------- end-of-hand result panel */

.tk-result__verdict {
    font-size: 1.15rem;
    font-weight: 700;
    margin: 0.4rem 0 0.15rem;
}

.tk-result__verdict--win { color: var(--color-success-600, #16a34a); }
.tk-result__verdict--lose { color: var(--color-danger-600, #dc2626); }
/* A watcher is on nobody's side, so the verdict states the fact without taking one. */
.tk-result__verdict--flat { color: var(--tk-tarok); }

.tk-result__note {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-bottom: 0.3rem;
}

.tk-result__bars {
    margin: 0.85rem 0;
}

.tk-pts {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.35rem 0;
}

.tk-pts__label {
    flex: 0 0 40%;
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.tk-pts__bar {
    position: relative;
    flex: 1;
    height: 0.7rem;
    background: var(--bg-tertiary);
    border-radius: 999px;
    overflow: visible;
}

.tk-pts__fill {
    height: 100%;
    border-radius: 999px;
    background: var(--text-tertiary);
    transition: width 0.4s ease;
}

/* The declarer's own bar is the one you watch against the 36 line. */
.tk-pts__fill--decl {
    background: var(--color-primary-500);
}

.tk-pts__need {
    position: absolute;
    top: -0.2rem;
    bottom: -0.2rem;
    width: 2px;
    background: var(--tk-tarok);
}

.tk-pts__val {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-size: 0.85rem;
    font-weight: 600;
}

.tk-result__need-note {
    font-size: 0.78rem;
    color: var(--text-tertiary);
    margin-top: 0.3rem;
}

.tk-result__chips {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin: 0.6rem 0;
}

.tk-result__chips-label {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.tk-chip {
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    background: rgba(227, 194, 115, 0.18);
    color: var(--tk-tarok);
    border: 1px solid rgba(227, 194, 115, 0.4);
}

.tk-result__sheet-head {
    margin: 0.9rem 0 0.25rem;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.tk-result__you {
    font-weight: 700;
}

.tk-result__you::before {
    content: '▸ ';
    color: var(--tk-tarok);
}

.tk-sheet {
    width: 100%;
    font-variant-numeric: tabular-nums;
}

.tk-sheet td {
    padding: 0.25rem 0;
    border-bottom: 1px solid var(--border-muted);
}

.tk-sheet td:last-child {
    text-align: right;
    font-weight: 600;
}

.tk-sheet tr:last-child td {
    border-bottom: none;
    border-top: 2px solid var(--border-default);
    font-size: 1.05rem;
}

.tk-positive { color: var(--color-success-600, #16a34a); }
.tk-negative { color: var(--color-danger-600, #dc2626); }

/* --------------------------------------------------------------- responsive */

@container (max-width: 40rem) {
    .tk-seat {
        min-width: 4.5rem;
        font-size: 0.75rem;
    }
}

@media (max-width: 36rem) {
    .tk {
        --tk-card-w: 3.2rem;
        --tk-card-h: 4.7rem;
    }

    .tk-hand .tk-card {
        margin-right: calc(var(--tk-card-w) * -0.5);
    }

    .tk-table {
        padding: 0.75rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tk-card,
    .tk-seat,
    .tk-talon-group {
        transition: none;
    }

    .tk-card--playable:hover {
        transform: none;
    }

    /* The trick is still HELD on screen - only the flight is removed. Skipping the
       pause as well would put the "you cannot see what was played" problem straight
       back for exactly the people least able to track fast movement. */
    .tk-card--flying {
        transition: opacity 0.2s ease;
        transform: none !important;
    }
}

/* --------------------------------------------------------- waiting room (M2) */

.tk-waiting {
    background: var(--bg-secondary);
    border: 1px solid var(--border-default);
    border-radius: 0.75rem;
    padding: 1.5rem;
    max-width: 32rem;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.tk-share {
    background: var(--bg-primary);
    border: 1px dashed var(--border-default);
    border-radius: 0.5rem;
    padding: 0.85rem 1rem;
}

.tk-share__label {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin-bottom: 0.35rem;
}

.tk-share__row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.tk-share__code {
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 1.6rem;
    font-weight: 700;
    letter-spacing: 0.25em;
    color: var(--tk-tarok);
}

/* The direct-link row sits under the code, with its own "Or share this link" label. */
.tk-share__row + .tk-share__label {
    margin-top: 0.75rem;
}

.tk-share__link {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.tk-share__link--tap {
    cursor: pointer;
    color: var(--tk-tarok);
}

.tk-share__row--link .btn {
    flex: 0 0 auto;
}

.tk-waiting__seats {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.tk-waiting__seat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0.85rem;
    border: 1px solid var(--border-default);
    border-radius: 0.5rem;
    background: var(--bg-primary);
}

.tk-waiting__seat--you {
    border-color: var(--tk-tarok);
    box-shadow: inset 0 0 0 1px var(--tk-tarok);
}

.tk-waiting__seat--empty {
    border-style: dashed;
    color: var(--text-tertiary);
    background: transparent;
}

.tk-waiting__seat-name {
    font-weight: 600;
}

.tk-waiting__seat--empty .tk-waiting__seat-name {
    font-weight: 400;
    font-style: italic;
}

.tk-waiting__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    align-items: center;
}

.tk-waiting__pulse {
    animation: tk-pulse 1.6s ease-in-out infinite;
}

@keyframes tk-pulse {
    0%, 100% { opacity: 0.55; }
    50% { opacity: 1; }
}

/* Presence: an absent player greys out at the table and in the waiting room. */
.tk-seat--away {
    opacity: 0.5;
}

.tk-seat__away {
    color: var(--text-tertiary);
    font-size: 0.8rem;
    font-style: italic;
}

/* "Thinking" robot next to an away human - the computer is covering their turns.
   Reuses the tk-pulse opacity keyframe (reduced-motion guarded below). */
.tk-seat__robot {
    margin-left: 0.35rem;
    color: var(--tk-tarok, #8a6d1f);
    font-size: 0.85rem;
    cursor: help;
    animation: tk-pulse 1.6s ease-in-out infinite;
}

/* Presence toasts - stacked, auto-dismissing corner notices. */
.tk-toast {
    position: fixed;
    left: 50%;
    bottom: 1.25rem;
    transform: translateX(-50%);
    z-index: 1080;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: center;
    pointer-events: none;
}

.tk-toast__item {
    max-width: min(90vw, 26rem);
    padding: 0.55rem 1rem;
    border-radius: 999px;
    background: var(--bg-inverse, #1a1a1a);
    color: var(--text-inverse, #fff);
    font-size: 0.9rem;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
    opacity: 0;
    transform: translateY(0.5rem);
    transition: opacity 0.25s ease, transform 0.25s ease;
}

.tk-toast__item--in {
    opacity: 1;
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
    .tk-seat__robot {
        animation: none;
    }
    .tk-toast__item {
        transition: none;
    }
}

/* --------------------------------------------------------------- lobby (M2) */

.tk-lobby-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.tk-lobby-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.7rem 0.95rem;
    border: 1px solid var(--border-default);
    border-radius: 0.5rem;
    background: var(--bg-secondary);
}

.tk-lobby-row__main {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.tk-lobby-row__host {
    font-weight: 600;
}

.tk-lobby-row__meta {
    color: var(--text-secondary);
    font-size: 0.85rem;
}

.tk-lobby-row__join {
    margin: 0;
    flex: 0 0 auto;
}

@media (prefers-reduced-motion: reduce) {
    .tk-waiting__pulse {
        animation: none;
    }
}

/* Bot marker on a seat during play - so a computer player never passes for a human. */
.tk-seat__bot {
    color: var(--text-tertiary);
    font-size: 0.75rem;
    font-weight: 500;
    text-transform: lowercase;
}

/* Your own rooms in the lobby - accented and badged so you spot them instantly. */
.tk-lobby-row--mine {
    border-color: var(--tk-tarok);
    box-shadow: inset 0 0 0 1px var(--tk-tarok);
}

.tk-lobby-row__badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--tk-tarok);
    border: 1px solid var(--tk-tarok);
    border-radius: 0.35rem;
    padding: 0.05rem 0.4rem;
    vertical-align: middle;
}

/* ------------------------------------------------------------------ leaderboard
   The ranking board and the "your rank" strip. --tk-tarok is the gold accent the
   light/dark themes already drive, so the board inherits the felt look for free. */
.tk-rank-me {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.35rem 1rem;
    padding: 0.85rem 1.15rem;
    border: 1px solid var(--tk-tarok);
    border-radius: var(--tk-radius);
    background: var(--tk-tarok-bg);
}

.tk-rank-me__label {
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.75;
}

.tk-rank-me__value {
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--tk-tarok);
}

.tk-rank-me__meta {
    font-size: 0.9rem;
    opacity: 0.85;
}

.tk-board {
    --bs-table-hover-bg: rgba(138, 109, 31, 0.08);
}

.tk-board__rank {
    width: 3rem;
    text-align: center;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.tk-board__name {
    font-weight: 600;
}

.tk-board__rating {
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    color: var(--tk-tarok);
}

.tk-board__you {
    display: inline-block;
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 0.05rem 0.4rem;
    border: 1px solid var(--tk-tarok);
    border-radius: 0.35rem;
    color: var(--tk-tarok);
    vertical-align: middle;
}

.tk-board__row--me {
    background: var(--tk-tarok-bg);
}

.tk-board__row--me td {
    border-bottom-color: var(--tk-tarok);
}

/* ------------------------------------------------------------------ felt centre
   The middle of the felt now hosts whatever the hand asks of you: the bid/king/talon
   controls, a blinking "your turn" flag above the trick, or a quiet "waiting" line. */
.tk-center {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    min-height: calc(var(--tk-card-h) + 2.5rem);
    width: 100%;
}

/* When the felt centre is holding the decision controls, give the box a translucent
   panel so it reads over the green felt rather than the page background. */
.tk-center--prompt .tk-prompt {
    background: rgba(0, 0, 0, 0.34);
    border-color: rgba(255, 255, 255, 0.18);
    color: #fff;
    max-width: 38rem;
    text-align: center;
    backdrop-filter: blur(2px);
}

.tk-center--prompt .tk-prompt__hint {
    color: rgba(255, 255, 255, 0.75);
}

.tk-center--prompt .tk-choices {
    justify-content: center;
}

.tk-center__waiting {
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.9rem;
    font-style: italic;
}

/* The blinking call-to-act, small, sitting above the cards. */
.tk-turnflag {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.05rem;
    padding: 0.3rem 0.9rem;
    border: 1px solid var(--tk-tarok);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.3);
    animation: tk-turnflag-blink 1.15s ease-in-out infinite;
}

.tk-turnflag__title {
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--tk-tarok);
    letter-spacing: 0.02em;
}

.tk-turnflag__hint {
    font-size: 0.72rem;
    color: rgba(255, 255, 255, 0.7);
}

@keyframes tk-turnflag-blink {
    0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(217, 181, 81, 0.0); }
    50% { opacity: 0.55; box-shadow: 0 0 12px 1px rgba(217, 181, 81, 0.35); }
}

.tk-skiphint {
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.8rem;
    margin-top: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
    .tk-turnflag {
        animation: none;
        border-color: var(--tk-tarok);
    }
}

/* The end-of-hand scoresheet, framed on the felt like the bid controls: a translucent
   dark panel so the green shows through, with the muted greys lifted to stay legible. */
.tk-center--result {
    width: 100%;
}

.tk-center--result .tk-result {
    width: 100%;
    max-width: 34rem;
    text-align: left;
    color: #fff;
    background: rgba(10, 20, 15, 0.82);
    border-color: rgba(255, 255, 255, 0.16);
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35);
    backdrop-filter: blur(3px);
}

.tk-center--result .tk-result__note,
.tk-center--result .tk-result__sheet-head,
.tk-center--result .tk-result__chips-label {
    color: rgba(255, 255, 255, 0.78);
}

.tk-center--result .tk-result__need-note {
    color: rgba(255, 255, 255, 0.55);
}

.tk-center--result .tk-pts__bar {
    background: rgba(255, 255, 255, 0.14);
}

.tk-center--result .tk-sheet td {
    border-bottom-color: rgba(255, 255, 255, 0.12);
}

.tk-center--result .tk-sheet tr:last-child td {
    border-top-color: rgba(255, 255, 255, 0.3);
}

/* Win/lose greens and reds pop brighter on the dark felt than the page defaults. */
.tk-center--result .tk-result__verdict--win,
.tk-center--result .tk-positive { color: #34d399; }
.tk-center--result .tk-result__verdict--lose,
.tk-center--result .tk-negative { color: #f87171; }

/* ---- "Wilder" discard on the felt: gold selection, springy hover, a live confirm ---- */
.tk-center--prompt .tk-card--selected {
    transform: translateY(-0.9rem) scale(1.04);
    box-shadow: 0 0 0 3px var(--tk-tarok),
                0 0 18px 2px rgba(217, 181, 81, 0.55),
                0 10px 20px rgba(0, 0, 0, 0.5);
}

.tk-center--prompt .tk-card--selected::after {
    background: linear-gradient(135deg, #f7dd8a, var(--tk-tarok));
    color: #1a1a1a;
    animation: tk-pick-pop 0.3s ease-out;
}

.tk-center--prompt .tk-card--playable:hover {
    transform: translateY(-0.55rem) rotate(-2deg);
    box-shadow: 0 0 14px 1px rgba(217, 181, 81, 0.4), 0 8px 16px rgba(0, 0, 0, 0.45);
}

.tk-center--prompt .tk-card--playable.tk-card--selected:hover {
    transform: translateY(-1.15rem) scale(1.05) rotate(-1deg);
}

@keyframes tk-pick-pop {
    0% { transform: scale(0) rotate(-30deg); }
    70% { transform: scale(1.35) rotate(8deg); }
    100% { transform: scale(1) rotate(0); }
}

/* The confirm button comes alive the instant the full set is chosen. */
.tk-center--prompt .tk-confirm {
    border-top-color: rgba(255, 255, 255, 0.18);
    justify-content: center;
}

.tk-center--prompt .tk-confirm__count {
    color: rgba(255, 255, 255, 0.85);
    font-size: 1.05rem;
}

.tk-center--prompt .tk-confirm .btn:not(:disabled) {
    background: linear-gradient(135deg, #f7dd8a, var(--tk-tarok));
    border-color: var(--tk-tarok);
    color: #1a1a1a;
    font-weight: 700;
    animation: tk-confirm-pulse 1.1s ease-in-out infinite;
}

@keyframes tk-confirm-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(217, 181, 81, 0); transform: translateY(0); }
    50% { box-shadow: 0 0 18px 4px rgba(217, 181, 81, 0.55); transform: translateY(-1px); }
}

@media (prefers-reduced-motion: reduce) {
    .tk-center--prompt .tk-card--selected::after,
    .tk-center--prompt .tk-confirm .btn:not(:disabled) {
        animation: none;
    }
}

/* ==========================================================================
   Standalone app (tarok.eventure.si) - slim skin + landing page
   ==========================================================================
   Chrome and landing styles for the standalone Tarok host. The game surfaces
   (.tk table/hub) are unchanged; these only dress the layouts/tarok.php shell
   and views/tarok/landing.php. All colours come from the platform semantic
   tokens so light/dark follows automatically. --tk-tarok is the gold accent
   already defined on .tk above.
   ========================================================================== */

.tarok-app {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.tarok-app__header {
    padding: 0.75rem 0;
    background: var(--header-bg, var(--bg-secondary));
    border-bottom: 1px solid var(--header-border, var(--border-default));
}

.tarok-app__wordmark {
    display: inline-flex;
    align-items: center;
    font-weight: 800;
    font-size: 1.25rem;
    letter-spacing: 0.01em;
    text-decoration: none;
    color: var(--text-primary);
}

.tarok-app__wordmark:hover {
    color: var(--tk-tarok);
}

.tarok-app__wordmark .fa-heart {
    color: var(--tk-red, #c0392b);
}

.tarok-app__user {
    display: inline-flex;
    align-items: center;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

/* Keep the language + theme toggles vertically centred with the buttons. */
.tarok-app__toggle {
    display: inline-flex;
    align-items: center;
}

.tarok-app__footer {
    padding: 1.25rem 0;
    background: var(--footer-bg, var(--bg-secondary));
    border-top: 1px solid var(--footer-border, var(--border-default));
}

/* ----- Landing ----------------------------------------------------------- */

.tarok-landing__hero {
    padding: clamp(3rem, 8vw, 6rem) 0 clamp(2rem, 5vw, 3.5rem);
    background:
        radial-gradient(120% 120% at 50% 0%, rgba(138, 109, 31, 0.12), transparent 60%),
        var(--bg-primary);
}

.tarok-landing__title {
    font-weight: 800;
    font-size: clamp(2rem, 5vw, 3.25rem);
    margin-bottom: 0.75rem;
}

.tarok-landing__lead {
    max-width: 42rem;
    margin: 0 auto 1.75rem;
    font-size: clamp(1.05rem, 2vw, 1.25rem);
    color: var(--text-secondary);
}

.tarok-landing__steps {
    padding: clamp(2rem, 5vw, 3.5rem) 0;
}

.tarok-landing__step {
    padding: 1.5rem;
    background: var(--card-bg);
    border: 1px solid var(--card-border, var(--border-default));
    border-radius: var(--border-radius-lg, 0.75rem);
    box-shadow: var(--card-shadow, none);
    text-align: center;
}

.tarok-landing__step-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    margin-bottom: 1rem;
    border-radius: 50%;
    background: var(--tk-tarok-bg, #fdf6e3);
    color: var(--tk-tarok, #8a6d1f);
    font-size: 1.25rem;
}

.tarok-landing__step-title {
    margin-bottom: 0.5rem;
}

.tarok-landing__step-desc {
    color: var(--text-secondary);
}

.tarok-landing__rooms {
    padding: clamp(2rem, 5vw, 3.5rem) 0;
}

.tarok-landing__rooms-list {
    max-width: 34rem;
}

.tarok-landing__board {
    padding: clamp(2rem, 5vw, 3.5rem) 0;
    background: var(--bg-secondary);
}

.tarok-landing__board-list {
    max-width: 32rem;
    margin: 0 auto;
    padding: 0;
    list-style: none;
    counter-reset: tarok-rank;
}

.tarok-landing__board-row {
    counter-increment: tarok-rank;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid var(--border-default);
}

.tarok-landing__board-row:last-child {
    border-bottom: 0;
}

.tarok-landing__board-row::before {
    content: counter(tarok-rank);
    flex: 0 0 1.6rem;
    font-weight: 700;
    color: var(--tk-tarok, #8a6d1f);
    text-align: center;
}

.tarok-landing__board-name {
    flex: 1 1 auto;
    font-weight: 600;
}

.tarok-landing__board-rating {
    color: var(--text-secondary);
    font-size: 0.9rem;
    white-space: nowrap;
}

.tarok-landing__outro {
    padding: clamp(2.5rem, 6vw, 4rem) 0;
}
