/* Euchre — live multiplayer card game (Components/Shared/Euchre/*.razor, DflWeb.Euchre.* backend).
   Card FRONT faces are a plain rank+suit layout — a traditional corner-index/pip/J-Q-K-portrait-art
   treatment was tried first and removed per the user's direction, including the
   wwwroot/images/cards/*.png art it depended on. The card BACK is the site's own branded
   wwwroot/images/DFL-background.png per the user's direction, framed like a real card back rather
   than a flat logo stamp — see .euchre-card__back-face below. */

.euchre-status {
    padding: 2rem;
    text-align: center;
    color: var(--dfl-text-muted);
}

.euchre-page {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0.75rem 0.75rem 0;
    max-width: 1100px;
    margin: 0 auto;
}

/* Mirrors euchre.css's identical rule for the same reason: nothing sits below .euchre-table (the
   fixed fab row / modal backdrop are out of flow), so .dfl-main's own trailing padding is pure
   unused space here. */
.dfl-main:has(> .euchre-page) {
    padding-bottom: 0;
}

/* Hides the site-wide per-sport tab row (SportNav.razor, .dfl-sport-nav) specifically on the Euchre
   2.0 page, per the user — it isn't relevant to Euchre and was just eating vertical space above the
   felt. Same :has() trick as the rule above: .dfl-sport-nav is MainLayout.razor's sibling of
   .dfl-main, not a descendant of it, so this has to key off .dfl-body (their shared ancestor)
   rather than .dfl-main itself. MainLayout.razor has no per-route awareness to gate this any other
   way without touching shared layout code, which this deliberately avoids — same reasoning as the
   .dfl-main override above, just one level higher up the tree. Does NOT touch DflTicker/NewsTicker
   (.dfl-ticker-stack) — the user named the sport tab row specifically, not the score/news tickers
   above it. */
.dfl-body:has(.euchre-page) .dfl-sport-nav {
    display: none;
}

/* Floating score readout, top-left of the felt per the user. Anchored to .euchre-table (the
   nearest positioned ancestor), not the viewport, so it stays pinned to the felt's own corner at
   every breakpoint rather than the page's. */
.euchre-score-pill {
    position: absolute;
    left: 0.6rem;
    top: 0.6rem;
    z-index: 6;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.15rem;
    padding: 0.35rem 0.6rem;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(2px);
}

.euchre-score-pill__row {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    color: #fff;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.euchre-score-pill__label {
    font-size: 0.72rem;
    font-weight: 600;
    color: rgba(255, 255, 255, 0.75);
}

.euchre-score-pill__value {
    font-size: 1rem;
}

/* Narration readout, top-RIGHT of the felt — mirrors .euchre-score-pill's top-left placement and
   pill styling exactly (same rgba background, same corner inset), just right-aligned instead of
   left-aligned. Status-only (no title row) per the user, capped at 25% of the table's own width (%
   here resolves against .euchre-table, the nearest positioned ancestor) — deliberately narrow
   enough that longer status strings are expected to WRAP across as many rows as needed rather than
   truncate, so no ellipsis/nowrap here unlike the score pill's labels. */
.euchre-narration {
    position: absolute;
    right: 0.6rem;
    top: 0.6rem;
    z-index: 6;
    padding: 0.35rem 0.6rem;
    border-radius: 10px;
    background: rgba(0, 0, 0, 0.4);
    backdrop-filter: blur(2px);
    max-width: 25%;
    text-align: right;
}

.euchre-narration__status {
    display: block;
    font-size: 0.68rem;
    color: rgba(255, 255, 255, 0.9);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
    white-space: normal;
    overflow-wrap: break-word;
}

/* Fixed corner FABs — same fixed bottom-left placement as the original (.euchre-fab-row), reused
   verbatim here since it's a page-chrome convention, not part of the felt/card redesign.
   Start Game/Play Again (.euchre-start-fab) joined this row when the old persistent title/status
   banner above the felt was removed per the user — those two actions only ever apply pre/post-game,
   so folding them into this already-conditional row means they take up zero space the rest of the
   time, unlike the banner they used to live in. */
.euchre-fab-row {
    position: fixed;
    left: 1rem;
    bottom: 1rem;
    z-index: 1200;
    display: flex;
    gap: 0.5rem;
}

.euchre-reset-fab,
.euchre-last-trick-fab,
.euchre-start-fab {
    padding: 0.55rem 0.9rem;
    border-radius: 999px;
    font-weight: 700;
    font-size: 0.85rem;
    cursor: pointer;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}

.euchre-reset-fab {
    border: 1px solid var(--dfl-danger);
    background: var(--dfl-surface);
    color: var(--dfl-danger);
}

