@import 'Portfolio.Client.m72alb7p86.bundle.scp.css';

/* /Components/Account/Pages/Manage/EnableAuthenticator.razor.rz.scp.css */
/* The enrolment QR: always black on white (scanners need the contrast, even in dark mode),
   sized to fit a 360px phone with room to spare. */
.authenticator-qr[b-o8fpfo6wyv] {
    width: min(60vmin, 14rem);
    aspect-ratio: 1;
    margin: 0.75rem auto;
    padding: 0.5rem;
    box-sizing: border-box;
    border-radius: 0.5rem;
    background: #ffffff;
}

.authenticator-qr[b-o8fpfo6wyv]  svg {
    display: block;
    width: 100%;
    height: 100%;
}
/* /Components/Account/Shared/AuthCard.razor.rz.scp.css */
/* Fill the viewport below the app bar (minus CenteredLayout's my-8) so the card sits
   vertically centered; min-height lets it grow and scroll on very short screens. */
.auth-page[b-vi77qcise3] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(100dvh - var(--mud-appbar-height, 64px) - 64px);
}

/* Centered auth card: one column at every width, sized for a ~360px phone first. */
/* Edged like a mahjong tile laid on felt: a gold hairline all the way round, a faint lit top
   bevel, and a soft drop shadow onto the table — no accent stripe. */
.auth-page[b-vi77qcise3]  .auth-card {
    width: min(100%, 420px);
    padding: clamp(16px, 4vw, 32px);
    border-radius: var(--radius-lg);
    border: 1px solid color-mix(in srgb, var(--gold) 38%, transparent);
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, var(--gold) 22%, transparent),
        inset 0 -2px 0 rgba(0, 0, 0, 0.35),
        0 10px 28px rgba(0, 0, 0, 0.45),
        0 2px 6px rgba(0, 0, 0, 0.35);
}

/* "── or ──" separator between sign-in methods; it lives in the caller's ChildContent, hence ::deep. */
.auth-page[b-vi77qcise3]  .or-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    color: var(--mud-palette-text-secondary);
    font-size: 0.8125rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.auth-page[b-vi77qcise3]  .or-divider::before,
.auth-page[b-vi77qcise3]  .or-divider::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--mud-palette-divider);
}

.auth-page[b-vi77qcise3]  .passkey-btn {
    width: 100%;
    min-height: 44px;
}

.auth-footer[b-vi77qcise3] {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px 16px;
    text-align: center;
}
/* /Components/Account/Shared/Turnstile.razor.rz.scp.css */
/* The widget is hidden (0px) unless Cloudflare needs the user to interact, so no height is reserved.
   Turnstile.razor.js picks "compact" (150x140, centered) on phones or narrow forms, else "flexible". */
turnstile-widget[b-ek3zx049m4] {
    display: block;
    width: 100%;
}

turnstile-widget[data-size="compact"] .turnstile-slot[b-ek3zx049m4] {
    display: flex;
    justify-content: center;
}

.turnstile-error[b-ek3zx049m4] {
    margin: 0.25rem 0 0;
    font-size: 0.8125rem;
    color: var(--mud-palette-error);
}
/* /Components/GuideArticle.razor.rz.scp.css */
/* Styles reach the pages' child content through ::deep, so every rule targets a guide class, and the
   element selectors only match direct children (">"): nothing here can hit markup rendered inside
   nested components such as MudButton or MahjongTile. */

/* Single readable column; MainLayout's .page-body already supplies the 1rem phone gutter. */
.guide-page[b-d8yqths0pe] {
    max-width: 720px;
    margin: 0 auto;
    padding: 1.5rem 0 3rem;
    color: var(--mud-palette-text-primary);
    line-height: 1.65;
    overflow-wrap: anywhere;
}

.guide-page[b-d8yqths0pe]  .guide-heading {
    margin-bottom: 1rem;
}

.guide-page[b-d8yqths0pe]  .guide-title {
    font-family: var(--font-serif);
    font-size: clamp(1.75rem, 6vw, 2.75rem);
    font-weight: 600;
    line-height: 1.15;
    margin: 0 0 0.75rem;
}

/* The router's FocusOnNavigate focuses the h1 for screen readers; it isn't interactive, so no ring. */
.guide-page[b-d8yqths0pe]  .guide-title:focus {
    outline: none;
}

.guide-page[b-d8yqths0pe]  .guide-lead {
    color: var(--mud-palette-text-secondary);
    font-size: 1.0625rem;
}

.guide-page[b-d8yqths0pe]  .guide-section {
    margin-top: 2rem;
    scroll-margin-top: 1rem;
}

.guide-page[b-d8yqths0pe]  .guide-section > h2 {
    font-size: 1.25rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

.guide-page[b-d8yqths0pe]  .guide-section > p {
    margin: 0 0 0.75rem;
}

.guide-page[b-d8yqths0pe]  .guide-list {
    margin: 0 0 0.75rem;
    padding-inline-start: 1.25rem;
}

.guide-page[b-d8yqths0pe]  .guide-list > li + li {
    margin-top: 0.375rem;
}

/* The tai table: pattern names left, values right in a tabular column. */
.guide-page[b-d8yqths0pe]  .guide-table {
    width: 100%;
    margin: 0 0 0.75rem;
    border-collapse: collapse;
    font-variant-numeric: tabular-nums;
}

.guide-page[b-d8yqths0pe]  .guide-table th,
.guide-page[b-d8yqths0pe]  .guide-table td {
    padding: 0.3rem 0.5rem;
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
}

.guide-page[b-d8yqths0pe]  .guide-table thead th {
    font-size: 0.8125rem;
    color: var(--mud-palette-text-secondary);
}

.guide-page[b-d8yqths0pe]  .guide-table th {
    text-align: start;
    font-weight: 500;
}

.guide-page[b-d8yqths0pe]  .guide-table td {
    text-align: end;
    font-weight: 600;
}

/* Text links padded to a comfortable tap height without changing the text flow. */
.guide-page[b-d8yqths0pe]  .guide-link {
    display: inline-block;
    padding-block: 0.625rem;
    color: var(--mud-palette-primary);
}

.guide-page[b-d8yqths0pe]  .guide-cta {
    margin-top: 0.5rem;
    min-height: 44px;
}

/* Example melds: labelled tile groups that wrap onto new rows on narrow screens. */
.guide-page[b-d8yqths0pe]  .meld-row {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 1.5rem;
    margin: 1rem 0;
}

.guide-page[b-d8yqths0pe]  .meld {
    margin: 0;
}

.guide-page[b-d8yqths0pe]  .meld-tiles {
    --tile-size: clamp(2.25rem, 9vw, 3rem);
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

/* A full 17-tile hand: smaller tiles so it fits two rows on a phone, one row on desktop. */
.guide-page[b-d8yqths0pe]  .meld-hand .meld-tiles {
    --tile-size: clamp(1.75rem, 8.5vw, 2.5rem);
}

.guide-page[b-d8yqths0pe]  .meld > figcaption,
.guide-page[b-d8yqths0pe]  .tile-card > figcaption {
    margin-top: 0.375rem;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* Tile guide: a responsive grid of captioned tiles. */
.guide-page[b-d8yqths0pe]  .tile-grid {
    --tile-size: clamp(2.75rem, 14vw, 3.5rem);
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr));
    gap: 1rem 0.5rem;
    margin: 1rem 0 0;
    padding: 0;
    list-style: none;
}

.guide-page[b-d8yqths0pe]  .tile-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin: 0;
    text-align: center;
}

/* Definition lists (the scoring patterns and the glossary): one bordered row per entry, the name and a
   badge/pinyin on a wrapping first line, the explanation below. Wraps instead of scrolling on a phone. */
.guide-page[b-d8yqths0pe]  .guide-defs {
    margin: 0 0 0.75rem;
    padding: 0;
}

.guide-page[b-d8yqths0pe]  .guide-def {
    padding: 0.625rem 0;
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    scroll-margin-top: 1rem;
}

.guide-page[b-d8yqths0pe]  .guide-def > dt {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.125rem 0.75rem;
    font-weight: 600;
}

.guide-page[b-d8yqths0pe]  .guide-def > dd {
    margin: 0.25rem 0 0;
    line-height: 1.55;
}

.guide-page[b-d8yqths0pe]  .guide-def-name {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0 0.5rem;
}

.guide-page[b-d8yqths0pe]  .guide-def-zh {
    font-size: 1.125rem;
}

.guide-page[b-d8yqths0pe]  .guide-def-meta {
    font-weight: 400;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* The tai value sits at the end of the name line when it fits, and wraps under the name otherwise. */
.guide-page[b-d8yqths0pe]  .guide-def-badge {
    margin-inline-start: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--mud-palette-primary);
}

/* A glossary term that links to its rule: the same bold name, with a dotted underline as the cue (never
   colour alone) and no extra line, so rows keep one rhythm whether or not they link. */
.guide-page[b-d8yqths0pe]  .guide-def-link {
    color: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 0.25em;
    min-height: 2rem;
}

.guide-page[b-d8yqths0pe]  .guide-def-link:hover,
.guide-page[b-d8yqths0pe]  .guide-def-link:focus-visible {
    color: var(--mud-palette-primary);
}

