/* _content/LiveEventBingo.Shared/Components/AccountDeletion/DeleteAccountAction.razor.rz.scp.css */
/* ADO #10264 -- type and colour ONLY.

   THERE IS NO LAYOUT IN THIS FILE, AND THERE MUST NOT BE. Bingo-Template S23.3 gives layout to six
   primitives; this component expresses all of its spacing through <Stack Gap> and <Inline Gap>.
   Adding `display: flex`, `gap`, `margin` or `flex` here -- or to any page-local rule targeting a
   primitive's class from the outside -- is the same violation written from the other end, and it is
   the reason the profile pages' legacy `mup-*` / `dup-*` rules are explicitly out of scope rather
   than something to extend.

   The one exception below is `padding-inline-start` on the list, which is a list-marker inset (the
   browser's own `ul` default, restated in token terms) rather than layout between siblings. A
   <Stack> cannot express where a bullet sits relative to its own text. */

.del-acct__heading[b-1ide2d33c0] {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-h3-mobile);
    font-weight: var(--meb-font-weight-semibold);
    line-height: var(--meb-font-lineheight-heading);
    color: var(--meb-text-default);
}

@media (min-width: 768px) {
    .del-acct__heading[b-1ide2d33c0] {
        font-size: var(--meb-font-size-h3-desktop);
    }
}

.del-acct__lead[b-1ide2d33c0] {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-mobile);
    line-height: var(--meb-font-lineheight-body);
    color: var(--meb-text-muted);
}

@media (min-width: 768px) {
    .del-acct__lead[b-1ide2d33c0] {
        font-size: var(--meb-font-size-body-desktop);
    }
}

.del-acct__list[b-1ide2d33c0] {
    padding-inline-start: var(--meb-space-inline-lg);
    color: var(--meb-text-default);
    line-height: var(--meb-font-lineheight-body);
}

/* The refusal state. --meb-accent-danger is the EXISTING destructive token -- the same one
   ButtonVariant.Danger resolves through (MebButton.razor.css). #10264 says explicitly not to add a
   new destructive token, and there is no need for one: this is the same meaning. */
.del-acct__error[b-1ide2d33c0] {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-sm-mobile);
    font-weight: var(--meb-font-weight-semibold);
    line-height: var(--meb-font-lineheight-body);
    color: var(--meb-accent-danger);
}

@media (min-width: 768px) {
    .del-acct__error[b-1ide2d33c0] {
        font-size: var(--meb-font-size-body-sm-desktop);
    }
}
/* _content/LiveEventBingo.Shared/Components/AdView.razor.rz.scp.css */
/* ===================================================================
   AdView.razor.css
   Ad slot component styles.

   Sizing contract:
     The outer slot div exposes --ad-width and --ad-height as scoped
     CSS custom properties. All inner size-dependent containers consume
     these vars rather than repeating inline @(Width)px/@(Height)px
     Blazor expressions on every inner element.

   Color contract:
     All color values reference --meb-* tokens from theme-default.css.
     Raw fallbacks (#f8f9fa, #dee2e6, etc.) are last-resort browser
     defaults only and must never be changed to match design intent.
   =================================================================== */

/* ── Outer slot shell ──────────────────────────────────────────────── */
/* The outer div sets --ad-width / --ad-height once; inner containers
   reference them via var(). No layout is authored at this level. */

/* ── Direct ad (image creative) ─────────────────────────────────────── */
.ad-container[b-opxvn16gxz] {
    width: 100%;
    height: 100%;
}

.ad-creative[b-opxvn16gxz] {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

.ad-wrapper[b-opxvn16gxz] {
    position: relative;
    overflow: hidden;
}

/* ── Status containers (blocked / loading / empty placeholder) ─────── */
/* Slot dimensions: consumes --ad-width / --ad-height tunnelled from the outer div
   via the CSS custom property sizing bridge in AdView.razor (style="--ad-width:...").
   §4.1 note: width/height here are slot geometry driven by the parent [Parameter] via
   CSS vars - no primitive parameter covers this concern.
   Centering: owned by <Inline Align="center" Justify="center"> wrapping
   <Stack Align="center"> in AdView.razor markup. Only visual surface
   properties remain here. */
.ad-status-container[b-opxvn16gxz] {
    width: var(--ad-width, auto);
    height: var(--ad-height, auto);
    background: var(--meb-surface-input-filled);
    border: var(--meb-border-width-sm) solid var(--meb-border-subtle);
    border-radius: var(--meb-radius-sm);
    padding: var(--meb-space-stack-lg);
    text-align: center;
    box-sizing: border-box;
}

/* ── Ad-blocker message ──────────────────────────────────────────────── */
/* SVG icon colour governed by currentColor so it inherits the token-
   controlled stroke from the CSS color property on the container. */
.ad-blocked-message svg[b-opxvn16gxz] {
    color: var(--meb-text-muted);
}

.ad-blocked-message__title[b-opxvn16gxz],
.ad-placeholder__label[b-opxvn16gxz] {
    color: var(--meb-text-default);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-semibold);
    margin: var(--meb-space-stack-none);
}

.ad-blocked-message__title[b-opxvn16gxz] {
    margin-block: var(--meb-space-stack-sm) var(--meb-space-stack-xs);
}

.ad-blocked-message__subtitle[b-opxvn16gxz] {
    color: var(--meb-text-muted);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-regular);
    margin: var(--meb-space-stack-none);
}

/* ── GAM ad container ────────────────────────────────────────────────── */
/* Width/height come from --ad-width / --ad-height set at the outer div. */
.gam-ad-container[b-opxvn16gxz] {
    width: var(--ad-width, auto);
    height: var(--ad-height, auto);
    background: transparent;
    position: relative;
}

    /* Hide the internal loading spinner once GPT injects the iframe */
    .gam-ad-container > div[id*="gam-slot"] > .gam-loading[b-opxvn16gxz] {
        display: none;
    }

    /* Ensure GAM iframe never overflows the container */
    .gam-ad-container iframe[b-opxvn16gxz] {
        max-width: 100%;
        max-height: 100%;
    }

/* ── GAM loading spinner wrapper ─────────────────────────────────────── */
/* §4.1 note: width/height here fill the parent .gam-ad-container (slot-sized via CSS vars).
   Centering of the spinner is owned by <Inline Align="center" Justify="center"> in markup. */
.gam-loading[b-opxvn16gxz] {
    width: 100%;
    height: 100%;
}

/* Fixed provider inventory, never stretch one unit into another form factor. */
.adsterra-slot[b-opxvn16gxz] {
    width: var(--ad-width);
    height: var(--ad-height);
}
/* _content/LiveEventBingo.Shared/Components/BlogAdSlot.razor.rz.scp.css */
/* #ads BlogAdSlot -- appearance only (typography/opacity). Layout is owned by the Stack primitive;
   this file deliberately targets NO layout properties (no flex/gap/display/margin), per the six-
   primitive layout ownership rule. */

.blog-ad-slot[b-shhen4waqo] {
    /* Vertical rhythm around the in-content unit is expressed via the Stack's own padding props at
       the call site; this class exists only as a scoping/label hook. */
}

.ad-label[b-shhen4waqo] {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-sm-desktop);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    opacity: 0.55;
}

/* #11047: the reserved ad box. Slot geometry, not layout: --ad-width / --ad-height come from the
   Width/Height [Parameter]s (same sizing bridge and same exception as AdView.razor.css
   ".ad-status-container" / ".adsterra-slot"); no primitive parameter covers a creative-sized box.
   A fixed height (not min-height) so the band neither grows when a provider answers late nor
   collapses when nothing fills, and overflow-y: clip so a misbehaving creative cannot grow it.
   The width is the creative's own width with no 100% cap and overflow-x stays visible, as on AdView's
   ".adsterra-slot": a 300 px creative on a 320 px phone (288 px content box) or a 728x90 in a desktop
   window under 728 px overflows into the gutter, fully visible, instead of being cropped. */
.ad-slot-reserve[b-shhen4waqo] {
    width: var(--ad-width);
    height: var(--ad-height);
    overflow-x: visible;
    overflow-y: clip;
}

/* #11047: labelled empty state inside the reserve (no-fill, declined without house, blocked image,
   #10785 suppression). Uses the same surface, border and radius tokens as AdView's "My Event Bingo"
   placeholder, but with no padding (it fills the reserved box) and a deliberately muted label.
   Tokens only; centering is owned by the Inline in the markup. */
.ad-slot-placeholder[b-shhen4waqo] {
    width: 100%;
    height: 100%;
    background: var(--meb-surface-input-filled);
    border: var(--meb-border-width-sm) solid var(--meb-border-subtle);
    border-radius: var(--meb-radius-sm);
    box-sizing: border-box;
}

.ad-slot-placeholder__label[b-shhen4waqo] {
    color: var(--meb-text-muted);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-semibold);
    margin: var(--meb-space-stack-none);
}
/* _content/LiveEventBingo.Shared/Components/Buttons/MebButton.razor.rz.scp.css */
/* ============================================================
   MebButton � scoped styles
   Base colors resolve through --button-* CSS custom properties
   emitted by ComponentTokenResolver. Hover/active/focus states
   fall back to --meb-button-* theme globals.
   ============================================================ */

/* ---- Wrapper ---- */

.ui-button-wrapper[b-kf5cur5f5g] {
    display: contents;
}

/* ---- Base ---- */

:is(button, a).meb-btn[b-kf5cur5f5g] {

    /* eliminate browser rendering completely */
    appearance: none;
    -webkit-appearance: none;
    background-color: transparent;
    outline: none;

    /* layout */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--meb-space-stack-12);

    padding: var(--meb-space-stack-sm) var(--meb-space-stack-md);

    border-radius: var(--meb-radius-pill);
    border: var(--meb-border-width-medium) solid var(--button-border, var(--meb-border-default));

    font-family: inherit;
    font-weight: var(--meb-font-weight-semibold);
    line-height: var(--meb-font-lineheight-tight);
    text-decoration: none;

    cursor: pointer;
    user-select: none;

    transition:
        transform var(--meb-motion-fast),
        filter var(--meb-motion-fast),
        box-shadow var(--meb-motion-fast),
        background var(--meb-motion-fast);
}

/* ---- Forced colors focus ring (ADO #11308) ---- */
/* The ring above is a box-shadow, which Windows High Contrast (forced-colors mode) strips, and the base
   rule sets outline: none, so a keyboard-focused button showed no focus indicator at all. A transparent
   outline is invisible in the normal look but forced-colors mode repaints outline-color with a system
   colour, so the button gets a visible ring there. No @media is needed. Every variant (QR included)
   shares this one rule; no variant :focus-visible rule may reset outline (a test pins that). */
:is(button, a).meb-btn:focus-visible[b-kf5cur5f5g] {
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
}

/* ---- Anchor (Href) disabled parity ---- */
/* An <a> cannot match :disabled, so the per-variant :disabled rules below never apply to the
   Href branch. MebButton emits aria-disabled="true" + tabindex="-1" when Disabled; this makes a
   disabled anchor inert and non-focusable to match the <button disabled> affordance. (Href CTAs
   are not Disabled today; this is correctness insurance for that combination. ADO #8592.) */
a.meb-btn[aria-disabled="true"][b-kf5cur5f5g] {
    pointer-events: none;
    cursor: not-allowed;
}

/* ---- Variants ---- */

:is(button, a).meb-btn.meb-btn--primary[b-kf5cur5f5g] {
    background: var(--button-background, var(--meb-accent-primary));
    color: var(--button-foreground, var(--meb-text-inverse));
    box-shadow: var(--button-shadow);
    border-color: var(--button-border, var(--meb-border-default));
}

:is(button, a).meb-btn.meb-btn--primary:hover[b-kf5cur5f5g] {
    background: var(--meb-button-primary-hover-background);
    box-shadow: var(--meb-button-primary-hover-shadow);
}

:is(button, a).meb-btn.meb-btn--primary:active[b-kf5cur5f5g] {
    background: var(--meb-button-primary-active-background);
    box-shadow: var(--meb-button-primary-active-shadow);
    transform: translateY(2px);
}

:is(button, a).meb-btn.meb-btn--primary:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-primary-focus-shadow);
}

:is(button, a).meb-btn:disabled[b-kf5cur5f5g],
:is(button, a).meb-btn.meb-btn--primary:disabled[b-kf5cur5f5g] {
    background: var(
      --button-surface-disabled,
      var(--meb-surface-disabled)
    );
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    border-color: var(
      --meb-button-primary-disabled-border,
      var(--meb-border-muted)
    );
    box-shadow: none;
    cursor: not-allowed;
}

:is(button, a).meb-btn.meb-btn--secondary[b-kf5cur5f5g] {
    background: var(--button-background, var(--meb-surface-card));
    color: var(--button-foreground, var(--meb-text-default));
    box-shadow: var(--button-shadow);
    border-color: var(--button-border, var(--meb-border-default));
}

:is(button, a).meb-btn.meb-btn--secondary:hover[b-kf5cur5f5g] {
    background: var(--meb-button-secondary-hover-background);
    box-shadow: var(--meb-button-secondary-hover-shadow);
}

:is(button, a).meb-btn.meb-btn--secondary:active[b-kf5cur5f5g] {
    background: var(--meb-button-secondary-active-background);
    box-shadow: var(--meb-button-secondary-active-shadow);
    transform: translateY(2px);
}

:is(button, a).meb-btn.meb-btn--secondary:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-secondary-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--secondary:disabled[b-kf5cur5f5g] {
    background: var(
      --button-surface-disabled,
      var(--meb-surface-disabled)
    );
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    border-color: var(
      --meb-button-secondary-disabled-border,
      var(--meb-border-muted)
    );
    box-shadow: none;
    cursor: not-allowed;
}

/* ---- Accent ---- */

:is(button, a).meb-btn.meb-btn--accent[b-kf5cur5f5g] {
    background: var(--button-background, var(--meb-accent-secondary));
    color: var(--button-foreground);
    box-shadow: var(--button-shadow);
    border-color: var(--button-border, var(--meb-border-default));
}

:is(button, a).meb-btn.meb-btn--accent:hover[b-kf5cur5f5g] {
    background: var(--meb-button-accent-hover-background);
    box-shadow: var(--meb-button-accent-hover-shadow);
}

:is(button, a).meb-btn.meb-btn--accent:active[b-kf5cur5f5g] {
    background: var(--meb-button-accent-active-background);
    box-shadow: var(--meb-button-accent-active-shadow);
    transform: translateY(2px);
}

:is(button, a).meb-btn.meb-btn--accent:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-accent-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--accent:disabled[b-kf5cur5f5g] {
    background: var(
      --button-surface-disabled,
      var(--meb-surface-disabled)
    );
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    border-color: var(
      --meb-button-accent-disabled-border,
      var(--meb-border-muted)
    );
    box-shadow: none;
    cursor: not-allowed;
}

/* ---- Danger ---- */

:is(button, a).meb-btn.meb-btn--danger[b-kf5cur5f5g] {
    background: var(--button-background, var(--meb-accent-danger));
    color: var(--button-foreground, var(--meb-text-inverse));
    box-shadow: var(--button-shadow);
    border-color: var(--button-border, var(--meb-border-default));
}

:is(button, a).meb-btn.meb-btn--danger:hover[b-kf5cur5f5g] {
    background: var(--meb-button-danger-hover-background);
    box-shadow: var(--meb-button-danger-hover-shadow);
}

:is(button, a).meb-btn.meb-btn--danger:active[b-kf5cur5f5g] {
    background: var(--meb-button-danger-active-background);
    box-shadow: var(--meb-button-danger-active-shadow);
    transform: translateY(2px);
}

:is(button, a).meb-btn.meb-btn--danger:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-danger-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--danger:disabled[b-kf5cur5f5g] {
    background: var(
      --button-surface-disabled,
      var(--meb-surface-disabled)
    );
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    border-color: var(
      --meb-button-danger-disabled-border,
      var(--meb-border-muted)
    );
    box-shadow: none;
    cursor: not-allowed;
}

/* ---- Ghost ---- */

:is(button, a).meb-btn.meb-btn--ghost[b-kf5cur5f5g] {
    background: var(--button-background, transparent);
    color: var(--button-foreground);
    border-color: transparent;
    box-shadow: none;
}

:is(button, a).meb-btn.meb-btn--ghost:hover[b-kf5cur5f5g] {
    background: var(--meb-button-ghost-hover-background);
    color: var(--meb-button-ghost-hover-foreground);
}

:is(button, a).meb-btn.meb-btn--ghost:active[b-kf5cur5f5g] {
    background: var(--meb-button-ghost-active-background);
}

:is(button, a).meb-btn.meb-btn--ghost:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-ghost-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--ghost:disabled[b-kf5cur5f5g] {
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    cursor: not-allowed;
}

/* ---- Link ---- */