.euchre-reset-fab:hover {
    background: var(--dfl-danger-bg);
}

.euchre-last-trick-fab {
    border: 1px solid var(--dfl-border-strong);
    background: var(--dfl-surface);
    color: var(--dfl-text);
}

.euchre-last-trick-fab:hover {
    background: var(--dfl-surface-hover);
}

.euchre-start-fab {
    border: 1px solid var(--dfl-brand);
    background: var(--dfl-brand);
    color: #fff;
}

.euchre-start-fab:hover {
    background: var(--dfl-brand-dark);
}

/* Table — a soft-cornered rectangle of felt rather than the original's thick-bordered oval, closer
   to the reference screenshot's full-bleed, edge-to-edge table. Same --euchre-card-w/-h +
   cross/enter offset custom-property mechanism as euchre.css (see that file's header comment for
   the crossY > cardH/2 non-overlap constraint this inherits unchanged), just under a euchre-*
   name and with slightly larger base card sizes for a chunkier, more "real deck" feel. */
.euchre-table {
    position: relative;
    width: 100%;
    box-sizing: border-box;
    /* Taller than the original 4/3 per the user — the trick pile (anchored near table-center via
       fixed px cross offsets) was overlapping seats' hands (anchored near the true table edges). A
       taller table pushes table-center farther from those fixed edge anchors without changing any of
       the px offsets themselves, giving both ends more room apart. (The dealer's up-card used to
       share this same crowding problem before it moved into EuchreSeat's own normal-flow layout —
       see that file's comment — but the taller table still helps the trick-pile/hand spacing on its
       own.) */
    aspect-ratio: 3 / 4;
    min-height: 560px;
    /* Caps the aspect-ratio-derived height so it can never exceed the desktop clamp's own 702px max
       (see the ≥720px override below) — per the user, width shrinking should only ever shrink the
       table's height too, never let it jump up. Without this, aspect-ratio alone (height = width *
       4/3) actually EXCEEDS 702px for any width above ~527px, so a window narrowing from wide down
       toward the 720px breakpoint would balloon the table to ~960px tall right before that breakpoint
       flips it back down to the desktop clamp — a sudden jump in the wrong direction. With both
       min-height and max-height set, the effective height is clamp(560px, width*4/3, 702px), which
       lines up exactly with the desktop side's own 702px cap at the breakpoint itself (no visible
       seam) and only decreases below 702px once width drops under ~527px. */
    max-height: 702px;
    border-radius: 28px;
    background:
        radial-gradient(ellipse at center, #2a8c4a 0%, #1c6b38 55%, #0f4a26 100%);
    border: 2px solid #0a3319;
    box-shadow: inset 0 0 60px rgba(0, 0, 0, 0.45), 0 12px 30px rgba(0, 0, 0, 0.3);
    /* NOT overflow:hidden — the felt's rounded corners are already clipped by border-radius on the
       background paint itself (border-box background-clip is the default); actual overflow:hidden
       here would additionally clip child content, and the trick-collect sweep keyframes
       (.euchre-trick-sweep-*) deliberately carry cards up to 3x the cross offset past the table's
       own edge as part of the "swept away to the winner's side" animation. */
    /* Bumped ~35% over the original sizing pass per the user's "bigger cards" ask (Trickster Cards
       screenshot comparison) — every dependent offset (cross/enter) is scaled by the same factor so
       the crossY > cardH/2 non-overlap constraint and the enter-animation travel distance both stay
       proportionally correct, not just the card box itself. */
    --euchre-card-w: 68px;
    --euchre-card-h: 97px;
    --euchre-cross-x: 100px;
    --euchre-cross-y: 62px;
    --euchre-enter-x: 142px;
    --euchre-enter-y: 119px;
}

@media (min-width: 720px) {
    .euchre-table {
        aspect-ratio: auto;
        /* Subtrahend trimmed (was 300px, then 240px) now that the old persistent title/status banner
           above the felt is gone and the min/max bounds raised — same "give the table more room to
           reduce the dealer-card/hand overlap" reasoning as the mobile aspect-ratio change above.
           Max cap: 780px, then briefly trimmed 10% to 702px, then put back to 780px, then set to
           720px, then back to 702px per the user. */
        height: clamp(460px, calc(100vh - 200px), 702px);
        /* Card size trimmed back ~15% (was 92x132) per the user — desktop specifically read as
           crowded even though mobile was fine at its own (unchanged) sizing, so only this breakpoint's
           values moved. Every dependent offset (cross/enter) scaled by the same ~0.85 factor so the
           crossY > cardH/2 non-overlap constraint and the enter-animation travel distance stay
           proportionally correct, not just the card box itself. */
        --euchre-card-w: 78px;
        --euchre-card-h: 112px;
        --euchre-cross-x: 111px;
        --euchre-cross-y: 71px;
        --euchre-enter-x: 161px;
        --euchre-enter-y: 132px;
        /* Desktop-only buffer per the user — the viewport-fixed .euchre-bid-panel (see that rule's
           own comment) sits at the physical bottom of the screen regardless of where the table ends,
           and on shorter desktop viewports the table's own bottom edge (and the bottom seat's hand,
           anchored via .euchre-seat-slot--bottom's own small inset) was landing close enough to the
           screen bottom that the bid panel covered the player's cards. Mobile didn't need this — left
           untouched. Only a modest amount per the user: the bid panel is still fine overlapping the
           fab-row/chat pill below the table, just not the hand above it.  */
        margin-bottom: 3rem;
    }
}

.euchre-seat-slot {
    position: absolute;
    display: flex;
    justify-content: center;
    z-index: 2;
}

.euchre-seat-slot--bottom {
    left: 50%;
    bottom: 0.5rem;
    transform: translateX(-50%);
}

.euchre-seat-slot--top {
    left: 50%;
    top: 0.6rem;
    transform: translateX(-50%);
}

.euchre-seat-slot--left {
    left: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
}

.euchre-seat-slot--right {
    right: 0.6rem;
    top: 50%;
    transform: translateY(-50%);
}

/* .euchre-seat is now the OUTER container of just two items — .euchre-seat__core (identity+hand,
   grouped so they always stack vertically together, see that class's own rule) and, when this seat
   is the dealer, .euchre-seat__up-card. This element's flex-direction varies per seat position
   (rules below) specifically so the up-card always lands on the side "inward toward the table" per
   the user, for all 4 positions:
     top:    column         (last child = physically LOWER in the box = toward center)
     bottom: column-reverse (last child = physically HIGHER under reversal = toward center)
     left:   row            (last child = RIGHTMOST in the row = toward center)
     right:  row-reverse    (last child = LEFTMOST under reversal = toward center)
   .euchre-seat__up-card is always rendered LAST in EuchreSeat.razor's markup (after .euchre-seat__
   core), so this one set of 4 direction rules is all that's needed — no per-position markup
   branching. */
.euchre-seat {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
    padding: 0.3rem;
    border-radius: 12px;
    min-width: 90px;
    transition: box-shadow 0.2s ease;
}

/* Groups identity+hand/mini-hand as one flex item that ALWAYS stacks them vertically (avatar/name
   above hand), regardless of which direction the outer .euchre-seat is currently using — see that
   rule's comment. This split is what lets the outer container flip to row/row-reverse for left/right
   without also turning identity and hand into side-by-side siblings. */
.euchre-seat__core {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.3rem;
}

/* MY seat only (seat-slot--bottom is always the viewer's own screen position — see
   EuchreLayout.ScreenPositionFor) — reversed so the identity block (avatar/name/dealer-tricks
   chips/Leave seat) renders at the box's TRUE-EDGE end regardless of how tall the hand grows,
   instead of at the box's CENTER-facing end. .euchre-seat-slot--bottom is anchored via `bottom`
   only (no `top`), so the box grows upward from the table's bottom edge as content is added; with
   the default (non-reversed) column order, the identity block — being the first child — landed at
   the box's center-facing edge, which crept further into the trick pile's own territory every time
   the hand got taller (more cards = taller box = identity pushed higher). That's what let a played
   trick card cover the identity block entirely (confirmed via a user screenshot: avatar/name/dealer
   chip gone, only "Leave seat" visible peeking out below the covering card) — and why it looked
   "fine" once the hand emptied to 0 cards on the last play (shortest possible box, identity already
   sitting safely down near the true edge). Reversing puts the identity block at the fixed
   true-edge end unconditionally; only the hand end (which shrinks card-by-card as tricks are played
   anyway, and is expected to visually approach the trick pile) drifts toward center as it grows.
   .euchre-seat-slot--top does NOT need this: its box is anchored the opposite way (`top` only), so
   its DOM order already puts identity at the true-edge end and hand at the center-facing end without
   any reversal. */
.euchre-seat-slot--bottom .euchre-seat {
    flex-direction: column-reverse;
}

/* Left/right seats: row-based instead of column-based, so the up-card (rendered last, see
   .euchre-seat's own comment) lands to the side facing the table's center rather than above/below
   the identity+hand stack. Gap back to the base 0.3rem (a one-off 0.55rem bump here was tried, then
   superseded — see .euchre-seat__up-card's own per-position margin rules below, which give proper
   rotation-aware clearance instead of a flat extra gap). */
.euchre-seat-slot--left .euchre-seat {
    flex-direction: row;
    align-items: center;
}

.euchre-seat-slot--right .euchre-seat {
    flex-direction: row-reverse;
    align-items: center;
}

/* A soft glow around the active seat's whole box (avatar + name pill), instead of the original's
   plain box-shadow ring — reads more like a highlighted spotlight on the felt.

   NOTE: a wider spread (16px/22px) was tried to clear the rotated mini-hand fan's overhang (box-shadow
   paints relative to .euchre-seat's UNROTATED layout box, so drooped/rotated outer fan cards can
   stick out past it without widening it) — user reverted, it looked worse blown up that large. Back
   to the original small spread; the fan-clipping issue this was meant to fix is unresolved, revisit
   with a different approach if it comes up again (e.g. sizing per-seat-type rather than one blanket
   number for every position). */
.euchre-seat--active {
    box-shadow: 0 0 0 3px rgba(255, 215, 0, 0.5), 0 0 18px 4px rgba(255, 215, 0, 0.25);
}

.euchre-seat--sitting-out {
    opacity: 0.45;
}

.euchre-seat__sit-btn {
    padding: 0.4rem 0.8rem;
    border-radius: 8px;
    border: 1px dashed rgba(255, 255, 255, 0.6);
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
    cursor: pointer;
    font-weight: 600;
}

.euchre-seat__sit-btn:hover {
    background: rgba(255, 255, 255, 0.2);
}

.euchre-seat__empty-label {
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.85rem;
}

.euchre-seat__identity {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    max-width: 100%;
    min-width: 0;
}

/* Default (left/right seats): avatar above name-pill, same as before. */
.euchre-seat__identity-row {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    min-width: 0;
}

/* Top/bottom seats: avatar LEFT of the name-pill instead, per the user — cuts the identity block's
   vertical footprint roughly in half (was avatar-height + gap + name-pill-height stacked, now just
   the taller of the two). For the bottom seat specifically (mine — see the flex-direction:column-
   reverse rule above), less identity height means less total box height, so the box's center-facing
   edge — where the hand sits — sits that much lower/closer to the true bottom edge instead of
   needing to leave room for a tall stacked identity underneath it. */
.euchre-seat-slot--top .euchre-seat__identity-row,
.euchre-seat-slot--bottom .euchre-seat__identity-row {
    flex-direction: row;
}

/* Name + chips as one translucent pill sitting just under the avatar — mirrors the reference
   screenshot's "Kirt • 0" / "DEALER" label look, instead of the original's inline text-shadowed
   name directly on the felt. */
.euchre-seat__name-pill {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 0.1rem;
    max-width: 100%;
    padding: 0.15rem 0.55rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.4);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
}

