/* _content/LiveEventBingo.Shared/Pages/Common/Components/FeaturePageShell.razor.rz.scp.css */
/* ADO #10609 -- FeaturePageShell scoped CSS.

   Limited to what the shell task's acceptance criterion calls "typography and the media slot's
   aspect-ratio":
     1. Typography (headings, lede, captions) -- tokens only, no raw font-family/size/weight literals.
     2. The media slot's aspect-ratio -- reserves layout space before the image loads, UA-independently
        (a stylesheet media query, not a Screen.IsMobile branch -- ADO #10609 MUST FIX 2).
     3. Making the image FILL that reserved slot instead of driving its own size off its width/height
        HTML attributes, and capping it so it cannot overflow a narrow viewport (MUST FIX 3) -- this is
        the media slot's aspect-ratio reservation actually being honored, not a separate concern. The
        selectors for this category use ::deep (round 4 CRITICAL 1) because CdnImage renders the
        actual <picture>/<img> inside ITS OWN component scope -- see the rule-level comment below for
        why a plain (non-::deep) selector here compiles but matches nothing.

   Everything else (spacing, alignment, columns, stacking) is owned by the Container / Stack / Grid /
   Inline primitives via their props (Gap, Padding, TemplateColumns*, TemplateAreas*), never by a rule
   here. No flex/gap/overflow/align-items/justify-content targeting a PRIMITIVE's own class. */

.feature-h1[b-5m8x3to7pr] {
    font-family: var(--font-family-display);
    font-size: var(--font-size-display-desktop);
    font-weight: var(--font-weight-display);
    line-height: var(--font-lineheight-display);
    color: var(--meb-text-default);
    margin-block-end: 0;
}

.feature-h2[b-5m8x3to7pr] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-h2-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin-block: 0;
}

.feature-h3[b-5m8x3to7pr] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-h3-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin-block: 0;
}

.feature-lede[b-5m8x3to7pr] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
}

.feature-faq-answer[b-5m8x3to7pr] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
    margin: 0;
}

.feature-media-caption[b-5m8x3to7pr] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-sm-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
    margin: 0;
}

/* Media frame aspect-ratio: reserves space so CdnImage's width/height don't need to load first to
   prevent layout shift. Desktop assets are 1200x628 (design "Image production plan"); the mobile
   asset is 800x800 (square) below the 768px breakpoint the Grid primitive itself already keys its
   own responsive behavior on. position:relative is required, not optional -- CdnImage.razor.css
   documents that its .cdn-image-placeholder is position:absolute; inset:0, so the parent must be
   positioned or the placeholder escapes to whatever ancestor IS positioned. Zero of the 29 planned
   image assets are published yet (ADO #10610), so the placeholder path is the LIVE path today.
   ADO #10609 MUST FIX 5: this frame wraps ONLY the image -- the caption <p> is a sibling below it
   (owned by the enclosing Stack's Gap), not a child inside this fixed-ratio box, where it used to
   render past the bottom edge and overlap the next section. */
.feature-media-frame[b-5m8x3to7pr] {
    position: relative;
    aspect-ratio: 1200 / 628;
}

@media (max-width: 767px) {
    .feature-media-frame[b-5m8x3to7pr] {
        aspect-ratio: 1 / 1;
        /* #11039 (U3): mobile-display is 800px wide; 800 x 1.35 / DPR 2 = 540, so cap the painted width at 520px
           (1.30x at DPR 2), the same centred cap #10983 uses for blog images. DPR 3 is #11007. width: 100% keeps the frame filling the flex-column stack up to the cap (auto margins would shrink it). */
        width: 100%;
        max-width: min(100%, 520px);
        margin-inline: auto;
    }
}