/* The payment formulas: set apart on their own line so they never wrap mid-expression in a sentence. */
.guide-page[b-d8yqths0pe]  .guide-formula {
    margin: 0 0 0.75rem;
    padding: 0.5rem 0.75rem;
    border-inline-start: 3px solid var(--mud-palette-primary);
    background: var(--mud-palette-action-default-hover, rgba(255, 255, 255, 0.05));
    border-radius: 0 6px 6px 0;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* FAQ: one tight block per question with the same gap whether or not it has a link. */
.guide-page[b-d8yqths0pe]  .guide-qa-list {
    margin-top: 1.5rem;
}

.guide-page[b-d8yqths0pe]  .guide-qa {
    padding: 1rem 0;
    border-bottom: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
}

.guide-page[b-d8yqths0pe]  .guide-qa:first-child {
    padding-top: 0;
}

.guide-page[b-d8yqths0pe]  .guide-qa > h2 {
    font-size: 1.125rem;
    font-weight: 600;
    margin: 0 0 0.375rem;
}

.guide-page[b-d8yqths0pe]  .guide-qa > p {
    margin: 0;
}

.guide-page[b-d8yqths0pe]  .guide-qa-link {
    display: inline-block;
    margin-top: 0.25rem;
    padding-block: 0.375rem;
    color: var(--mud-palette-primary);
}

/* "More to read": wrapping pill links with a 44px tap height instead of a loose bullet list. */
.guide-page[b-d8yqths0pe]  .guide-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.guide-page[b-d8yqths0pe]  .guide-chips > a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.2));
    border-radius: 999px;
    color: var(--mud-palette-primary);
    text-decoration: none;
}

.guide-page[b-d8yqths0pe]  .guide-chips > a:hover,
.guide-page[b-d8yqths0pe]  .guide-chips > a:focus-visible {
    border-color: var(--mud-palette-primary);
}

/* Table of contents under a page's lead (/scoring): a native <details>, closed until opened. Phone first: one
   column of links that are each a 44px tap target; two columns from 600px. Never hover-only, no script. */
.guide-page[b-d8yqths0pe]  .guide-toc {
    margin-top: 1.25rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.2));
    border-radius: var(--radius-md, 8px);
}

.guide-page[b-d8yqths0pe]  .guide-toc summary {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding: 0 1rem;
    cursor: pointer;
    font-weight: 600;
    color: var(--mud-palette-primary);
}

.guide-page[b-d8yqths0pe]  .guide-toc summary:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: -2px;
}

.guide-page[b-d8yqths0pe]  .guide-toc-list {
    margin: 0;
    padding: 0 1rem 0.75rem;
    list-style: none;
}

/* A group is a section label (small, gold, spaced, with a hairline under it); its patterns are the items,
   indented behind a left rule. Different size, colour, case and shape, so the two levels don't rely on colour. */