.euchre-seat__name-text {
    max-width: 96px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Two chip-ROW groups (dealer alone; trump+tricks together — see EuchreSeat.razor's markup comment)
   sit side by side in one row by default (top/bottom/general case — matches the original single-row
   look exactly). Left/right override below stacks the two groups into separate lines instead. */
.euchre-seat__chips {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.euchre-seat__chip-row {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.euchre-seat__chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 15px;
    padding: 0 4px;
    border-radius: 4px;
    font-size: 0.62rem;
    font-weight: 800;
    line-height: 1;
    letter-spacing: 0.02em;
}

.euchre-seat__chip--dealer {
    background: var(--dfl-warning);
    color: #1a1a1a;
}

.euchre-seat__chip--trump {
    background: #1a1a1a;
    color: #fff;
    min-width: 15px;
}

.euchre-seat__chip--red {
    color: #ff6b6b;
}

.euchre-seat__chip--tricks {
    background: rgba(255, 255, 255, 0.25);
    min-width: 15px;
    border-radius: 999px;
}

/* Left/right seats only, per the user — DEALER goes on its own line, with the trump/tricks chips (if
   present) on a line below it, instead of all three squeezed into one row. Top/bottom keep the base
   single-line behavior untouched.

   A flex-wrap:wrap + flex-basis:100%-on-the-dealer-chip trick was tried first, but a multi-line
   wrapped flex container sizes its OWN width to fit its widest line, and flex-basis:100% then
   stretches the dealer chip's background to match THAT width — so when the trump+tricks line was
   wider than "DEALER" alone, the dealer pill visibly stretched to match it. flex-direction:column
   avoids this: each chip-row group sizes to its own content independently (align-items:center
   overrides the default cross-axis stretch), so the dealer pill stays exactly "DEALER"-sized
   regardless of how wide the line below it is. */
.euchre-seat-slot--left .euchre-seat__chips,
.euchre-seat-slot--right .euchre-seat__chips {
    flex-direction: column;
    align-items: center;
}

.euchre-seat__sitting-out {
    font-size: 0.68rem;
    color: rgba(255, 255, 255, 0.7);
    font-style: italic;
}

.euchre-seat__leave-btn {
    border: none;
    background: none;
    padding: 0;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.68rem;
    text-decoration: underline;
    cursor: pointer;
}

.euchre-seat__leave-btn:hover {
    color: #fff;
}

/* The dealer's kitty/up-card — an ordinary flex sibling of .euchre-seat__core within the outer
   .euchre-seat (see EuchreSeat.razor's comment for why it moved here from an absolutely-positioned
   overlay, and .euchre-seat's own CSS comment for how its position ends up "inward toward the
   table" for every seat position). No manual offset needed: by construction it can never overlap
   this seat's other content at any screen size. Uses the ambient --euchre-card-w/-h from
   .euchre-table (NOT the smaller mini-hand-scoped size), so it reads as a full-size card same as
   the trick pile. Label-above-card is the default (matches bottom/left/right); top gets an override
   below flipping it to label-BELOW-card instead, per the user — deliberately just this inner
   direction, not touched by moving the whole block, so the up-card's own position/side relative to
   the seat is completely unaffected. */
.euchre-seat__up-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
}

/* Top dealer only: "Dealer" label below the card instead of above it, per the user — everything
   else about this seat's up-card (which side it sits on, its size) is untouched. */
.euchre-seat-slot--top .euchre-seat__up-card {
    flex-direction: column-reverse;
}

/* Extra clearance on the side of the up-card FACING .euchre-seat__core, per the user — the mini-
   hand's own fan (.euchre-seat__mini-hand) rotates AND droops its outer two cards (see that
   element's own comments), so its true bounding box reaches noticeably past the nominal, unrotated
   card height/width. A plain flex `gap` sized for the nominal card box (which is all the base
   .euchre-seat__up-card gets, via .euchre-seat's own gap) left the up-card sitting right against —
   or under, for top specifically — those drooped/rotated outer cards even though it cleared the
   mini-hand's flat CENTER card fine. These three margins are the fix; a flat gap bump on
   .euchre-seat-slot--left/--right was tried first and is superseded by this (see that rule's own
   comment) since it's a proper per-side offset instead of a blanket one. Bottom doesn't need this —
   the player's OWN hand (EuchreHand.razor) is a plain unrotated row, not a fan. */
.euchre-seat-slot--top .euchre-seat__up-card {
    margin-top: 1.75rem;
}

.euchre-seat-slot--left .euchre-seat__up-card {
    margin-left: 1.75rem;
}

.euchre-seat-slot--right .euchre-seat__up-card {
    margin-right: 1.75rem;
}

.euchre-seat__up-card-label {
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.85);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

.euchre-seat__discard-label {
    color: #fff;
    font-size: 0.8rem;
    font-weight: 600;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
}

/* Opponents' face-down mini-fan — smaller card size scoped locally by shadowing the two sizing
   variables (rather than hardcoding px on individual cards, as the original .euchre-seat__hand--back
   rule did) so EuchreCard's own var(--euchre-card-w/-h) reads this container's values instead of
   .euchre-table's, with zero changes needed inside EuchreCard itself. */
.euchre-seat__mini-hand {
    display: flex;
    --euchre-card-w: 41px;
    --euchre-card-h: 58px;
}

@media (min-width: 720px) {
    .euchre-seat__mini-hand {
        --euchre-card-w: 51px;
        --euchre-card-h: 74px;
    }
}

.euchre-seat__mini-hand-slot {
    margin-left: calc(var(--euchre-card-w) * -0.62);
}

.euchre-seat__mini-hand-slot:first-child {
    margin-left: 0;
}

/* --fan-rise (EuchreSeat.razor) droops the outer cards down slightly per the user, same technique
   as the (since-reverted) own-hand fan — see EuchreHand.razor's git history / the euchre project
   memory for why it didn't stick there; it's a better fit here since this fan is purely decorative
   (no click targets to protect). */
.euchre-seat__mini-hand-slot .euchre-card {
    transform: rotate(var(--fan-rotate, 0deg)) translateY(var(--fan-rise, 0px));
}

/* Own hand — a plain straight row again (see EuchreHand.razor's comment for why the fan was
   dropped): nowrap, not wrap, so a 6-card hand (briefly, before discarding) shrinks to fit one row
   instead of breaking onto a second line. */
.euchre-hand {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.75rem 0;
}

.euchre-hand .euchre-card {
    flex: 0 1 auto;
    min-width: 0;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
    .euchre-hand .euchre-card--playable:hover {
        transform: translateY(-10px);
        box-shadow: 0 10px 18px rgba(0, 0, 0, 0.45);
    }
}

.euchre-hand .euchre-card--playable:active {
    transform: translateY(-3px) scale(0.97);
}

/* Cards */

.euchre-card {
    position: relative;
    width: var(--euchre-card-w, 50px);
    height: var(--euchre-card-h, 72px);
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    line-height: 1.1;
    border-radius: calc(var(--euchre-card-w, 50px) * 0.14);
    border: 1px solid #cbd5e1;
    background: #fffdf8;
    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.35), 0 1px 1px rgba(0, 0, 0, 0.15);
    overflow: hidden;
}

.euchre-card--red {
    color: #b3261e;
}

.euchre-card--black {
    color: #1a1a2e;
}

.euchre-card--trump {
    background: linear-gradient(155deg, #fff8e6 0%, #fde49a 100%);
    border-color: #c9971a;
}

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

.euchre-card:disabled {
    opacity: 1;
}

.euchre-card--illegal:disabled {
    opacity: 0.4;
    filter: grayscale(60%);
}

/* Plain rank+suit front, scaled off --euchre-card-w instead of a fixed rem size so it tracks the
   table's own responsive/mini-hand card sizing. A traditional corner-index/pip/face-art treatment
   was tried here first and removed per user direction (including the J/Q/K portrait art it depended
   on — see git history, not a wwwroot file, for that art). */
.euchre-card__rank {
    font-size: calc(var(--euchre-card-w, 50px) * 0.44);
    font-weight: 700;
}

.euchre-card__suit {
    font-size: calc(var(--euchre-card-w, 50px) * 0.5);
}

/* Back — the site's own branded artwork rather than a plain repeating stripe, per the user's
   direction. background-size:cover crops the (portrait, badge-centered) source image down to
   whatever the current card size's aspect ratio is instead of stretching/distorting it.
   The card's own outer border (base .euchre-card rule: 1px solid light gray) becomes the gold trim
   for a back-face card — a single frame around the full logo image, not a gray outline around an
   inset gold-bordered square. Widened slightly (1px -> 2px) so the trim actually reads as trim. */
.euchre-card--back {
    border: 2px solid #d4a017;
    background: #0b1220;
}

/* inset:0, no border, no border-radius, no box-shadow of its own — the logo fills the card exactly
   up to .euchre-card's own (already-gold, for a back) border, clipped to that border's rounded
   corners by the card's overflow:hidden rather than needing a second, separate inner frame. */
.euchre-card__back-face {
    position: absolute;
    inset: 0;
    display: block;
    background-image: url("/images/DFL-background.png");
    background-size: cover;
    background-position: center;
}

/* Trick area */

.euchre-trick-area {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 3;
}

.euchre-trick-play {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: calc(var(--euchre-card-h, 72px) / -2);
    margin-left: calc(var(--euchre-card-w, 50px) / -2);
}

/* Resting positions — upright, no rotation, per the user (a "tossed onto the felt" look with a
   fixed per-direction tilt was tried and explicitly reversed: played cards should stay upright). */
.euchre-trick-play--bottom {
    margin-top: calc(var(--euchre-card-h, 72px) / -2 + var(--euchre-cross-y, 46px));
}

.euchre-trick-play--top {
    margin-top: calc(var(--euchre-card-h, 72px) / -2 - var(--euchre-cross-y, 46px));
}

.euchre-trick-play--left {
    margin-left: calc(var(--euchre-card-w, 50px) / -2 - var(--euchre-cross-x, 74px));
}

.euchre-trick-play--right {
    margin-left: calc(var(--euchre-card-w, 50px) / -2 + var(--euchre-cross-x, 74px));
}

.euchre-trick-play--winner .euchre-card {
    box-shadow: 0 0 0 3px var(--dfl-warning), 0 4px 14px rgba(0, 0, 0, 0.5);
    transform: scale(1.14);
}

.euchre-trick-play--entering {
    animation-duration: 0.25s;
    animation-timing-function: ease-out;
}

.euchre-trick-enter--bottom {
    animation-name: euchre-enter-bottom;
}

.euchre-trick-enter--top {
    animation-name: euchre-enter-top;
}

.euchre-trick-enter--left {
    animation-name: euchre-enter-left;
}

.euchre-trick-enter--right {
    animation-name: euchre-enter-right;
}

@keyframes euchre-enter-bottom {
    from {
        opacity: 0;
        transform: translate(0, var(--euchre-enter-y, 88px)) scale(0.6);
    }
    to {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }
}

@keyframes euchre-enter-top {
    from {
        opacity: 0;
        transform: translate(0, calc(-1 * var(--euchre-enter-y, 88px))) scale(0.6);
    }
    to {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }
}

@keyframes euchre-enter-left {
    from {
        opacity: 0;
        transform: translate(calc(-1 * var(--euchre-enter-x, 105px)), 0) scale(0.6);
    }
    to {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }
}

@keyframes euchre-enter-right {
    from {
        opacity: 0;
        transform: translate(var(--euchre-enter-x, 105px), 0) scale(0.6);
    }
    to {
        opacity: 1;
        transform: translate(0, 0) scale(1);
    }
}

.euchre-trick-play--collecting {
    animation: euchre-trick-sweep-bottom 1.3s ease-in forwards;
}

/* Same rigid-group sweep idea as euchre.css (see that file's comment for why a shared vector can
   never change any card's position RELATIVE to the others) — one keyframe per winning side so each
   sweeps toward its own edge of the table; no rotation baked in (upright throughout, per the user). */
.euchre-trick-collect--bottom {
    animation-name: euchre-trick-sweep-bottom;
}

.euchre-trick-collect--top {
    animation-name: euchre-trick-sweep-top;
}

.euchre-trick-collect--left {
    animation-name: euchre-trick-sweep-left;
}

.euchre-trick-collect--right {
    animation-name: euchre-trick-sweep-right;
}

@keyframes euchre-trick-sweep-bottom {
    0%, 70% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
    }
    100% {
        transform: translate(0, calc(3 * var(--euchre-cross-y, 46px))) scale(0.55);
        opacity: 0;
    }
}

@keyframes euchre-trick-sweep-top {
    0%, 70% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
    }
    100% {
        transform: translate(0, calc(-3 * var(--euchre-cross-y, 46px))) scale(0.55);
        opacity: 0;
    }
}