/* ADO #10609 MUST FIX 2 + MUST FIX 3 (round 3) + CRITICAL 1 (round 4): the frame's aspect-ratio
   above is the ONE UA-independent CLS reservation (no width/height attribute varies by device -- see
   the file header comment). These rules make the image FILL that reserved box rather than drive its
   own size: without them, <img width="1200" height="628"> with no CSS cap lays out at its intrinsic
   1200px and overflows every viewport narrower than that -- there is no global img{max-width:100%}
   reset anywhere in this repo (verified against every stylesheet under LiveEventBingo.Shared/wwwroot/css
   and LiveEventBingo.Web/wwwroot/css; the only global img rule is Bootstrap reboot's
   vertical-align:middle), which is why blog-section-variants.css and .article-hero img each had to
   add their own cap, and this is the feature-page equivalent. object-fit:cover on a 1200x628 (or,
   under 767px, 1x1) box crops rather than distorts. picture is inline by default and would otherwise
   leave a baseline gap under the box.

   ::deep IS REQUIRED HERE, NOT OPTIONAL (CRITICAL 1, round 4): CdnImage.razor renders <picture> and
   <img> itself, inside CdnImage's OWN component scope. Blazor CSS isolation stamps every rule in
   this file with FeaturePageShell's scope attribute and every element CdnImage renders with
   CdnImage's DIFFERENT scope attribute -- a plain ".feature-media-frame picture" selector (no ::deep)
   can never match an element carrying a different component's scope attribute at all, so the rule
   compiles, ships, and matches NOTHING. This shipped as silently-dead CSS for exactly that reason
   before this fix. ::deep is the documented, sanctioned escape hatch for precisely this shape --
   "crossing nested shared-control boundaries" (CLAUDE.md) -- not a violation of the scoped-CSS rule.
   Pinned by FeaturePageShellRenderTests, which asserts the rendered <img> actually carries the
   feature-media-img class ::deep depends on matching. */
.feature-media-frame[b-5m8x3to7pr]  picture {
    display: block;
    width: 100%;
    height: 100%;
}

.feature-media-frame[b-5m8x3to7pr]  .feature-media-img {
    display: block;
    width: 100%;
    height: 100%;
    /* Static SSR retains its selected image after resize. Preserve the full screenshot even
       when that desktop image is now displayed inside the square phone frame. */
    object-fit: contain;
}

/* Mobile typography -- mirrors legal-page-shell.css's @media (max-width: 767px) block, the file
   this shell is modelled on. Without this, phones get desktop display sizes: FeaturePageShell.razor
   only ever emits the -desktop token names above, so the -mobile ones must be applied here. */
@media (max-width: 767px) {
    .feature-h1[b-5m8x3to7pr] {
        font-size: var(--font-size-display-mobile);
    }

    .feature-h2[b-5m8x3to7pr] {
        font-size: var(--font-size-h2-mobile);
    }

    .feature-h3[b-5m8x3to7pr] {
        font-size: var(--font-size-h3-mobile);
    }

    .feature-lede[b-5m8x3to7pr],
    .feature-faq-answer[b-5m8x3to7pr] {
        font-size: var(--font-size-body-mobile);
    }

    .feature-media-caption[b-5m8x3to7pr] {
        font-size: var(--font-size-body-sm-mobile);
    }
}
/* _content/LiveEventBingo.Shared/Pages/Common/Pages/Features/FeatureBingoTemplates.razor.rz.scp.css */
/* ADO #10612 -- FeatureBingoTemplates scoped CSS.

   Same scope as FeaturePageShell.razor.css (ADO #10609): typography (tokens only) and the group
   image's aspect-ratio, nothing else. Layout/spacing inside the catalogue body is owned by the
   Stack/Grid/Inline primitives via their props (see the .razor file), never by a rule here. This
   file exists ONLY because the catalogue's grouped-cards shape does not fit FeaturePageShell's
   single-image-per-section contract (see the .razor file's header comment) -- everything FeaturePageShell
   itself already styles (h1/h2/lede/FAQ/hero media) is untouched here. */

.fbt-group-h3[b-aa1fmb89hr] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-h3-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin: 0;
}

.fbt-section-h2[b-aa1fmb89hr] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-h2-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin-block: 0;
}

.fbt-group-caption[b-aa1fmb89hr] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-sm-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
    margin: 0;
}

.fbt-card-name[b-aa1fmb89hr] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-body-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin: 0;
}

.fbt-card-squares[b-aa1fmb89hr],
.fbt-card-use[b-aa1fmb89hr] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-sm-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
    margin: 0;
    padding-inline-start: 1.1em;
}

.fbt-card-play[b-aa1fmb89hr] {
    font-family: var(--font-family-body);
    font-weight: var(--font-weight-heading);
}