:is(button, a).meb-btn.meb-btn--link[b-kf5cur5f5g] {
    background: var(--button-background, transparent);
    color: var(--button-foreground);
    border-color: transparent;
    box-shadow: none;
    text-decoration: underline;
    padding: var(--meb-space-stack-none);
}

:is(button, a).meb-btn.meb-btn--link:hover[b-kf5cur5f5g] {
    color: var(--meb-button-link-hover-foreground);
}

:is(button, a).meb-btn.meb-btn--link:active[b-kf5cur5f5g] {
    color: var(--meb-button-link-active-foreground);
}

:is(button, a).meb-btn.meb-btn--link:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-link-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--link:disabled[b-kf5cur5f5g] {
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    text-decoration: none;
    cursor: not-allowed;
}

/* ---- Info ---- */

:is(button, a).meb-btn.meb-btn--info[b-kf5cur5f5g] {
    background: var(--button-background, var(--meb-button-info-background));
    color: var(--button-foreground, var(--meb-button-info-foreground));
    box-shadow: var(--button-shadow, var(--meb-button-info-shadow));
    border-color: var(--button-border, var(--meb-button-info-border));
}

:is(button, a).meb-btn.meb-btn--info:hover[b-kf5cur5f5g] {
    background: var(--meb-button-info-hover-background);
    box-shadow: var(--meb-button-info-hover-shadow);
}

:is(button, a).meb-btn.meb-btn--info:active[b-kf5cur5f5g] {
    background: var(--meb-button-info-active-background);
    box-shadow: var(--meb-button-info-active-shadow);
    transform: translateY(2px);
}

:is(button, a).meb-btn.meb-btn--info:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-info-focus-shadow);
}

:is(button, a).meb-btn.meb-btn--info:disabled[b-kf5cur5f5g] {
    background: var(
      --button-surface-disabled,
      var(--meb-surface-disabled)
    );
    color: var(
      --button-text-disabled,
      var(--meb-text-muted)
    );
    border-color: var(
      --meb-button-info-disabled-border,
      var(--meb-border-muted)
    );
    box-shadow: none;
    cursor: not-allowed;
}

/* ---- Sizes ---- */

:is(button, a).meb-btn.meb-btn--small[b-kf5cur5f5g] {
    padding: var(--meb-space-stack-xs) var(--meb-space-stack-12);
    font-size: var(--meb-font-size-body-sm-desktop);
}

:is(button, a).meb-btn.meb-btn--medium[b-kf5cur5f5g] {
    padding: var(--meb-space-stack-sm) var(--meb-space-stack-md);
    font-size: var(--meb-font-size-body-desktop);
}

:is(button, a).meb-btn.meb-btn--large[b-kf5cur5f5g] {
    padding: var(--meb-space-stack-12) var(--meb-space-stack-lg);
    font-size: var(--meb-font-size-h3-desktop);
}

/* ---- Inner elements ---- */

.meb-btn__icon[b-kf5cur5f5g] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.meb-btn__label[b-kf5cur5f5g] {
    display: inline-flex;
    align-items: center;
}

/* ---- QR Variants (Neo-Brutalist / 6138) ---- */

:is(button, a).meb-btn.meb-btn--qrprimary[b-kf5cur5f5g] {
    background: var(--meb-surface-button-qrprimary);
    color: var(--meb-text-button-qrprimary);
    box-shadow: var(--meb-shadow-button-qrprimary);
    border: var(--meb-border-width-md) solid var(--meb-border-button-qrprimary);
    border-radius: var(--meb-border-radius-full);
    font-weight: var(--font-weight-bold);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
    font-size: var(--meb-font-size-body-desktop);
}

    :is(button, a).meb-btn.meb-btn--qrprimary:active[b-kf5cur5f5g] {
        transform: translate(var(--meb-space-stack-xxs), var(--meb-space-stack-xxs));
        box-shadow: var(--meb-shadow-none);
    }

:is(button, a).meb-btn.meb-btn--qrsecondary[b-kf5cur5f5g] {
    background: var(--meb-surface-button-qrsecondary);
    color: var(--meb-text-button-qrsecondary);
    box-shadow: var(--meb-shadow-button-qrsecondary);
    border: var(--meb-border-width-md) solid var(--meb-border-button-qrsecondary);
    border-radius: var(--meb-border-radius-full);
    font-weight: var(--font-weight-bold);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
    font-size: var(--meb-font-size-body-desktop);
    min-width: var(--meb-layout-qr-button-width);
}

    :is(button, a).meb-btn.meb-btn--qrsecondary:active[b-kf5cur5f5g] {
        transform: translate(var(--meb-space-stack-xxs), var(--meb-space-stack-xxs));
        box-shadow: var(--meb-shadow-none);
    }

/* ADO #11163: the QR variants had no focus rule, so keyboard focus was invisible (outline is none).
   This rule must stay AFTER both :active rules above (same specificity) so a pressed, focused button keeps its ring. */
:is(button, a).meb-btn.meb-btn--qrprimary:focus-visible[b-kf5cur5f5g],
:is(button, a).meb-btn.meb-btn--qrsecondary:focus-visible[b-kf5cur5f5g] {
    box-shadow: var(--meb-button-primary-focus-shadow);
}
/* _content/LiveEventBingo.Shared/Components/Buttons/MebPill.razor.rz.scp.css */
/* ============================================================
   MebPill — scoped styles for the selection pill component.
   Renders directly as <button> with no wrapper div, allowing
   correct use inside role="group" aria patterns.

   All colors via var(--meb-*) CSS variables. Theme changes
   propagate automatically through the CSS cascade — no JS
   re-render required.
   ============================================================ */

button.meb-pill[b-ub2y4ac8dw] {
    /* Reset browser button defaults */
    appearance: none;
    -webkit-appearance: none;
    /* outline: none here is intentional — the :focus-visible rule below adds it
       back for keyboard navigation only; mouse/touch users don't see the ring */
    outline: none;

    /* spacing tokens: block = --meb-space-stack-sm (8px), inline = --meb-space-inline-20 (20px) */
    padding: var(--meb-space-stack-sm) var(--meb-space-inline-20);
    border: var(--meb-border-width-md) solid var(--meb-border-default);
    border-radius: var(--meb-radius-pill);
    background-color: var(--meb-surface-card);
    color: var(--meb-text-default);

    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-regular);
    line-height: var(--meb-font-lineheight-tight);

    cursor: pointer;
    user-select: none;

    transition:
        background-color var(--meb-motion-fast),
        box-shadow var(--meb-motion-fast);
}

button.meb-pill:hover[b-ub2y4ac8dw] {
    background-color: var(--meb-surface-section-feature);
    box-shadow: var(--meb-shadow-sm);
}

button.meb-pill.meb-pill--active[b-ub2y4ac8dw] {
    background-color: var(--meb-accent-primary);
    color: var(--meb-text-inverse);
    box-shadow: var(--meb-shadow-surface-comic);
}

/* CT-05: visible focus ring — not color-only */
button.meb-pill:focus-visible[b-ub2y4ac8dw] {
    outline: var(--meb-focus-ring-width) solid var(--meb-accent-primary);
    outline-offset: var(--meb-focus-ring-offset);
}
/* _content/LiveEventBingo.Shared/Components/CdnImage.razor.rz.scp.css */
/* CdnImage.razor.css
   CT-04 T3-05: Scoped component styles for the CdnImage shared component.
   Compliance:
     - Only §4.1-allowed CSS properties authored directly (position, inset, overflow).
     - All visual values (background-color, border) use var(--meb-*) tokens.
     - No @media queries, no raw colors, no raw font/size/weight values.
*/

/* Explicit missing-image placeholder.
   position:absolute + inset:0 fills the parent art zone which provides fixed height
   via aspect-ratio (established by CT-04 T3-04 for all four art zones).
   The parent art zone must declare position:relative — satisfied by:
     .bl-lead-image (Desktop lead)           — position:relative ✅ (CT-04 T3-04)
     .bl-article-thumb (Desktop standard)    — position:relative ✅ (pre-existing)
     .bl-mobile-article-thumb (Mobile both)  — position:relative ✅ (CT-04 T3-05)
   Governed tokens consumed:
     surface.disabled  → --meb-surface-disabled  (#f0f0f0 default)
     border.width.sm   → --meb-border-width-sm
     border.subtle     → --meb-border-subtle      (#d6d6d6 default)  */
.cdn-image-placeholder[b-630u07yrvq] {
    position: absolute;
    inset: 0;
    background-color: var(--meb-surface-disabled);
    border: var(--meb-border-width-sm) solid var(--meb-border-subtle);
}
/* _content/LiveEventBingo.Shared/Components/CdnVideo.razor.rz.scp.css */
/* CdnVideo.razor.css
   ADO #8903 (T3): scoped styles for the CdnVideo shared primitive.
   Compliance (Bingo-Template §23/§4.1):
     - Only §4.1-allowed raw props authored directly (display, position, inset, aspect-ratio, object-fit).
     - All visual values use var(--meb-*) tokens; no raw colors / shadows / borders.
     - No @media queries.
   NOTE: the CLS-critical aspect-ratio RESERVATION for the blog lives in render-blocking
   blog-section-variants.css (the scoped bundle defers — #8593/#8632). The rules here are the
   element baseline + the placeholder; --clip-aspect (an inline token-driven value) drives the ratio. */

.cdn-video[b-gb5vok77sv] {
    display: block;
    object-fit: contain;
}

/* Missing/unresolved-video placeholder — token-colored sized box. Self-contained (a normal block that
   reserves its OWN aspect-ratio box) so it needs no position:relative on the parent — a direct consumer
   (hero / /playgame, deferred §13) that doesn't attach OnError still gets a correctly-sized box. */
.cdn-video-placeholder[b-gb5vok77sv] {
    display: block;
    width: 100%;
    aspect-ratio: var(--clip-aspect, 16 / 9);
    max-height: 60vh;
    background-color: var(--meb-surface-disabled);
    border: var(--meb-border-width-sm) solid var(--meb-border-subtle);
}

/* ── #9461: AmbientLoop custom overlay play/pause toggle ──────────────────────────────────────────────
   The frame is the positioning CONTEXT only; it is a plain block that fills the figure and takes its
   height from the <video>, so it changes neither the figure's pre-metadata layout box nor the video's
   sizing (both owned by blog-section-variants.css). CRITICAL (#9157): the toggle is position:absolute, so
   it contributes ZERO to layout — the figure's definite pre-metadata size (flex-basis / aspect-ratio box)
   is never derived from, nor disturbed by, this control. Only §4.1-allowed raw props authored directly
   (display, position, inset, transform, sizing); all colour/shadow/border/radius values are var(--meb-*)
   tokens (scrim via color-mix, mirroring components/modal.css). */
.cdn-video-frame[b-gb5vok77sv] {
    position: relative;
    display: block;
}

.cdn-video-toggle[b-gb5vok77sv] {
    /* Progressive enhancement (#9458): hidden until cdn-video.js proves the button is wired and sets
       data-cdn-toggle-active — native <video controls> is the affordance until then. */
    display: none;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    /* Fixed size — NEVER derived from the clip's intrinsic dimensions (#9157). */
    inline-size: 3rem;
    block-size: 3rem;
    padding: 0;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--meb-radius-pill);
    background: color-mix(in srgb, var(--meb-palette-neutral-black) 55%, transparent);
    color: var(--meb-text-inverse);
    box-shadow: var(--meb-shadow-md);
    cursor: pointer;
    transition: opacity 150ms ease-in-out, background 150ms ease-in-out;
}

.cdn-video-toggle[data-cdn-toggle-active='1'][b-gb5vok77sv] {
    display: inline-flex;
}

.cdn-video-toggle:hover[b-gb5vok77sv] {
    background: color-mix(in srgb, var(--meb-palette-neutral-black) 70%, transparent);
}

/* Clean decorative look: while the loop plays the button fades out; hover or keyboard focus brings it
   back, so it is always operable. Paused always shows it (the Play affordance). opacity:0 keeps the button
   focusable + in the accessibility tree (unlike display:none/visibility:hidden), so a keyboard user can
   still Tab to it and :focus-visible reveals it. */
.cdn-video-toggle[data-state='playing'][b-gb5vok77sv] {
    opacity: 0;
}
.cdn-video-frame:hover .cdn-video-toggle[b-gb5vok77sv],
.cdn-video-toggle:focus-visible[b-gb5vok77sv] {
    opacity: 1;
}
.cdn-video-toggle:focus-visible[b-gb5vok77sv] {
    outline: var(--meb-border-width-medium) solid var(--meb-text-inverse);
    outline-offset: 2px;
}

.cdn-video-toggle__icon[b-gb5vok77sv] {
    inline-size: 1.5rem;
    block-size: 1.5rem;
    display: block;
    fill: currentColor;
    pointer-events: none;
}

/* Show the glyph matching the state; hide the other. Default (paused) shows Play. */
.cdn-video-toggle .cdn-video-toggle__icon--pause[b-gb5vok77sv] {
    display: none;
}
.cdn-video-toggle[data-state='playing'] .cdn-video-toggle__icon--play[b-gb5vok77sv] {
    display: none;
}
.cdn-video-toggle[data-state='playing'] .cdn-video-toggle__icon--pause[b-gb5vok77sv] {
    display: block;
}
/* _content/LiveEventBingo.Shared/Components/GameDeletion/DeleteGameAction.razor.rz.scp.css */
/* ADO #11162: colour and type of the delete area's text only (no layout; Stack/Inline own it).
   The --ng-* custom properties are the /editgame page's tokens, inherited from .ng-root. */
.dg-hint[b-4ue5p45o6l] {
    color: var(--ng-text-muted);
    font-size: var(--ng-fs-sm-d);
}

.dg-error[b-4ue5p45o6l] {
    color: var(--ng-bad-fg);
    font-size: var(--ng-fs-sm-d);
    font-weight: var(--ng-fw-medium);
}
/* _content/LiveEventBingo.Shared/Components/HomepageFeaturedPosts.razor.rz.scp.css */
/* ===================================================================
   HomepageFeaturedPosts.razor.css (#9000)
   Typography only — all layout is owned by the Container/Stack/Grid/Inline
   primitives in the markup. All colours/sizes resolve through --meb-* tokens;
   no raw hex, no layout properties on primitive classes.
   =================================================================== */

[b-ynl1lkp3jh] .hp-from-blog__heading {
    margin: var(--meb-space-stack-none);
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-bold);
    font-size: var(--meb-font-size-h2-desktop);
    line-height: var(--meb-font-lineheight-heading);
    color: var(--meb-text-default);
}

[b-ynl1lkp3jh] .hp-from-blog__title {
    margin: var(--meb-space-stack-none);
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-bold);
    font-size: var(--meb-font-size-h3-desktop);
    line-height: var(--meb-font-lineheight-heading);
    color: var(--meb-text-default);
}

[b-ynl1lkp3jh] .hp-from-blog__excerpt {
    margin: var(--meb-space-stack-none);
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-regular);
    font-size: var(--meb-font-size-body-desktop);
    line-height: var(--meb-font-lineheight-body);
    color: var(--meb-text-default);
    /* Clamp the excerpt to a stable 3 lines so mixed-length descriptions keep
       the card grid even and reserve consistent height (no CLS). */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Mobile type ramp — matches how the shared surface handles small viewports
   (typography-only media query, not layout). */
@media (max-width: 767px) {
    [b-ynl1lkp3jh] .hp-from-blog__heading {
        font-size: var(--meb-font-size-h2-mobile);
    }

    [b-ynl1lkp3jh] .hp-from-blog__title {
        font-size: var(--meb-font-size-h3-mobile);
    }

    [b-ynl1lkp3jh] .hp-from-blog__excerpt {
        font-size: var(--meb-font-size-body-mobile);
    }
}
/* _content/LiveEventBingo.Shared/Components/Share/ShareGameSheet.razor.rz.scp.css */
/* ── ShareGameSheet.razor.css ─────────────────────────────────────────────────
 * CSS ownership: only §4.1-permitted properties (position, overflow, z-index,
 * transform, clip, aspect-ratio, object-fit, object-position, inset).
 * Typography, color, spacing, shadow, border-radius → governed tokens via MebButton / Modal.
 * ──────────────────────────────────────────────────────────────────────────── */

/* Constrains the QR SVG within its natural bounds.
   Width/height are intentionally not set here — QrCodeDisplay owns its dimensions
   via PixelsPerModule. overflow:hidden prevents any SVG bleeding outside the block. */