@keyframes euchre-trick-sweep-left {
    0%, 70% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
    }
    100% {
        transform: translate(calc(-3 * var(--euchre-cross-x, 74px)), 0) scale(0.55);
        opacity: 0;
    }
}

@keyframes euchre-trick-sweep-right {
    0%, 70% {
        transform: translate(0, 0) scale(1);
        opacity: 1;
    }
    100% {
        transform: translate(calc(3 * var(--euchre-cross-x, 74px)), 0) scale(0.55);
        opacity: 0;
    }
}

.euchre-trick-enter-then-collect--bottom {
    animation: euchre-enter-bottom 0.15s ease-out forwards, euchre-trick-sweep-bottom 1.15s ease-in 0.15s forwards;
}

.euchre-trick-enter-then-collect--top {
    animation: euchre-enter-top 0.15s ease-out forwards, euchre-trick-sweep-top 1.15s ease-in 0.15s forwards;
}

.euchre-trick-enter-then-collect--left {
    animation: euchre-enter-left 0.15s ease-out forwards, euchre-trick-sweep-left 1.15s ease-in 0.15s forwards;
}

.euchre-trick-enter-then-collect--right {
    animation: euchre-enter-right 0.15s ease-out forwards, euchre-trick-sweep-right 1.15s ease-in 0.15s forwards;
}