/* Group image frame: same 1200x628 / 1x1-under-767px aspect-ratio contract as
   FeaturePageShell.razor.css's .feature-media-frame (design "Image production plan" -- every
   planned asset is desktop-display 1200x628, mobile-display 800x800). position:relative for the
   same reason: CdnImage's placeholder is position:absolute; inset:0. */
.fbt-group-media-frame[b-aa1fmb89hr] {
    position: relative;
    aspect-ratio: 1200 / 628;
}

@media (max-width: 767px) {
    .fbt-group-media-frame[b-aa1fmb89hr] {
        aspect-ratio: 1 / 1;
        /* #11039 (U3): mobile-display is 800px wide; 800 x 1.35 / DPR 2 = 540, so cap the painted width at 520px
           (1.30x at DPR 2), the same centred cap #10983 uses for blog images. DPR 3 is #11007. width: 100% keeps the frame filling the flex-column stack up to the cap (auto margins would shrink it). */
        width: 100%;
        max-width: min(100%, 520px);
        margin-inline: auto;
    }
}

/* ::deep required -- CdnImage renders <picture>/<img> in its OWN component scope (see
   FeaturePageShell.razor.css's matching rule for the full explanation). */
.fbt-group-media-frame[b-aa1fmb89hr]  picture {
    display: block;
    width: 100%;
    height: 100%;
}

.fbt-group-media-frame[b-aa1fmb89hr]  .fbt-group-media-img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

@media (max-width: 767px) {
    .fbt-group-h3[b-aa1fmb89hr] {
        font-size: var(--font-size-h3-mobile);
    }

    .fbt-section-h2[b-aa1fmb89hr] {
        font-size: var(--font-size-h2-mobile);
    }

    .fbt-card-name[b-aa1fmb89hr],
    .fbt-card-squares[b-aa1fmb89hr],
    .fbt-card-use[b-aa1fmb89hr],
    .fbt-group-caption[b-aa1fmb89hr] {
        font-size: var(--font-size-body-sm-mobile);
    }
}
/* _content/LiveEventBingo.Shared/Pages/Common/Pages/Features/FeatureVirtualBingo.razor.rz.scp.css */
/* ADO #10841 -- FeatureVirtualBingo scoped CSS.

   Typography only (tokens only), for the at-a-glance list and the setup steps the page passes
   through FeaturePageShell's AfterStories slot. Shell classes are scoped to the shell component,
   so this page needs its own copies, following FeatureBingoTemplates.razor.css (.fbt-section-h2).
   Spacing between and inside the sections is owned by the Stack primitives in the .razor file;
   the one exception is the li + li rule below. */

/* Matches FeaturePageShell.razor.css's .feature-h2. */
.fvb-section-h2[b-5t3r4xo17b] {
    font-family: var(--font-family-heading);
    font-size: var(--font-size-h2-desktop);
    font-weight: var(--font-weight-heading);
    line-height: var(--font-lineheight-heading);
    color: var(--meb-text-default);
    margin-block: 0;
}

/* Body text matches FeaturePageShell.razor.css's .feature-lede. */
.fvb-glance-list[b-5t3r4xo17b],
.fvb-setup-steps[b-5t3r4xo17b] {
    font-family: var(--font-family-body);
    font-size: var(--font-size-body-desktop);
    font-weight: var(--font-weight-body);
    line-height: var(--font-lineheight-body);
    color: var(--meb-text-muted);
    margin: 0;
    padding-inline-start: 1.25em;
}

/* Markers set explicitly, as the homepage block does: the repo's reboot sets ul to
   list-style none, and the setup steps are a numbered sequence. */
.fvb-glance-list[b-5t3r4xo17b] {
    list-style: disc;
}

.fvb-setup-steps[b-5t3r4xo17b] {
    list-style: decimal;
}

/* Space between items, as the homepage block does: no primitive can sit between a list
   and its items. */
.fvb-glance-list li + li[b-5t3r4xo17b],
.fvb-setup-steps li + li[b-5t3r4xo17b] {
    margin-block-start: var(--meb-space-2);
}

@media (max-width: 767px) {
    .fvb-section-h2[b-5t3r4xo17b] {
        font-size: var(--font-size-h2-mobile);
    }

    .fvb-glance-list[b-5t3r4xo17b],
    .fvb-setup-steps[b-5t3r4xo17b] {
        font-size: var(--font-size-body-mobile);
    }
}