.guide-page[b-d8yqths0pe]  .guide-toc-list ul {
    margin: 0 0 0.75rem 0.25rem;
    padding: 0 0 0 0.75rem;
    list-style: none;
    border-inline-start: 2px solid color-mix(in srgb, var(--gold, #c9a227) 35%, transparent);
}

.guide-page[b-d8yqths0pe]  .guide-toc a {
    display: flex;
    align-items: center;
    min-height: 44px;
    color: inherit;
    text-decoration: none;
}

.guide-page[b-d8yqths0pe]  .guide-toc a:hover,
.guide-page[b-d8yqths0pe]  .guide-toc a:focus-visible {
    color: var(--mud-palette-primary);
    text-decoration: underline;
}

.guide-page[b-d8yqths0pe]  .guide-toc a.guide-toc-group {
    margin-top: 0.25rem;
    border-bottom: 1px solid color-mix(in srgb, var(--gold, #c9a227) 30%, transparent);
    font-family: var(--font-mono);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--gold, #c9a227);
}

.guide-page[b-d8yqths0pe]  .guide-toc a.guide-toc-group:hover,
.guide-page[b-d8yqths0pe]  .guide-toc a.guide-toc-group:focus-visible {
    color: var(--mud-palette-text-primary);
}

/* The sections after the patterns (payment, dealer bonus, overlaps): the same label style, set apart from the
   groups above by a little space. */
.guide-page[b-d8yqths0pe]  .guide-toc-extra:first-of-type,
.guide-page[b-d8yqths0pe]  .guide-toc-list > li:not(.guide-toc-extra) + .guide-toc-extra {
    margin-top: 0.75rem;
}

@media (min-width: 600px) {
    .guide-page[b-d8yqths0pe]  .guide-toc-list {
        columns: 2;
        column-gap: 2rem;
    }

    .guide-page[b-d8yqths0pe]  .guide-toc-list > li {
        break-inside: avoid;
    }
}

/* The how-to-build explanation under a pattern's one-line rule (/scoring), set apart as its own paragraph. */
.guide-page[b-d8yqths0pe]  .guide-def-detail {
    display: block;
    margin-top: 0.375rem;
    color: var(--mud-palette-text-secondary);
}
/* /Components/Landing/HeroSection.razor.rz.scp.css */
/* Full-bleed hero: break out of the layout's .page-body horizontal padding. */
.hero[b-kfyq72cunx] {
    position: relative;
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    min-height: calc(100dvh - 64px);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 3rem 1.25rem;
    box-sizing: border-box;
    text-align: center;
    /* The decorative tiles always show the original green: reset the player's tile-wafer
       preference (stamped on <html>) so each tile SVG falls back to its hard-coded green. */
    --tile-wafer-face: initial;
    --tile-wafer-bevel: initial;
    --tile-wafer-edge: initial;
    --tile-wafer-rim: initial;
    /* Same for the tile-theme ink palette: the hero art keeps the classic inks. */
    --tile-ink-red: initial;
    --tile-ink-green: initial;
    --tile-ink-blue: initial;
    --tile-ink-magenta: initial;
}

/* Scattered background tiles. */
.hero-tiles[b-kfyq72cunx] {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.hero-tile[b-kfyq72cunx] { position: absolute; }
.hero-tile.t1[b-kfyq72cunx] { top: 6rem; left: 2rem; opacity: 0.2; }
.hero-tile.t2[b-kfyq72cunx] { top: 8rem; right: 3rem; opacity: 0.15; }
.hero-tile.t3[b-kfyq72cunx] { bottom: 8rem; left: 6rem; opacity: 0.2; }
.hero-tile.t4[b-kfyq72cunx] { bottom: 6rem; right: 5rem; opacity: 0.15; }
.hero-tile.t5[b-kfyq72cunx] { top: 50%; left: 1rem; opacity: 0.1; }
.hero-tile.t6[b-kfyq72cunx] { top: 50%; right: 1.5rem; opacity: 0.1; }
.hero-tile.t7[b-kfyq72cunx] { top: 4rem; left: 30%; opacity: 0.1; }
.hero-tile.t8[b-kfyq72cunx] { top: 5rem; right: 28%; opacity: 0.1; }
.hero-tile.t9[b-kfyq72cunx] { bottom: 4rem; left: 34%; opacity: 0.1; }
.hero-tile.t10[b-kfyq72cunx] { bottom: 5rem; right: 32%; opacity: 0.1; }
.hero-tile.t11[b-kfyq72cunx] { top: 32%; left: 11rem; opacity: 0.12; }
.hero-tile.t12[b-kfyq72cunx] { bottom: 28%; right: 10rem; opacity: 0.12; }

/* Board preview under the call to action: a framed 16:9 table, full width on phones, capped on desktop. */
.hero-preview[b-kfyq72cunx] {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 56rem;
    margin-top: 3rem;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--mud-palette-lines-default, #1e3325);
    box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.45);
    text-align: initial;
}

/* ---- Simulated play: a pure-CSS loop over the static preview board ----
   One round, a quarter of --preview-loop per seat in turn order East (bottom) → South (right) →
   West (top) → North (left). On its turn a seat's nameplate lights up and its last discard (the tile
   GamePreviewState marks as played this round) slides into the pool from its side, while the wall
   count ticks down for each opponent's draw. East's discard is the drawn tile, which leaves the hand.
   The round then resets for the next loop. Only runs when the viewer allows motion; otherwise the
   board holds the snapshot at East's turn with the round's discards removed. */
.hero-preview[b-kfyq72cunx] {
    --preview-loop: 16s;
}

@media (prefers-reduced-motion: reduce) {
    .hero-preview[b-kfyq72cunx]  .discards > :last-child { display: none; }
}

@media (prefers-reduced-motion: no-preference) {
    /* Nameplates: one shared loop, phase-shifted so each seat owns its quarter. The plate itself
       stays the dark resting pill (overriding East's static active gold + pulse); the gold fill and
       its glow live on a ::before layer whose OPACITY is animated, so the hand-off composites
       instead of repainting background/box-shadow every frame. Only the small text colour flips. */
    .hero-preview[b-kfyq72cunx]  .board .seat-label-inner {
        background: rgba(0, 0, 0, 0.45);
        border-color: rgba(255, 255, 255, 0.12);
        box-shadow: none;
        transition: none;
        animation: preview-turn-b-kfyq72cunx var(--preview-loop) ease-in-out var(--turn-offset, 0s) infinite;
    }
    .hero-preview[b-kfyq72cunx]  .board .seat-label-inner::before {
        content: "";
        position: absolute;
        inset: -1px;
        z-index: -1;
        border-radius: inherit;
        border: 1px solid rgba(255, 255, 255, 0.35);
        background: var(--mud-palette-primary, #c9a227);
        box-shadow: 0 0 12px rgba(201, 162, 39, 0.75);
        animation: preview-turn-glow-b-kfyq72cunx var(--preview-loop) ease-in-out var(--turn-offset, 0s) infinite;
    }
    .hero-preview[b-kfyq72cunx]  .right-side { --turn-offset: calc(var(--preview-loop) * -0.75); }
    .hero-preview[b-kfyq72cunx]  .top-side { --turn-offset: calc(var(--preview-loop) * -0.5); }
    .hero-preview[b-kfyq72cunx]  .left-side { --turn-offset: calc(var(--preview-loop) * -0.25); }

    /* The wind glyph follows the plate's text colour (the game dims it per active state). */
    .hero-preview[b-kfyq72cunx]  .board .seat-label-inner .seat-wind {
        color: inherit;
        opacity: 0.7;
    }

    /* East's "to discard" tag, only rendered on the snapshot's active seat: fades and slides in
       place (transform/opacity only; its slot in the plate stays reserved). */
    .hero-preview[b-kfyq72cunx]  .player-hud .seat-turn {
        display: inline-block;
        transform-origin: left center;
        animation: preview-turn-tag-b-kfyq72cunx var(--preview-loop) ease-in-out infinite;
    }

    /* East's drawn tile lifts out of the hand and fades (transform/opacity only). */
    .hero-preview[b-kfyq72cunx]  .player-hud li:has(button.tile[data-drawn="true"]) {
        animation: preview-drawn-b-kfyq72cunx var(--preview-loop) ease-in-out infinite;
    }

    /* …and the hand closes over its slot, re-centring as a real removal would: the neighbours on
       each side slide half a tile pitch (0.81 × --tile-size, after the hand's overlap) toward it.
       Transform only — the slot itself keeps its layout box. */
    .hero-preview[b-kfyq72cunx]  .player-hud li:has(~ li button.tile[data-drawn="true"]) {
        --preview-close: calc(var(--tile-size) * 0.405);
        animation: preview-close-gap-b-kfyq72cunx var(--preview-loop) ease-in-out infinite;
    }
    .hero-preview[b-kfyq72cunx]  .player-hud li:has(button.tile[data-drawn="true"]) ~ li {
        --preview-close: calc(var(--tile-size) * -0.405);
        animation: preview-close-gap-b-kfyq72cunx var(--preview-loop) ease-in-out infinite;
    }

    /* Each seat's round discard, hidden until its turn. Discard blocks are rotated to face their
       seat, so +Y is toward the seat: the tile slides in from the player's side. */
    .hero-preview[b-kfyq72cunx]  .discards > :last-child { opacity: 0; }
    .hero-preview[b-kfyq72cunx]  .discard-quad-bottom .discards > :last-child {
        animation: preview-discard-east-b-kfyq72cunx var(--preview-loop) ease-out infinite;
    }
    .hero-preview[b-kfyq72cunx]  .discard-quad-right .discards > :last-child {
        animation: preview-discard-south-b-kfyq72cunx var(--preview-loop) ease-out infinite;
    }
    .hero-preview[b-kfyq72cunx]  .discard-quad-top .discards > :last-child {
        animation: preview-discard-west-b-kfyq72cunx var(--preview-loop) ease-out infinite;
    }
    .hero-preview[b-kfyq72cunx]  .discard-quad-left .discards > :last-child {
        animation: preview-discard-north-b-kfyq72cunx var(--preview-loop) ease-out infinite;
    }

    /* The wall count: the server-rendered number is swapped for a CSS counter stepped down per draw. */
    .hero-preview[b-kfyq72cunx]  .board-center-count {
        position: relative;
        visibility: hidden;
        counter-reset: preview-deck var(--preview-deck, 68);
        animation: preview-deck-b-kfyq72cunx var(--preview-loop) step-end infinite;
    }
    .hero-preview[b-kfyq72cunx]  .board-center-count::after {
        content: counter(preview-deck);
        visibility: visible;
        position: absolute;
        inset: 0;
        text-align: center;
    }
}

/* Plate text: dark on the gold turn fill, light on the resting pill. */
@keyframes preview-turn-b-kfyq72cunx {
    0%, 23%, 100% { color: var(--mud-palette-primary-text, #0a1510); }
    26%, 97% { color: rgba(255, 255, 255, 0.82); }
}

/* The gold fill + glow layer behind the plate. */
@keyframes preview-turn-glow-b-kfyq72cunx {
    0%, 23%, 100% { opacity: 1; }
    26%, 97% { opacity: 0; }
}

@keyframes preview-turn-tag-b-kfyq72cunx {
    0%, 20%, 100% { opacity: 0.85; transform: none; }
    26%, 97% { opacity: 0; transform: translateX(-0.25rem) scaleX(0.6); }
}

@keyframes preview-drawn-b-kfyq72cunx {
    0%, 9%, 100% { opacity: 1; transform: none; }
    13%, 96% { opacity: 0; transform: translateY(-60%); }
}

/* Hand neighbours close the drawn tile's gap once it has lifted away, and reopen it as it returns. */
@keyframes preview-close-gap-b-kfyq72cunx {
    0%, 12%, 100% { transform: none; }
    17%, 95% { transform: translateX(var(--preview-close)); }
}

@keyframes preview-discard-east-b-kfyq72cunx {
    0%, 11% { opacity: 0; transform: translateY(80%) scale(1.15); }
    15%, 96% { opacity: 1; transform: none; }
    100% { opacity: 0; transform: none; }
}

@keyframes preview-discard-south-b-kfyq72cunx {
    0%, 36% { opacity: 0; transform: translateY(80%) scale(1.15); }
    40%, 96% { opacity: 1; transform: none; }
    100% { opacity: 0; transform: none; }
}

@keyframes preview-discard-west-b-kfyq72cunx {
    0%, 61% { opacity: 0; transform: translateY(80%) scale(1.15); }
    65%, 96% { opacity: 1; transform: none; }
    100% { opacity: 0; transform: none; }
}

@keyframes preview-discard-north-b-kfyq72cunx {
    0%, 86% { opacity: 0; transform: translateY(80%) scale(1.15); }
    90%, 96% { opacity: 1; transform: none; }
    100% { opacity: 0; transform: none; }
}

/* Snapshot count is East's post-draw wall (GamePreviewState.DeckCount); each opponent draws one. */
@keyframes preview-deck-b-kfyq72cunx {
    0% { --preview-deck: 68; }
    25% { --preview-deck: 67; }
    50% { --preview-deck: 66; }
    75% { --preview-deck: 65; }
}

.hero-content[b-kfyq72cunx] {
    position: relative;
    z-index: 1;
    max-width: 46rem;
    width: 100%;
}

/* Every line of copy — including lines that wrap on a phone — gets the same space above it:
   line-height is the font size plus one fixed gap, and the blocks themselves stack with no margin. */
.hero-copy[b-kfyq72cunx] {
    --line-gap: 0.75rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 1.25rem;
}

.hero-copy > *[b-kfyq72cunx] {
    margin: 0;
    line-height: calc(1em + var(--line-gap));
}

.hero-title[b-kfyq72cunx] {
    font-family: var(--font-serif);
    font-weight: 700;
    font-size: clamp(2.75rem, 8vw, 4.5rem);
}

.hero-title-en[b-kfyq72cunx] {
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.hero-tagline[b-kfyq72cunx] {
    color: var(--mud-palette-text-secondary, #7fa384);
    font-size: clamp(1rem, 2.5vw, 1.25rem);
}

.hero-cta[b-kfyq72cunx] {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    justify-content: center;
    align-items: stretch;
}

/* Both CTAs share identical dimensions, at least the 44px touch-target floor. */
[b-kfyq72cunx] .cta-btn {
    min-width: 11rem;
    min-height: var(--tap-min);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding-inline: 1.25rem;
    font-size: 0.875rem;
    font-weight: 600;
    border-radius: var(--tile-radius);
    box-sizing: border-box;
}

/* The Play link to /play: gold fill with the theme's dark-on-gold text, like a filled primary button. */
[b-kfyq72cunx] .cta-primary {
    gap: 0.25rem;
    background: var(--mud-palette-primary);
    box-shadow: 0 4px 24px rgba(201, 162, 39, 0.3);
}

/* MudLink sets its own (primary-coloured) text, which would vanish on the gold fill. */
[b-kfyq72cunx] a.cta-primary,
[b-kfyq72cunx] a.cta-primary:hover,
[b-kfyq72cunx] a.cta-primary .mud-icon-root {
    color: var(--mud-palette-primary-contrast-text, #0a1510) !important;
}

[b-kfyq72cunx] .cta-primary:hover {
    filter: brightness(1.1);
}

/* Raised felt, never --mud-palette-secondary (a light sage foreground colour). The sage input
   outline gives the button a ≥3:1 edge against the hero felt. */
[b-kfyq72cunx] .cta-secondary {
    background: var(--felt-surface);
    border: 1px solid var(--mud-palette-lines-inputs, #56785e);
    color: var(--mud-palette-text-primary, #e8dfc8);
    transition: border-color 0.15s ease-out, color 0.15s ease-out;
}

[b-kfyq72cunx] .cta-secondary:hover {
    border-color: var(--mud-palette-primary, #c9a227);
    color: var(--mud-palette-primary, #c9a227);
}

/* One clear keyboard ring on both CTAs, offset so it reads against the gold primary too. */
[b-kfyq72cunx] .cta-btn:focus-visible {
    outline: 2px solid var(--gold);
    outline-offset: 3px;
}

/* Quiet text link to the rules guide under the board preview, padded to a comfortable tap height
   and lifted above the scattered background tiles like the content. */
.hero-learn[b-kfyq72cunx] {
    position: relative;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-min);
    margin-top: 1rem;
    padding: 0 0.5rem;
    font-size: 0.9375rem;
    color: var(--mud-palette-primary);
    text-decoration: underline;
    text-underline-offset: 0.2em;
}

@media (max-width: 480px) {
    .hero-cta[b-kfyq72cunx] {
        flex-direction: column;
        align-items: center;
    }

    [b-kfyq72cunx] .cta-btn {
        width: 100%;
        max-width: 20rem;
    }
}

/* On small phones the scattered edge tiles crowd the content — hide them. */
@media (max-width: 600px) {
    .hero-tile.t1[b-kfyq72cunx], .hero-tile.t2[b-kfyq72cunx], .hero-tile.t5[b-kfyq72cunx], .hero-tile.t6[b-kfyq72cunx],
    .hero-tile.t7[b-kfyq72cunx], .hero-tile.t8[b-kfyq72cunx], .hero-tile.t9[b-kfyq72cunx], .hero-tile.t10[b-kfyq72cunx],
    .hero-tile.t11[b-kfyq72cunx], .hero-tile.t12[b-kfyq72cunx] { display: none; }
    .hero-preview[b-kfyq72cunx] { margin-top: 2rem; }
}
/* /Components/Landing/LandingModes.razor.rz.scp.css */
/* Home-page game-mode cards, phone first: one column at 360px, two from 600px, three from 960px. The look is
   /play's card (felt tile, gold hairline, per-mode accent kept to the tag, edge and subtitle so the text stays
   high-contrast; the tag says the same thing in words). */
.landing-modes[b-swh5zdj20q] {
    max-width: 72rem;
    margin: 0 auto;
    padding: clamp(2.5rem, 8vw, 5rem) 0 0;
    box-sizing: border-box;
    /* Below the fold on first paint: skip layout and paint until it scrolls near the viewport. */
    content-visibility: auto;
    contain-intrinsic-size: auto 60rem;
}

.landing-head[b-swh5zdj20q] {
    margin-bottom: 1.5rem;
}

.landing-title[b-swh5zdj20q] {
    font-family: var(--font-serif);
    font-weight: 700;
    font-size: clamp(1.6rem, 5vw, 2.5rem);
    line-height: 1.2;
    margin: 0.25rem 0 0;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-mode-grid[b-swh5zdj20q] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

@media (min-width: 600px) {
    .landing-mode-grid[b-swh5zdj20q] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.25rem;
    }
}

@media (min-width: 960px) {
    .landing-mode-grid[b-swh5zdj20q] {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.landing-mode[b-swh5zdj20q] {
    --mode-accent: var(--gold);
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: clamp(16px, 4vw, 24px);
    border-radius: var(--radius-lg);
    background: var(--felt-surface, #162b1c);
    border: 1px solid color-mix(in srgb, var(--gold) 38%, transparent);
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, var(--gold) 22%, transparent),
        inset 0 -2px 0 rgba(0, 0, 0, 0.35),
        0 10px 28px rgba(0, 0, 0, 0.45),
        0 2px 6px rgba(0, 0, 0, 0.35);
}

.landing-mode-training[b-swh5zdj20q] {
    --mode-accent: #5fbf75;
}

.landing-mode-private[b-swh5zdj20q] {
    --mode-accent: #a99be0;
}

/* Hover lift only where hover exists and motion is welcome; touch gets no hover-only affordance. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .landing-mode[b-swh5zdj20q] {
        transition: transform 0.2s ease-out, border-color 0.2s ease-out;
    }

    .landing-mode:hover[b-swh5zdj20q] {
        transform: translateY(-2px);
        border-color: color-mix(in srgb, var(--mode-accent) 60%, transparent);
    }
}

.landing-mode-top[b-swh5zdj20q] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.landing-mode[b-swh5zdj20q]  .landing-mode-icon {
    font-size: 2rem;
    width: 2rem;
    height: 2rem;
}

.landing-tag[b-swh5zdj20q] {
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--mode-accent) 50%, transparent);
    background: color-mix(in srgb, var(--mode-accent) 14%, transparent);
    color: var(--mode-accent);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}

.landing-mode-title[b-swh5zdj20q] {
    font-family: var(--font-serif);
    font-size: 1.375rem;
    margin: 0;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-mode-subtitle[b-swh5zdj20q] {
    margin: 0.125rem 0 0;
    font-size: 0.8125rem;
    color: var(--mode-accent);
}

.landing-mode-desc[b-swh5zdj20q] {
    flex: 1;
    margin: 0;
    color: var(--mud-palette-text-secondary, #7fa384);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.landing-mode-meta[b-swh5zdj20q] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.5rem;
    margin: 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--mud-palette-divider, rgba(255, 255, 255, 0.12));
}

.landing-mode-meta dt[b-swh5zdj20q] {
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.landing-mode-meta dd[b-swh5zdj20q] {
    margin: 0.125rem 0 0;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

/* The only link in the card; its ::after stretches over the whole card so any tap on it navigates. */
.landing-mode-link[b-swh5zdj20q] {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    min-height: var(--tap-min);
    font-weight: 600;
    color: var(--mode-accent);
    text-decoration: none;
}

/* The link is inline-flex, which drops a leading space, so the arrow carries its own gap. */
.landing-mode-arrow[b-swh5zdj20q] {
    margin-inline-start: 0.375rem;
}

.landing-mode-link[b-swh5zdj20q]::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
}

.landing-mode-link:focus-visible[b-swh5zdj20q] {
    outline: none;
}

.landing-mode-link:focus-visible[b-swh5zdj20q]::after {
    outline: 2px solid var(--mode-accent);
    outline-offset: 2px;
}
/* /Components/Landing/LandingRules.razor.rz.scp.css */
/* Home-page rules overview, phone first: steps in one column at 360px, two from 600px, four from 960px. */
.landing-rules[b-pcnwpw9s8w] {
    max-width: 72rem;
    margin: 0 auto;
    padding: clamp(2.5rem, 8vw, 5rem) 0 clamp(2.5rem, 8vw, 4rem);
    box-sizing: border-box;
    /* Below the fold on first paint: skip layout and paint until it scrolls near the viewport. */
    content-visibility: auto;
    contain-intrinsic-size: auto 70rem;
}

.landing-head[b-pcnwpw9s8w] {
    margin-bottom: 1.5rem;
}

.landing-title[b-pcnwpw9s8w] {
    font-family: var(--font-serif);
    font-weight: 700;
    font-size: clamp(1.6rem, 5vw, 2.5rem);
    line-height: 1.2;
    margin: 0.25rem 0 0;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-steps[b-pcnwpw9s8w] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 600px) {
    .landing-steps[b-pcnwpw9s8w] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 2rem 1.5rem;
    }
}

@media (min-width: 960px) {
    .landing-steps[b-pcnwpw9s8w] {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* The big numeral is decoration (the list already numbers the steps), so it stays dim; the gold rule below it
   is the Figma's step divider. */
.landing-step-number[b-pcnwpw9s8w] {
    display: block;
    font-family: var(--font-serif);
    font-size: 2.25rem;
    font-weight: 700;
    line-height: 1;
    color: var(--mud-palette-lines-default, #2b4a35);
}

.landing-step-number[b-pcnwpw9s8w]::after {
    content: "";
    display: block;
    width: 2rem;
    height: 2px;
    margin-top: 1rem;
    background: var(--gold);
}

.landing-step-title[b-pcnwpw9s8w] {
    margin: 1rem 0 0.5rem;
    font-size: 1.125rem;
    font-weight: 600;
}

.landing-step-title a[b-pcnwpw9s8w] {
    display: inline-block;
    padding-block: 0.5rem;
    color: var(--mud-palette-text-primary, #e8dfc8);
    text-decoration: none;
}

.landing-step-title a:hover[b-pcnwpw9s8w],
.landing-step-title a:focus-visible[b-pcnwpw9s8w] {
    color: var(--gold);
    text-decoration: underline;
}

.landing-step-desc[b-pcnwpw9s8w] {
    margin: 0;
    font-size: 0.9375rem;
    line-height: 1.55;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.landing-why[b-pcnwpw9s8w],
.landing-hands[b-pcnwpw9s8w] {
    max-width: 48rem;
    margin-top: clamp(2rem, 6vw, 3rem);
}

.landing-why p[b-pcnwpw9s8w],
.landing-hands p[b-pcnwpw9s8w] {
    margin: 0.5rem 0 0;
    line-height: 1.65;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.landing-why-title[b-pcnwpw9s8w] {
    margin: 0;
    font-family: var(--font-serif);
    font-size: 1.375rem;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-chips[b-pcnwpw9s8w] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.75rem;
}

.landing-chips > a[b-pcnwpw9s8w] {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap-min);
    padding: 0 1rem;
    border: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
    border-radius: 999px;
    color: var(--mud-palette-text-primary, #e8dfc8);
    text-decoration: none;
}

.landing-chips > a:hover[b-pcnwpw9s8w],
.landing-chips > a:focus-visible[b-pcnwpw9s8w] {
    border-color: var(--gold);
    color: var(--gold);
}

.landing-callout[b-pcnwpw9s8w] {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: clamp(2.5rem, 7vw, 4rem);
    padding: clamp(1.25rem, 4vw, 2rem);
    border: 1px solid color-mix(in srgb, var(--gold) 30%, transparent);
    border-radius: var(--radius-lg);
    background: var(--felt-surface, #162b1c);
}

@media (min-width: 720px) {
    .landing-callout[b-pcnwpw9s8w] {
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
    }
}

.landing-callout-title[b-pcnwpw9s8w] {
    margin: 0 0 0.375rem;
    font-family: var(--font-serif);
    font-size: 1.5rem;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-callout p[b-pcnwpw9s8w] {
    margin: 0;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.landing-callout-actions[b-pcnwpw9s8w] {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    flex-shrink: 0;
}

.landing-btn[b-pcnwpw9s8w] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--tap-min);
    padding: 0 1.25rem;
    border-radius: var(--radius-md);
    font-weight: 600;
    text-decoration: none;
}

.landing-btn-primary[b-pcnwpw9s8w] {
    background: var(--gold);
    color: #0a1510;
}

.landing-btn-primary:hover[b-pcnwpw9s8w],
.landing-btn-primary:focus-visible[b-pcnwpw9s8w] {
    filter: brightness(1.1);
}

.landing-btn-secondary[b-pcnwpw9s8w] {
    border: 1px solid var(--mud-palette-lines-default, #2b4a35);
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.landing-btn-secondary:hover[b-pcnwpw9s8w],
.landing-btn-secondary:focus-visible[b-pcnwpw9s8w] {
    border-color: var(--gold);
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/* Sticky-footer shell: a viewport-tall column in which .page-body takes the spare height,
   so the footer sits at the bottom of the screen even when a page's content is short. */
.site-shell[b-gk0xuebvlm] {
    display: flex;
    flex-direction: column;
    min-height: 100dvh;
}

/* Content wrapper: gives ordinary pages (account, etc.) horizontal breathing room,
   while full-bleed landing sections break out of it with a 100vw margin trick.
   No bottom padding so a flush footer leaves no strip of background beneath it;
   overflow-x: clip absorbs the sub-pixel overshoot of the 100vw breakout so the
   page never scrolls sideways. Now a top-level element of the layout (the header is
   the sticky <SiteHeader>), so it carries the scope attribute directly — no ::deep. */
.page-body[b-gk0xuebvlm] {
    flex: 1 0 auto; /* grow into the shell's spare height, never shrink below content */
    padding-inline: 1rem;
    overflow-x: clip;
}

/* The top bar and brand now come from the shared <SiteHeader>/<BrandLogo> components. */

/* The header's "Log in" button (MudButton, so reached through ::deep) meets the touch-target floor. */
.site-shell[b-gk0xuebvlm]  .site-signin {
    min-height: var(--tap-min);
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/* Blazor's reconnect dialog, re-skinned into the felt/gold world: a raised felt card over a
   darkened felt backdrop, gold actions with the dark primary-contrast text. Colours come from the
   emitted --mud-palette-* and the app.css :root tokens; the fallbacks are the same felt values. */
#components-reconnect-modal[b-auijnkhgwr] {
    display: none;
    position: fixed;
    inset: 0;
    z-index: 1400;
    overflow: hidden;
    background-color: transparent;
    border: none;
    width: 100%;
    max-width: 100%;
    max-height: 100%;
    margin: 0;
    padding: 0;
}

    #components-reconnect-modal[b-auijnkhgwr]::backdrop {
        background: rgba(6, 18, 12, 0.6);
    }

    #components-reconnect-modal.components-reconnect-show[b-auijnkhgwr],
    #components-reconnect-modal[open][b-auijnkhgwr],
    #components-reconnect-modal.components-reconnect-failed[b-auijnkhgwr],
    #components-reconnect-modal.components-reconnect-repeated-attempt[b-auijnkhgwr],
    #components-reconnect-modal.components-reconnect-paused[b-auijnkhgwr],
    #components-reconnect-modal.components-reconnect-resume-failed[b-auijnkhgwr],
    #components-reconnect-modal.components-pause[b-auijnkhgwr],
    #components-reconnect-modal.components-resume-failed[b-auijnkhgwr] {
        display: flex;
        align-items: center;
        justify-content: center;
    }

/* Soft felt lighting behind the card (same radial glow as .felt-texture), no off-palette hues. */
.components-reconnect-backdrop[b-auijnkhgwr] {
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background:
        radial-gradient(ellipse at 50% 40%, rgba(22, 43, 28, 0.55) 0%, transparent 65%),
        rgba(6, 18, 12, 0.55);
}

.components-reconnect-surface[b-auijnkhgwr] {
    width: min(30rem, 100%);
    box-sizing: border-box;
    border-radius: var(--radius-lg, 16px);
    border: 1px solid var(--mud-palette-lines-default, #1e3325);
    background: var(--mud-palette-surface, #0f1e14);
    box-shadow: 0 1.5rem 3rem rgba(0, 0, 0, 0.5);
    color: var(--mud-palette-text-primary, #e8dfc8);
    padding: 1.25rem;
}

.components-reconnect-header[b-auijnkhgwr] {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    margin-bottom: 0.5rem;
}

    .components-reconnect-header h2[b-auijnkhgwr] {
        margin: 0;
        font-family: var(--font-serif);
        font-size: 1.125rem;
        font-weight: 600;
        line-height: 1.3;
    }

/* The "whose turn" amber marks the waiting state; a solid dot, no halo. */
.components-reconnect-status-dot[b-auijnkhgwr] {
    flex: 0 0 auto;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 50%;
    background: var(--turn-amber, #ffc742);
}

.components-reconnect-supporting[b-auijnkhgwr],
.components-reconnect-message[b-auijnkhgwr] {
    margin: 0;
    line-height: 1.5;
    font-size: 0.9375rem;
}

.components-reconnect-supporting[b-auijnkhgwr] {
    color: var(--mud-palette-text-secondary, #7fa384);
    margin-bottom: 0.875rem;
}

.components-reconnect-message[b-auijnkhgwr] {
    font-weight: 500;
}

.components-reconnect-danger[b-auijnkhgwr] {
    color: var(--mud-palette-error, #e0574c);
}

.components-reconnect-actions[b-auijnkhgwr] {
    margin-top: 1rem;
    display: flex;
    gap: 0.625rem;
    justify-content: flex-end;
}

.components-reconnect-first-attempt-visible[b-auijnkhgwr],
.components-reconnect-repeated-attempt-visible[b-auijnkhgwr],
.components-reconnect-failed-visible[b-auijnkhgwr],
.components-pause-visible[b-auijnkhgwr],
.components-resume-failed-visible[b-auijnkhgwr] {
    display: none;
}

dialog[open].components-reconnect-show .components-reconnect-first-attempt-visible[b-auijnkhgwr] {
    display: block;
}

dialog[open].components-reconnect-show .components-rejoin-loader[b-auijnkhgwr] {
    display: inline-flex;
}

dialog[open].components-reconnect-failed .components-reconnect-failed-visible[b-auijnkhgwr] {
    display: block;
}

dialog[open].components-reconnect-failed #components-reconnect-button[b-auijnkhgwr] {
    display: inline-flex;
}

dialog[open].components-reconnect-repeated-attempt .components-reconnect-repeated-attempt-visible[b-auijnkhgwr] {
    display: block;
}

dialog[open].components-reconnect-repeated-attempt .components-rejoin-loader[b-auijnkhgwr] {
    display: inline-flex;
}

dialog[open].components-reconnect-paused .components-pause-visible[b-auijnkhgwr],
dialog[open].components-pause .components-pause-visible[b-auijnkhgwr] {
    display: block;
}

dialog[open].components-reconnect-paused #components-resume-button[b-auijnkhgwr],
dialog[open].components-pause #components-resume-button[b-auijnkhgwr],
dialog[open].components-reconnect-resume-failed #components-resume-button[b-auijnkhgwr],
dialog[open].components-resume-failed #components-resume-button[b-auijnkhgwr] {
    display: inline-flex;
}

dialog[open].components-reconnect-resume-failed .components-resume-failed-visible[b-auijnkhgwr],
dialog[open].components-resume-failed .components-resume-failed-visible[b-auijnkhgwr] {
    display: block;
}

.components-rejoin-loader[b-auijnkhgwr] {
    display: none;
    margin-bottom: 0.625rem;
    gap: 0.5rem;
}

    .components-rejoin-loader div[b-auijnkhgwr] {
        width: 0.5625rem;
        height: 0.5625rem;
        border-radius: 50%;
        background-color: var(--mud-palette-primary, #c9a227);
        animation: reconnect-pulse-b-auijnkhgwr 1.2s infinite ease-in-out both;
    }

        .components-rejoin-loader div:nth-child(1)[b-auijnkhgwr] {
            animation-delay: -0.24s;
        }

        .components-rejoin-loader div:nth-child(2)[b-auijnkhgwr] {
            animation-delay: -0.12s;
        }

@keyframes reconnect-pulse-b-auijnkhgwr {
    0%, 80%, 100% {
        transform: scale(0);
    }

    40% {
        transform: scale(1);
    }
}

/* Reduced motion: hold the three dots still at a stepped opacity instead of pulsing
   (the "Rejoining…" text beside them already says what is happening). */
@media (prefers-reduced-motion: reduce) {
    .components-rejoin-loader div[b-auijnkhgwr] {
        animation: none;
        transform: none;
        opacity: 0.85;
    }

        .components-rejoin-loader div:nth-child(2)[b-auijnkhgwr] {
            opacity: 0.6;
        }

        .components-rejoin-loader div:nth-child(3)[b-auijnkhgwr] {
            opacity: 0.35;
        }
}

#components-reconnect-button[b-auijnkhgwr],
#components-resume-button[b-auijnkhgwr] {
    display: none;
    align-items: center;
    justify-content: center;
    min-width: 6rem;
    min-height: var(--tap-min, 44px);
    cursor: pointer;
    padding: 0 1rem;
    border: 1px solid transparent;
    border-radius: var(--tile-radius);
    background-color: var(--mud-palette-primary, #c9a227);
    color: var(--mud-palette-primary-text, #0a1510);
    font: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    line-height: 1.2;
    transition: filter 140ms ease-out, transform 140ms ease-out;
}

    #components-reconnect-button:hover[b-auijnkhgwr],
    #components-resume-button:hover[b-auijnkhgwr] {
        filter: brightness(1.08);
    }

    #components-reconnect-button:active[b-auijnkhgwr],
    #components-resume-button:active[b-auijnkhgwr] {
        transform: translateY(1px);
    }

    #components-reconnect-button:focus-visible[b-auijnkhgwr],
    #components-resume-button:focus-visible[b-auijnkhgwr] {
        outline: 2px solid var(--mud-palette-text-primary, #e8dfc8);
        outline-offset: 2px;
    }
/* /Components/Layout/UserMenu.razor.rz.scp.css */
.usermenu[b-5n21x4wuxu] {
    display: inline-flex;
}

.usermenu-trigger[b-5n21x4wuxu] {
    /* 44x44 hit area around the small (24px) avatar, which keeps its visual size. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tap-min);
    height: var(--tap-min);
    margin-inline-end: -10px; /* keep the avatar where it sat against the header edge */
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    line-height: 0;
    border-radius: 50%;
    /* Anchor for CSS anchor positioning where supported (progressive enhancement below). */
    anchor-name: --usermenu-anchor;
}

/* The native popover renders in the top layer. Reset the UA centering/border and pin it
   just under the app bar at the right edge. This fixed fallback works everywhere, including
   iOS 17-18 which lacks CSS anchor positioning. It scrolls inside itself when the viewport
   is too short (landscape phones) instead of running off-screen. */
.usermenu-pop[b-5n21x4wuxu] {
    margin: 0;
    inset: auto;
    position: fixed;
    top: calc(4rem + 8px); /* the 4rem SiteHeader + gap */
    right: 8px;
    min-width: 210px;
    max-height: calc(100dvh - 4rem - 16px);
    padding-block: 4px;
    border: none;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* Precise horizontal anchoring to the avatar where supported (Chrome 133+, Safari 26+,
   Firefox 147+). Stays position: fixed so the menu is pinned to the viewport under the
   (fixed) app bar and never tracks page scroll off the top when scrolled to the bottom. */
@supports (anchor-name: --a) {
    .usermenu-pop[b-5n21x4wuxu] {
        position: fixed;
        position-anchor: --usermenu-anchor;
        top: calc(anchor(bottom) + 8px);
        right: anchor(right);
        left: auto;
        bottom: auto;
    }
}

.usermenu-item[b-5n21x4wuxu] {
    display: flex;
    align-items: center;
    width: 100%;
    box-sizing: border-box;
    font: inherit;
    color: inherit;
    text-align: left;
    text-decoration: none;
    border: none;
    background: none;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

/* MudBlazor's .mud-list-item-clickable hover comes from list context we don't use here,
   so highlight rows explicitly on hover and keyboard focus. Keyboard focus adds an inset gold
   ring (≥3:1 on the menu surface) so it never reads as a mere hover tint. */
.usermenu-item:hover[b-5n21x4wuxu],
.usermenu-item:focus-visible[b-5n21x4wuxu] {
    background-color: var(--mud-palette-action-default-hover, rgba(255, 255, 255, 0.08));
}

.usermenu-item:focus-visible[b-5n21x4wuxu] {
    outline: 2px solid var(--gold);
    outline-offset: -2px;
}

.usermenu-form[b-5n21x4wuxu] {
    margin: 0;
}

.usermenu-divider[b-5n21x4wuxu] {
    height: 0;
    margin: 4px 0;
    border: none;
    border-top: 1px solid var(--mud-palette-divider, rgba(255, 255, 255, 0.12));
}

.usermenu-sub[b-5n21x4wuxu] {
    /* Anchor for absolutely-positioned current-language hint / caret. */
    width: 100%;
}

/* Remove the native disclosure triangle across browsers. */
.usermenu-sub > summary[b-5n21x4wuxu] {
    list-style: none;
}
.usermenu-sub > summary[b-5n21x4wuxu]::-webkit-details-marker {
    display: none;
}

.usermenu-sub-label[b-5n21x4wuxu] {
    flex: 1 1 auto;
}

.usermenu-sub-current[b-5n21x4wuxu] {
    margin-left: 8px;
    font-size: 0.8125rem;
    opacity: 0.6;
    white-space: nowrap;
}

/* The caret is rendered by <MudIcon> (a child component), so its SVG doesn't carry this
   component's scoped-CSS attribute — reach it with ::deep. */
.usermenu-sub[b-5n21x4wuxu]  .usermenu-sub-caret {
    margin-left: 4px;
    transition: transform 0.15s ease;
}

.usermenu-sub[open][b-5n21x4wuxu]  .usermenu-sub-caret {
    transform: rotate(90deg);
}

/* Hide the summary's current-language hint once expanded (the checked row shows it). */
.usermenu-sub[open] .usermenu-sub-current[b-5n21x4wuxu] {
    display: none;
}

.usermenu-submenu[b-5n21x4wuxu] {
    padding-left: 20px;
}

.usermenu-lang[b-5n21x4wuxu] {
    padding-left: 16px;
}

/* Small section label inside the Tile colors submenu ("Face ink" / "Back"). */
.usermenu-sub-heading[b-5n21x4wuxu] {
    margin: 6px 0 0;
    padding: 4px 16px 0 20px;
    font-size: 0.75rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.6;
}

.usermenu-lang-check[b-5n21x4wuxu] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    margin-right: 12px;
    color: var(--mud-palette-primary, currentColor);
}

.usermenu-lang-active[b-5n21x4wuxu] {
    font-weight: 600;
}

/* Tile-back color row: label on the left (flex:1 via .usermenu-sub-label), the native color
   swatch and a compact Apply button on the right. The <label> wrapper is a .usermenu-item so the
   whole row hovers/highlights like the others. */
.usermenu-color[b-5n21x4wuxu] {
    margin: 0;
}

/* A 44x44 control whose 11px padding insets the visible 22px swatch: a full touch target with the
   same look. Negative block margins keep the row at its usual height. */
.usermenu-color-input[b-5n21x4wuxu] {
    flex: 0 0 auto;
    box-sizing: border-box;
    width: var(--tap-min);
    height: var(--tap-min);
    padding: 11px;
    margin: -8px -3px -8px -3px;
    border: none;
    border-radius: var(--radius-md);
    background: none;
    cursor: pointer;
}

.usermenu-color-input:focus-visible[b-5n21x4wuxu] {
    outline: 2px solid var(--gold);
    outline-offset: -2px;
}

/* Trim the UA swatch chrome so the color fills the rounded swatch, which carries the outline. */
.usermenu-color-input[b-5n21x4wuxu]::-webkit-color-swatch-wrapper {
    padding: 0;
}
.usermenu-color-input[b-5n21x4wuxu]::-webkit-color-swatch {
    border: 1px solid var(--mud-palette-lines-inputs, #56785e);
    border-radius: var(--radius-sm);
}
.usermenu-color-input[b-5n21x4wuxu]::-moz-color-swatch {
    border: 1px solid var(--mud-palette-lines-inputs, #56785e);
    border-radius: var(--radius-sm);
}
.usermenu-color-input:hover[b-5n21x4wuxu]::-webkit-color-swatch {
    border-color: var(--mud-palette-primary, #c9a227);
}
.usermenu-color-input:hover[b-5n21x4wuxu]::-moz-color-swatch {
    border-color: var(--mud-palette-primary, #c9a227);
}

/* Icon toggle: Fill (apply the picked color) by default, Reset once a custom color is saved. */
.usermenu-color-toggle[b-5n21x4wuxu] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tap-min); /* 44px hit area; the 20px icon keeps its visual size */
    height: var(--tap-min);
    margin: -10px -12px -10px 0;
    padding: 0;
    color: var(--mud-palette-primary, #c9a227);
    background: none;
    border: none;
    border-radius: 50%;
    cursor: pointer;
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

.usermenu-color-toggle:hover[b-5n21x4wuxu] {
    background-color: rgba(var(--mud-palette-primary-rgb, 201, 162, 39), 0.12);
}

.usermenu-color-toggle:focus-visible[b-5n21x4wuxu] {
    outline: 2px solid var(--gold);
    outline-offset: -2px;
}

.usermenu-color-reset[b-5n21x4wuxu],
.usermenu-color-custom .usermenu-color-apply[b-5n21x4wuxu] {
    display: none;
}

.usermenu-color-custom .usermenu-color-reset[b-5n21x4wuxu] {
    display: inline-flex;
}

/* Tile-theme preview: the four inks as small dots at the end of each preset row. */
.usermenu-swatches[b-5n21x4wuxu] {
    display: inline-flex;
    gap: 3px;
    margin-left: 8px;
}

.usermenu-swatches > span[b-5n21x4wuxu] {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 1px solid rgba(255, 255, 255, 0.35);
}

/* The screen-reader switch shows its state as the trailing hint; make the "on" state read as active. */
.usermenu-item[role="switch"][aria-checked="true"] .usermenu-sub-current[b-5n21x4wuxu] {
    opacity: 1;
    font-weight: 600;
    color: var(--mud-palette-primary, currentColor);
}

@media (forced-colors: active) {
    .usermenu-swatches > span[b-5n21x4wuxu] {
        forced-color-adjust: none;
    }
}
/* /Components/Pages/Contact.razor.rz.scp.css */
/* Full-bleed page filling the viewport below the 4rem SiteHeader. It breaks out of MainLayout's
   .page-body gutter with the same 100vw margin trick as the landing sections (.page-body clips the
   sub-pixel overshoot). Phone-first: intro stacked above the form; two full-height panels ≥960px. */
.contact-page[b-3qsnul3tr9] {
    width: 100vw;
    margin-inline: calc(50% - 50vw);
    min-height: calc(100dvh - 4rem);
    display: grid;
    grid-template-rows: auto 1fr;
}

/* ---- Intro panel ---- */
.contact-intro[b-3qsnul3tr9] {
    background:
        radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--mud-palette-primary) 14%, transparent), transparent 60%),
        var(--mud-palette-surface);
    border-bottom: 1px solid var(--mud-palette-lines-default);
    padding: 1.5rem 1rem 1.25rem;
}

.contact-intro-inner[b-3qsnul3tr9] {
    max-width: 480px;
    margin-inline: auto;
}

.contact-heading[b-3qsnul3tr9] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.5rem;
}

.contact-heading[b-3qsnul3tr9]  .contact-heading-icon {
    font-size: 2rem;
}

.contact-intro[b-3qsnul3tr9]  .contact-title {
    font-size: clamp(1.625rem, 5vw, 2.5rem);
    line-height: 1.15;
}

.contact-intro[b-3qsnul3tr9]  .contact-lead {
    color: var(--mud-palette-text-secondary);
}

/* What each category is for — only where there's room beside the form. */
.contact-topics[b-3qsnul3tr9] {
    display: none;
    list-style: none;
    margin: 2rem 0 0;
    padding: 0;
    gap: 1.25rem;
}

.contact-topic[b-3qsnul3tr9] {
    display: flex;
    align-items: flex-start;
    gap: 0.875rem;
}

.contact-topic[b-3qsnul3tr9]  .contact-topic-icon {
    flex: none;
    margin-top: 0.125rem;
}

.contact-topic-name[b-3qsnul3tr9] {
    font-weight: 600;
    color: var(--mud-palette-text-primary);
}

.contact-topic-hint[b-3qsnul3tr9] {
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary);
}

/* ---- Form panel ---- */
.contact-form-panel[b-3qsnul3tr9] {
    padding: 1.5rem 1rem 2.5rem;
}

.contact-form-inner[b-3qsnul3tr9] {
    max-width: 640px;
    margin-inline: auto;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Name + email side by side once there's room. */
.contact-row[b-3qsnul3tr9] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.75rem;
}

/* Full-width send button on phones; natural width, right-aligned from tablet up. */
.contact-actions[b-3qsnul3tr9]  .contact-send {
    width: 100%;
    min-height: 48px;
}

/* Native <select> dressed in MudBlazor's outlined-field markup. */
.contact-select[b-3qsnul3tr9] {
    position: relative;
    cursor: pointer;
}

.contact-select[b-3qsnul3tr9]  select {
    appearance: none;
    width: 100%;
    /* MudBlazor's dense-outlined padding targets input elements only, so mirror it (10.5px 14px). */
    padding: 10.5px 2.25rem 10.5px 14px;
    border: 0;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
    color-scheme: dark;
}

.contact-select[b-3qsnul3tr9]  select:focus {
    outline: none;
}

.contact-select[b-3qsnul3tr9]  option {
    background-color: var(--mud-palette-surface);
    color: var(--mud-palette-text-primary);
}

.contact-select:focus-within[b-3qsnul3tr9]  .mud-input-outlined-border {
    border-color: var(--mud-palette-primary);
    border-width: 2px;
}

.contact-select[b-3qsnul3tr9]  .contact-select-arrow {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
    color: var(--mud-palette-action-default);
}

/* Honeypot: off-screen rather than display:none so naive bots still fill it. */
.contact-hp[b-3qsnul3tr9] {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

@media (min-width: 600px) {
    .contact-row[b-3qsnul3tr9] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .contact-actions[b-3qsnul3tr9] {
        display: flex;
        justify-content: flex-end;
    }

    .contact-actions[b-3qsnul3tr9]  .contact-send {
        width: auto;
        padding-inline: 2rem;
    }
}

@media (min-width: 960px) {
    .contact-page[b-3qsnul3tr9] {
        grid-template-rows: none;
        grid-template-columns: minmax(360px, 5fr) 7fr;
    }

    .contact-intro[b-3qsnul3tr9] {
        display: flex;
        align-items: center;
        border-bottom: 0;
        border-right: 1px solid var(--mud-palette-lines-default);
        padding: 3rem clamp(2rem, 4vw, 4rem);
    }

    .contact-intro-inner[b-3qsnul3tr9] {
        margin-inline: auto 0;
        width: 100%;
    }

    .contact-topics[b-3qsnul3tr9] {
        display: grid;
    }

    .contact-form-panel[b-3qsnul3tr9] {
        display: flex;
        align-items: center;
        padding: 3rem clamp(2rem, 5vw, 5rem);
    }

    .contact-form-inner[b-3qsnul3tr9] {
        width: 100%;
        margin-inline: 0 auto;
    }
}
/* /Components/Pages/Credits.razor.rz.scp.css */
/* Single readable column; MainLayout's .page-body already supplies the 1rem phone gutter. */
.credits-page[b-jdiecsve6b] {
    max-width: 680px;
    margin: 0 auto;
    padding: 1.5rem 0 3rem;
    color: var(--mud-palette-text-primary);
    line-height: 1.6;
    overflow-wrap: anywhere;
}

.credits-heading[b-jdiecsve6b] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.credits-heading[b-jdiecsve6b]  .credits-heading-icon {
    font-size: 2rem;
}

.credits-heading[b-jdiecsve6b]  .credits-title {
    font-size: clamp(1.625rem, 5vw, 2.5rem);
    line-height: 1.15;
}

.credits-lead[b-jdiecsve6b] {
    color: var(--mud-palette-text-secondary);
}

.credits-page section[b-jdiecsve6b] {
    margin-top: 1.75rem;
}

.credits-page h2[b-jdiecsve6b] {
    font-size: 1.125rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

.credits-page p[b-jdiecsve6b] {
    margin: 0 0 0.5rem;
}

.credits-page ul[b-jdiecsve6b] {
    margin: 0 0 0.5rem;
    padding-inline-start: 1.25rem;
}

.credits-page li + li[b-jdiecsve6b] {
    margin-top: 0.375rem;
}

.credits-page a[b-jdiecsve6b] {
    color: var(--mud-palette-primary);
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* The landing page is composed of full-bleed section components (HeroSection; the
   SiteFooter comes from MainLayout), each of which owns its own scoped styles.
   Nothing to style here. */
/* /Components/Pages/Play.razor.rz.scp.css */
/* Game-modes page, phone first: one column at 360px, two cards side by side from 600px. */
.play-page[b-pxg38osbqs] {
    max-width: 72rem;
    margin: 0 auto;
    padding: 2rem 0 3rem;
    box-sizing: border-box;
}

.play-head[b-pxg38osbqs] {
    margin-bottom: 1.5rem;
}

.play-title[b-pxg38osbqs] {
    font-family: var(--font-serif);
    font-weight: 700;
    font-size: clamp(1.8rem, 5vw, 2.5rem);
    line-height: 1.2;
    color: var(--mud-palette-text-primary, #e8dfc8);
    margin: 0;
}

.play-grid[b-pxg38osbqs] {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
}

@media (min-width: 600px) {
    .play-grid[b-pxg38osbqs] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 1.25rem;
    }
}

/* A tile laid on felt, like the auth card: gold hairline, lit top bevel, soft drop shadow. */
.play-card[b-pxg38osbqs] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: clamp(16px, 4vw, 28px);
    border-radius: var(--radius-lg);
    background: var(--felt-surface, #162b1c);
    border: 1px solid color-mix(in srgb, var(--gold) 38%, transparent);
    box-shadow:
        inset 0 1px 0 color-mix(in srgb, var(--gold) 22%, transparent),
        inset 0 -2px 0 rgba(0, 0, 0, 0.35),
        0 10px 28px rgba(0, 0, 0, 0.45),
        0 2px 6px rgba(0, 0, 0, 0.35);
}

/* Each mode has its own accent (the Figma's green / purple), kept to the tag pill, its edge and the subtitle so
   text on the felt stays high-contrast; the tag and subtitle also say the same thing in words. */
.play-card-quick[b-pxg38osbqs] {
    --mode-accent: var(--gold);
}

.play-card-training[b-pxg38osbqs] {
    --mode-accent: #5fbf75;
}

.play-card-private[b-pxg38osbqs] {
    --mode-accent: #a99be0;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
    .play-card[b-pxg38osbqs] {
        transition: transform 0.2s ease-out, border-color 0.2s ease-out;
    }

    .play-card:hover[b-pxg38osbqs] {
        transform: translateY(-2px);
        border-color: color-mix(in srgb, var(--mode-accent) 60%, transparent);
    }
}

.play-card-top[b-pxg38osbqs] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 0.75rem;
}

.play-tag[b-pxg38osbqs] {
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--mode-accent) 50%, transparent);
    background: color-mix(in srgb, var(--mode-accent) 14%, transparent);
    color: var(--mode-accent);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    white-space: nowrap;
}

.play-card-subtitle[b-pxg38osbqs] {
    margin: 0.125rem 0 0;
    font-size: 0.8125rem;
    color: var(--mode-accent);
}

/* Footer info row, like the Figma card's "vs AI / No wait". */
.play-card-meta[b-pxg38osbqs] {
    display: flex;
    gap: 1.5rem;
    margin: 0;
    padding-top: 0.75rem;
    border-top: 1px solid var(--mud-palette-divider, rgba(255, 255, 255, 0.12));
}

.play-card-meta dt[b-pxg38osbqs] {
    font-size: 0.6875rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.play-card-meta dd[b-pxg38osbqs] {
    margin: 0.125rem 0 0;
    font-family: var(--font-mono);
    font-size: 0.8125rem;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.play-card[b-pxg38osbqs]  .play-card-icon {
    font-size: 2rem;
    width: 2rem;
    height: 2rem;
}

.play-card-title[b-pxg38osbqs] {
    font-family: var(--font-serif);
    font-size: 1.375rem;
    margin: 0;
    color: var(--mud-palette-text-primary, #e8dfc8);
}

.play-card-desc[b-pxg38osbqs] {
    margin: 0;
    color: var(--mud-palette-text-secondary, #7fa384);
    font-size: 0.9375rem;
    line-height: 1.5;
}

.play-form[b-pxg38osbqs] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}


[b-pxg38osbqs] .play-btn {
    min-height: var(--tap-min);
}

/* Bot level: three native radios styled as a segmented control. The radio itself is visually hidden but
   stays focusable and screen-reader visible; the chosen segment is filled, never colour alone (a check mark too). */
.level-picker[b-pxg38osbqs] {
    display: flex;
    gap: 0.5rem;
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0;
}

.level-picker legend[b-pxg38osbqs] {
    min-height: 1.25rem;
    line-height: 1.25rem;
    padding: 0;
    margin-bottom: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.level-option[b-pxg38osbqs] {
    position: relative;
    flex: 1 1 0;
    min-width: 0;
}

.level-option input[b-pxg38osbqs] {
    position: absolute;
    inset: 0;
    opacity: 0;
    margin: 0;
    cursor: pointer;
}

.level-option span[b-pxg38osbqs] {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    min-height: var(--tap-min);
    padding: 0 0.5rem;
    border-radius: var(--tile-radius);
    border: 1px solid var(--mud-palette-lines-inputs, #56785e);
    color: var(--mud-palette-text-primary, #e8dfc8);
    font-size: 0.875rem;
    text-align: center;
}

.level-option input:checked + span[b-pxg38osbqs] {
    background: color-mix(in srgb, var(--gold) 22%, transparent);
    border-color: var(--gold);
    font-weight: 600;
}

.level-option input:checked + span[b-pxg38osbqs]::before {
    content: "\2713";
}

.level-option input:focus-visible + span[b-pxg38osbqs] {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

/* Join by room code. */
/* The join box's label row and gap match the level picker's legend, so the two option blocks are the same height. */
.join-form[b-pxg38osbqs] {
    gap: 0.5rem;
}

.join-label[b-pxg38osbqs] {
    min-height: 1.25rem;
    line-height: 1.25rem;
    font-size: 0.875rem;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.join-row[b-pxg38osbqs] {
    display: flex;
    gap: 0.5rem;
}

.join-input[b-pxg38osbqs] {
    flex: 1 1 auto;
    min-width: 0;
    min-height: var(--tap-min);
    padding: 0 0.75rem;
    border-radius: var(--tile-radius);
    border: 1px solid var(--mud-palette-lines-inputs, #56785e);
    background: transparent;
    color: var(--mud-palette-text-primary, #e8dfc8);
    font-family: var(--font-mono);
    font-size: 1rem;
    letter-spacing: 0.1em;
}

.join-input:focus-visible[b-pxg38osbqs] {
    outline: 2px solid var(--gold);
    outline-offset: 2px;
}

[b-pxg38osbqs] .join-btn {
    min-height: var(--tap-min);
}

.join-error[b-pxg38osbqs] {
    margin: 0;
    color: var(--mud-palette-error, #f44336);
    font-size: 0.875rem;
}

/* Side by side, the cards share one set of grid rows (top, title, description, info, options, action) through
   subgrid, so the info dividers sit at the same height and each card's main button is on the same bottom line,
   whatever the text length or language. Stacked (phones), each card is just a column in DOM order, which
   already puts the action last. */
@media (min-width: 600px) {
    .play-card[b-pxg38osbqs] {
        display: grid;
        grid-row: span 6;
        grid-template-rows: subgrid;
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0.75rem;
    }

    /* Within a row, the options and the main action sit at the row's bottom (here "end" is the block axis; in the
       stacked flex column it would be the inline one, so it's set only here). */
    .play-action[b-pxg38osbqs],
    .join-form[b-pxg38osbqs],
    .level-picker[b-pxg38osbqs],
    .play-note[b-pxg38osbqs] {
        align-self: end;
    }

    /* Training wraps its options and action in one form, which spans their two rows. */
    .training-form[b-pxg38osbqs] {
        display: grid;
        grid-row: span 2;
        grid-template-rows: subgrid;
        grid-template-columns: minmax(0, 1fr);
        row-gap: 0.75rem;
    }
}

/* The Quick match card has no options, just a one-line reassurance in the options row. */
.play-note[b-pxg38osbqs] {
    margin: 0;
    font-size: 0.8125rem;
    line-height: 1.4;
    color: var(--mud-palette-text-secondary, #7fa384);
}

/* Three modes: three columns once there is room for them (two columns, with the third wrapping, below that). */
@media (min-width: 960px) {
    .play-grid[b-pxg38osbqs] {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
/* /Components/Pages/Privacy.razor.rz.scp.css */
/* Single readable column; MainLayout's .page-body already supplies the 1rem phone gutter. */
.privacy-page[b-p4c7hqw1iq] {
    max-width: 680px;
    margin: 0 auto;
    padding: 1.5rem 0 3rem;
    color: var(--mud-palette-text-primary);
    line-height: 1.6;
    overflow-wrap: anywhere;
}

.privacy-heading[b-p4c7hqw1iq] {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.privacy-heading[b-p4c7hqw1iq]  .privacy-heading-icon {
    font-size: 2rem;
}

.privacy-heading[b-p4c7hqw1iq]  .privacy-title {
    font-size: clamp(1.625rem, 5vw, 2.5rem);
    line-height: 1.15;
}

.privacy-heading[b-p4c7hqw1iq]  .privacy-updated,
.privacy-lead[b-p4c7hqw1iq] {
    color: var(--mud-palette-text-secondary);
}

.privacy-page section[b-p4c7hqw1iq] {
    margin-top: 1.75rem;
}

.privacy-page h2[b-p4c7hqw1iq] {
    font-size: 1.125rem;
    font-weight: 600;
    margin: 0 0 0.5rem;
}

.privacy-page h3[b-p4c7hqw1iq] {
    font-size: 1rem;
    font-weight: 600;
    margin: 1rem 0 0.375rem;
}

.privacy-page p[b-p4c7hqw1iq] {
    margin: 0 0 0.5rem;
}

.privacy-page ul[b-p4c7hqw1iq] {
    margin: 0 0 0.5rem;
    padding-inline-start: 1.25rem;
}

.privacy-page li + li[b-p4c7hqw1iq] {
    margin-top: 0.375rem;
}

/* Links padded to a comfortable tap height without changing the text flow. */
.privacy-page a[b-p4c7hqw1iq] {
    display: inline-block;
    padding-block: 0.625rem;
    color: var(--mud-palette-primary);
}
/* /Components/ScoringExampleHand.razor.rz.scp.css */
/* A worked hand under a scoring pattern. Phone first: sets are nowrap groups that wrap as whole sets, so a hand
   of 17 tiles flows over a few rows at 360px instead of overflowing or shrinking the tiles to specks. */
.scoring-example[b-jkglbh2tp3] {
    margin: 0.75rem 0 0;
    padding: 0.75rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.2));
    border-radius: var(--radius-md, 8px);
    background: color-mix(in srgb, var(--felt-surface, #162b1c) 55%, transparent);
}

.example-label[b-jkglbh2tp3] {
    margin-bottom: 0.5rem;
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.example-sets[b-jkglbh2tp3],
.example-extra[b-jkglbh2tp3] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.5rem 0.75rem;
}

.example-extra[b-jkglbh2tp3] {
    margin-top: 0.625rem;
}

.example-set[b-jkglbh2tp3] {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-end;
    gap: 2px;
}

/* Eight flowers and seasons: allow the row of bonus tiles itself to wrap on a narrow screen. */
.example-set-wrap[b-jkglbh2tp3] {
    flex-wrap: wrap;
}

.example-extra-label[b-jkglbh2tp3] {
    flex-basis: 100%;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.example-caption[b-jkglbh2tp3] {
    margin: 0.625rem 0 0;
    font-size: 0.75rem;
    color: var(--mud-palette-text-secondary, #7fa384);
}

.example-score[b-jkglbh2tp3] {
    margin: 0.75rem 0 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.2));
}

.example-score li[b-jkglbh2tp3] {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.25rem 0;
}

.example-tai[b-jkglbh2tp3] {
    font-family: var(--font-mono);
    white-space: nowrap;
}

.example-total[b-jkglbh2tp3] {
    margin: 0.25rem 0 0;
    font-weight: 600;
    text-align: end;
}
/* /Components/ScrollToTop.razor.rz.scp.css */
/* Bottom-right floating button, 48px (above the 44px touch floor). On phones it sits above the 64px
   BottomNav bar and the home-indicator inset; from 600px, where that bar is gone, it drops to the corner. */
.scroll-to-top[b-1g7jwj39dc] {
    position: fixed;
    right: max(1rem, env(safe-area-inset-right, 0px));
    bottom: calc(64px + env(safe-area-inset-bottom, 0px) + 1rem);
    z-index: 1000; /* above page content, below the bottom bar (1050) and MudBlazor popovers/dialogs */
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--gold, #c9a227);
    color: #0a1510;
    text-decoration: none;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.45);
    -webkit-tap-highlight-color: transparent;
}

@media (min-width: 600px) {
    .scroll-to-top[b-1g7jwj39dc] {
        right: max(1.5rem, env(safe-area-inset-right, 0px));
        bottom: calc(1.5rem + env(safe-area-inset-bottom, 0px));
    }
}

.scroll-to-top:hover[b-1g7jwj39dc] {
    filter: brightness(1.1);
}

.scroll-to-top:focus-visible[b-1g7jwj39dc] {
    outline: 3px solid var(--mud-palette-text-primary, #e8dfc8);
    outline-offset: 3px;
}

@media (forced-colors: active) {
    .scroll-to-top[b-1g7jwj39dc] {
        border: 2px solid ButtonText;
    }
}

/* Reveal after the first screenful, driven by the page scroll itself (no script): hidden, not just transparent,
   at the top, so it isn't a focus stop you can't see. Browsers without scroll-driven animations skip this
   block and keep the button always visible, which is still correct. */
@supports (animation-timeline: scroll()) {
    .scroll-to-top[b-1g7jwj39dc] {
        animation: scroll-to-top-reveal-b-1g7jwj39dc linear both;
        animation-timeline: scroll(root block);
        animation-range: 240px 480px;
    }

    @keyframes scroll-to-top-reveal-b-1g7jwj39dc {
        from {
            opacity: 0;
            visibility: hidden;
        }

        to {
            opacity: 1;
            visibility: visible;
        }
    }
}