.share-sheet__qr-wrap[b-rxhs9fz9gn] {
    overflow: hidden;
    position: relative;
}
/* _content/LiveEventBingo.Shared/Components/UI/AvatarPicker/AvatarPicker.razor.rz.scp.css */
/* ===== AvatarPicker Component (SCOPED) ===== */
/*
 * Avatar catalog picker -- a radiogroup of real <button> options, each nesting an
 * <Avatar> disc tinted by the player's MarkColor.
 *
 * WHY SCOPED CSS (deliberate divergence from ThemePicker's wwwroot/css/components/
 * theme-picker.css): non-scoped component CSS is lazy-loaded and must be registered
 * in BOTH LiveEventBingo.Web/Components/App.razor AND LiveEventBingo/wwwroot/index.html
 * or it silently never loads -- the trap that forced ProfileSettingsExtras.razor.css
 * into ~60 lines of ::deep duplication. Scoped CSS compiles into the render-blocking
 * bundle: no registration, no ::deep, no silent miss on one of the five surfaces.
 *
 * SCOPE REACH: .ui-avatarpicker, .ui-avatarpicker-option and .ui-avatarpicker-check
 * are elements THIS component renders, so the b-xxxxx scope attribute lands on them
 * and these rules apply. The nested Avatar's chrome (disc, the svg 70% sizing rule,
 * the .selected ring) comes from NON-scoped avatar.css and is deliberately untouched
 * here -- re-declaring it in this file would compile to svg[b-xxxxx] and match
 * nothing, because MarkupString-injected children never receive the scope attribute.
 *
 * No external margin / gap (Bingo-Template §1792) -- the host section owns the
 * surrounding rhythm. The internal grid is permitted per §8.7: the component is
 * positioning its own options inside its own bounding box.
 *
 * No entrance animation (the host is a settings panel) and no prefers-reduced-motion
 * block: this file adds no motion of its own. Avatar's own transition is DS-owned and
 * already carries its own reduced-motion handling.
 */

/* Grid geometry MATCHES theme-picker.css exactly -- same column track AND same gap token --
   so the avatar grid and the colour grid align column-for-column when stacked in the Options
   tab. Both matter: auto-fill's column COUNT is a function of the gap, so a mismatched gap
   silently yields a different number of columns at the same container width (8px vs 12px is
   4 columns vs 3 at ~320px). theme-picker.css's gap was a raw `12px`; it is now
   var(--meb-space-stack-12) -- the identical value -- specifically so both files can share
   one token. Keep these two rules in lockstep. */
.ui-avatarpicker[b-xpvinye8uy] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: var(--meb-space-stack-12);
}

.ui-avatarpicker--compact[b-xpvinye8uy] {
    grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
    gap: var(--meb-space-stack-sm);
}

/* Reset native button chrome -- the nested <Avatar> supplies all visual weight.
   position: relative anchors the corner pip below. */
.ui-avatarpicker-option[b-xpvinye8uy] {
    position: relative;
    appearance: none;
    -webkit-appearance: none;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    font: inherit;
    cursor: pointer;
    border-radius: var(--meb-border-radius-full);
    outline: none;
}

.ui-avatarpicker-option:focus-visible[b-xpvinye8uy] {
    outline: var(--meb-focus-ring-width) solid var(--meb-accent-primary);
    outline-offset: var(--meb-focus-ring-offset);
}

.ui-avatarpicker-option:disabled[b-xpvinye8uy] {
    cursor: default;
    opacity: var(--meb-opacity-muted);
}

/* Selection indicator is a CORNER PIP (bottom-right), NOT a centred check.
   Deliberate: a centred glyph would obscure the very avatar being chosen. And the
   nested Avatar's .selected ring alone is too subtle here, because every disc in the
   grid shares the same MarkColor tint -- the ring is the only differentiator, so it
   needs the pip's reinforcement. */
.ui-avatarpicker-check[b-xpvinye8uy] {
    position: absolute;
    right: -2px;
    bottom: -2px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    border-radius: var(--meb-border-radius-full);
    background: var(--meb-accent-primary);
    color: var(--meb-text-inverse);
    border: var(--meb-border-width-sm) solid var(--meb-border-default);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-bold);
    line-height: var(--meb-font-lineheight-tight);
    pointer-events: none;
}
/* _content/LiveEventBingo.Shared/Components/UI/GameIcon/GameIcon.razor.rz.scp.css */
/* ADO #10783 -- GameIcon. The box is the slot: its size, --game-icon-size, is set per data-slot by
   the ONE shared slot rule in design-system-root.css (the photo preview's sample boxes use the same
   rule), because the class attribute must stay a static literal (see GameIcon.razor). Its background
   is a palette token, so Fit padding reads as intentional in both themes. No transition or animation
   anywhere: the photo paints over the SVG. */

.game-icon[b-9ifgqc0qse] {
    position: relative;
    display: block;
    inline-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    block-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    min-inline-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    min-block-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    box-sizing: border-box;
    border-radius: var(--meb-game-icon-radius);
    border: var(--meb-border-width-sm) solid var(--meb-border-default);
    background: var(--meb-surface-avatar-subtle);
    overflow: hidden;
}

.game-icon__svg[b-9ifgqc0qse],
.game-icon__photo[b-9ifgqc0qse],
.game-icon__photo img[b-9ifgqc0qse] {
    position: absolute;
    inset: 0;
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

/* The catalog SVG arrives as MarkupString, which never carries this component's scope attribute,
   so ::deep is the only way to size it (crossing the injected-markup boundary). */
.game-icon__svg[b-9ifgqc0qse]  svg {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

.game-icon__photo img[b-9ifgqc0qse] {
    object-fit: cover;
}

/* #10938: the staged local photo is a bare img (no picture wrapper), so the rule above does not match it. */
img.game-icon__photo[b-9ifgqc0qse] {
    object-fit: cover;
}

img.game-icon__photo[data-fit="fit"][b-9ifgqc0qse] {
    object-fit: contain;
}

/* Set by the inline onerror (plain DOM, works before hydration). The SVG underneath shows. */
.game-icon.game-icon--failed .game-icon__photo[b-9ifgqc0qse] {
    display: none;
}

/* Set by the inline onload (plain DOM, works before hydration). A loaded photo hides the catalog SVG,
   so a Fit photo's transparent padding (and a logo's own transparency) shows the slot background, not
   the catalog icon (design "Rendering and slot sizes"; T7b D1). A later failure wins: the SVG is the
   error fallback. */
.game-icon.game-icon--loaded:not(.game-icon--failed) .game-icon__svg[b-9ifgqc0qse] {
    visibility: hidden;
}
/* _content/LiveEventBingo.Shared/Components/UI/GameIcon/GameIconCreateUploadNotice.razor.rz.scp.css */
/* ADO #10783 (T6b2) -- the post-create photo upload's progress line and failure row, at the top of the
   create-completed popup. Layout comes from the Inline primitive (the row) and the popup's Stack (the
   spacing around the notice); this file only styles the text, with no outer margin. */
.game-icon-create-progress[b-fndm2ns721],
.game-icon-create-failed__text[b-fndm2ns721] {
    margin: 0;
    font-size: var(--meb-font-size-body-mobile);
    text-align: center;
    overflow-wrap: anywhere;
}
/* _content/LiveEventBingo.Shared/Components/UI/GameIcon/GameIconOwnerPanel.razor.rz.scp.css */
/* ADO #10783 (T3u) -- owner photo controls under the edit page's icon box. Layout (direction, gap,
   alignment, wrapping) comes from the Stack and Inline primitives in the markup; this file only styles
   the text lines. */
.game-icon-owner-panel__fit[b-8dlinmqsi0],
.game-icon-owner-panel__status[b-8dlinmqsi0],
.game-icon-owner-panel__message[b-8dlinmqsi0] {
    margin: 0;
    max-width: 22rem;
    font-size: var(--meb-font-size-body-mobile);
    text-align: center;
    overflow-wrap: anywhere;
}
/* _content/LiveEventBingo.Shared/Components/UI/GameIcon/GameIconPhotoInput.razor.rz.scp.css */
/* ADO #10783 -- the owner's photo file selection. The native "Choose File / No file chosen" control is
   the browser's, not the app's, so it is visually hidden (NOT display:none: it keeps its place in the tab
   order and the label shows its focus) and the label that wraps it is drawn as the small secondary
   MebButton. A label is the only element the browser opens the file dialog for without a script, so
   this cannot be a MebButton; the tokens are MebButton.razor.css's fallback tokens (nothing emits the
   per-instance --button-* overrides here). Hover and active are gated on the disabled modifier, and the
   focus ring follows the hidden input's :focus-visible, so a pointer click on the label shows no ring. */
.game-icon-photo-input__button[b-c5g3nx9o79] {
    position: relative; /* anchors the visually hidden input below */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: var(--meb-space-stack-xs) var(--meb-space-stack-12);
    border-radius: var(--meb-radius-pill);
    border: var(--meb-border-width-medium) solid var(--meb-border-default);
    background: var(--meb-surface-card);
    color: var(--meb-text-default);
    font-family: inherit;
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-semibold);
    line-height: var(--meb-font-lineheight-tight);
    cursor: pointer;
    user-select: none;
    transition:
        transform var(--meb-motion-fast),
        box-shadow var(--meb-motion-fast),
        background var(--meb-motion-fast);
}

.game-icon-photo-input__button:not(.game-icon-photo-input__button--disabled):hover[b-c5g3nx9o79] {
    background: var(--meb-button-secondary-hover-background);
    box-shadow: var(--meb-button-secondary-hover-shadow);
}

.game-icon-photo-input__button:not(.game-icon-photo-input__button--disabled):active[b-c5g3nx9o79] {
    background: var(--meb-button-secondary-active-background);
    box-shadow: var(--meb-button-secondary-active-shadow);
    transform: translateY(2px);
}

/* The input is the label's only focusable child, so :has(:focus-visible) is its keyboard focus. The
   :not() keeps this rule at the hover rule's specificity, so a keyboard-focused label still shows its
   ring while the pointer happens to rest on it (as MebButton's later-in-source focus rule does). */
.game-icon-photo-input__button:not(.game-icon-photo-input__button--disabled):has(:focus-visible)[b-c5g3nx9o79] {
    /* Transparent outline: forced-colors mode strips the box-shadow ring and repaints this one in a
       system colour (ADO 11309). Same for the :focus-within fallback below. */
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--meb-button-secondary-focus-shadow);
}

/* WebViews without :has() (iOS before 15.4, Android WebView before 105) drop the rule above as invalid;
   this keeps a keyboard ring there, at the cost of also showing it after a pointer click. */
@supports not selector(:has(*)) {
    .game-icon-photo-input__button:not(.game-icon-photo-input__button--disabled):focus-within[b-c5g3nx9o79] {
        outline: var(--meb-focus-ring-width) solid transparent;
        outline-offset: var(--meb-focus-ring-offset);
        box-shadow: var(--meb-button-secondary-focus-shadow);
    }
}

.game-icon-photo-input__button--disabled[b-c5g3nx9o79] {
    background: var(--meb-surface-disabled);
    color: var(--meb-text-muted);
    border-color: var(--meb-button-secondary-disabled-border, var(--meb-border-muted));
    box-shadow: none;
    cursor: not-allowed;
    transform: none;
}

/* The input is a child component's element (InputFile), so it needs ::deep. Visually hidden, still focusable. */
.game-icon-photo-input__button[b-c5g3nx9o79]  input[type="file"] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0; /* resets the user-agent border on the hidden control; no token applies to a 1px clipped box */
}
/* _content/LiveEventBingo.Shared/Components/UI/GameIcon/GameIconPhotoPreview.razor.rz.scp.css */
/* ADO #10783 -- the owner's photo preview. Layout (direction, gap, alignment, wrapping) comes from the
   Stack and Inline primitives in the markup; this file only sizes and decorates the sample boxes and
   styles the text. Each sample box is a game-icon slot: the slot's size (--game-icon-size, set per
   data-slot by the ONE shared rule in design-system-root.css), the game-icon radius and border, and the
   game-icon slot surface as background, so Fit's padding reads as intentional in both themes (design
   "Rendering and slot sizes"). object-fit stands in for the server's processing: cover = Fill
   (center-crop), contain = Fit (pad). */

.game-icon-photo-preview__box[b-9zwxvhsldj] {
    display: block;
    inline-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    block-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    min-inline-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    min-block-size: var(--game-icon-size, var(--meb-game-icon-size-list-desktop));
    box-sizing: border-box;
    border-radius: var(--meb-game-icon-radius);
    border: var(--meb-border-width-sm) solid var(--meb-border-default);
    background: var(--meb-surface-avatar-subtle);
    overflow: hidden;
}

.game-icon-photo-preview__img[b-9zwxvhsldj] {
    display: block;
    inline-size: 100%;
    block-size: 100%;
}

.game-icon-photo-preview__img--fill[b-9zwxvhsldj] {
    object-fit: cover;
}

.game-icon-photo-preview__img--fit[b-9zwxvhsldj] {
    object-fit: contain;
}

.game-icon-photo-preview__name[b-9zwxvhsldj] {
    min-inline-size: 0;
    overflow-wrap: anywhere;
    font-weight: 600;
}

.game-icon-photo-preview__fit[b-9zwxvhsldj] {
    min-inline-size: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

.game-icon-photo-preview__hint[b-9zwxvhsldj] {
    margin: 0;
    color: var(--meb-text-muted);
}
/* _content/LiveEventBingo.Shared/Components/UI/Icon/MebIcon.razor.rz.scp.css */
/* In-house icon renderer (#7820 / #8432). Telerik-free replacement for <TelerikSvgIcon>. */

.meb-svg-icon[b-owxs9riuiq] {
    display: inline-block;
    width: 1.25rem;
    height: 1.25rem;
    flex-shrink: 0;
    fill: currentColor;
    vertical-align: middle;
}

.meb-svg-icon.size-sm[b-owxs9riuiq] {
    width: 1rem;
    height: 1rem;
}

.meb-svg-icon.size-md[b-owxs9riuiq] {
    width: 1.25rem;
    height: 1.25rem;
}

.meb-svg-icon.size-lg[b-owxs9riuiq] {
    width: 1.5rem;
    height: 1.5rem;
}

.meb-svg-icon.size-xl[b-owxs9riuiq] {
    width: 2rem;
    height: 2rem;
}

.meb-svg-icon.size-xxl[b-owxs9riuiq] {
    width: 2.5rem;
    height: 2.5rem;
}
/* _content/LiveEventBingo.Shared/Components/UI/Link/Link.razor.rz.scp.css */
/* ============================================================
   Link — scoped styles for the UI Link navigation component.

   CtaPrimary / CtaSecondary variants render the anchor element
   with CTA button visual styling while preserving anchor (<a>)
   semantics for navigation. This is the correct component for
   "looks like a button, navigates like a link".

   display:inline-block is required for <a> elements to render
   block-model padding correctly without flex-layout violations.
   ============================================================ */

/* ---- CtaPrimary + CtaSecondary shared base ---- */

a.ui-link.variant-ctaprimary[b-xxn4jx2lde],
a.ui-link.variant-ctasecondary[b-xxn4jx2lde] {
    display: inline-block;
    text-align: center;

    /* spacing tokens: block = --meb-space-stack-12 (12px), inline = --meb-space-inline-lg (24px) */
    padding: var(--meb-space-stack-12) var(--meb-space-inline-lg);
    border-radius: var(--meb-radius-sm);

    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-bold);
    line-height: var(--meb-font-lineheight-tight);
    text-decoration: none;

    cursor: pointer;
    user-select: none;
    border: var(--meb-border-width-md) solid var(--meb-border-default);

    transition: box-shadow var(--meb-motion-fast);
}

/* CT-05: visible focus ring — not color-only */
a.ui-link.variant-ctaprimary:focus-visible[b-xxn4jx2lde],
a.ui-link.variant-ctasecondary:focus-visible[b-xxn4jx2lde] {
    outline: var(--meb-focus-ring-width) solid var(--meb-accent-primary);
    outline-offset: var(--meb-focus-ring-offset);
}

/* ---- CtaPrimary ---- */

a.ui-link.variant-ctaprimary[b-xxn4jx2lde] {
    background-color: var(--meb-button-primary-background);
    color: var(--meb-text-inverse);
    box-shadow: var(--meb-button-primary-shadow);
}

a.ui-link.variant-ctaprimary:hover[b-xxn4jx2lde] {
    background-color: var(--meb-button-primary-hover-background);
    box-shadow: var(--meb-button-primary-hover-shadow);
}

/* ---- CtaSecondary ---- */

a.ui-link.variant-ctasecondary[b-xxn4jx2lde] {
    background-color: var(--meb-accent-secondary);
    color: var(--meb-text-default);
    box-shadow: var(--meb-button-secondary-shadow);
}

a.ui-link.variant-ctasecondary:hover[b-xxn4jx2lde] {
    background-color: var(--meb-button-secondary-hover-background);
    box-shadow: var(--meb-button-secondary-hover-shadow);
}
/* _content/LiveEventBingo.Shared/Components/UI/Loader/MebLoader.razor.rz.scp.css */
/* In-house loading overlay (#7820 / #8434). Telerik-free replacement for TelerikLoaderContainer. */

.meb-loader-overlay[b-2d4wrvz2s4] {
    position: fixed;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    background: var(--meb-surface-overlay, rgba(255, 255, 255, 0.7));
    z-index: 1000;
}