/* Bid panel — the "notification for trump calling," per the user, now pinned to the BOTTOM OF THE
   SCREEN (viewport-fixed, like the fab-row) instead of centered over the felt. Reverses the earlier
   "dead center of the felt" placement: now that top/bottom identity is more compact and the hand can
   sit lower, a screen-fixed bottom prompt reads as sitting right where the player's own attention
   already is (near their cards), and it sidesteps the old percentage-of-table sizing hack entirely
   — no more needing the up-card to stay clear of it, since a viewport-fixed element can never
   overlap anything table-relative by construction. bottom offset is now flush with the very bottom
   of the screen per the user, deliberately overlapping the fab-row (Reset Game/Last Trick) and the
   chat pill while the bid panel is up — the user explicitly said that overlap is fine, this only
   shows during bidding turns anyway. z-index still above the fab-row (1200) so the bid panel wins
   the overlap rather than getting hidden under it. */
.euchre-bid-panel {
    position: fixed;
    left: 50%;
    bottom: 0.3rem;
    transform: translateX(-50%);
    z-index: 1250;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    padding: 0.9rem;
    border-radius: 10px;
    background: var(--dfl-surface);
    border: 1px solid var(--dfl-border);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    /* Widened per the user (was min(26rem, 94vw)) — a bigger, more prominent bottom notification,
       not sized to just barely fit its contents. width alone would only ever grow the box up to
       96vw; max-width is the actual clamp once 96vw would exceed 34rem on a wider screen. */
    width: 96vw;
    max-width: 34rem;
}