.meb-loader-spinner[b-2d4wrvz2s4] {
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    border: 4px solid var(--meb-border-muted, rgba(0, 0, 0, 0.12));
    border-top-color: var(--meb-accent-primary);
    animation: meb-loader-spin-b-2d4wrvz2s4 0.8s linear infinite;
}

.meb-loader-text[b-2d4wrvz2s4] {
    font-weight: var(--meb-font-weight-semibold);
    color: var(--meb-text-default);
}

@keyframes meb-loader-spin-b-2d4wrvz2s4 {
    to {
        transform: rotate(360deg);
    }
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Cards/BingoProgressPill.razor.rz.scp.css */
/* ===================================================================
   BingoProgressPill.razor.css
   Lit letters sit in a filled dark pill; unlit letters trail outside.
   Token-governed; no raw hex.
   =================================================================== */

.bingo-pill[b-2zjilxs6ik] {
    display: inline-flex;
    align-items: center;
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-bold);
    font-size: var(--meb-font-size-body-desktop);
    line-height: 1;
    white-space: nowrap;
}

.bingo-pill-seg[b-2zjilxs6ik] {
    display: inline-flex;
    align-items: center;
    padding-block: var(--meb-space-stack-xs);
}

/* Lit prefix — filled dark pill, light letters. */
.bingo-pill-seg--on[b-2zjilxs6ik] {
    background: var(--meb-palette-neutral-black, var(--meb-text-default));
    color: var(--meb-palette-neutral-white, var(--meb-text-inverse));
    border-radius: var(--meb-radius-full);
    padding-inline: var(--meb-space-inline-sm);
}

/* Remaining letters — plain text after the pill. */
.bingo-pill-seg--off[b-2zjilxs6ik] {
    color: var(--meb-text-default);
    padding-inline: var(--meb-space-inline-xs);
}

/* Each letter gets a consistent advance so B/I/N/G/O line up across the
   on/off boundary. */
.bingo-pill-ltr[b-2zjilxs6ik] {
    min-width: 1.15em;
    text-align: center;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Cards/DesktopGameRow.razor.rz.scp.css */
/* ===================================================================
   DesktopGameRow.razor.css
   Visual surfaces only -- the 5-column layout is owned by the Grid
   primitive in the markup. Intrinsic micro-layout of leaf elements
   (pill / meta / share / clickable main) uses flex, like every other
   in-house control (cf. checkbox.css). Colour, shadow, border and radius
   route through tokens; intrinsic px sizing / spacing / motion on leaf
   elements follows the in-house component-CSS norm (cf. checkbox.css).
   Rows are flush, full-width members of the white list card (Figma
   293:3274): white by default, alternating blue stripe, hairline divider.
   =================================================================== */

.gl-row[b-g3owq5lqww] {
    background: var(--meb-surface-card);
    padding: 16px 32px;
    border-bottom: 1px solid var(--meb-border-subtle);
}

/* Alternating stripe (parent sets Striped on every other row). */
.gl-row--striped[b-g3owq5lqww] {
    background: var(--meb-surface-row-stripe);
}

.gl-row:last-child[b-g3owq5lqww] {
    border-bottom: none;
}

/* 1 - state-icon pill (50x50). Active = Bingo Orange + comic shadow; finalized/scheduled = white. */
.gl-state-pill[b-g3owq5lqww] {
    inline-size: 50px;
    block-size: 50px;
    border-radius: var(--meb-radius-full);
    border: 1px solid var(--meb-border-default);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--meb-text-heading-brand);
    box-shadow: var(--meb-shadow-surface-comic-sm);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
}

.gl-state-pill--active[b-g3owq5lqww] {
    background: var(--meb-palette-orange-bingo);
}

.gl-state-pill--finalized[b-g3owq5lqww],
.gl-state-pill--scheduled[b-g3owq5lqww] {
    background: var(--meb-surface-card);
}

.gl-state-pill:hover[b-g3owq5lqww] {
    transform: translate(-1px, -1px);
    box-shadow: var(--meb-shadow-surface-comic);
}

.gl-state-pill:focus-visible[b-g3owq5lqww] {
    /* Transparent, not none: forced-colors mode strips the box-shadow ring and repaints this outline in a system colour (ADO 11309). */
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

/* 2 - clickable main (avatar + name + privacy). Button reset + intrinsic flex; phrasing-only content. */
.gl-row-main[b-g3owq5lqww] {
    appearance: none;
    background: none;
    border: none;
    margin: 0;
    padding: 0;
    /* Fills its grid cell so the name below can claim the whole track; inline-flex left the button at
       content width, which truncated names that had room to spare. */
    display: flex;
    inline-size: 100%;
    min-width: 0;
    align-items: center;
    gap: var(--meb-space-inline-md, 16px);
    text-align: start;
    cursor: pointer;
    color: inherit;
    font: inherit;
}

/* The game icon slot (.gl-avatar until #10783) is now the shared GameIcon, which owns its own box. */

.gl-row-text[b-g3owq5lqww] {
    display: flex;
    flex-direction: column;
    gap: var(--meb-space-stack-xs, 4px);
    align-items: flex-start;
    /* Take the space the avatar leaves, so the name ellipsises only at the true edge of the cell. */
    flex: 1 1 auto;
    min-width: 0;
}

.gl-row-name[b-g3owq5lqww] {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-bold, 700);
    font-size: var(--meb-font-size-h3-desktop, 24px);
    line-height: 1.2;
    color: var(--meb-text-heading-brand);
    /* No fixed cap: col-2 is a flexible track (see markup), so the name uses whatever width the
       viewport allows. The old min(240px, 100%) cap existed to stop the name stretching the then-
       `auto` column and truncated names that had room to spare.
       Wrap rather than ellipsising on one line: at ~900-1000px a single 24px line only fits ~14
       characters, which cut even short names ("Baby Shower B..."). Three lines carry the whole name
       at full brand type size -- the longest name live on prod, "Ice Breaker Bingo (Shared Marking)"
       (34 chars), needs all three at that width and was still clipped at two. The clamp is a ceiling,
       not a floor: at >= ~1280px every current name still renders on a single line and row height is
       unchanged. Full name stays on title + the row's aria-label. #9494. */
    max-width: 100%;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Privacy = plain navy sublabel under the name (no badge surface), per Figma. */
.gl-row-privacy[b-g3owq5lqww] {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-desktop, 16px);
    font-weight: var(--meb-font-weight-regular, 400);
    color: var(--meb-text-heading-brand);
    line-height: 1.2;
}

/* 3 - lifecycle status text. Clip within col-3 so a long "Starts on {date}" (Scheduled) ellipsises
   inside its own track instead of overflowing rightward into the "#"/players meta (col-4). #9494.
   Mirrors .gl-row-name's clip. min-width:0 lets this grid item shrink below its nowrap min-content
   width so overflow/ellipsis engage instead of the text painting outside the cell. The track itself
   is sized by the Grid primitive in the markup -- this only governs the leaf's behaviour inside it. */
.gl-row-status[b-g3owq5lqww] {
    font-size: var(--meb-font-size-body-desktop, 16px);
    color: var(--meb-text-default);
    min-width: 0;
    /* Intrinsic micro-layout of a leaf element (cf. checkbox.css): Scheduled stacks date over time. */
    display: flex;
    flex-direction: column;
    gap: var(--meb-space-stack-xs, 4px);
    line-height: 1.2;
}

/* Each line clips independently so a long month/time still ellipsises inside the track rather than
   painting into the "#"/players meta (col-4). Stacking means neither line normally needs to. */
.gl-row-status-line[b-g3owq5lqww] {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gl-row-status-line--sub[b-g3owq5lqww] {
    color: var(--meb-text-muted);
}

/* 4 - call-count (#) + players, plain (no chip surface) with a slash divider. */
.gl-meta[b-g3owq5lqww] {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--meb-text-default);
    font-size: var(--meb-font-size-body-desktop, 16px);
    white-space: nowrap;
}

.gl-meta-sep[b-g3owq5lqww] {
    color: var(--meb-text-muted);
    font-size: var(--meb-font-size-body-desktop, 16px);
}

/* 5 - share button (blue r40). */
.gl-share[b-g3owq5lqww] {
    inline-size: 50px;
    block-size: 50px;
    border-radius: var(--meb-radius-full);
    border: 1px solid var(--meb-border-default);
    background: var(--meb-palette-blue-sky);
    color: var(--meb-text-inverse);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: var(--meb-shadow-surface-comic-sm);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
}

.gl-share:hover[b-g3owq5lqww] {
    transform: translate(-1px, -1px);
    box-shadow: var(--meb-shadow-surface-comic);
}

.gl-share:focus-visible[b-g3owq5lqww] {
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

/* Expired (Finalized) games — no hover lift on state pill or share button */
.gl-row[data-game-status="Finalized"] .gl-state-pill:hover[b-g3owq5lqww] {
    transform: none;
    box-shadow: var(--meb-shadow-surface-comic-sm);
}

.gl-row[data-game-status="Finalized"] .gl-share:hover[b-g3owq5lqww] {
    transform: none;
    box-shadow: var(--meb-shadow-surface-comic-sm);
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Cards/GameRowActionMenu.razor.rz.scp.css */
/* ADO #10785 (D15): the /gamelist row menu (Share, Report photo). The wrapper takes the trigger's grid
   cell; the panel opens to the LEFT of the trigger and UPWARD from its bottom edge. Both list cards
   clip with overflow:hidden, so a panel dropping below the last row would be cut off; above the first
   row sits the card's own search header, so opening upward is never clipped. Layout (the trigger row,
   the item column and their gaps) belongs to the Inline / Stack primitives in the markup; this file keeps
   the anchoring and the surfaces. */
.gl-rowmenu[b-d7iox04yw6] {
    position: relative;
}

.gl-rowmenu__panel[b-d7iox04yw6] {
    position: absolute;
    right: calc(100% + var(--meb-space-stack-xs));
    bottom: 0;
    /* Local stacking only: above the neighbouring rows, never competing with modal z-indexes. */
    z-index: 20;
    min-width: 10rem;
    width: max-content;
    padding: var(--meb-space-stack-xs);
    background: var(--meb-surface-card);
    border: var(--meb-border-width-sm) solid var(--meb-border-default);
    border-radius: var(--meb-border-radius-sm);
    box-shadow: var(--meb-shadow-dropdown, var(--meb-shadow-sm));
}

.gl-rowmenu__item[b-d7iox04yw6] {
    appearance: none;
    border: none;
    background: transparent;
    text-align: left;
    width: 100%;
    min-height: 2.75rem;
    padding: var(--meb-space-stack-xs) var(--meb-space-inline-sm);
    border-radius: var(--meb-border-radius-sm);
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-sm-desktop);
    color: var(--meb-text-default);
    cursor: pointer;
}

.gl-rowmenu__item:hover[b-d7iox04yw6],
.gl-rowmenu__item:focus-visible[b-d7iox04yw6] {
    background: var(--meb-surface-input-filled);
}

.gl-rowmenu__item:focus-visible[b-d7iox04yw6] {
    outline: var(--meb-focus-ring-width) solid var(--meb-accent-primary);
    outline-offset: var(--meb-focus-ring-offset);
}

.gl-rowmenu__item:disabled[b-d7iox04yw6] {
    opacity: 0.6;
    cursor: default;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Cards/MobileGameRow.razor.rz.scp.css */
/* ===================================================================
   MobileGameRow.razor.css
   Visual surfaces for the mobile /gamelist row (Figma 341:31). Column
   layout is owned by the Grid primitive; intrinsic micro-layout of leaf
   elements (pill / thumbnail / main / share) uses flex, like every other
   in-house control. Colour, shadow, border, radius and motion route
   through tokens; intrinsic px sizing/spacing follows the component-CSS
   norm (cf. checkbox.css). Leaner than the desktop row -- no status/#/users.
   =================================================================== */

/* Flush, full-width row inside the white card (no per-row radius/gap); divider between rows. */
.gl-mrow[b-of8uh2xt6l] {
    padding: 8px 12px;
    min-height: 56px;
    background: var(--meb-surface-card);
    border-bottom: 1px solid var(--meb-border-subtle);
}

/* Alternating stripe (parent sets Striped on every other row). */
.gl-mrow--striped[b-of8uh2xt6l] {
    background: var(--meb-surface-row-stripe);
}

.gl-mrow:last-child[b-of8uh2xt6l] {
    border-bottom: none;
}

/* Native button-chrome reset for the bespoke pill/share controls (iOS/Safari WKWebView primary target). */
.gl-mstate[b-of8uh2xt6l],
.gl-mshare[b-of8uh2xt6l] {
    appearance: none;
    -webkit-appearance: none;
}

/* state-icon pill (44x44). Active = Bingo Orange; finalized/scheduled = white. */
.gl-mstate[b-of8uh2xt6l] {
    inline-size: 44px;
    block-size: 44px;
    border-radius: var(--meb-radius-full);
    border: 1px solid var(--meb-border-default);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    color: var(--meb-text-heading-brand);
    box-shadow: var(--meb-shadow-surface-comic-sm);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
}

.gl-mstate--active[b-of8uh2xt6l] {
    background: var(--meb-palette-orange-bingo);
}

.gl-mstate--finalized[b-of8uh2xt6l],
.gl-mstate--scheduled[b-of8uh2xt6l] {
    background: var(--meb-surface-card);
}

.gl-mstate:focus-visible[b-of8uh2xt6l] {
    /* Transparent, not none: forced-colors mode strips the box-shadow ring and repaints this outline in a system colour (ADO 11309). */
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

/* Date badge (My Games tab) — stacked day / abbreviated month / time, replaces state pill.
   44×44 footprint; rounded rect with navy bg. */
.gl-mdate[b-of8uh2xt6l] {
    inline-size: 44px;
    block-size: 44px;
    flex: 0 0 auto;
    border-radius: var(--meb-radius-10);
    border: 1px solid var(--meb-border-default);
    background: var(--meb-palette-neutral-black);
    color: var(--meb-text-inverse);
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    cursor: pointer;
    padding: 2px 4px;
    box-shadow: var(--meb-shadow-surface-comic-sm);
    transition: transform var(--meb-motion-fast), box-shadow var(--meb-motion-fast);
    appearance: none;
    -webkit-appearance: none;
}

.gl-mdate__day[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-extrabold, 800);
    font-size: 15px;
    line-height: 1.1;
}

.gl-mdate__month[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-semibold, 600);
    font-size: 8px;
    line-height: 1.1;
    letter-spacing: 0.3px;
}

.gl-mdate__time[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-regular, 400);
    font-size: 8px;
    line-height: 1.1;
}

.gl-mdate:focus-visible[b-of8uh2xt6l] {
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

/* main (thumbnail + name + privacy sublabel) -- button reset + intrinsic flex; phrasing-only content. */
.gl-mrow-main[b-of8uh2xt6l] {
    appearance: none;
    background: none;
    border: none;
    margin: 0;
    padding: 0;
    inline-size: 100%;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    gap: var(--meb-space-inline-xs, 6px);
    text-align: start;
    cursor: pointer;
    color: inherit;
    font: inherit;
}

/* The main row-body is the largest tap target and the Tab-focusable element -- give it a focus ring too. */
.gl-mrow-main:focus-visible[b-of8uh2xt6l] {
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    border-radius: var(--meb-radius-10);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

/* The game icon slot (.gl-mthumb until #10783) is now the shared GameIcon, which owns its own box. */

.gl-mtext[b-of8uh2xt6l] {
    display: flex;
    flex-direction: column;
    gap: var(--meb-space-stack-xs, 4px);
    align-items: flex-start;
    /* Take the space the thumbnail leaves: without this the block sized to content and the name
       ellipsised at ~167px when ~214px was available. Mirrors .gl-row-text on the desktop row. */
    flex: 1 1 auto;
    min-width: 0;
}

.gl-mname[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-bold, 700);
    font-size: var(--meb-font-size-body-mobile, 15px);
    line-height: 1.2;
    color: var(--meb-text-heading-brand);
    /* Wrap to at most three lines instead of ellipsising on one -- a truncated game name is worse
       than a taller row (5 of the 8 names live on prod were being cut here). The clamp is a ceiling:
       names that fit still render on one line and the row keeps its 56px min-height. #9494. */
    max-width: 100%;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: anywhere;
}

/* Sublabel line: privacy, and (Scheduled only) the local start moment after a dot separator.
   Wraps rather than clipping so the date is never half-shown on a narrow handset. */
.gl-msub[b-of8uh2xt6l] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--meb-space-inline-xs, 6px);
    min-width: 0;
}

/* Privacy = plain navy sublabel under the name (no badge surface), per Figma 341:31. */
.gl-mbadge[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-size: 12px;
    font-weight: var(--meb-font-weight-regular, 400);
    color: var(--meb-text-heading-brand);
    line-height: 1.2;
}