.euchre-bid-panel__header {
    font-weight: 600;
    color: var(--dfl-text);
    text-align: center;
}

.euchre-bid-panel__alone {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.9rem;
    color: var(--dfl-text-muted);
}

.euchre-bid-panel__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.5rem;
}

.euchre-bid-panel__pass-btn {
    padding: 0.45rem 1rem;
    border-radius: 8px;
    border: 1px solid var(--dfl-border-strong);
    background: var(--dfl-surface-alt);
    color: var(--dfl-text);
    cursor: pointer;
    font-weight: 600;
}

.euchre-bid-panel__pass-btn:hover {
    background: var(--dfl-surface-hover);
}

/* Round-2 "call trump" buttons — just the suit glyph per the user (was e.g. "♦ Diamonds"), on a
   real-card white face rather than the surface-themed pass button, so the suit reads the same way
   it does on an actual card. Colors match .euchre-card--red/--black exactly for consistency. */
.euchre-bid-panel__suit-btn {
    width: 3.2rem;
    height: 3.2rem;
    border-radius: 10px;
    border: 1px solid #cbd5e1;
    background: #ffffff;
    font-size: 1.7rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

.euchre-bid-panel__suit-btn--red {
    color: #b3261e;
}

.euchre-bid-panel__suit-btn--black {
    color: #1a1a2e;
}

.euchre-bid-panel__suit-btn:hover {
    background: #f2f2f2;
}

/* Last Trick modal */

.euchre-last-trick-modal {
    width: min(22rem, 100%);
    padding: 1rem 1.1rem 1.25rem;
    border-radius: 12px;
    background: var(--dfl-surface, #fff);
    box-shadow: 0 16px 48px rgba(15, 61, 107, 0.28);
}

.euchre-last-trick-modal__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.75rem;
    color: var(--dfl-brand-dark, #0f3d6b);
}

.euchre-last-trick-modal__close {
    border: none;
    background: none;
    padding: 0.25rem;
    font-size: 1rem;
    line-height: 1;
    color: var(--dfl-text-muted);
    cursor: pointer;
}

.euchre-last-trick-modal__cards {
    aspect-ratio: 1 / 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    justify-items: center;
    align-items: center;
    gap: 0.4rem;
    padding: 0.75rem;
    border-radius: 10px;
    background: radial-gradient(ellipse at center, #2a8c4a 0%, #0f4a26 100%);
    border: 4px solid #0a3319;
}

.euchre-last-trick-modal__card--top {
    grid-column: 2;
    grid-row: 1;
}

.euchre-last-trick-modal__card--left {
    grid-column: 1;
    grid-row: 2;
}

.euchre-last-trick-modal__card--right {
    grid-column: 3;
    grid-row: 2;
}

.euchre-last-trick-modal__card--bottom {
    grid-column: 2;
    grid-row: 3;
}

/* Mobile spacing — same rationale as euchre.css's identical media query: the table's WIDTH is what
   gets tight on a narrow phone (min-height keeps it well above strict 4:3), so left/right seat
   content and trick-card offsets both need pulling in together. */
@media (max-width: 480px) {
    .euchre-table {
        --euchre-card-w: 51px;
        --euchre-card-h: 74px;
        --euchre-cross-x: 70px;
        --euchre-cross-y: 49px;
        --euchre-enter-x: 95px;
        --euchre-enter-y: 84px;
    }

    .euchre-seat-slot--left {
        left: 0.2rem;
    }

    .euchre-seat-slot--right {
        right: 0.2rem;
    }

    .euchre-seat {
        min-width: 0;
        padding: 0.2rem;
        gap: 0.2rem;
    }

    .euchre-seat__name-pill {
        max-width: 84px;
        font-size: 0.68rem;
    }

    .euchre-seat__name-text {
        max-width: 60px;
    }

    .euchre-seat__mini-hand {
        --euchre-card-w: 30px;
        --euchre-card-h: 43px;
    }

    .euchre-bid-panel {
        padding: 0.6rem;
        gap: 0.4rem;
    }

    .euchre-bid-panel__actions {
        gap: 0.3rem;
    }

    .euchre-bid-panel__alone {
        font-size: 0.75rem;
        gap: 0.25rem;
    }

    .euchre-bid-panel .draft-pick-btn,
    .euchre-bid-panel__pass-btn {
        padding: 0.35rem 0.55rem;
        font-size: 0.72rem;
    }

    .euchre-bid-panel__suit-btn {
        width: 2.6rem;
        height: 2.6rem;
        font-size: 1.35rem;
    }
}