/* The whole sublabel line is one typographic voice -- same size, weight and colour as the privacy
   label. A muted grey date read as a different (smaller) size next to the navy "Public" even though
   both are 12px; the dot separator alone is enough to divide them. */
.gl-msub-sep[b-of8uh2xt6l],
.gl-mstart[b-of8uh2xt6l] {
    font-family: var(--meb-font-family-primary);
    font-size: 12px;
    font-weight: var(--meb-font-weight-regular, 400);
    color: var(--meb-text-heading-brand);
    line-height: 1.2;
}

.gl-mstart[b-of8uh2xt6l] {
    white-space: nowrap;
}

/* trailing action menu (3-dot vertical ellipsis) — minimal, no background circle. */
.gl-mshare[b-of8uh2xt6l] {
    inline-size: 32px;
    block-size: 32px;
    flex: 0 0 auto;
    border-radius: var(--meb-radius-full);
    border: none;
    background: transparent;
    color: var(--meb-text-heading-brand);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background var(--meb-motion-fast);
}

.gl-mshare:focus-visible[b-of8uh2xt6l] {
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    box-shadow: var(--focus-ring-shadow, var(--meb-button-primary-focus-shadow));
}

.gl-mshare:hover[b-of8uh2xt6l] {
    background: var(--meb-surface-row-stripe);
}

/* Expired (Finalized) games — no hover background on share button */
.gl-mrow[data-game-status="Finalized"] .gl-mshare:hover[b-of8uh2xt6l] {
    background: transparent;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/GameReportStatus.razor.rz.scp.css */
/* ADO #10785 (D13): the viewer's report marks on the game header. The line itself is the Inline
   primitive (Gap xs, wrapping); this file styles the items' text only. The items are separated by a
   middle dot drawn in CSS so the accessible text stays the two phrases. */
.game-report-status__item[b-sz04jdak4e] {
    color: var(--meb-text-muted, var(--meb-text-default));
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-sm-desktop);
    line-height: var(--meb-font-lineheight-body);
}

.game-report-status__item + .game-report-status__item[b-sz04jdak4e]::before {
    content: "\00B7";
    content: "\00B7" / "";
    margin-right: var(--meb-space-inline-xs);
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/NavBar/DesktopNavBar.razor.rz.scp.css */
/* ===================================================================
   DesktopNavBar.razor.css
   All colours resolved through token vars — no raw hex.
   Font sizes / weights resolved through typography token vars.
   Migrated from inline <style> in DesktopNavBar.razor.
   =================================================================== */

/* ── Nav outer shell ────────────────────────────────────────────────────────── */
.header-container[b-0oi4yp1h6o] {
    width: 100%;
}

/* nav-inner (the <Inline> layout root) is deliberately NOT styled from here. A rule naming it was
   removed under ADO #10548: like D-02 and D-03 below it targeted an <Inline> component root, which
   carries Inline's scope attribute and not this component's, so `.nav-inner.ui-inline` compiled to a
   selector that matches nothing. It declared width: 100%, which the row has anyway -- the Inline root
   is a block-level flex container inside a <nav>, so it already fills the width; removing the rule
   changes nothing on screen, which is the point. Anything that must reach it goes through
   `.header-container ::deep` (see the 900px block) or an <Inline> parameter.
   ScopedCssTargetsPrimitiveRootGuardTests pins this at zero repo-wide. */

/* ── 1. Brand region ────────────────────────────────────────────────── */
.desktop-nav-brand[b-0oi4yp1h6o] {    /* D-01 §4.1 Primitive gap: <Inline> does not expose per-child flex-basis/grow/shrink.
       flex: 0 0 auto prevents the brand region from growing or shrinking
       within the parent <Inline> row. Approved CSS residual. */    flex: 0 0 auto;
}

.desktop-nav-logo-link[b-0oi4yp1h6o] {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
}

/* ── 2. Desktop primary navigation links ────────────────────────────── */
/* gap and align-items are owned by <Inline Gap="lg" Align="center">. */
/* D-02 REMOVED (ADO #10548). The rule that stood here declared flex: 1 1 auto and
   justify-content: center on this region and NEVER APPLIED: .desktop-nav-links is the root of an
   <Inline> CHILD component, so it carries Inline's scope attribute rather than this component's, and
   a scoped selector naming it matches nothing. Measured on production 2026-09-12 -- computed flex was
   the Inline default 0 1 auto and justify-content was flex-start, so neither declaration had ever
   been in effect. Removed rather than revived through ::deep: making it effective would introduce a
   centred, space-filling links row that has never shipped, which is a design change, not this bug's
   fix. The wrap this ticket is about is fixed by the tablet gap rule in the 900px block instead.
   The same scope miss is why .desktop-nav-link below has to anchor on .header-container ::deep. */

/* ::deep pierces the <NavLink> boundary — each NavLink renders an <a> element that does NOT
   carry this component's scope attribute, so a bare .desktop-nav-link rule never matches and
   the global a{} link color (blue, ~3.86:1 on the peach surface) wins, failing WCAG AA.
   Anchor on .header-container (a scoped plain <nav> in THIS razor) so --nav-text (dark, ~10.9:1)
   reaches the link. NOTE: cannot anchor on .desktop-nav-links — it is an <Inline> child
   component whose root does NOT carry this component's scope (unlike MobileNavBar's plain
   .mobile-nav-links div). A11y (#8596). */
.header-container[b-0oi4yp1h6o]  .desktop-nav-link {
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-medium);
    color: var(--nav-text);
    text-decoration: none;
    padding: var(--meb-space-stack-xs) var(--meb-space-stack-none);
    border-bottom: var(--meb-border-width-md) solid transparent;
    transition: color var(--meb-motion-fast), border-color var(--meb-motion-fast);
}

.header-container[b-0oi4yp1h6o]  .desktop-nav-link:hover {
    color: var(--nav-text);
    border-bottom-color: var(--nav-text);
    text-decoration: none;
}

.header-container[b-0oi4yp1h6o]  .desktop-nav-link.active {
    font-weight: var(--meb-font-weight-bold);
    color: var(--nav-text);
    border-bottom-color: var(--nav-text);
    text-decoration: none;
}

/* ── 3. Actions region ──────────────────────────────────────────────── */
/* gap is owned by <Inline Gap="sm">. */
/* Spacing between actions and avatar is owned by the token system.      */
/* D-03 REPLACED BY A PRIMITIVE PROP (ADO #10548). The rule here declared flex: 0 0 auto plus a
   margin-inline-end, and never applied, for the same scope reason as D-02 -- measured on production,
   the computed values were the Inline default 0 1 auto and a margin of 0px. The premise it was
   written under was also wrong: <Inline> DOES expose flex-shrink, as Shrinkable, so the no-shrink
   half now lives where it belongs, on the component -- see Shrinkable="false" in DesktopNavBar.razor.
   That is what stops the two button labels being squeezed onto two lines at tablet widths.
   The margin is deliberately NOT revived: it has never been on screen, so restoring it would move the
   actions region for every user while fixing a bug about the opposite problem. */

/* ── Brand logo ──────────────────────────────────────────────────────── */
.bingo-icon[b-0oi4yp1h6o] {
    width: 9em;
    height: 4em;
    /* contain (not the <img> default of fill) so the 2.11:1 lockup is not
       stretched to the 9:4 (2.25:1) box. */
    object-fit: contain;
}

.nav-menu-icon[b-0oi4yp1h6o] {
    width: 36px;
    height: 36px;
    color: var(--nav-text);
}

/* ── Avatar region (5708/5709) ────────────────────────────────────────── */
.nav-avatar-link[b-0oi4yp1h6o] {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    border-radius: var(--meb-radius-full);
    transition: opacity var(--meb-motion-fast);
}

.nav-avatar-link:hover[b-0oi4yp1h6o] {
    opacity: 0.8;
    text-decoration: none;
}

.nav-avatar-region[b-0oi4yp1h6o] {
    /* D-04 §4.1 Primitive gap: the avatar region is a compound flex row (icon + optional badge).
       display: flex / align-items / flex-shrink cannot be expressed through <Inline> parameters
       because the avatar region is itself a child of <Inline Gap="sm">, not its own primitive scope.
       margin-inline-end provides token-governed spacing to the right edge. */
    display: flex;
    align-items: center;
    flex-shrink: 0;
    margin-inline-end: var(--meb-space-inline-xs);
}

.nav-avatar-anonymous[b-0oi4yp1h6o] {
    background-color: var(--nav-avatar-anon-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.nav-avatar[b-0oi4yp1h6o] {
    width: 40px;
    height: 40px;
    border-radius: var(--meb-radius-full);
    overflow: hidden;
}

/* #10835: the user's avatar arrives as (MarkupString)AvatarMarkup, and raw markup carries no
   scope attribute, so a bare "svg"/"img" here never matched it. ::deep reaches it; ">" keeps the
   rule on the avatar's root element rather than any svg nested inside it. */
.nav-avatar[b-0oi4yp1h6o]  > svg,
.nav-avatar[b-0oi4yp1h6o]  > img {
    /* !important: avatar markup may carry its own width/height attributes or inline style;
       this keeps it filling the circle. */
    width: 100% !important;
    height: 100% !important;
}

/* ── 10-N: Avatar popover anchor + button reset ──────────────────────────
   The anchor gives the absolute-positioned NavUserPopover card its relative root.
   The button reset strips browser UA styles so the avatar circle renders identically
   to the former NavLink (no default border, background, or padding). */
.nav-avatar-popover-anchor[b-0oi4yp1h6o] {
    position: relative;
}

.nav-avatar-btn[b-0oi4yp1h6o] {
    /* Button UA reset -- visual output must match the former NavLink. */
    display: inline-flex;
    align-items: center;
    background: none;
    border: none;
    padding: 0;
    margin: 0;
    cursor: pointer;
    border-radius: var(--meb-radius-full, 9999px);
    transition: opacity var(--meb-motion-fast, 150ms);
    color: var(--nav-text);
}

.nav-avatar-btn:hover[b-0oi4yp1h6o] {
    opacity: 0.8;
}

.nav-avatar-btn:focus-visible[b-0oi4yp1h6o] {
    outline: 2px solid var(--meb-color-focus-ring, var(--meb-palette-accent-500, #6366f1));
    outline-offset: 2px;
}

/* ── Narrow-desktop reclaim (tablet portrait, ~768-900) ──────────────────
   The full nav row -- brand + links + actions + avatar -- intrinsically
   needs more than the 768px desktop minimum ("tablet = desktop"), so at the
   narrow end the avatar region overflows the right edge (~44px). Reclaim it
   by shrinking the oversized brand logo and tightening the actions->avatar
   gap. Visual-only residual sizing on non-primitive elements (the logo asset
   and the already-residual actions margin); primitive gaps stay owned by
   <Inline>. CSS media query is the sanctioned responsive lever here (same
   pattern as chat-bubble.css), not component-side width logic. */
@media (max-width: 900px) {
    .bingo-icon[b-0oi4yp1h6o] {
        width: 6.25em;
        height: 2.78em;
    }

    /* ADO #10548: at 768px the header row needs 812px of content in 721px of space, so the links and
       both button labels wrap onto a second line. Recovering 91px by tightening the two gaps -- 24px
       to 8px between links (5 gaps) and 16px to 8px between regions (3 gaps) -- brings it to 708px,
       which fits with 13px to spare. Measured on the deployed site, not estimated.
       ::deep is REQUIRED here: both targets are <Inline> component roots and do not carry this
       component's scope attribute, which is exactly why the rule that used to sit in this block had
       no effect. .header-container is a plain <nav> rendered by this component, so it does carry it. */
    .header-container[b-0oi4yp1h6o]  .nav-inner,
    .header-container[b-0oi4yp1h6o]  .desktop-nav-links {
        column-gap: var(--meb-space-inline-sm);
    }
}


/* _content/LiveEventBingo.Shared/Pages/Common/Components/NavBar/MobileNavBar.razor.rz.scp.css */
/* ===================================================================
   MobileNavBar.razor.css
   All colours resolved through token vars — no raw hex.
   Font sizes / weights resolved through typography token vars.
   Migrated from inline <style> in MobileNavBar.razor.

   ── Glass-morphism surface vars ──────────────────────────────────────
   The burger panel uses white alpha overlays derived from the amber
   panel background. These are scoped custom properties rather than
   full tokens since alpha channels cannot be stored in ThemeColors rows.
   They are isolated here so a future token migration can replace them.
   =================================================================== */

/* ── Top bar ──────────────────────────────────────────────────────────── */
/* display, flex-direction, align-items, justify-content are owned by     */
/* <Inline Justify="between" Align="center">. Width is set via w-100.     */
/* Full-bleed to the screen edges on mobile: MainLayout wraps every page
   in <Container> which insets content by --container-padding (16px). The
   app header is meant to span the full width on mobile, so widen by twice
   that inset and pull back by it. The negative margins make the margin-box
   exactly 100%, so the parent <Stack Align="center"> still centres it while
   the border-box reaches both edges -- no horizontal overflow (avoids the
   100vw + scrollbar trap). Reads the container's own inherited
   --container-padding so it tracks the inset token. */
.mobile-nav-outer[b-5wlwlsvr0q] {
    width: calc(100% + 2 * var(--container-padding, var(--meb-space-stack-md)));
    margin-inline: calc(-1 * var(--container-padding, var(--meb-space-stack-md)));
}

/* ::deep pierces the <Inline> CSS isolation boundary — Inline renders the
   mobile-top-bar div so it won't have the component scope attribute. */
.mobile-nav-outer[b-5wlwlsvr0q]  .mobile-top-bar.ui-inline {
    width: 100%;
}

.mobile-nav-outer[b-5wlwlsvr0q]  .mobile-top-bar {
    padding: var(--meb-space-stack-10) var(--meb-space-stack-md);
    background: var(--nav-surface);
}

/* APPROVED EXCEPTION: ::deep pierces the <NavLink> boundary — NavLink renders the <a> element directly.
   .mobile-nav-logo-link IS the <a> element; cannot wrap in <Inline> because NavLink IS the element.
   display:inline-flex + align-items:center are required to vertically centre the logo image inside the link.
   §4.1 approved for ::deep layout on non-primitive elements. */
.mobile-nav-outer[b-5wlwlsvr0q]  .mobile-nav-logo-link {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
}

.mobile-nav-logo[b-5wlwlsvr0q] {
    /* 52px (up from 44px): the wide MY EVENT BINGO lockup needs the extra height
       for the "MY EVENT" line to stay legible on the mobile top bar. */
    height: 52px;
    width: auto;
}

/* ── Hamburger button ─────────────────────────────────────────────────── */
/* APPROVED EXCEPTION: .mobile-hamburger-btn is a native <button> element that stacks three
   SVG lines vertically. Cannot use <Stack> inside a <button> element without introducing
   unnecessary wrapper markup. display:flex + flex-direction:column is the only viable
   rendering approach for a CSS-only hamburger icon. §4.1 approved for atomic button rendering. */
.mobile-hamburger-btn[b-5wlwlsvr0q] {
    background: none;
    border: none;
    padding: var(--meb-space-stack-6);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    gap: var(--meb-space-stack-none);
}

/* CSS-only hamburger lines — no inline SVG (5725) */
.mobile-hamburger-line[b-5wlwlsvr0q] {
    display: block;
    width: 28px;
    height: 3px;
    border-radius: var(--meb-radius-xs);
    background-color: var(--nav-text);
    margin: var(--meb-space-stack-xxs) var(--meb-space-stack-none);
}

/* ── Full-screen overlay ──────────────────────────────────────────────── */
/* APPROVED EXCEPTION: .mobile-burger-overlay is a position:fixed full-viewport scrim.
   display:flex + align-items:flex-start + justify-content:center centre the burger panel
   horizontally and pin it near the top. Cannot use a layout primitive because this is a
   fixed-position overlay layer that is outside normal document flow. §4.1 approved. */
.mobile-burger-overlay[b-5wlwlsvr0q] {
    position: fixed;
    inset: var(--meb-space-stack-none);
    z-index: 2000;
    /* FIXED: was var(--meb-shadow-md) which is a box-shadow shorthand — not a valid background value.
       Replaced with a governed semi-transparent scrim using palette.neutral.black. */
    background: color-mix(in srgb, var(--meb-palette-neutral-black) 40%, transparent);
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

/* ── Burger panel — amber brand surface ───────────────────────────────── */
/* Glass-morphism overlay opacities are scoped here; candidate for        */
/* nav.mobile.panel.* alpha tokens in a future migration.                 */
.mobile-burger-panel[b-5wlwlsvr0q] {
    /* ── Scoped glass-morphism surface vars ──────────────────────────────────────
       Migrated from raw rgba() to color-mix() derivations (approved exception:
       "Glass-morphism scoped vars with color-mix()" in compliance pack v1).
       Alpha channels cannot be stored in ThemeColors rows — these scoped vars
       are the approved pattern until a nav.mobile.panel.* alpha token family
       is added to the token system. ── */
    --panel-row-bg:          color-mix(in srgb, var(--meb-palette-neutral-white) 30%, transparent);
    --panel-row-hover-bg:    color-mix(in srgb, var(--meb-palette-neutral-white) 45%, transparent);
    --panel-avatar-bg:       color-mix(in srgb, var(--meb-palette-neutral-white) 50%, transparent);
    --panel-avatar-border:   color-mix(in srgb, var(--meb-palette-neutral-white) 70%, transparent);
    --panel-divider:         color-mix(in srgb, var(--meb-palette-neutral-white) 35%, transparent);
    --panel-dot-color:       color-mix(in srgb, var(--meb-palette-neutral-black) 12%, transparent);
    /* var(--meb-text-inverse) governs the panel auth button text; previously raw "white" */
    --panel-auth-text:       var(--meb-text-inverse);
    /* --panel-overlay removed: was unused. The overlay backdrop color is var(--meb-shadow-md) on .mobile-burger-overlay */

    /* Height budget handed to the panel's <Stack MaxHeight="var(--burger-panel-max-height)">.
       This declares a VALUE, not a layout property: max-height and overflow stay owned by the
       Stack primitive (MaxHeight + Scrollable="vertical"), so no page-local rule targets a
       primitive's layout. It lives here, in the same block as the offsets it must stay in sync
       with, rather than as a five-term calc() inline in the markup.

       Subtracted, in source order:
         margin-block-start   -- the panel's own inset from the top of the fixed overlay
         padding-block-start  -- panel padding, outside the Stack's scrollport
         padding-block-end    -- ditto, at the bottom
         a second space.stack.md -- bottom breathing gap, mirroring the top inset
         --consent-banner-height -- what the cookie-consent banner currently occupies at the
             bottom edge. Published (and cleared) by wwwroot/js/consent-banner.js, which owns
             that fixed bottom bar; it already coordinates the same edge with the mobile sticky
             CTA via body[data-consent-pending] (#9019). Falls back to 0px when no banner is up
             and on the MAUI host, which does not load consent-banner.js at all. */
    --burger-panel-max-height: calc(
        100dvh
        - var(--meb-space-stack-md)
        - var(--meb-space-stack-lg)
        - var(--meb-space-stack-xl)
        - var(--meb-space-stack-md)
        - var(--consent-banner-height, 0px));

    /* Amber panel surface — token from AddMobileNavPanelTokens migration */
    background: var(--nav-mobile-panel-bg);
    /* Halftone dot pattern at the bottom — purely decorative */
    background-image:
        linear-gradient(to bottom, var(--nav-mobile-panel-bg) 60%, transparent 100%),
        radial-gradient(circle, var(--panel-dot-color) 1.5px, transparent 1.5px);
    background-size: 100% 100%, 16px 16px;
    background-position: top, bottom;

    width: 90vw;
    max-width: 400px;
    border-radius: var(--meb-radius-panel);
    /* Column layout is owned by <Stack Gap="2xs"> inside the panel markup. */
    /* APPROVED EXCEPTION: margin-block-start positions the panel away from the top of the position:fixed
       overlay. Cannot be owned by <Stack> because the overlay uses position:fixed and the panel is its
       direct content — there is no primitive-owned parent chain here. §4.1 approved. */
    margin-block-start: var(--meb-space-stack-md);
    padding-block-start: var(--meb-space-stack-lg);   /* space.stack.lg = 24px ≈ 1.5em */
    padding-inline: var(--meb-space-inline-lg);         /* space.inline.lg = 24px ≈ 1.5em */
    padding-block-end: var(--meb-space-stack-xl);       /* space.stack.xl = 32px ≈ 2em */
    box-shadow: var(--meb-shadow-lg);
}

/* ── User profile row ─────────────────────────────────────────────────── */
/* APPROVED EXCEPTION: ::deep pierces the <NavLink> boundary — NavLink renders as <a>.
   .mobile-profile-row IS the <a> element, so display:flex, gap, and margin-block-end
   must be applied here via ::deep. Cannot wrap in <Inline> because NavLink IS the row.
   §4.1 approved for ::deep layout on non-primitive elements. */
.mobile-burger-panel[b-5wlwlsvr0q]  .mobile-profile-row {
    display: flex;
    align-items: center;
    gap: var(--meb-space-stack-14);
    padding: var(--meb-space-stack-10) var(--meb-space-stack-12);
    border-radius: var(--meb-radius-pill);
    background: var(--panel-row-bg);
    text-decoration: none;
    color: var(--nav-mobile-panel-text);
    transition: var(--meb-motion-fast);
    margin-block-end: var(--meb-space-stack-sm); /* space.stack.sm (8px) below profile row */
}

.mobile-burger-panel[b-5wlwlsvr0q]  .mobile-profile-row:hover {
    background: var(--panel-row-hover-bg);
    text-decoration: none;
}

/* APPROVED EXCEPTION: .mobile-profile-avatar is an atomic circular avatar element.
   display:flex + align-items:center + justify-content:center centre the icon/image inside
   the fixed-size circle. Cannot use <Inline> because this is a 42×42px fixed element
   rendered as a direct child of the ::deep NavLink row — no primitive wrapper is viable
   without introducing spurious DOM nodes. §4.1 approved for atomic avatar rendering. */
.mobile-profile-avatar[b-5wlwlsvr0q] {
    width: 42px;
    height: 42px;
    border-radius: var(--meb-radius-full);
    overflow: hidden;
    background: var(--panel-avatar-bg);
    border: var(--meb-border-width-md) solid var(--panel-avatar-border);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: var(--meb-space-stack-none);
}

/* #10835: the user's avatar arrives as (MarkupString)AvatarMarkup, and raw markup carries no
   scope attribute, so a bare "svg"/"img" here never matched it. ::deep from the circle does;
   ">" keeps the rule on the avatar's root element rather than any svg nested inside it. */
.mobile-profile-avatar[b-5wlwlsvr0q]  > svg,
.mobile-profile-avatar[b-5wlwlsvr0q]  > img {
    /* !important: avatar markup may carry its own width/height attributes or inline style;
       this keeps it filling the circle. */
    width: 100% !important;
    height: 100% !important;
}

/* #10835: the fallback icon is a MebIcon <svg>, rendered by that component, so it lacks this
   component's scope and a bare .mobile-profile-avatar-icon never matched (it drew at MebIcon's
   20px default). ::deep from the avatar circle reaches it. */
.mobile-profile-avatar[b-5wlwlsvr0q]  .mobile-profile-avatar-icon {
    /* !important required: the avatar "svg" rule above sets 100% !important, and this more
       specific rule must win for the fallback icon. */
    width: 26px !important;
    height: 26px !important;
    color: var(--nav-mobile-panel-text);
}

.mobile-profile-name[b-5wlwlsvr0q] {
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-bold);
    color: var(--nav-mobile-panel-text);
    flex: 1 1 auto;
}

/* #10835: the chevron is a MebIcon <svg>, rendered by that component, so ::deep is needed
   to reach it. The row's align-items:center centers it; fill follows color. */
.mobile-burger-panel[b-5wlwlsvr0q]  .mobile-profile-chevron {
    color: var(--nav-mobile-panel-text);
    opacity: 0.7;
}

/* ── Divider ──────────────────────────────────────────────────────────── */
.mobile-nav-divider[b-5wlwlsvr0q] {
    height: 1px;
    background: var(--panel-divider);
    margin-block: var(--meb-space-stack-10); /* space.stack.10 = 10px */
}

/* ── Navigation links ─────────────────────────────────────────────────── */
/* Column layout is owned by <Stack Gap="2xs"> inside <nav> in the markup.
   space.stack.2xs = 2px (AddRadiusAndSpaceExtTokens migration). */
.mobile-nav-links[b-5wlwlsvr0q] {
    padding-block: var(--meb-space-stack-sm); /* space.stack.sm (8px) */
}

/* ::deep pierces the <NavLink> boundary — each NavLink renders an <a> element. */
.mobile-nav-links[b-5wlwlsvr0q]  .mobile-nav-link {
    display: block;
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-regular);
    color: var(--nav-mobile-panel-text);
    text-decoration: none;
    padding: var(--meb-space-stack-10) var(--meb-space-stack-20);
    border-radius: var(--meb-radius-md);
    text-align: center;
    width: 100%;
    transition: var(--meb-motion-fast);
}

.mobile-nav-links[b-5wlwlsvr0q]  .mobile-nav-link:hover {
    background: var(--panel-row-bg);
    text-decoration: none;
    color: var(--nav-mobile-panel-text);
}

/* Active = current page gets bold weight */
.mobile-nav-links[b-5wlwlsvr0q]  .mobile-nav-link.active {
    font-weight: var(--meb-font-weight-bold);
    color: var(--nav-mobile-panel-text);
}

/* ── Login / Logout pill buttons ──────────────────────────────────────── */
.mobile-auth-btn[b-5wlwlsvr0q] {
    display: block;
    width: 100%;
    padding: var(--meb-space-stack-14) var(--meb-space-stack-lg);
    border: none;
    border-radius: var(--meb-radius-pill);
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-bold);
    letter-spacing: var(--meb-font-letter-spacing-tight);
    cursor: pointer;
    /* Vertical spacing owned by parent <Stack Gap="2xs"> + divider margins; no margin needed here. */
    transition: var(--meb-motion-fast);
    box-shadow: var(--meb-shadow-sm);
    color: var(--panel-auth-text);
}

.mobile-auth-btn:hover[b-5wlwlsvr0q] {
    opacity: 0.9;
    transform: translateY(-1px);
}

.mobile-auth-btn:active[b-5wlwlsvr0q] {
    opacity: 1;
    transform: translateY(0);
}

/* Blue — Log In */
.mobile-login-btn[b-5wlwlsvr0q] {
    background: var(--nav-mobile-login-bg);
}

/* Coral/red — Log Out */
.mobile-logout-btn[b-5wlwlsvr0q] {
    background: var(--nav-mobile-logout-bg);
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/NavBar/NavUserPopover.razor.rz.scp.css */
/* ===================================================================
   NavUserPopover.razor.css
   #7801 10-N -- Header user-menu popover (Figma 293:9788 / 293:9799)
   All colours resolved through token vars -- no raw hex.
   =================================================================== */

/* ── Backdrop (click-outside close) ───────────────────────────────── */
.nav-user-popover-backdrop[b-en0ork16v6] {
    position: fixed;
    inset: 0;
    z-index: 200;
    background: transparent;
}

/* ── Card ─────────────────────────────────────────────────────────── */
.nav-user-popover-card[b-en0ork16v6] {
    position: absolute;
    top: calc(100% + var(--meb-space-stack-xs, 6px));
    right: 0;
    z-index: 201;
    min-width: 220px;
    background: var(--meb-surface-card, #ffffff);
    border-radius: var(--meb-border-radius-md, 16px);
    box-shadow: var(--meb-shadow-lg, 0 10px 24px rgba(0,0,0,0.22));
    padding: var(--meb-space-stack-sm, 12px) var(--meb-space-inline-sm, 12px);
    display: flex;
    flex-direction: column;
    gap: var(--meb-space-stack-xs, 8px);
}

/* ── Profile row (NavLink) ────────────────────────────────────────── */
/* #10835: NavLink renders the <a> itself, so the <a> lacks this component's scope attribute
   and a bare .nav-user-popover-profile-row selector never matched: the row rendered as a
   block-level underlined link with the avatar stacked above the name. ::deep from the card
   (which does carry the scope) reaches it, the same way MobileNavBar.razor.css styles its
   NavLink rows.
   Follows the existing APPROVED EXCEPTION on .mobile-profile-row in MobileNavBar.razor.css (same
   rationale, same §4.1 ruling): NavLink IS the row element, so display:flex, align-items and gap
   are applied here via ::deep; it cannot be wrapped in <Inline> because NavLink is the row. */
.nav-user-popover-card[b-en0ork16v6]  .nav-user-popover-profile-row {
    display: flex;
    align-items: center;
    gap: var(--meb-space-inline-xs, 8px);
    text-decoration: none;
    padding: var(--meb-space-stack-xs, 8px) var(--meb-space-inline-xs, 8px);
    border-radius: var(--meb-border-radius-sm, 8px);
    transition: background var(--meb-motion-fast, 150ms);
}

.nav-user-popover-card[b-en0ork16v6]  .nav-user-popover-profile-row:hover {
    background: var(--meb-surface-hover, rgba(0,0,0,0.05));
    text-decoration: none;
}

/* ── Avatar circle ────────────────────────────────────────────────── */
.nav-user-popover-avatar[b-en0ork16v6] {
    width: 36px;
    height: 36px;
    border-radius: var(--meb-radius-full, 9999px);
    overflow: hidden;
    flex-shrink: 0;
    background: var(--nav-avatar-anon-bg, var(--meb-palette-neutral-200, #e5e7eb));
    display: flex;
    align-items: center;
    justify-content: center;
}

/* #10835: the user's avatar arrives as (MarkupString)AvatarMarkup, and raw markup carries no
   scope attribute, so a bare "svg"/"img" here never matched it. ::deep from the circle does;
   ">" keeps the rule on the avatar's root element rather than any svg nested inside it. */
.nav-user-popover-avatar[b-en0ork16v6]  > svg,
.nav-user-popover-avatar[b-en0ork16v6]  > img {
    /* !important: avatar markup may carry its own width/height attributes or inline style;
       this keeps it filling the circle. */
    width: 100% !important;
    height: 100% !important;
}

.nav-user-popover-anon-icon[b-en0ork16v6] {
    width: 22px;
    height: 22px;
    color: var(--meb-palette-neutral-500, #6b7280);
}

/* ── Display name ─────────────────────────────────────────────────── */
.nav-user-popover-name[b-en0ork16v6] {
    flex: 1 1 auto;
    font-size: var(--meb-font-size-body-sm-desktop, 0.875rem);
    font-weight: var(--meb-font-weight-medium, 500);
    color: var(--meb-color-text-primary, #111827);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Chevron ──────────────────────────────────────────────────────── */
/* #10835: a MebIcon <svg> (size sm), rendered by that component, so ::deep reaches it.
   The row's align-items:center centers it; fill follows color. */
.nav-user-popover-card[b-en0ork16v6]  .nav-user-popover-chevron {
    color: var(--meb-color-text-secondary, #6b7280);
}

/* ── Actions list ─────────────────────────────────────────────────── */
.nav-user-popover-actions[b-en0ork16v6] {
    display: flex;
    flex-direction: column;
    gap: var(--meb-space-stack-xs, 8px);
    padding-top: var(--meb-space-stack-xs, 6px);
    border-top: 1px solid var(--meb-border-color-subtle, var(--meb-palette-neutral-100, #f3f4f6));
}

/* ── Individual action button (width override) ────────────────────── */
.nav-user-popover-action-btn[b-en0ork16v6] {
    width: 100%;
    justify-content: center;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/NavBar/StaticNavBar.razor.rz.scp.css */
/* StaticNavBar first paint mirrors the real nav so the prerender-to-interactive swap does not jump
   (ADO 10960): bar height 64 desktop / 72 mobile, same logo box, same padding. No hex; px geometry
   mirrors MobileNavBar/DesktopNavBar. Layout (row, gap, wrap, justify) comes from the Inline primitive;
   this file keeps visuals and the menu clip/reveal on a plain wrapper div. Desktop vs mobile follows
   the same html[data-meb-screen-mode] hint that MainLayout's startup switcher uses; mobile is the
   default, matching that switcher. */
/* Mobile: full-bleed bar like MobileNavBar (.mobile-nav-outer + .mobile-top-bar). */
.static-navigation[b-tv291n7s80] {
    /* The width calc already includes the padding; Bootstrap's global border-box reset loads async (App.razor preload/onload), so do not rely on it at first paint. */
    box-sizing: border-box;
    width: calc(100% + 2 * var(--container-padding, var(--meb-space-stack-md)));
    margin-inline: calc(-1 * var(--container-padding, var(--meb-space-stack-md)));
    position: relative;
    padding: var(--meb-space-stack-10) var(--meb-space-stack-md);
    background: var(--nav-surface);
}

.static-navigation-logo-link[b-tv291n7s80] {
    display: inline-block;
    text-decoration: none;
}

.static-navigation-logo[b-tv291n7s80] {
    display: block;
    height: 52px;
    width: auto;
}

/* No-JS toggle: visually hidden but focusable (keyboard, screen reader). */
.static-navigation-toggle[b-tv291n7s80],
.static-navigation-visually-hidden[b-tv291n7s80] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
    opacity: 0;
}

/* Hamburger label: lines stack as blocks; the first/last line's outer margin is folded into the padding so the
   height matches MobileNavBar's flex-column button. */
.static-navigation-hamburger[b-tv291n7s80] {
    display: block;
    cursor: pointer;
    padding: calc(var(--meb-space-stack-6) + var(--meb-space-stack-xxs)) var(--meb-space-stack-6);
}

.static-navigation-toggle:focus-visible ~ .static-navigation-hamburger[b-tv291n7s80] {
    outline: var(--meb-border-width-md) solid var(--nav-text);
    outline-offset: var(--meb-space-stack-xxs);
}

.static-navigation-hamburger-line[b-tv291n7s80] {
    display: block;
    width: 28px;
    height: 3px;
    border-radius: var(--meb-radius-xs);
    background-color: var(--nav-text);
    margin: var(--meb-space-stack-none);
}

.static-navigation-hamburger-line + .static-navigation-hamburger-line[b-tv291n7s80] {
    margin-block-start: calc(2 * var(--meb-space-stack-xxs));
}

/* Mobile: links and buttons are visually collapsed but stay real, focusable links. The toggle
   (checkbox, works without JS) or keyboard focus reveals them. */
.static-navigation-menu[b-tv291n7s80] {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.static-navigation-toggle:checked ~ .static-navigation-menu[b-tv291n7s80],
.static-navigation-menu:focus-within[b-tv291n7s80] {
    inset-inline: 0;
    inset-block-start: 100%;
    inline-size: auto;
    block-size: auto;
    clip-path: none;
    overflow: visible;
    white-space: normal;
    z-index: 2;
    padding: var(--meb-space-stack-10) var(--meb-space-stack-md);
    background: var(--nav-surface);
}

.static-navigation-link[b-tv291n7s80] {
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-medium);
    color: var(--nav-text);
    text-decoration: none;
    padding: var(--meb-space-stack-xs) var(--meb-space-stack-none);
    border-bottom: var(--meb-border-width-md) solid transparent;
}

.static-navigation-link:hover[b-tv291n7s80],
.static-navigation-link:focus-visible[b-tv291n7s80] {
    border-bottom-color: var(--nav-text);
    text-decoration: none;
}

/* Desktop: the header row of DesktopNavBar (logo box 9em x 4em = 64px tall, no surface, no bleed). */
html[data-meb-screen-mode="desktop"] .static-navigation[b-tv291n7s80] {
    width: 100%;
    margin-inline: 0;
    padding: 0;
    background: none;
}

html[data-meb-screen-mode="desktop"] .static-navigation-logo[b-tv291n7s80] {
    width: 9em;
    height: 4em;
    object-fit: contain;
}

html[data-meb-screen-mode="desktop"] .static-navigation-hamburger[b-tv291n7s80],
html[data-meb-screen-mode="desktop"] .static-navigation-toggle[b-tv291n7s80] {
    display: none;
}

html[data-meb-screen-mode="desktop"] .static-navigation-menu[b-tv291n7s80],
html[data-meb-screen-mode="desktop"] .static-navigation-menu:focus-within[b-tv291n7s80],
html[data-meb-screen-mode="desktop"] .static-navigation-toggle:checked ~ .static-navigation-menu[b-tv291n7s80] {
    position: static;
    /* §4.1 Primitive gap: Inline does not expose per-child grow. Approved CSS residual. */
    flex: 1 1 auto;
    inline-size: auto;
    block-size: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    padding: 0;
    background: none;
}

/* Visual residual sizing, mirrors DesktopNavBar.razor.css 900px block. */
@media (max-width: 900px) {
    html[data-meb-screen-mode="desktop"] .static-navigation-logo[b-tv291n7s80] {
        width: 6.25em;
        height: 2.78em;
    }
}

/* Tablet parity (ADO 10994 owner decision): the real nav never shows My Games, Settings or Log In inline (they live
   in the avatar popover). At 768-1100px the static row hides those three links so it stays one line at the real
   nav's height; above 1100px the full 9-link row fits on one line at the same height. Only on routes that hydrate:
   static-only routes (data-static-only-route) never swap to the real nav, so they keep all 9 links and may wrap. */
@media (min-width: 768px) and (max-width: 1100px) {
    html[data-meb-screen-mode="desktop"] .static-navigation:not([data-static-only-route]) .static-navigation-link--account[b-tv291n7s80] {
        display: none;
    }
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Popups/BingoPopup.razor.rz.scp.css */
/* WonByMe winner celebration — on-system replacement for the old raster
   wordmark. Layout-free: the SlideInPanel + page own placement; this styles
   only the celebratory wordmark and its idle heartbeat. Tokens only. */

.bingo-win[b-m5psc36y2k] {
    text-align: center;
    pointer-events: none;
}

/* Self-win only: a dim scrim band behind the wordmark so it pops and the live
   board recedes for the 10s celebration. Feathered top/bottom edges keep it
   from reading as a hard rectangle; pointer-events stay off so the game still
   continues underneath (D33 non-blocking). The dark band also lifts contrast
   for pale mark colors (D22). The calmer other-player variant gets no scrim. */
.bingo-win--self[b-m5psc36y2k] {
    padding-block: var(--meb-space-stack-xl, 2rem);
    background: linear-gradient(
        to bottom,
        transparent 0%,
        var(--meb-surface-overlay) 22%,
        var(--meb-surface-overlay) 78%,
        transparent 100%);
}

/* Entrance duration for the shared ui-anim bounce-in. The animation-name +
   overshoot easing + prefers-reduced-motion handling all come from the global
   ui-anim system (animation.css); we only supply the duration token. */
.bingo-win-word[b-m5psc36y2k] {
    animation-duration: var(--meb-motion-winpop, 480ms);
}

.bingo-win-headline[b-m5psc36y2k] {
    display: inline-block;
    font-family: var(--meb-font-family-primary);
    font-size: clamp(2.5rem, 12vw, 7rem);
    font-weight: var(--meb-font-weight-bold);
    line-height: 1.05;
    text-transform: uppercase;
    /* Winner's mark color; the shadow halo keeps pale mark colors legible on
       any surface (WCAG AA guardrail, D22). */
    color: var(--bingo-win-color, var(--meb-text-default));
    text-shadow: var(--meb-shadow-win);
    /* Idle heartbeat, starting after the entrance pop settles. */
    animation: bingoWinPulse-b-m5psc36y2k var(--meb-motion-winpulse, 1800ms) ease-in-out var(--meb-motion-winpop, 480ms) infinite;
}

/* Other-player win is intentionally calmer — neutral color, no pulse. The
   full dopamine treatment is reserved for the viewer's own win (#7822). */
.bingo-win--other .bingo-win-headline[b-m5psc36y2k] {
    font-size: clamp(1.5rem, 7vw, 3.5rem);
    color: var(--meb-text-default);
    animation: none;
}

@keyframes bingoWinPulse-b-m5psc36y2k {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.06); }
}

@media (prefers-reduced-motion: reduce) {
    .bingo-win-headline[b-m5psc36y2k] {
        animation: none;
    }
}
/* _content/LiveEventBingo.Shared/Pages/Common/Components/Popups/QRPopup.razor.rz.scp.css */
/* QRPopup.razor.css */

/* §4.1 Art Placement: The scanner frame is a functional media region. 
   Layout is governed by Card and Stack primitives in the Razor file. */
.qr-frame[b-wx8c0qzqs6],
.qr-scanner-content[b-wx8c0qzqs6],
.qr-scanner-wrapper[b-wx8c0qzqs6],
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader-div,
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader-div>div,
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader {
    /* Reset all backgrounds to transparent to remove faint gray boxes (6158) */
    background: transparent !important;
    background-color: transparent !important;
    box-shadow: none !important;
    border: none !important;
}

.qr-frame[b-wx8c0qzqs6] {
    width: 100%;
    max-width: var(--meb-layout-qr-button-width);
    margin: 0 auto;
    position: relative;
    overflow: visible !important;
}

/* Fill the frame with scanner content */
.qr-scanner-content[b-wx8c0qzqs6] {
    position: relative;
    width: 100%;
    height: 100%;
}

.qr-scanner-wrapper[b-wx8c0qzqs6] {
    width: 100%;
    height: 100%;
    position: relative;
    overflow: visible;
}

/* Force library containers to fill the frame */
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader-div,
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader-div>div {
    display: block !important;
    height: 100% !important;
    width: 100% !important;
}

/* APPROVED EXCEPTION: Third-party barcode library (.barcode-reader) renders its own DOM tree
   without Blazor primitive wrappers. display:flex + flex-direction:column are required to
   stack the camera-select panel above the video frame. No Blazor primitive can own layout
   inside a library-rendered subtree. §4.1 + §11 approved exception for library overrides.
   Refs: T6158. */
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader {
    display: flex !important;
    flex-direction: column !important;
    height: 100% !important;
    width: 100% !important;
    position: relative !important;
}

/* Position the selection panel OUTSIDE the bordered video frame (6158) */
.qr-scanner-wrapper[b-wx8c0qzqs6]  [data-action="sourceSelectPanel"] {
    flex: 0 0 auto !important;
    position: relative !important;
    width: 100% !important;
    padding: var(--meb-space-stack-none) var(--meb-space-stack-none) var(--meb-space-stack-sm) 0 !important;
    /* Space between selector and border */
    background-color: transparent !important;
    border: none !important;
    z-index: 10 !important;
}

/* Hide the selection panel if there's only one camera (modern CSS :has() solution) (6158) */
.qr-scanner-wrapper[b-wx8c0qzqs6]  [data-action="sourceSelectPanel"]:not(:has(.source-select option:nth-child(2))) {
    display: none !important;
}

/* Style the actual dropdown select element */
    .qr-scanner-wrapper[b-wx8c0qzqs6]  .source-select {
        display: block !important;
        height: var(--meb-layout-qr-scanner-select-height) !important;
        width: 100% !important;
        background-color: var(--meb-palette-neutral-white) !important;
        border: var(--meb-border-width-sm) solid var(--meb-border-accordion) !important;
        border-radius: var(--meb-border-radius-sm) !important;
        color: var(--meb-text-default) !important;
        font-size: var(--meb-font-size-body-sm-desktop) !important;
        padding: var(--meb-space-stack-none) var(--meb-space-stack-sm) !important;
        box-shadow: var(--meb-shadow-sm);
        cursor: pointer;
        text-align: center;
    }

/* #11388: reserves the scanner square from the first render (same box as the video frame below) so the modal does not jump on mount. */
.qr-scanner-placeholder[b-wx8c0qzqs6] {
    width: 100%;
    aspect-ratio: 1 / 1;
    border: var(--meb-border-width-md) solid var(--meb-surface-qr-frame-border);
    border-radius: var(--meb-border-radius-xxl);
    background-color: var(--meb-palette-neutral-black);
}

/* Video container div — This is now the visual "frame" with the border and radius (6158) */
.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader>div:not([data-action="sourceSelectPanel"]) {
    flex: 1 1 auto !important;
    position: relative !important;
    width: 100% !important;
    aspect-ratio: 1 / 1 !important;
    border: var(--meb-border-width-md) solid var(--meb-surface-qr-frame-border) !important;
    border-radius: var(--meb-border-radius-xxl) !important;
    overflow: hidden !important;
    background-color: var(--meb-palette-neutral-black) !important;
}

/* Video element centered inside its flex container */
.qr-scanner-wrapper[b-wx8c0qzqs6]  .video,
.qr-scanner-wrapper[b-wx8c0qzqs6]  canvas {
    position: absolute !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    width: calc(100% + var(--meb-space-inline-10)) !important;
    height: calc(100% + var(--meb-space-stack-12)) !important;
    object-fit: cover !important;
    z-index: 1 !important;
}

/* §4.2 Visual Feedback: Add a premium scanning line animation inside the video frame (6158) */
@keyframes qr-scan-line-b-wx8c0qzqs6 {
    0% {
        transform: translateY(-100%);
        opacity: var(--meb-space-stack-none);
    }

    10% {
        opacity: 1;
    }

    90% {
        opacity: 1;
    }

    100% {
        transform: translateY(0);
        opacity: var(--meb-space-stack-none);
    }
}

.qr-scanner-wrapper[b-wx8c0qzqs6]  .barcode-reader>div:not([data-action="sourceSelectPanel"])::after {
    content: "";
    position: absolute;
    left: var(--meb-space-stack-none);
    right: var(--meb-space-stack-none);
    top: var(--meb-space-stack-none);
    height: 100%;
    /* #11388: the line is a no-repeat band at the bottom of a full-height box that slides with transform only,
       so the animation never triggers layout (the old top animation logged layout shifts every frame). */
    background: linear-gradient(90deg,
            transparent 0%,
            var(--meb-surface-qr-frame-border) 50%,
            transparent 100%) no-repeat bottom / 100% var(--meb-border-width-lg);
    filter: drop-shadow(var(--meb-space-stack-none) var(--meb-space-stack-none) var(--meb-space-stack-12) var(--meb-surface-qr-frame-border));
    z-index: 2;
    animation: qr-scan-line-b-wx8c0qzqs6 2.5s ease-in-out infinite;
    pointer-events: none;
}

.qr-instruction[b-wx8c0qzqs6] {
    max-width: var(--meb-layout-qr-modal-width);
    font-size: var(--meb-font-size-body-desktop);
    /* Slightly larger for better readability */
    line-height: var(--meb-font-lineheight-body);
    color: var(--meb-text-default);
    font-weight: var(--meb-font-weight-medium);
}

.meb-body-sm.qr-instruction[b-wx8c0qzqs6] {
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-medium);
}

.qr-validation-error[b-wx8c0qzqs6] {
    background-color: var(--meb-palette-error-subtle);
    border: var(--meb-border-width-sm) solid var(--meb-palette-error-primary);
    border-radius: var(--meb-border-radius-md);
    padding: var(--meb-space-stack-sm) var(--meb-space-stack-md);
    color: var(--meb-palette-error-primary);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-medium);
    text-align: center;
    width: 100%;
}

.qr-validation-success[b-wx8c0qzqs6] {
    background-color: var(--meb-surface-success);
    border: var(--meb-border-width-sm) solid var(--meb-border-success);
    border-radius: var(--meb-border-radius-md);
    padding: var(--meb-space-stack-sm) var(--meb-space-stack-md);
    color: var(--meb-text-success);
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-medium);
    text-align: center;
    width: 100%;
}


.qr-upload-label[b-wx8c0qzqs6] {
    width: 100%;
    cursor: pointer;
}

.qr-upload-label[b-wx8c0qzqs6]  .ui-button-wrapper {
    pointer-events: none;
}

/* Enforce uniform button width for all actions (6138) */
[b-wx8c0qzqs6] .ui-button-wrapper button {
    width: var(--meb-layout-qr-button-width);
}

.qr-upload-input-wrapper[b-wx8c0qzqs6] {
    display: none;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Pages/Terms/AboutUs.razor.rz.scp.css */
/* ===================================================================
   AboutUs.razor.css
   Legacy styles (.terms-container, .feature-section, .values-section,
   .cta-section) have been removed — they were orphaned after the
   AboutUs page was refactored to use .au-* classes defined in the
   page's own <style> block.

   All active AboutUs styles live in the page-inline <style> block
   inside AboutUs.razor. They are scoped to .au-* selectors and use
   only var(--meb-*) / var(--font-*) token vars.
   =================================================================== */

/* Inline prose links (Link renders in a child scope, so ::deep is required): underlined at rest so
   link colour is not the only cue (WCAG 1.4.1). Higher specificity than the global .ui-link text-decoration: none (wwwroot/css/components/link.css). */
[b-0wx0vg66cu] a.ui-link.au-inline-link {
    text-decoration: underline;
}
/* _content/LiveEventBingo.Shared/Pages/Common/Pages/Terms/ContactUs.razor.rz.scp.css */
/* ===================================================================
   ContactUs.razor.css
   All colours resolved through token vars — no raw hex or rgba.
   Migrated verbatim from the inline <style> block; @@media → @media.
   =================================================================== */

/* ── Section 1: Hero ────────────────────────────────────────────── */
[b-961h5b39xr] .contact-hero {
    text-align: center;
}

[b-961h5b39xr] .contact-hero h1 {
    font-family: var(--meb-font-family-accent);
    font-size: var(--meb-font-size-display-desktop);
    font-weight: var(--meb-font-weight-regular);
    line-height: var(--meb-font-lineheight-display);
    color: var(--meb-text-default);
}

[b-961h5b39xr] .contact-hero__lead {
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-regular);
    color: var(--meb-text-default);
    line-height: var(--meb-font-lineheight-body);
}

/* #8998: visible contact email — mirrors the lead paragraph type ramp; link colour inherits global anchor styling. */
[b-961h5b39xr] .contact-hero__email {
    font-size: var(--meb-font-size-body-desktop);
    font-weight: var(--meb-font-weight-regular);
    color: var(--meb-text-default);
    line-height: var(--meb-font-lineheight-body);
}

/* ── Section 2: Form Card ────────────────────────────────────────── */
[b-961h5b39xr] .form-group {
    /* Vertical stacking and label-field gap owned by <Stack Gap="xs"> in markup.
       No flex or gap needed here — the primitive owns this concern. */
}

[b-961h5b39xr] label,
[b-961h5b39xr] .loading-indicator {
    font-family: var(--meb-font-family-primary);
    font-weight: var(--meb-font-weight-regular);
    line-height: var(--meb-font-lineheight-body);
}

/* Input / textarea token-bound styling */
[b-961h5b39xr] .form-control {
    width: 100%;
    padding: var(--meb-space-stack-10);
    border: var(--meb-border-width-sm) solid var(--meb-border-input);
    border-radius: var(--meb-radius-input);
    background: var(--meb-surface-input);
    color: var(--meb-text-input);
    font-family: var(--meb-font-family-primary);
}

[b-961h5b39xr] .form-control::placeholder {
    color: var(--meb-text-input-placeholder);
}

/* Token-driven focus ring — visible `:focus-visible` state */
[b-961h5b39xr] .form-control:focus,
[b-961h5b39xr] .form-control:focus-visible {
    /* Transparent, not none: forced-colors mode strips the box-shadow ring and repaints this outline in a
       system colour (ADO 11309). */
    outline: var(--meb-focus-ring-width) solid transparent;
    outline-offset: var(--meb-focus-ring-offset);
    border-color: var(--meb-border-input-focus);
    box-shadow: 0 var(--meb-space-stack-none) var(--meb-space-stack-none) var(--meb-focus-ring-width) var(--meb-border-input-focus);
}

/* Blazor validation error state — applied by DataAnnotationsValidator */
[b-961h5b39xr] .form-control.modified.invalid {
    border-color: var(--meb-border-input-error);
}

[b-961h5b39xr] .form-control:disabled {
    background: var(--meb-surface-input-disabled);
    color: var(--meb-text-input-disabled);
    cursor: not-allowed;
}

/* Bot-trap field: off-screen and clipped (not display:none, which bots skip); aria-hidden in markup */
[b-961h5b39xr] .contact-extra {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
}

[b-961h5b39xr] .alert {
    padding: var(--meb-space-stack-15);
    border: var(--meb-border-width-sm) solid transparent;
    border-radius: var(--meb-radius-sm);
}

[b-961h5b39xr] .alert-danger {
    color: var(--meb-text-danger);
    background-color: var(--meb-surface-danger);
    border-color: var(--meb-border-danger);
}

[b-961h5b39xr] .alert-success {
    color: var(--meb-text-success);
    background-color: var(--meb-surface-success);
    border-color: var(--meb-border-success);
}

[b-961h5b39xr] .loading-indicator {
    font-size: var(--meb-font-size-body-sm-desktop);
    color: var(--meb-text-muted);
}

/* ── Section 3: Trust Strip ──────────────────────────────────────── */
[b-961h5b39xr] .contact-trust-strip {
    text-align: center;
}

[b-961h5b39xr] .trust-item {
    font-family: var(--meb-font-family-primary);
    font-size: var(--meb-font-size-body-desktop);
    color: var(--meb-text-default);
}

/* ── Responsive: mobile font overrides driven by C# IsMobile (Screen.IsMobile) ─ */
/* Applied via .contact-page--mobile CSS modifier class set in ContactUs.razor.      */
[b-961h5b39xr] .contact-page--mobile .contact-hero h1 {
    font-size: var(--meb-font-size-display-mobile);
}

[b-961h5b39xr] .contact-page--mobile .contact-hero__lead,
[b-961h5b39xr] .contact-page--mobile .contact-hero__email,
[b-961h5b39xr] .contact-page--mobile .trust-item {
    font-size: var(--meb-font-size-body-mobile);
}
/* _content/LiveEventBingo.Shared/Shared/BlogDetails.razor.rz.scp.css */
/* .page-background is on the root element of BlogDetails.razor — no ::deep needed */
.page-background[b-6aqamlp07x] {
  min-height: 100vh;
  background: var(--meb-surface-card);
  width: 100%;
}

/* #7967: error notice when Load() fails (network, 5xx, JSON parse, null-body 200).
   Layout (centering, max-width, block padding) is owned by the <Container> primitive
   wrapping this element in BlogDetails.razor — per Bingo-Template §23.3 layout
   ownership rules. Only visual treatment (border, surface, inline padding, alignment)
   lives here. */
.blog-detail-error[b-6aqamlp07x] {
  padding-inline: var(--meb-space-inline-md);
  padding-block: var(--meb-space-stack-md);
  border: var(--meb-border-width-md) solid var(--meb-accent-danger);
  border-radius: var(--meb-radius-md);
  background: var(--meb-surface-card);
  color: var(--meb-text-default);
  text-align: center;
}
.blog-detail-error p[b-6aqamlp07x] {
  margin: 0;
}

/* All rules below target elements inside child components (Desktop/MobileBlogDetails).
   ::deep is required so Blazor scoping does not block them. */
[b-6aqamlp07x] .container {
  max-width: 1200px;
  margin-inline: auto;
  padding: 16px;
}

[b-6aqamlp07x] .hero-img {
  width: auto !important;
  height: auto !important;
  object-fit: contain !important;
  max-height: 25vh;
  display: block;
  margin: var(--meb-space-stack-none) auto;
}

[b-6aqamlp07x] .disclaimer-text {
  color: var(--meb-text-inverse);
}

[b-6aqamlp07x] .ad-wrapper {
  padding-block: var(--meb-space-stack-md);
}

[b-6aqamlp07x] .article-root {
  /* TOKEN: font.family.primary — §4.2 compliant */
  font-family: "Montserrat", "Open Sans", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, "Helvetica Neue", Arial, sans-serif;
  min-height: 100vh;
}

/* floating-play: §4.1-allowed positioning rules only.
   Responsive sizing is handled via .floating-play--compact applied by IsMobile branching in the child component (§1.3). */
[b-6aqamlp07x] .floating-play--compact {
  right: 12px;
  bottom: 12px;
  padding: 10px;
}

[b-6aqamlp07x] .floating-play--compact .play-text {
  display: none;
}
/* _content/LiveEventBingo.Shared/Shared/BuiltInGameFooter.razor.rz.scp.css */
/* CT-09 T6668 / Bingo UI compliance: BuiltInGameFooter CTA band.
   All visuals from tokens. Layout owned by Container + Inline primitives.
   Only §4.1-allowed raw properties used (overflow, position as needed). */

/* ── CTA band ───────────────────────────────────────────────────────────── */
/* Full-width background band; no radius, no border \u2014 edge-to-edge strip. */
.cta-band[b-1pe60devm1] {
    background: var(--meb-blog-surface-footer);
    overflow: hidden; /* §4.1 — clips any decorative overflow */
}

/* ── CTA row ─────────────────────────────────────────────────────────────── */
/* Inline primitive owns justify-between alignment; row needs vertical padding. */
[b-1pe60devm1] .cta-row {
    padding-top: var(--meb-space-stack-xl);
    padding-bottom: var(--meb-space-stack-xl);
}

/* ── Copy column ─────────────────────────────────────────────────────────── */
[b-1pe60devm1] .cta-copy {
    flex: 1; /* approved exception: copy column fills remaining Inline width */
    min-width: var(--meb-space-stack-none);
}

/* ── Heading ─────────────────────────────────────────────────────────────── */
/* #7855-B: section role per Frozen Detail v1.2 §5. BuiltInGameFooter renders
   inside the blog detail article tree (DesktopBlogDetails.razor) so it inherits
   Poppins from BlogLayout's heading-family rule via the .blog-standalone-layout
   selector. #7968: mobile no longer renders this footer (CT-01 intent reaffirmed). */
[b-1pe60devm1] .cta-heading {
    font-size: var(--meb-blog-font-size-role-section);
    font-weight: var(--meb-blog-text-role-section-weight);
    line-height: var(--meb-blog-text-role-section-lineheight);
    color: var(--meb-text-inverse);
    margin: var(--meb-space-stack-none);
}

/* ── Sub-heading ─────────────────────────────────────────────────────────── */
[b-1pe60devm1] .cta-subheading {
    font-size: var(--meb-blog-font-size-subtitle);
    font-weight: var(--meb-font-weight-regular);
    color: var(--meb-text-inverse);
    margin: var(--meb-space-stack-none);
    opacity: var(--meb-opacity-soft);
}
/* _content/LiveEventBingo.Shared/Shared/Components/SiteFooter.razor.rz.scp.css */
/* ThemeService supplies footer custom properties; the stylesheet derives only visual overlays. */
.site-footer[b-nbtxblkcrz] {
    --footer-icon-bg: color-mix(in srgb, var(--footer-text) 12%, transparent);
    --footer-icon-bg-hover: color-mix(in srgb, var(--footer-text) 25%, transparent);
    --footer-separator: color-mix(in srgb, var(--footer-text) 8%, transparent);
    background-color: var(--footer-bg);
    color: var(--footer-text);
    padding-block-start: var(--meb-space-stack-40);
    width: 100%;
    box-sizing: border-box;
}

.footer-logo-link[b-nbtxblkcrz] {
    display: inline-block;
    text-decoration: none;
    line-height: var(--meb-space-stack-none);
}

.footer-logo-link:focus-visible[b-nbtxblkcrz] {
    outline: var(--meb-border-width-md) solid var(--footer-focus);
    outline-offset: var(--meb-focus-ring-offset-lg);
    border-radius: var(--meb-radius-sm);
}

.footer-logo-img[b-nbtxblkcrz] {
    width: 136px;
    height: auto;
    display: block;
}

.footer-col-heading[b-nbtxblkcrz] {
    font-size: var(--meb-font-size-body-sm-desktop);
    font-weight: var(--meb-font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--meb-font-letter-spacing-loose);
    color: var(--footer-text);
    margin: var(--meb-space-stack-none);
    margin-block-end: var(--meb-space-stack-12);
    padding: var(--meb-space-stack-none);
}

.footer-col-links[b-nbtxblkcrz] {
    list-style: none;
    padding: var(--meb-space-stack-none);
    margin: var(--meb-space-stack-none);
    /* Adjacent siblings provide list spacing because Stack cannot own li spacing. */
}

.footer-col-links li + li[b-nbtxblkcrz] {
    margin-block-start: var(--meb-space-stack-12);
}

.footer-col-links a[b-nbtxblkcrz] {
    text-decoration: none;
    color: var(--footer-link);
    font-size: var(--meb-font-size-body-sm-desktop);
}

.footer-col-links a:hover[b-nbtxblkcrz] {
    text-decoration: underline;
    color: var(--footer-link-hover);
}

.footer-col-links a:focus-visible[b-nbtxblkcrz] {
    outline: var(--meb-border-width-md) solid var(--footer-focus);
    outline-offset: var(--meb-focus-ring-offset);
}

.footer-copyright-bar[b-nbtxblkcrz] {
    padding-block: var(--meb-space-stack-lg) var(--meb-space-stack-md);
    border-top: var(--meb-border-width-sm) solid var(--footer-separator);
}

.footer-copyright[b-nbtxblkcrz] {
    font-size: var(--meb-font-size-body-sm-desktop);
    padding-block-start: var(--meb-space-stack-12);
    margin: var(--meb-space-stack-none);
    color: var(--footer-text);
    opacity: var(--meb-opacity-footer-text);
}

.site-footer[b-nbtxblkcrz]  a.footer-social-link {
    display: inline-block;
    min-inline-size: var(--meb-size-touch-target);
    min-block-size: var(--meb-size-touch-target);
    padding-block: var(--meb-space-stack-sm);
    padding-inline: var(--meb-space-inline-sm);
    border-radius: var(--meb-radius-sm);
    color: var(--footer-link);
    text-decoration: none;
}

.site-footer[b-nbtxblkcrz]  a.footer-social-link:hover {
    color: var(--footer-link-hover);
    text-decoration: underline;
}

.site-footer[b-nbtxblkcrz]  a.footer-social-link:focus-visible {
    outline: var(--meb-border-width-md) solid var(--footer-focus);
    outline-offset: var(--meb-focus-ring-offset);
}

/* #10662: the anchor is the touch target; the official badge inside it is never restyled. */
.site-footer[b-nbtxblkcrz]  a.footer-store-link {
    display: inline-block;
    min-inline-size: var(--meb-size-touch-target);
    min-block-size: var(--meb-size-touch-target);
    max-inline-size: 100%;
    padding-block: var(--meb-space-stack-sm);
    border-radius: var(--meb-radius-sm);
    color: var(--footer-link);
    font-size: var(--meb-font-size-body-sm-desktop);
    text-decoration: none;
}

.site-footer[b-nbtxblkcrz]  a.footer-store-link:hover {
    color: var(--footer-link-hover);
    text-decoration: underline;
}

.site-footer[b-nbtxblkcrz]  a.footer-store-link:focus-visible {
    outline: var(--meb-border-width-md) solid var(--footer-focus);
    outline-offset: var(--meb-focus-ring-offset);
}

/* Scales down with the brand column (never under 136px, see SiteFooter.razor) and keeps its aspect ratio:
   Apple stays at 120x40, Google is 40px tall at the floor, Microsoft about 37px, each above its own minimum. */
.footer-store-badge[b-nbtxblkcrz] {
    display: block;
    max-inline-size: 100%;
    block-size: auto;
}

/* #10933: store attribution small print; stays inside the narrow brand column and wraps. */
.footer-store-legal[b-nbtxblkcrz] {
    margin: var(--meb-space-stack-none);
    max-inline-size: 100%;
    overflow-wrap: anywhere;
    color: var(--footer-text);
    opacity: var(--meb-opacity-footer-text);
    font-size: var(--meb-font-size-body-sm-desktop);
}
/* _content/LiveEventBingo.Shared/Shared/MainLayout.razor.rz.scp.css */
.page[b-4zp38bsmaj] {
    position: relative;
}

/* Spacing + the full-viewport height reservation that centres these status states (so the footer doesn't
   ride up and shift during the GameUser-null gate) are owned by the wrapping
   <Stack MinHeight="100dvh" Align="center" Justify="center"> in MainLayout.razor — no page CSS needed here
   now that Stack.MinHeight is wired (ADO #8848). These plain <div>s carry visual styling only. */
.shell-status-message[b-4zp38bsmaj],
.shell-status-loader[b-4zp38bsmaj] {
    /* visual-only — layout owned by the wrapping Stack primitive */
}

/* ── Global layout utilities (MainLayout-scoped) ──────────────────── */
/* Used directly in MainLayout.razor markup; safely scoped. */
.main-body[b-4zp38bsmaj] {
    /* Fill the centered container width (matching the header) instead of
       shrink-wrapping to content. The body Stack is Align="center", so without
       this a block child centers at its content width, boxing wide pages (e.g.
       the gameplay board) into a narrow column inside the 1280px container. */
    width: 100%;
    max-width: 100%;
}

/* Visually-hidden SEO nav — positions off-screen for screen-reader/crawlers only. */
/* The six !important declarations are required to override any layout cascade      */
/* that might make this element visible. This is a recognised a11y pattern.         */
.seo-primary-nav[b-4zp38bsmaj] {
    position: absolute !important;
    left: -9999px !important;
    top: auto !important;
    width: 1px !important;
    height: 1px !important;
    overflow: hidden !important;
    white-space: nowrap !important;
}

.div-visible[b-4zp38bsmaj] {
}
.div-nonvisible[b-4zp38bsmaj] {
    display: none;
}
/* Screen mode is measured by IScreenSizeService. Unknown mode gets a neutral
   placeholder so MainLayout does not render the wrong navigation first. */
.nav-measurement-placeholder[b-4zp38bsmaj] {
    width: 100%;
    min-height: var(--meb-size-touch-target);
}

/* Startup navigation switcher.
   The real screen-mode owner is IScreenSizeService. This CSS only prevents the
   Unknown lifecycle state from visually flashing the wrong header before the
   measured viewport callback reaches Blazor. The html[data-meb-screen-mode]
   value is set by the early startup hint script and later kept in sync by
   bingo.js / ResizeObserverService. */
.nav-startup-switcher[b-4zp38bsmaj],
.nav-startup-option[b-4zp38bsmaj] {
    width: 100%;
}

/* Mobile remains the no-JS/default posture because Bingo is mobile-first. */
.nav-startup-option--desktop[b-4zp38bsmaj] {
    display: none;
}

html[data-meb-screen-mode="desktop"] .nav-startup-option--mobile[b-4zp38bsmaj] {
    display: none;
}

html[data-meb-screen-mode="desktop"] .nav-startup-option--desktop[b-4zp38bsmaj] {
    display: block;
}

html[data-meb-screen-mode="mobile"] .nav-startup-option--mobile[b-4zp38bsmaj] {
    display: block;
}

html[data-meb-screen-mode="mobile"] .nav-startup-option--desktop[b-4zp38bsmaj] {
    display: none;
}
