@import '_content/Tma.Business.Surface/Tma.Business.Surface.f2ayes3q9t.bundle.scp.css';
@import '_content/Tma.Surface.Components/Tma.Surface.Components.9sglkgrss1.bundle.scp.css';

/* /Components/Layout/MainLayout.razor.rz.scp.css */
#blazor-error-ui[b-jtk51gox6l] {
    background: var(--removable-soft, #fff4cc);
    border-top: 1px solid var(--hairline-strong, rgba(44, 62, 80, 0.18));
    bottom: 0;
    box-shadow: 0 -1px 2px var(--hairline-strong, rgba(44, 62, 80, 0.18));
    color: var(--ink-1, #2c3e50);
    display: none;
    left: 0;
    padding: 0.6rem 1.25rem 0.7rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
}

#blazor-error-ui .dismiss[b-jtk51gox6l] {
    cursor: pointer;
    position: absolute;
    right: 0.75rem;
    top: 0.5rem;
}

/* F-706 (operator employees family): --removable-soft is a fully OPAQUE hex in the light theme
   (tokens.css #F9EFE2), so the light bar above is legible against anything scrolled beneath it — but
   the SAME token resolves to a TRANSLUCENT wash in dark mode (rgba(245, 176, 74, .13)), correct for a
   chip tint on a card, wrong for a fixed full-bleed alert bar that must guarantee its own contrast no
   matter what page content is currently underneath it. Overriding onto the token's own opaque sibling
   --removable-solid (tokens.css) — the same fix shape as the sibling F-421 banner (circuit-watch.css
   #circuit-connect-ui) and the checkout email field's dark override (CheckoutEmailCorrectionForm.razor.css)
   — reusing that banner's own already-measured amber/dark-amber pair so all three connectivity
   affordances read as one family. */
:root[data-theme="dark"] #blazor-error-ui[b-jtk51gox6l] {
    background: var(--removable-solid, #4a3a12);
}
/* /Components/Layout/MainLayoutBottomNav.razor.rz.scp.css */
/* NEW.8 (owner ruling 2026-08-14 evening, reassigned from the patron lane, F-567): the marketing
   bottom nav rendered on desktop. ShellSurfaceResolver.ShellClasses records the PRIOR deliberate
   design in its own doc comment — "Marketing keeps its bottom bar at every width" — the owner ruling
   supersedes it. The workbench surface already hides its bottom nav at >=1280 (shell.css's
   .tma-shell.has-workdrawer rule, once the sticky drawer becomes the desktop nav) and the admin
   surface never renders one at all (R16); only Marketing had no surface class to key an equivalent
   media query off, because ShellSurfaceResolver.ShellClasses returns an empty string for it. Scoped
   here (zero shell.css growth) rather than the shared design-system sheet, mirroring
   MainLayoutContent.razor.css's own "WHY HERE rather than in shell.css" reasoning for the identical
   is-public-site per-route need. Matches the SAME 1280px breakpoint shell.css already uses for the
   other two surfaces (the shell's own breakpoint convention). */
@media (min-width: 1280px) {
    .site-shell.is-public-site .tma-bottomnav[b-bba5ou1xw7] {
        display: none;
    }
}
/* /Components/Layout/MainLayoutContent.razor.rz.scp.css */
/* ============================================================================
   The marketing routes' content column.

   The prototype wraps every marketing page in `<main class="area-wrap">`, which
   is what gives the design its centred reading column and its 20/32/48px gutter.
   This host has no such element: the ported bands are direct children of the
   shell's own `.app-canvas`, which spans the viewport, so they rendered
   edge-to-edge at every width.

   MEASURED, prototype vs port, same headless Chrome, first card's left offset
   and width — the whole divergence, and the only one left after the banding fix:

       375px    proto  20 / 335      port   0 / 375
       900px    proto  72 / 370      port   0 / 442
      1440px    proto 358 / 231      port   0 / 469

   (h1 size 35/63/64, card surface #FFFFFF light and #182535 dark, and the 44px
   button height all already matched exactly, in both themes.)

   Reproduced as a column on the BANDS rather than as padding on the canvas, for
   two reasons. Padding on `.app-canvas` would restyle every unported public
   route that shares it. And `.cta-band` already owns its own --sp-7/--sp-5
   padding, so a second inline padding would compound inside it — the width form
   leaves that untouched while landing the identical content box:

       width     = 100% - 2 * gutter          (the gutter at every width)
       max-width = --w-reading - 2 * gutter    (`.area-wrap`'s own content box)

   Scoped to `.area-head` / `.area-section` (base.css's two ported section
   primitives) and `.cta-band` (the one band that carries neither), so it reaches
   the ported vocabulary and nothing else — an unported route has no element that
   matches.

   WHY HERE rather than in shell.css, which is where the shell's other layout
   corrections live: shell.css is the app bar's own sheet and its fitness test
   forbids ANY per-route selector in it (DESIGN-SYSTEM §4 — the bar never
   restyles between areas), and `is-public-site` is exactly that. This component
   is the one that authors `.app-canvas`, so the rule lives with the element it
   qualifies. `::deep` is required because the bands are rendered by the page
   inside `@Body` and therefore carry no scope attribute of their own.
   ========================================================================== */

.site-shell.is-public-site .app-canvas[b-16ddodza4w]  > .area-head,
.site-shell.is-public-site .app-canvas[b-16ddodza4w]  > .area-section,
.site-shell.is-public-site .app-canvas[b-16ddodza4w]  > .cta-band {
    box-sizing: border-box;
    width: calc(100% - 2 * var(--gutter));
    max-width: calc(var(--w-reading) - 2 * var(--gutter));
    margin-inline: auto;
}

/* NEW.4 (owner ruling 2026-08-14 evening): the footer tagline's two phrase groups (own data-i18n
   keys each, split so the whole-paragraph textContent write i18n.js does for a single data-i18n
   element can never wipe a structural break) each stay on one line. The ONE plain space between the
   two spans, in MainLayoutContent.razor's own markup, is therefore the only place the browser can
   ever wrap — right after "guest clarity," — so a single word can never strand alone. */
.footer-tagline-lead[b-16ddodza4w],
.footer-tagline-trail[b-16ddodza4w] {
    white-space: nowrap;
}

/* NEW.6 (owner ruling 2026-08-14 evening), corrected under NEW.1 (owner-reported 2026-08-15): on
   desktop, an operator/employee's closed workspace drawer left a grey slab where the drawer had
   been. MEASURED: shell.css's own R45 rule reserves the drawer's 300px gutter on .tma-shell-main
   UNCONDITIONALLY (open or closed), so the content column never shifts — but with the drawer
   closed (translated off-screen) that reserved gutter showed through to .tma-shell-main's own
   paint, which was nothing explicit, so it fell through to the shell's plain --bg canvas token.
   .app-canvas (this file's other element, one level in) is what the gutter has to match — and the
   ORIGINAL fix matched the wrong rule: app.css's bare `.app-canvas { background: #ffffff }` is the
   base rule, but every is-app-preview route (every operator/admin/workspace/flashcards screen —
   is-local-menus-route, the one patron surface, can never combine with is-app-preview; see
   MainLayout.Routing.cs) is governed by a MORE SPECIFIC app.css rule that actually wins the
   cascade and paints #f4f8fb instead. So even in light mode the gutter was a shade off. Both
   surfaces now consume ONE shared token, --app-preview-canvas-bg — undefined in light mode (so
   each side's own literal fallback below is what light mode renders, matching app.css's real
   winning rule exactly) and redefined ONLY in admin.css's body.theme-dark block, from MudBlazor's
   own dark palette. One assignment point means the two sides cannot drift apart again, in either
   theme, open or closed. Scoped to .is-app-preview only: the marketing shell's .app-canvas keeps
   its own current appearance. */
.site-shell.is-app-preview .tma-shell-main[b-16ddodza4w] {
    background: var(--app-preview-canvas-bg, #f4f8fb);
}

/* Owner ruling 2026-08-15 (fourth pass on the footer logo, SUPERSEDES the third pass's desktop-inline-
   small 23px breakpoint override below): the mobile size is right — the logo should render roughly the
   SAME size at every width, not shrink to a near-invisible 23px mark once the tablet breakpoint hits.
   MEASURED: the footer's own layout (app.css .site-footer) is an unconditional centered/stacked grid at
   every width already (NEW.3 there), so there is no "inline beside the tagline" arrangement for a small
   mark to belong to on desktop — this is a pure sizing fix, no layout side effect. One unconditional rule,
   one source of truth (the app.css .footer-logo img rule is retired). */
.footer-logo img[b-16ddodza4w] {
    height: auto;
    max-width: 168px;
}

/* NEW.7 (owner ruling 2026-08-14 evening): belt-and-braces alongside app.css's h1:focus suppression
   — the sink is already visually hidden by base.css's .visually-hidden (clip: rect(0 0 0 0)), which
   clips its own outline too, but this makes the "never visible" guarantee explicit rather than
   relying on that side effect. */
#route-focus-sink:focus[b-16ddodza4w] {
    outline: none;
}

/* F-657 NEW.5 (owner desktop feedback, 2026-08-20): a real, visible gap between the last content
   element and the footer's blue band, site-wide, from ONE rule rather than a per-page patch.

   MEASURED: app.css already carried a "NEW.5" rule for exactly this (owner ruling 2026-08-15) —
   `padding: var(--sp-section) 1rem 0.75rem;` on .site-footer — but padding paints INSIDE an element's
   own background, and .site-footer's background is the solid --tma-blue fill. So that 36px of
   padding-top was 36px of MORE BLUE above the logo, never a gap showing the page's own canvas colour
   before the footer starts — the owner re-reported the identical symptom five days later.

   The fix: background-clip: padding-box confines .site-footer's own blue fill to its padding and
   content boxes; a transparent top border of the SAME width then leaves that reserved strip unpainted,
   so whatever actually sits behind the footer (.app-canvas's own themed background, light or dark)
   shows through instead. Composes correctly even when the section immediately above ends in a dark
   band: the two boxes never overlap, so the band's own colour ends at its own edge and the transparent
   strip always reveals .app-canvas, not whatever the previous section painted.

   app.css's margin-top: auto (unchanged) still pushes the footer to the bottom of a short page, and
   the footer's total box height is unchanged — the 36px moved from padding-top to border-top-width
   rather than being added — so neither the flex math nor the footer's overall size regresses. Landed
   here rather than growing app.css further: app.css sits inside its enforced public-surface byte
   budget with too little headroom for this addition (AppCssPublicSurfaceBudgetTests). */
.site-footer[b-16ddodza4w] {
    padding-top: 0;
    border-top: var(--sp-section) solid transparent;
    background-clip: padding-box;
}

/* F-700 (owner + live-measured 2026-08-22): shell.css reserves a 60px padding-bottom on .tma-shell-canvas
   (.tma-shell-main > .tma-shell-canvas, unconditional) so page content never sits under the fixed
   .tma-bottomnav below it. .site-footer's own margin-top: auto (app.css) pins it to the canvas's bottom
   edge, so that reservation paints as a plain light strip below the dark footer whenever nothing is left
   to clear. At >=1280 that is exactly the marketing/patron case: MainLayoutBottomNav.razor.css already
   sets .tma-bottomnav to display: none for is-public-site at this same breakpoint (F-567/NEW.8), so the
   60px is dead space there. Below 1280 the bar is still real and fixed, so the reservation stays — this
   rule only fires once the bar it clears is already gone.

   Landed here (not shell.css) for the same reason as every other is-public-site canvas/footer correction
   above: ShellChromeCssTests.The_app_bar_carries_no_per_route_override forbids shell.css from carrying an
   is-public-site selector at all. (0,3,0) beats shell.css's (0,2,0) source rule outright, so the override
   wins on specificity alone — shell.css's own reservation is untouched, and every other surface that still
   needs it (workbench below 1280, the patron surface below 1280) is unaffected. */
@media (min-width: 1280px) {
    .site-shell.is-public-site .tma-shell-canvas[b-16ddodza4w] {
        padding-bottom: 0;
    }
}

/* F-705: the same shell.css reservation, and the same dead strip, on the platform console — reported by F-700
   above as out of its scope rather than folded in silently. R16: the console renders NO bottom nav at ANY width
   (MainLayout.razor gates it on ShellSurfaceResolver.HasBottomNav, and it carries no marketing footer either
   since F-704), so the 60px it reserves for one is dead below the last of every console page, at every width.

   UNCONDITIONAL, unlike the marketing rule above: that one waits for 1280 because below it the marketing/patron
   bar is real and fixed and the clearance is load-bearing. The console has nothing to clear at any width, so a
   breakpoint here would leave the strip on every phone and tablet console page.

   Keyed on has-no-bottomnav, which ShellSurfaceResolver mints from HasBottomNav itself — NOT on is-admin-route.
   That class is derived from the path while the bottom nav is derived from the principal, and it is wrong in
   both directions: an operator's own workspace destinations live under /admin/* and still render the fixed bar
   below 1280 (it would slide under the bar), while a signed-in TMA admin on any non-/admin route is still the
   console and would keep the strip. Same reason as F-700 for living here rather than in shell.css, and it is
   likewise an override — shell.css's own reservation is untouched and every shell that needs it keeps it. */
.site-shell.has-no-bottomnav .tma-shell-canvas[b-16ddodza4w] {
    padding-bottom: 0;
}
/* /Components/Layout/MainLayoutDrawer.razor.rz.scp.css */
/* ============================================================================
   NEW.1a — Variant A's drawer chrome (`appbar-variants/variant-a.html`:
   `.drawer-head`, `.drawer-body`), lifted value for value. F-735 (owner ruling
   2026-08-23) retired the pinned `.drawer-foot` this file used to also carry —
   see MainLayoutDrawer.razor for where its rows moved.

   SCOPED beside the component, per SHELL.8's rule. app.css keeps the panel's
   older `.drawer-head` / `.drawer-logo` block and is under a hard byte cap, so
   the head's NEW values are stated here — a scoped selector carries this
   component's attribute, which out-ranks the single-class rules there without
   an !important and without editing a capped public sheet.
   ========================================================================== */

/* The head is now a brand slot, not a 112x52 logo box: the mark sits beside the
   wordmark at the app bar's own 26px, so both ends of the shell read as one
   brand. Without these, app.css's `.drawer-logo { height: 52px; width: 112px }`
   would size the LINK and its 50px `img` would tower over the wordmark. */
.drawer-head .drawer-logo[b-i96stjdzz9] {
  display: flex;
  align-items: center;
  gap: var(--sp-icon-text);
  height: auto;
  width: auto;
  min-width: 0;
  color: var(--ink-1);
  font-size: var(--t-16);
  font-weight: 900;
  letter-spacing: -.01em;
  text-decoration: none;
}

.drawer-head .drawer-logo > span[b-i96stjdzz9] {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.drawer-head .drawer-logo img.mark[b-i96stjdzz9] {
  width: 26px;
  height: 26px;
  max-height: none;
  border-radius: 7px;
  object-fit: contain;
  flex: none;
}

/* The design icon button that replaced the MudIconButton. `.icon-btn`'s own
   sizing lives in shell.css (it is shell-wide and owned by no component); what
   is here is only the UA button reset the prototype's `.icon-btn` block carries
   and this element needs. */
.drawer-head .drawer-close[b-i96stjdzz9] {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--touch);
  height: var(--touch);
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.drawer-head .drawer-close:hover[b-i96stjdzz9] {
  background: var(--surface-2);
  color: var(--ink-1);
}

/* ::deep, and not as a preference: the glyph is rendered by TmaIcon, so it
   carries THAT component's scope attribute — a plain descendant selector
   compiles to one this sheet's attribute can never match, and fails silently
   at TmaIcon's own default size. Same trap TmaDrawerGroup.razor.css records. */
.drawer-head .drawer-close[b-i96stjdzz9]  .icon {
  width: 20px;
  height: 20px;
}
/* /Components/Layout/MainLayoutToolbar.razor.rz.scp.css */
/* ============================================================================
   NEW.1a — Variant A's app-bar context CHIP (`appbar-variants/variant-a.html`,
   the `.context-chip` block), lifted value for value.

   SCOPED, per the rule SHELL.8 set for every port chip after it: a component's
   look lives beside its .razor, never appended to shell.css/app.css. app.css
   also sits ~350 bytes under a hard public-surface byte cap (F-416/F-191), so
   "just add four lines there" is a build failure waiting rather than a style
   choice.

   The two-line stack itself (.toolbar-workspace-brand and its per-line
   ellipsis) already ports in app.css and is NOT duplicated here — this is only
   the chip shell the variant adds around it, plus the UA button reset that
   shell needs, since the slot is an interactive affordance on this platform
   (a tap opens the drawer's workspace switcher) where the prototype's is too.
   ========================================================================== */

.context-chip[b-pmp7nftxrn] {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.2;
  padding: 4px var(--sp-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--hairline-strong);
  background: var(--surface-2);
  color: var(--ink-1);
  font: inherit;
  cursor: pointer;
  margin-inline-start: var(--sp-2);
  min-width: 0;
}

/* The colour is stated on the line, not left to inherit: shell.css paints the whole `.context` slot
   --ink-3, which is right for a bare label and wrong for the chip's primary line. */
.context-chip .concept[b-pmp7nftxrn] {
  font-size: var(--t-14);
  font-weight: 700;
  color: var(--ink-1);
}

.context-chip .loc[b-pmp7nftxrn] {
  font-size: 11px;
  color: var(--ink-3);
}
/* /Components/Layout/TmaUserMenu.razor.rz.scp.css */
/* Placement only. The popover's own look — surface, hairline, radius, elevation, .menu-item/.menu-sep/
   .menu-head — is the ported design system in shell.css and is not repeated or overridden here.

   The prototype positions its popover with inline left/top computed from the anchor's client rect,
   because there it is appended to <body>. This host renders the menu inside its trigger, so the same
   placement falls out of an anchored `position: absolute` with no measuring and no JS — and it stays
   correct when the bar reflows, which the measured version does not. Inline-direction properties so it
   mirrors under RTL. */

.tma-menu-anchor[b-auyc25fqlz] {
    align-items: center;
    display: inline-flex;
    position: relative;
}

/* shell.css already sets position/z-index/appearance on .tma-menu-pop; this only says WHERE. */
.tma-menu-pop[b-auyc25fqlz] {
    inset-block-start: calc(100% + 8px);
    inset-inline-end: 0;
}

/* Closes on an outside click. Transparent, and below the popover but above the page. */
.tma-menu-scrim[b-auyc25fqlz] {
    background: transparent;
    inset: 0;
    position: fixed;
    z-index: calc(var(--z-popover) - 1);
}

/* F-597: the markup always renders and THIS is the closed state — one class carries the whole
   open/closed contract, so the same flip works from Blazor (interactive routes) and from
   site-interop.js (the circuit-less marketing landings, body[data-drawer-owner="client"]).
   `display: none` beats whatever display shell.css gives the popover, so a closed menu can never
   leak through, and the closed scrim can never eat a click. */
.tma-menu-anchor:not(.is-open) > .tma-menu-scrim[b-auyc25fqlz],
.tma-menu-anchor:not(.is-open) > .tma-menu-pop[b-auyc25fqlz] {
    display: none;
}

/* F-592/fb0818m-06 (dark-mode-crawl-1, NEW.3): the trailing-tick visibility rule moved OUT of this
   scoped sheet into shell.css, beside the rest of this popover's ported look (.menu-item/.menu-sep/
   .menu-head, per this file's own header). MEASURED: Blazor's CSS-isolation scope attribute is stamped
   on every element THIS component renders directly, but never reaches <TmaIcon>'s own root <svg> (a
   cross-assembly child component) — so the scoped selector's rewritten form, `.menu-tick[b-scope]`,
   could never match anything, and the "only .is-current shows it" rule silently applied to nothing:
   BOTH theme rows kept their tick (owner report, 2026-08-18, item 5). shell.css is a plain, unscoped
   stylesheet, so the same selector works there without depending on scope propagation across a
   component boundary at all. See ThemeModeTickVisibilityTests for the regression guard. */

/* ---- the bottom-nav / rail trigger ------------------------------------------------------------
   The prototype's .nav-user is a direct child of .bottomnav, so shell.css sizes and positions it as a
   flex item there. Wrapping it to anchor the popover would otherwise take that away: the wrapper, not
   the button, is the flex item now. These three rules hand the layout back — width and slot cap on
   mobile, and at >=1280 the bottom-anchoring that shell.css puts on .nav-user has to move up to the
   wrapper or the button would push against a box that has already been placed.

   They live here rather than in shell.css on purpose: the wrapper is this host's way of anchoring a
   popover without JS measuring, not part of the design system. shell.css should keep describing the
   design's own markup. */

.tma-menu-anchor.is-nav-user[b-auyc25fqlz] {
    flex: 1;
    max-width: 120px;
}

.tma-menu-anchor.is-nav-user > .nav-user[b-auyc25fqlz] {
    width: 100%;
}

/* Opens upward: the trigger is pinned to the bottom of the viewport, so `top` would put the menu
   off-screen entirely. */
.tma-menu-anchor.is-nav-user > .tma-menu-pop[b-auyc25fqlz] {
    inset-block-end: calc(100% + 8px);
    inset-block-start: auto;
}

/* SCOPED TO THE RAIL, which is what this block was always about. Unscoped it fired at >=1280 on EVERY
   surface, and on a marketing page — where the bar stays a horizontal bottom nav because the shell is not
   .rail-desktop — `width: 100%` on a flex item in that row made the user-menu wrapper eat the bar.
   MEASURED at 1280 on production: the wrapper laid out 1270px wide and the four destinations were crushed
   to 77.45 / 44.34 / 29.36 / 58.98px, with "Find food near you" wrapping to three lines. shell.css already
   scopes its half of the same rules this way (.tma-shell.rail-desktop .tma-bottomnav ...); this half was
   the one that got left global. */
@media (min-width: 1280px) {
    .tma-shell.rail-desktop .tma-menu-anchor.is-nav-user[b-auyc25fqlz] {
        flex: none;
        margin-block-start: auto;
        max-width: none;
        width: 100%;
    }
}
/* /Components/Pages/AdminDashboard.razor.rz.scp.css */
/* W3 — the bare /admin console's own held-back-reset correction (SHELL.8/W1a's pattern: base.css
   deliberately keeps the prototype's `* { margin: 0 }` out, so a UA <p> margin survives unless the
   page that adds the paragraph corrects it in its own scope). TmaMarketingHero only carries ONE lede
   paragraph; this page's second sentence (the Description the MudBlazor AppPageHeader used to render)
   rides in the hero's ChildContent slot and needs the same correction TmaSection's own lede gets. */
.admin-console-lead[b-2x1g3ifem9] {
  margin: var(--gap-lede) 0 0;
  max-width: var(--w-line);
}
/* /Components/Pages/DataSources.razor.rz.scp.css */
/* ============================================================================
   /data-sources — the source table, the verify bar, and the credit block's fact list.

   Scoped rather than added to app.css on purpose: the public wwwroot text-asset
   budget is capped by a pre-commit hook and app.css sits at it, so page-scoped
   CSS ships in the page's own isolated sheet. The <dl> and its rows are authored
   in DataSources.razor, so CSS isolation stamps them and these rules reach them.

   Everything here is one of two things: a UA default the design's held-back
   reset does not cancel (the <dl>/<dd> margins), or the row rhythm — and both
   distances are tokens.css's, so the light and dark themes track with no second
   rule. The card, its padding, its surface and its type all come from
   TmaFeatureCard and base.css and are NOT restated.
   ========================================================================== */

/* NEW.6 (corporate-fidelity-lift): the table and verify bar, lifted verbatim from the prototype's
   components.css (`.table-wrap`/`.table`/`.unverified-bar`, lines 832-846 and 518-525) — neither
   ships in base.css/shell.css (only the primitives those two sheets already carry are ported), so
   this page-scoped sheet is where a table first needs them. */
.table-wrap[b-hdku969wzw] {
  overflow-x: auto;
  max-width: 100%;
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface);
}

table.table[b-hdku969wzw] {
  width: 100%;
  border-collapse: collapse;
}

.table th[b-hdku969wzw] {
  text-align: start;
  padding: var(--sp-table-cell-y) var(--sp-table-cell-x);
  font-size: var(--t-cap);
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--ink-3);
  border-bottom: 1px solid var(--hairline);
  white-space: nowrap;
}

.table td[b-hdku969wzw] {
  padding: var(--sp-table-cell-y) var(--sp-table-cell-x);
  font-size: var(--t-14);
  color: var(--ink-1);
}

.table tbody tr:nth-child(even)[b-hdku969wzw] {
  background: color-mix(in srgb, var(--surface-2) 55%, transparent);
}

.unverified-bar[b-hdku969wzw] {
  display: flex;
  align-items: center;
  gap: var(--sp-icon-text);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--radius-sm);
  background: var(--unsafe-soft);
  color: var(--unsafe);
  font-size: var(--t-14);
  font-weight: 700;
  margin-top: var(--sp-5);
}

.data-source-credits[b-hdku969wzw] {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  margin-top: var(--sp-5);
}

.data-source-attribution[b-hdku969wzw] {
  margin: 0;
}

.data-source-facts[b-hdku969wzw] {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  margin: var(--sp-3) 0 0;
}

.data-source-fact[b-hdku969wzw] {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}

/* The term is the quiet half of the pair — the value beside it is what a reader
   is scanning for, and `--ink-3` is the design's own de-emphasis step. */
.data-source-fact dt[b-hdku969wzw] {
  color: var(--ink-3);
  font-weight: 600;
}

.data-source-fact dd[b-hdku969wzw] {
  margin: 0;
}

.data-source-visit[b-hdku969wzw] {
  margin-top: var(--sp-3);
}
/* /Components/Pages/Diners.razor.rz.scp.css */
/* Diner branch — mobile-first patron teaser that segues straight into the WASM item-first journey at
   /app/. The page is static SSR (no interactive circuit), so the single "Find your menu" anchor carries
   the whole hand-off: it is a plain anchor well above the 44px minimum, and nothing gates browsing. */

.diner-branch-hero[b-jnrc0p59nr] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
    max-width: 46rem;
    margin: 0 auto 1.5rem;
    padding: 0 1.25rem;
    text-align: left;
}

.diner-branch-headline[b-jnrc0p59nr] {
    font-weight: 800;
    line-height: 1.2;
}

.diner-branch-subhead[b-jnrc0p59nr] {
    color: var(--mud-palette-text-secondary);
    line-height: 1.5;
}

.diner-branch-actions[b-jnrc0p59nr] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
}

/* Primary CTA: the one clear path straight into /app/ — never behind an account. */
.diner-branch-primary[b-jnrc0p59nr] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.85rem 1.5rem;
    border-radius: 0.75rem;
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--mud-elevation-2);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.diner-branch-primary:hover[b-jnrc0p59nr],
.diner-branch-primary:focus-visible[b-jnrc0p59nr] {
    transform: translateY(-2px);
    box-shadow: var(--mud-elevation-6);
}

.diner-branch-primary:focus-visible[b-jnrc0p59nr] {
    outline: 3px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* The "no account needed" reassurance stays quiet — it is a note, not a gate. */
.diner-branch-note[b-jnrc0p59nr] {
    color: var(--mud-palette-text-secondary);
    font-size: 0.9rem;
    line-height: 1.5;
}

.diner-branch-section[b-jnrc0p59nr] {
    max-width: 46rem;
    margin: 0 auto;
    padding: 0 1.25rem;
}

.diner-branch-path-grid[b-jnrc0p59nr] {
    margin-top: 1rem;
}

/* Tablet and up: the hero relaxes and the CTA sits inline rather than full-bleed. */
@media (min-width: 768px) {
    .diner-branch-actions[b-jnrc0p59nr] {
        flex-direction: row;
        align-items: center;
    }

    .diner-branch-primary[b-jnrc0p59nr] {
        min-width: 16rem;
    }
}

/* Desktop: a touch more breathing room at the top of the teaser. */
@media (min-width: 1280px) {
    .diner-branch-hero[b-jnrc0p59nr] {
        margin-top: 0.5rem;
    }
}
/* /Components/Pages/Error.razor.rz.scp.css */
/* F-541 (hub ruling 2026-08-13): the real page behind app.UseExceptionHandler("/Error") (RequestPipeline.cs) —
   previously Blazor's unbranded stock scaffold ("Error." / "Development Mode" boilerplate meant for a developer,
   never a real visitor). Restyled to the branded empty-state shape the prototype's auth/error.html proposes for
   exactly this page ("the live platform's error page is an unbranded stock framework scaffold. This screen
   proposes the branded replacement"). RequestId/ShowRequestId logic in the code-behind is untouched — only how it
   is presented changed. Same centered empty-state shape and token rationale as SignInInterrupted.razor.css. */

.signed-out-panel[b-ls1qz3ykkz] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    padding: 2.5rem 1.75rem;
    background: var(--public-surface);
    border-color: var(--public-border);
}

.signed-out-icon[b-ls1qz3ykkz] {
    color: var(--public-muted);
}

.signed-out-panel .mud-typography-body1[b-ls1qz3ykkz] {
    color: var(--public-muted);
    max-width: 40ch;
}

.error-request-id[b-ls1qz3ykkz] {
    font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
    color: var(--public-muted);
}

.signed-out-actions[b-ls1qz3ykkz] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
    max-width: 320px;
    margin-top: 0.5rem;
}
/* /Components/Pages/ForRestaurants.razor.rz.scp.css */
/* Restaurant branch — mobile-first sales landing that drives into the signup -> Stripe chain.
   The page is static SSR (no interactive circuit), so the CTA links and plan cards carry the whole
   funnel: every touch target is a plain anchor well above the 44px minimum. */

.restaurant-branch-hero[b-jnfr9ozrss] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    align-items: flex-start;
    max-width: 46rem;
    margin: 0 auto 1.5rem;
    padding: 0 1.25rem;
    text-align: left;
}

.restaurant-branch-headline[b-jnfr9ozrss] {
    font-weight: 800;
    line-height: 1.2;
}

.restaurant-branch-subhead[b-jnfr9ozrss] {
    color: var(--mud-palette-text-secondary);
    line-height: 1.5;
}

.restaurant-branch-actions[b-jnfr9ozrss] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
}

/* Primary CTA: the one clear path into /signup. */
.restaurant-branch-primary[b-jnfr9ozrss] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 48px;
    padding: 0.85rem 1.5rem;
    border-radius: 0.75rem;
    background: var(--mud-palette-primary);
    color: var(--mud-palette-primary-text);
    font-weight: 700;
    text-decoration: none;
    box-shadow: var(--mud-elevation-2);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

.restaurant-branch-primary:hover[b-jnfr9ozrss],
.restaurant-branch-primary:focus-visible[b-jnfr9ozrss] {
    transform: translateY(-2px);
    box-shadow: var(--mud-elevation-6);
}

.restaurant-branch-primary:focus-visible[b-jnfr9ozrss],
.restaurant-branch-secondary:focus-visible[b-jnfr9ozrss],
.restaurant-plan-cta:focus-visible[b-jnfr9ozrss] {
    outline: 3px solid var(--mud-palette-primary);
    outline-offset: 2px;
}

/* Secondary links: calculator + pricing, quieter than the primary CTA. */
.restaurant-branch-secondary[b-jnfr9ozrss] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    font-weight: 600;
    color: var(--mud-palette-primary);
    text-decoration: none;
}

.restaurant-branch-secondary:hover[b-jnfr9ozrss] {
    text-decoration: underline;
}

/* Static plan cards — each is a per-plan deep link into /signup?...&planKind=<kind>. */
.restaurant-plan-grid[b-jnfr9ozrss] {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    width: 100%;
}

/* F-657: this page is [ExcludeFromInteractiveRouting] (static SSR, no circuit -- see the file header
   above), so --mud-palette-* is never a plain CSS token here: MudBlazor bakes its resolved hex values
   in at render time from TmaThemeProviderHost's IsDarkMode="State.IsDark", and ThemeModeState.IsDark
   only becomes correct once a live circuit's OnAfterRenderAsync round-trips to browser storage -- which
   never happens on this route. Every --mud-palette-* reference below was therefore frozen to the LIGHT
   palette regardless of the visitor's actual dark-mode choice (TmaTheme.cs PaletteLight.Surface =
   #FFFFFF), while the un-colored title/price inherited the surrounding page's real (dark-mode-correct)
   ambient text color -- near-white on white. Ported to the SAME --public-*/tokens.css family every
   other static public element already uses correctly (SignInInterrupted.razor.css's own precedent: a
   pure CSS custom property the browser resolves from data-theme before any Blazor circuit exists)[b-jnfr9ozrss],
   pinned by ForRestaurantsPlanCardDarkModeTests.cs. */
.restaurant-plan-card[b-jnfr9ozrss] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 1.5rem 1.25rem;
    border: 1px solid var(--public-border);
    border-radius: 1rem;
    background: var(--public-surface);
    box-shadow: 0 12px 30px rgba(44, 62, 80, 0.12);
}

/* Reuses .pricing-plan-card.is-best-value's own accent (app.css) literally -- that card is INTERACTIVE
   (Pricing.razor carries no [ExcludeFromInteractiveRouting]) and already ships this exact gradient/
   border pair correctly in both themes, so this card now matches its already-proven twin instead of
   inventing a second dark-safe accent. */
.restaurant-plan-card--featured[b-jnfr9ozrss] {
    background: linear-gradient(180deg, rgba(51, 204, 204, 0.16), var(--public-surface) 36%);
    border-color: rgba(51, 204, 204, 0.48);
}

.restaurant-plan-name[b-jnfr9ozrss] {
    color: var(--public-text);
    font-size: 1.1rem;
    font-weight: 700;
}

.restaurant-plan-price[b-jnfr9ozrss] {
    color: var(--public-text);
    font-size: 1.5rem;
    font-weight: 800;
}

.restaurant-plan-cadence[b-jnfr9ozrss] {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--public-muted);
}

.restaurant-plan-lock[b-jnfr9ozrss] {
    align-self: flex-start;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--accent-soft);
    color: var(--accent-fg);
    font-size: 0.75rem;
    font-weight: 700;
}

.restaurant-plan-cta[b-jnfr9ozrss] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    margin-top: 0.5rem;
    padding: 0.65rem 1.25rem;
    border-radius: 0.65rem;
    border: 1px solid var(--accent-fg);
    color: var(--accent-fg);
    font-weight: 700;
    text-decoration: none;
    transition: background 0.15s ease, color 0.15s ease;
}

.restaurant-plan-card--featured .restaurant-plan-cta[b-jnfr9ozrss] {
    background: var(--accent-strong);
    color: var(--accent-on-strong);
    border-color: var(--accent-strong);
}

.restaurant-plan-cta:hover[b-jnfr9ozrss] {
    background: var(--accent-strong);
    color: var(--accent-on-strong);
}

/* Tablet: the actions sit inline and the plan cards fan out. */
@media (min-width: 768px) {
    .restaurant-branch-actions[b-jnfr9ozrss] {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: center;
    }

    .restaurant-plan-grid[b-jnfr9ozrss] {
        grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    }
}

/* Desktop: a touch more breathing room around the hero. */
@media (min-width: 1280px) {
    .restaurant-branch-hero[b-jnfr9ozrss] {
        padding: 0.5rem 1.25rem 0;
    }
}
/* /Components/Pages/Home.razor.rz.scp.css */
/* Restaurant-first front door — mobile-first (375px base, layered up with min-width).
   The page is static SSR: no interactive circuit, so styling carries the whole experience.
   The hero itself is TmaMarketingHero + TmaActionLink now (NEW.2's componentization pass) — its
   look, tap targets, and AA contrast are owned by base.css/TmaActionLink.razor.css and the design
   tokens, not by this page. Only the diner band below remains page-owned markup. */

/* The diner entry: one unmissable full-width band straight into the patron app. */
.home-diner-band[b-spijl2gq41] {
    padding: 1rem 1.25rem 3rem;
    max-width: 72rem;
    margin: 0 auto;
}

.home-diner-link[b-spijl2gq41] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    min-height: 44px;
    padding: 1.5rem 1.25rem;
    border: 1px solid var(--hairline);
    border-radius: 1rem;
    background: var(--surface);
    text-align: left;
    text-decoration: none;
    color: var(--ink-1);
    box-shadow: var(--elev-1);
    transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}

.home-diner-link:hover[b-spijl2gq41],
.home-diner-link:focus-visible[b-spijl2gq41] {
    transform: translateY(-2px);
    box-shadow: var(--elev-4);
    border-color: var(--accent);
}

.home-diner-link:focus-visible[b-spijl2gq41] {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
}

.home-diner-icon[b-spijl2gq41] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 0.75rem;
    background: var(--surface-2);
}

.home-diner-copy[b-spijl2gq41] {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.home-diner-title[b-spijl2gq41] {
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.2;
}

.home-diner-body[b-spijl2gq41] {
    color: var(--ink-2);
    font-size: 0.95rem;
    line-height: 1.5;
}

.home-diner-cta[b-spijl2gq41] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-weight: 700;
    /* W1a: was a fixed AA-safe literal shade (measured against the white card only, per F-136) —
       MudBlazor's palette vars never tracked data-theme on this page, which is exactly what the
       dark-styling ruling (2026-08-09) exposed as white-on-white once the light lock came off
       (measured live). --eyebrow is the design system's teal accent and carries its own AA-checked
       value in both themes, so this rule now needs no page-owned literal or per-theme override. */
    color: var(--eyebrow);
}

/* Tablet and up: the diner band becomes one horizontal row. */
@media (min-width: 768px) {
    .home-diner-band[b-spijl2gq41] {
        padding: 1.5rem 2rem 4rem;
    }

    .home-diner-link[b-spijl2gq41] {
        flex-direction: row;
        align-items: center;
        padding: 1.75rem 2rem;
    }

    .home-diner-copy[b-spijl2gq41] {
        flex: 1;
    }
}
/* /Components/Pages/HostMarketOffer.razor.rz.scp.css */
/* The market-switcher chip row from the prototype's market-offer.html foot — the one piece of
   this page that had no production equivalent. Everything else here (plan builder, FIFA stats,
   story, claim steps) is real functionality that already exceeds the design's stub content, kept
   for the same reason /contact kept its live form instead of the prototype's five-field fixture. */

.host-market-switcher[b-6wkqhnk9f1] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-2);
    justify-content: center;
    margin: 2rem auto 3rem;
    max-width: 72rem;
    padding: 0 1.25rem;
}

.host-market-chip[b-6wkqhnk9f1] {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 var(--sp-4);
    border: 1px solid var(--hairline-strong);
    border-radius: var(--radius-pill);
    background: var(--surface-2);
    color: var(--ink-1);
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.host-market-chip:hover[b-6wkqhnk9f1] {
    border-color: var(--accent);
    color: var(--accent-fg);
}

.host-market-chip:focus-visible[b-6wkqhnk9f1] {
    outline: 3px solid var(--accent);
    outline-offset: 2px;
}

.host-market-chip.is-on[b-6wkqhnk9f1] {
    border-color: var(--accent);
    color: var(--accent-fg);
    font-weight: 700;
}
/* /Components/Pages/MenuItemSlides.razor.rz.scp.css */
/* design-w2f-team-study-tools (NEW.1): the deck builder panel and its settings drawer onto business/
   menu-item-slides.html's card/token vocabulary. Deck generation, source selection and every settings
   field (MenuItemSlides.razor.cs, .Deck.cs, .Fields.cs, .Source.cs) are BEHAVIOR and untouched here —
   this pass adds classes to no element; every selector targets an existing hook this page already
   renders.

   ADDITIVE token pass, same reasoning as MenuItemSlidesMemoryPractice.razor.css: a Blazor scoped
   selector always outranks the bare global class app.css already carries for the same name, so this
   overlay wins without deleting app.css's matching rules (unverifiable without a browser under this
   lane's auth-blocked, no-preview_start constraint) and without adding a single byte to app.css itself.

   ::deep reaches MudPaper/MudIconButton/MudButton's own rendered roots; plain selectors reach the
   `<div>`/`<aside>`/`<header>`/`<footer>` markup authored directly in this page. */

[b-07vwyii2ys] .flashcards-builder-panel {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
}

.flashcards-source-stat[b-07vwyii2ys] {
    background: var(--accent-soft);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    color: var(--ink-1);
}

.flashcards-source-stat small[b-07vwyii2ys] {
    color: var(--ink-3);
}

.flashcards-section-picker[b-07vwyii2ys] {
    background: var(--surface-2);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
}

.flashcards-section-option[b-07vwyii2ys] {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
}

.flashcards-drawer-backdrop[b-07vwyii2ys] {
    background: rgba(0, 0, 0, .55);
}

.flashcards-settings-drawer[b-07vwyii2ys] {
    background: var(--surface);
    border-left: 1px solid var(--hairline);
    box-shadow: var(--elev-4);
}

.flashcards-settings-head[b-07vwyii2ys] {
    border-bottom: 1px solid var(--hairline);
}
/* /Components/Pages/MenuItemSlides/MenuItemSlidesMemoryPractice.razor.rz.scp.css */
/* design-w2f-team-study-tools (NEW.1): the four memory-practice modes (blur/words/initials/type) onto
   business/study.html's `.mem-tab`/`.mem-group`/`.mem-token`/`.mem-status` token vocabulary. The mode
   switch, blur clamp, word-build, initials and typed-phrase scoring (MenuItemSlides.Memory.cs,
   FlashcardMemoryEngine) are BEHAVIOR and untouched here — every rule below targets an existing class
   this component already renders, so no markup changed.

   This is an ADDITIVE token pass over `app.css`'s pre-existing hardcoded-hex rules for these same
   classes, not a removal: a Blazor scoped selector (`.class[b-xyz]`) always outranks the bare global
   `.class` selector on specificity, so these rules win without deleting app.css's ~200 matching lines
   under a byte cap (F-191/F-416) and without an unverifiable "delete + hope nothing else used it" step.
   The dead app.css rules are now-superseded weight, flagged to the hub as follow-up debt rather than
   removed blind — this pass has no way to visually re-verify a global-file deletion (auth-blocked, no
   preview_start per lane constraints).

   ::deep reaches MudIcon/MudButton/MudTextField's own rendered roots; plain selectors reach the
   `<button>`/`<span>`/`<section>` markup authored directly in this component. */

[b-ozin07yu13] .menu-memory-tab {
    background: var(--surface);
    border-color: var(--hairline);
    border-radius: var(--radius-sm);
    color: var(--ink-2);
}

[b-ozin07yu13] .menu-memory-tab:hover,
[b-ozin07yu13] .menu-memory-tab:focus-visible {
    border-color: var(--hairline-strong);
}

[b-ozin07yu13] .menu-memory-tab.is-active {
    background: var(--accent-soft);
    border-color: var(--accent-strong);
    color: var(--accent-fg);
}

[b-ozin07yu13] .menu-memory-radio {
    background: var(--surface);
    border-color: var(--hairline-strong);
}

[b-ozin07yu13] .menu-memory-tab.is-active .menu-memory-radio {
    border-color: var(--accent-strong);
}

[b-ozin07yu13] .menu-memory-tab.is-active .menu-memory-radio::after {
    background: var(--accent-strong);
}

[b-ozin07yu13] .menu-memory-tab-icon {
    color: var(--accent-strong);
}

[b-ozin07yu13] .menu-memory-tab-copy small {
    color: var(--ink-3);
}

.menu-memory-status[b-ozin07yu13] {
    color: var(--ink-3);
    font-size: var(--t-cap);
    font-weight: 700;
}

.menu-memory-value-group + .menu-memory-value-group[b-ozin07yu13] {
    margin-top: var(--sp-3);
}

.menu-memory-value-group h3[b-ozin07yu13] {
    color: var(--ink-1);
    font-size: var(--t-cap);
    font-weight: 800;
    letter-spacing: var(--track-caps-head);
    text-transform: uppercase;
}

.menu-memory-reference[b-ozin07yu13] {
    background: var(--surface-2);
    border-radius: var(--radius-sm);
    padding: var(--sp-2) var(--sp-3);
}

.menu-memory-word.is-hidden[b-ozin07yu13] {
    border-radius: 4px;
    filter: blur(6px);
    transition: filter .2s ease;
}

.menu-memory-type-token[b-ozin07yu13],
.menu-memory-initial-token[b-ozin07yu13] {
    border: 1px dashed var(--hairline-strong);
    border-radius: var(--radius-sm);
    color: var(--ink-3);
    display: inline-block;
    font-size: var(--t-14);
    padding: 2px 8px;
}

.menu-memory-type-token.is-correct[b-ozin07yu13],
.menu-memory-initial-token.is-correct[b-ozin07yu13] {
    border-color: var(--safe);
    border-style: solid;
    color: var(--ink-1);
}

.menu-memory-type-token.is-incorrect[b-ozin07yu13],
.menu-memory-initial-token.is-incorrect[b-ozin07yu13] {
    border-color: var(--unsafe);
    border-style: solid;
    color: var(--unsafe);
}
/* /Components/Pages/PatronAccount.razor.rz.scp.css */
/* The shared include/exclude term modules, wearing this site's skin.

   The MARKUP is the patron app's — one editor, so include/exclude behaves the same wherever a guest meets it — but
   the patron app's stylesheet is not loaded here, so the account page dresses those hooks in its own tokens rather
   than importing a second design language next to the Mud fields around them.

   These live in the page's isolated stylesheet rather than app.css for two reasons: app.css is a browser-visible
   asset held to a size budget, and these rules apply to exactly one page. `::deep` is what carries them past the
   component boundary into the modules' own markup — and into MoodPreferenceCard, which is only ever rendered here.

   Mobile-first: the add row wraps on a narrow phone and every control keeps a 44px tap target. Measured headless at
   375 / 768 / 1280 — no overflow at any width, chips wrap to three rows at 375. */

.patron-account-management-grid[b-yz169e5rhn]  .term-module,
.patron-account-card-grid[b-yz169e5rhn]  .term-module {
    display: grid;
    gap: 0.5rem;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-module-label,
.patron-account-card-grid[b-yz169e5rhn]  .term-module-label {
    color: var(--tma-muted);
    font-size: 0.74rem;
    font-weight: 900;
    text-transform: uppercase;
}

.patron-account-management-grid[b-yz169e5rhn]  .ym-chip-input,
.patron-account-card-grid[b-yz169e5rhn]  .ym-chip-input {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-module-input,
.patron-account-card-grid[b-yz169e5rhn]  .term-module-input {
    background: var(--mud-palette-surface);
    border: 1px solid var(--tma-border);
    border-radius: 4px;
    color: var(--tma-ink);
    flex: 1 1 8rem;
    font: inherit;
    min-height: 44px;
    padding: 0.5rem 0.75rem;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-module-input:focus-visible,
.patron-account-card-grid[b-yz169e5rhn]  .term-module-input:focus-visible {
    border-color: var(--mud-palette-primary);
    outline: 1px solid var(--mud-palette-primary);
}

.patron-account-management-grid[b-yz169e5rhn]  .term-module-add,
.patron-account-card-grid[b-yz169e5rhn]  .term-module-add {
    background: transparent;
    border: 1px solid var(--mud-palette-primary);
    border-radius: 4px;
    color: var(--mud-palette-primary);
    cursor: pointer;
    font-weight: 700;
    min-height: 44px;
    min-width: 44px;
    padding: 0 1rem;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-chips,
.patron-account-card-grid[b-yz169e5rhn]  .term-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-chips li,
.patron-account-card-grid[b-yz169e5rhn]  .term-chips li {
    align-items: center;
    display: inline-flex;
}

/* The chip pill repeats the read-only mood term pill (.patron-mood-term-list span in app.css) so the editable and
   summary views of the same terms read as one set. */
.patron-account-management-grid[b-yz169e5rhn]  .term-chips .search-chip,
.patron-account-card-grid[b-yz169e5rhn]  .term-chips .search-chip {
    background: color-mix(in srgb, var(--mud-palette-primary) 10%, transparent);
    border: 1px solid var(--tma-border);
    border-radius: 999px;
    color: var(--tma-ink);
    font-size: 0.78rem;
    font-weight: 700;
    line-height: 1;
    padding: 0.42rem 0.58rem;
}

.patron-account-management-grid[b-yz169e5rhn]  .term-chips .search-chip.is-exclusion,
.patron-account-card-grid[b-yz169e5rhn]  .term-chips .search-chip.is-exclusion {
    background: color-mix(in srgb, var(--mud-palette-warning) 12%, transparent);
}

.patron-account-management-grid[b-yz169e5rhn]  .term-chip-remove,
.patron-account-card-grid[b-yz169e5rhn]  .term-chip-remove {
    align-items: center;
    background: none;
    border: 0;
    color: var(--tma-muted);
    cursor: pointer;
    display: inline-flex;
    font-size: 1.1rem;
    justify-content: center;
    line-height: 1;
    min-height: 44px;
    min-width: 44px;
}
/* /Components/Pages/PrintableMenuTemplates.razor.rz.scp.css */
/* design-w3-employee-and-display-surfaces (NEW.1, part 2): the printable-menu template preview's own
   print regime, scoped to this page only. app.css already carries ONE shared @media print block, but
   it belongs to the QR templates/designer and flashcards surfaces (DO-NOT-TOUCH per the QR-templates-
   builder guard) — adding this page's rules there would grow a cross-surface block instead of keeping
   print rules with the page that owns them. Sending this workbench to a physical printer shows ONLY the
   selected preset's sheet at full width; the preset/paper picker state (SelectedPreset/SelectedPaper in
   PrintableMenuTemplates.razor's @code block) and the --printable-menu-* custom properties it computes
   are untouched — this sheet only hides on-screen chrome and re-sizes the sheet's own box for paper. */

@media print {
    .printable-menu-controls[b-rozva9mfwe],
    .printable-menu-preview-head[b-rozva9mfwe],
    .printable-menu-coverage-grid[b-rozva9mfwe] {
        display: none !important;
    }

    .printable-menu-workbench[b-rozva9mfwe] {
        display: block !important;
    }

    .printable-menu-preview-panel[b-rozva9mfwe] {
        background: none !important;
        border: 0 !important;
        box-shadow: none !important;
        position: static !important;
    }

    .printable-menu-preview[b-rozva9mfwe] {
        aspect-ratio: auto !important;
        border: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        break-inside: avoid;
        margin: 0 !important;
        max-width: none !important;
        width: 100% !important;
    }
}
/* /Components/Pages/QrTemplates.razor.rz.scp.css */
/* F-553 (NEW.1): QR templates builder page onto the design system's card/token vocabulary. ADDITIVE overlay only
   (design-w2f's menu-item-slides/admin-setup technique) — Blazor CSS isolation scopes every selector below to the
   elements THIS page renders, so it wins over app.css's shared `.tool-panel` rule on selector specificity (a scoped
   class selector compiles to a compound class+attribute selector) without touching that rule, which other pages
   still use as-is. `.qr-template-spec-item` is unique to this page, but stays scoped/additive for the same reason.

   Skin only: colour/background/border-colour/shadow. No display, gap, padding, or grid-template-columns override —
   this page's layout (workbench grid, control-group spacing, segmented-control sizing) is untouched. */

.qr-template-controls-panel[b-qjprocu3mj] {
    background: var(--surface);
    border-color: var(--hairline);
    box-shadow: var(--elev-1);
}

.qr-template-spec-item[b-qjprocu3mj] {
    background: var(--surface-2);
    border-color: var(--hairline);
}

.qr-template-spec-item small[b-qjprocu3mj] {
    color: var(--ink-3);
}

.qr-template-spec-item strong[b-qjprocu3mj] {
    color: var(--ink-1);
}
/* /Components/Pages/SignedOut.razor.rz.scp.css */
/* F-541 (hub ruling 2026-08-13): the real, wired page for the prototype's auth/signed-out.html — restyle only,
   the data-analytics-event/label attributes in the markup are untouched. Same centered empty-state shape as
   SignInInterrupted.razor.css (see that file's header for the token rationale) — kept as a second scoped file
   rather than a shared one because Razor Pages/Components CSS isolation only reaches one page. */

.signed-out-panel[b-om3letbidm] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    padding: 2.5rem 1.75rem;
    background: var(--public-surface);
    border-color: var(--public-border);
}

.signed-out-icon[b-om3letbidm] {
    color: var(--public-muted);
}

.signed-out-panel .mud-typography-body1[b-om3letbidm] {
    color: var(--public-muted);
    max-width: 40ch;
}

.signed-out-actions[b-om3letbidm] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
    max-width: 320px;
    margin-top: 0.5rem;
}
/* /Components/Pages/SignInInterrupted.razor.rz.scp.css */
/* F-541 (hub ruling 2026-08-13): the real, wired page for the prototype's auth/interrupted.html — restyle only,
   the FB-24 anti-redirect-loop behavior in the code-behind is untouched. Ported look: a centered icon over the
   message, actions stacked full-width beneath, matching the prototype's Auth.frame empty-state card. Colors ride
   the public shell's own theme-aware tokens (--public-*, defined in app.css and swapped under
   :root[data-theme="dark"] .site-shell.is-public-site) rather than the design prototype's separate token set, so
   this page changes theme in lockstep with the rest of the public site instead of importing a second palette. */

.signed-out-panel[b-lg5ux8d3us] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    text-align: center;
    padding: 2.5rem 1.75rem;
    background: var(--public-surface);
    border-color: var(--public-border);
}

.signed-out-icon[b-lg5ux8d3us] {
    color: var(--public-muted);
}

.signed-out-panel .mud-typography-body1[b-lg5ux8d3us] {
    color: var(--public-muted);
    max-width: 40ch;
}

.signed-out-actions[b-lg5ux8d3us] {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    width: 100%;
    max-width: 320px;
    margin-top: 0.5rem;
}
/* /Components/Pages/StartCheckout.razor.rz.scp.css */
/* ============================================================================
   /signup + /start-checkout — the surfaces this page owns, re-cut onto the
   design tokens.

   SCOPED, NOT app.css, for two reasons and both are load-bearing. app.css is
   ~70 bytes under its enforced public-surface cap (PublicSurfaceAuditTests via
   scripts/audit-public-surface.mjs), so it cannot take another rule at all; and
   SHELL.8's rule is that a component's look lives beside its .razor, which is
   what keeps two port chips file-disjoint instead of serialising on one file's
   merge.

   These selectors NARROW the app.css rules of the same name rather than
   replacing them: the grid geometry (columns, gaps, the 1280/768 steps) stays
   where it is, and what is restated here is only the part that was painted with
   a literal. Blazor's isolation rewrites each selector with this component's
   scope attribute and the host loads Tma.CorporateSite.styles.css AFTER app.css,
   so these win by specificity and by order — deliberately both, so neither an
   attribute-order change nor a link-order change can silently un-apply them.

   🔴 WHY THIS SHEET EXISTS AT ALL: the panels below were `#f8fbfc`, `#f4fbff`
   and `rgba(41,128,185,.22)`. Those are FIXED light values, so on the dark theme
   this page painted three light cards beside a hero and a section painting
   `--surface` — the same theme-deaf defect SHELL.6 measured on the drawer's ink,
   which was invisible in review because each rule was individually correct.
   Every value here is a token, so both themes are real by construction.
   ========================================================================== */

/* The design's `.card`, lifted from TmaFeatureCard.razor.css rather than
   imported: `.card` is component-scoped by design (base.css owns layout and type
   primitives, not surfaces), so a plain <div class="card"> written by a PAGE
   matches nothing at all — silently, which is the SHELL.8 `::deep` trap in its
   other direction. The block is small enough to state; the alternative is a
   global `.card` that restyles ~145 unported routes. */
.checkout-start-card[b-6zrbz89ktq] {
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-card-pad);
  box-shadow: var(--elev-1);
  gap: var(--sp-related);
}

/* The submit's own state message. One line, in the flow, above the form it
   describes — not a floating alert, because the snackbar already carries the
   transient copy and this is the durable one. `--warn` / `--ink-2` rather than a
   severity palette: the design has exactly one warning ink. */
.checkout-start-message[b-6zrbz89ktq] {
  margin: 0;
  color: var(--ink-2);
}

.checkout-start-message.is-warning[b-6zrbz89ktq] {
  color: var(--warn, var(--error));
  font-weight: 600;
}

/* The plan summary and the promotion note: both were light-pinned panels. They
   become the design's FLAT card — inside an already-elevated card, a second
   shadow reads as a stack of trays rather than a group. */
.checkout-start-summary[b-6zrbz89ktq],
.checkout-start-promo[b-6zrbz89ktq] {
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  box-shadow: none;
}

.checkout-start-summary small[b-6zrbz89ktq],
.checkout-start-summary em[b-6zrbz89ktq],
.checkout-start-promo small[b-6zrbz89ktq] {
  color: var(--ink-3);
}

.checkout-start-summary strong[b-6zrbz89ktq] {
  color: var(--ink-1);
}

.checkout-start-promo strong[b-6zrbz89ktq] {
  color: var(--ink-1);
}

/* The fieldset the plan picker sits in — same hairline as everything else, so
   the three groups inside the card read as one system. */
.checkout-start-plans[b-6zrbz89ktq] {
  border-color: var(--hairline);
  border-radius: var(--radius);
}

.checkout-start-plans-label[b-6zrbz89ktq] {
  color: var(--ink-1);
}

/* The actions row is the design's `.row-wrap`: the buttons bring their own
   `--btn-h` height from TmaActionLink, so all this owns is the gap and the wrap.
   Stated rather than inherited because app.css's rule sizes MudButton children
   that no longer exist here. */
.checkout-start-actions[b-6zrbz89ktq] {
  gap: var(--sp-related);
}

/* NEW.5 (owner report 2026-08-14): Mud's outlined label shrinks only via a C#-toggled class, which
   needs a live circuit — a keystroke typed before the circuit attaches, or an autofill (neither
   fires a C# event), leaves it sitting on the text. app.css has no headroom left under its enforced
   public-surface cap (same reason this whole sheet exists — see the header above), so this scoped
   ::deep fallback reproduces Mud's own shrink transform via two native browser states needing no
   circuit at all: :focus-within (floats from the field's very first keystroke) and :autofill (via
   :has(), the only way to reach the sibling label from the input's own pseudo-class). ::deep is
   required because MudBlazor renders this markup itself, several component boundaries below this
   page's own scope (through MudTextField / TmaEmailField). */
.checkout-start-grid[b-6zrbz89ktq]  .mud-input-control-input-container:focus-within .mud-input-label-outlined,
.checkout-start-grid[b-6zrbz89ktq]  .mud-input-control-input-container:has(.mud-input-slot:autofill) .mud-input-label-outlined {
  transform: translate(14px, -6px) scale(0.75);
  max-width: calc((100% - 14px) / .75);
}

/* Owner ruling 2026-08-15: the three signup fields stack on MOBILE — the app.css stack rule only
   engaged below 560px, above real phone viewports, leaving three cramped columns with truncated
   labels. The platform's mobile/tablet boundary is 768px; the scoped selector outranks app.css's
   bare class, so this wins without touching the shared sheet. */
/* NEW.1 concept-structure block. Tokens only, same as everything else in this sheet, and stated here
   rather than in app.css for the reason the header gives (the public-surface byte cap). The options are
   a two-column grid on the desktop card and stack at the mobile step below, which is the same 768px
   boundary the account fields already stack on — mobile-first by construction, not by a second guess. */
.checkout-start-concept[b-6zrbz89ktq] {
  display: flex;
  flex-direction: column;
  gap: var(--sp-tight, .5rem);
}

.checkout-start-concept-head[b-6zrbz89ktq] {
  display: flex;
  align-items: center;
  gap: var(--sp-tight, .5rem);
}

.checkout-start-concept-label[b-6zrbz89ktq] {
  color: var(--ink-1);
  font-weight: 600;
}

/* The `?` control: a real button, sized to the platform's minimum touch target so it is usable on the
   phone this form is filled in on. */
.checkout-start-concept-help-toggle[b-6zrbz89ktq] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.75rem;
  min-height: 2.75rem;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
}

.checkout-start-concept-help-toggle:hover[b-6zrbz89ktq],
.checkout-start-concept-help-toggle[aria-expanded="true"][b-6zrbz89ktq] {
  color: var(--accent, var(--ink-1));
}

.checkout-start-concept-help[b-6zrbz89ktq] {
  margin: 0;
  color: var(--ink-2);
}

.checkout-start-concept-options[b-6zrbz89ktq] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-related);
}

.checkout-start-concept-option[b-6zrbz89ktq] {
  display: flex;
  align-items: center;
  gap: var(--sp-tight, .5rem);
  padding: var(--sp-card-pad, 1rem);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  background: var(--surface-2);
  color: var(--ink-1);
  cursor: pointer;
}

.checkout-start-concept-option.is-selected[b-6zrbz89ktq] {
  border-color: var(--accent, var(--ink-1));
}

@media (max-width: 47.9375rem) {
    .checkout-start-grid[b-6zrbz89ktq] {
        grid-template-columns: 1fr;
    }

    .checkout-start-concept-options[b-6zrbz89ktq] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/ThankYouPage.razor.rz.scp.css */
/* ============================================================================
   /thank-you-white-glove (+ the -email twin) — the one card shape this page
   owns that the vocabulary has no component for.

   SCOPED, NOT app.css: that sheet is ~70 bytes under its enforced public-surface
   cap, and SHELL.8's rule is that a look lives beside the markup that emits it.

   WHY A CARD BLOCK HERE rather than TmaFeatureCard. That component always emits
   its body paragraph, so a card whose body is a LIST renders an empty <p> with
   `--sp-2` above and below — a phantom gap under every heading. It cannot be
   corrected from this sheet either: the paragraph carries the CARD's scope
   attribute, not this page's, which is the `::deep` trap SHELL.8 recorded (a
   plain selector compiles to something that matches nothing, SILENTLY).

   The `.card` declarations are lifted from TmaFeatureCard.razor.css rather than
   imported, because `.card` is component-scoped BY DESIGN — base.css owns layout
   and type primitives, not surfaces, so a global `.card` would restyle ~145
   unported routes. Every value is a token, so both themes are real: `--surface`
   and `--hairline` flip in tokens.css's dark block and so does the whole
   elevation ramp.
   ========================================================================== */

.thank-you-card[b-wmf9uz17ud] {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  padding: var(--sp-card-pad);
  box-shadow: var(--elev-1);
}

/* The UA's list indent and bullet, replaced by the design's own hanging marker.
   `list-style: none` plus a `::marker`-free check would need a pseudo-element
   with content, which a screen reader may or may not announce; a plain disc at
   the design's `--ink-3` says "list item" once, in the one place it belongs. */
.thank-you-checklist[b-wmf9uz17ud] {
  margin: var(--sp-2) 0 0;
  padding-inline-start: var(--sp-4);
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  color: var(--ink-2);
}

.thank-you-checklist li[b-wmf9uz17ud]::marker {
  color: var(--ink-3);
}

/* The held-back reset, per-component as W1a requires: base.css deliberately does
   NOT ship `* { margin: 0 }`, so this heading would take a UA <h*>-style margin
   from MudBlazor's normalize and break the card's 12/20 rhythm. Zeroed inside
   this scope, which reaches this heading and nothing else. */
.thank-you-card .t-card-title[b-wmf9uz17ud] {
  margin: 0;
}
/* /Components/Pages/WhiteGlove.razor.rz.scp.css */
/* ============================================================================
   /white-glove's page-level paused state (NEW.3, corporate-fidelity-lift).

   Lifted verbatim from the prototype's `.empty` block (assets/css/components.css:848-859) — the
   entire page falls back to this ONE state when the White-Glove platform switch is off
   (white-glove.html:27-41, www.js:72-79 whiteGloveOn()). Scoped here rather than added to app.css:
   app.css sits at the pre-commit hook's text-asset byte cap (DataSources.razor.css's own remark),
   so new page-scoped rules ship in their own isolated sheet.
   ========================================================================== */

.empty[b-0nd43hfwvk] {
  display: grid;
  place-items: center;
  gap: var(--sp-3);
  text-align: center;
  padding: var(--sp-9) var(--sp-5);
  border: 1.5px dashed var(--hairline-strong);
  border-radius: var(--radius);
  color: var(--ink-3);
}

.empty .icon[b-0nd43hfwvk] {
  width: 34px;
  height: 34px;
}

.empty .empty-title[b-0nd43hfwvk] {
  font-weight: 800;
  color: var(--ink-2);
  font-size: var(--t-16);
}

.empty .t-compact[b-0nd43hfwvk] {
  max-width: 40ch;
}

/* The prototype's paused-state actions row carries its own inline `margin-top:var(--sp-4)` — moved
   to this scoped class rather than an inline style, matching how every other ported band on this
   host authors spacing. */
.white-glove-paused-actions[b-0nd43hfwvk] {
  margin-top: var(--sp-4);
  justify-content: center;
}
/* /Components/Pages/WhiteGloveIntake.razor.rz.scp.css */
/* NEW.5 (owner report 2026-08-14): Mud's outlined label shrinks only via a C#-toggled class, which
   needs a live circuit — a keystroke typed before the circuit attaches, or an autofill (neither
   fires a C# event), leaves it sitting on the text. app.css has no headroom left under its enforced
   public-surface cap (scripts/audit-public-surface.mjs), so this scoped ::deep fallback reproduces
   Mud's own shrink transform via two native browser states needing no circuit at all: :focus-within
   (floats from the field's very first keystroke) and :autofill (via :has(), the only way to reach
   the sibling label from the input's own pseudo-class). ::deep is required because MudBlazor renders
   this markup itself, several component boundaries below this page's own scope. This route sits
   behind RestaurantToolGate (sign-in required), so it is not one of the public forms the audit
   targets, but the identical MudBlazor defect reproduces for a signed-in operator, so it is fixed
   here too. Keyed off .intake-form, the wrapper around every field on this page. */
.intake-form[b-nkzjraa04v]  .mud-input-control-input-container:focus-within .mud-input-label-outlined,
.intake-form[b-nkzjraa04v]  .mud-input-control-input-container:has(.mud-input-slot:autofill) .mud-input-label-outlined {
    transform: translate(14px, -6px) scale(0.75);
    max-width: calc((100% - 14px) / .75);
}
/* /Components/Shared/CheckoutEmailCorrectionForm.razor.rz.scp.css */
/* Scoped, not app.css: that stylesheet sits at its enforced public-surface byte cap, and this chrome belongs to one
   component (same reasoning as CheckoutVerificationStep.razor.css, whose tokens and fallbacks this mirrors so the two
   groups on the page share one rhythm). */
.checkout-email-correction[b-329la1l47h] {
    width: 100%;
}

/* Secondary to the code box by weight, not by hiding: a stranded buyer has to be able to FIND this, and the
   underline plus a 44px target is what makes it read as the action it is on a phone. */
.checkout-email-correction-summary[b-329la1l47h] {
    display: flex;
    align-items: center;
    min-height: 44px;
    font-size: var(--t-16, 1rem);
    font-weight: 600;
    line-height: var(--lh-compact, 1.35);
    text-decoration: underline;
    cursor: pointer;
    color: var(--brand-blue-strong, #1F6E9C);
}

.checkout-email-correction-summary:focus-visible[b-329la1l47h] {
    outline: 2px solid var(--brand-blue-strong, #1F6E9C);
    outline-offset: 2px;
}

/* One group, same internal rhythm as the code form next to it. */
.checkout-email-correction-form[b-329la1l47h] {
    display: flex;
    flex-direction: column;
    gap: var(--sp-label-control, 8px);
    width: 100%;
    margin-top: var(--sp-3, 12px);
}

.checkout-email-correction-help[b-329la1l47h] {
    margin: 0;
    font-size: var(--t-14, 0.875rem);
    line-height: var(--lh-body, 1.5);
    opacity: 0.78;
}

/* Full width and left-aligned, unlike the code field: an address is read left-to-right and can be long, so the
   centred, letter-spaced treatment that makes six digits legible would make this one hard to check. */
.checkout-email-correction-input[b-329la1l47h] {
    width: 100%;
    min-height: 48px;
    padding: var(--sp-3, 12px) var(--sp-4, 16px);
    font-size: var(--t-16, 1rem);
    border: 1px solid rgba(44, 62, 80, 0.38);
    border-radius: 0.5rem;
    /* NEW.3 (owner report 2026-08-17): this well was a FIXED #fff, so on the dark theme the address field
       painted a bright white box beside the code field one group over — which W1c had already re-cut onto the
       tokens (CheckoutVerificationStep.razor.css:106). `--surface` is #FFFFFF in tokens.css's light block, so
       light mode renders the identical byte; the dark block flips it to the card surface. The fallback stays
       for this sheet's own stated reason: on the public site a token sheet that fails to load must still
       leave a usable field. */
    background: var(--surface, #fff);
    color: inherit;
}

/* The ink and the hairline are paired to the surface above rather than tokenised outright: their LIGHT
   literals (`inherit`, which resolves to app.css's body ink, and a 38%-opacity dark-blue rule) are not the
   light value of any token, so consuming one would have silently restyled light mode too. Overriding only
   under the resolved dark theme keeps light byte-identical and still gives the dark field readable ink and a
   hairline that is visible against it. Keyed on `:root[data-theme="dark"]` — theme-boot.js stamps that before
   first paint, and this control renders on a static-SSR payment route where `body.theme-dark` (written by the
   circuit, after connect) would arrive too late. Blazor rewrites the LAST compound of the selector with this
   component's scope attribute, so the rule still cannot leak past this input. */
:root[data-theme="dark"] .checkout-email-correction-input[b-329la1l47h] {
    border-color: var(--hairline-strong, rgba(236, 240, 241, 0.22));
    color: var(--ink-1, #edf2f6);
}

.checkout-email-correction-input:focus-visible[b-329la1l47h] {
    outline: 2px solid var(--brand-blue-strong, #1F6E9C);
    outline-offset: 2px;
    border-color: var(--brand-blue-strong, #1F6E9C);
}
/* /Components/Shared/CheckoutEmbeddedPaymentStep.razor.rz.scp.css */
.checkout-embedded-step[b-wy1h0utbfg] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: 100%;
}

.checkout-embedded-heading[b-wy1h0utbfg] {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
}

.checkout-embedded-heading span[b-wy1h0utbfg] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.checkout-embedded-heading small[b-wy1h0utbfg] {
    opacity: 0.78;
}

/* The Stripe iframe is responsive; our chrome only has to give it full width and honest height,
   down to the 375px mobile-first baseline. */
.checkout-embedded-mount[b-wy1h0utbfg] {
    width: 100%;
    min-height: 480px;
}

.checkout-embedded-retry[b-wy1h0utbfg] {
    display: flex;
    justify-content: flex-start;
}
/* /Components/Shared/CheckoutVerificationStep.razor.rz.scp.css */
/* ============================================================================
   The post-payment route's own chrome — W1c, re-cut onto the design tokens.

   Scoped, not app.css: that stylesheet sits at its enforced public-surface byte
   cap (~70 bytes of headroom), and this chrome belongs to one component anyway —
   the SHELL.8 rule that keeps two port chips file-disjoint.

   WHAT W1c CHANGED, and why it was worth changing on a live payment route.
   Every surface below used to be a FIXED light value: `background: #fff` on both
   fields, `rgba(44, 62, 80, 0.38)` on their borders, and
   `var(--brand-blue-strong, #1F6E9C)` on the focus ring. On the dark theme this
   route therefore painted two white input wells and a white card beside a hero
   painting `--surface` — the same theme-deaf defect SHELL.6 measured on the
   drawer's ink, invisible in review because each rule was individually correct.
   `--surface` / `--surface-2` / `--hairline` / `--accent` / `--ink-*` all flip in
   tokens.css's dark block, so both themes are now real by construction and no
   colour literal remains in this file.

   The SEMANTIC spacing tokens are kept in preference to the raw --sp-N scale:
   --sp-label-control and --sp-control-help say WHY a gap exists, which is what
   stops a later edit quietly flattening the form's hierarchy back out. The var()
   fallbacks stay for the same reason they were added — this renders on the
   public site, where a token sheet failing to load must degrade to a usable form
   rather than a collapsed one.
   ========================================================================== */

/* The design's `.card`, stated rather than imported: `.card` is scoped to
   TmaFeatureCard by design (base.css owns layout and type primitives, not
   surfaces), so a plain <div class="card"> written here would match nothing at
   all, silently. */
.checkout-verification-card[b-e5p0lmoelz] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    /* Group-level rhythm: the alert, the form and the resend action are separate groups, so they sit a field-gap
       apart rather than the old uniform 1rem, which read as one undifferentiated stack. */
    gap: var(--sp-field-field, 24px);
    width: 100%;
    max-width: 32rem;
    background: var(--surface, #fff);
    border: 1px solid var(--hairline, rgba(44, 62, 80, 0.16));
    border-radius: var(--radius, 12px);
    box-shadow: var(--elev-1, none);
    padding: var(--sp-card-pad, 20px);
}

/* One line of state, in the flow, above the thing it is about — not a floating
   alert. The design has no alert primitive on its www surface, and the two
   severities differ by exactly one declaration, which is the honest size of the
   difference between "a new code is on its way" and "that code is not valid". */
.checkout-verification-alert[b-e5p0lmoelz] {
    width: 100%;
    margin: 0;
    color: var(--ink-2);
}

.checkout-verification-alert.is-safe[b-e5p0lmoelz] {
    color: var(--safe, var(--ink-1));
    font-weight: 600;
}

.checkout-verification-alert.is-warning[b-e5p0lmoelz] {
    color: var(--warn, var(--error));
    font-weight: 600;
}

.checkout-verification-fallback[b-e5p0lmoelz] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sp-label-control, 8px);
    width: 100%;
}

/* The form is ONE group: label -> field -> help -> action. Its internal gaps are deliberately tighter than the
   card's, so the eye reads it as a single unit instead of four floating items. */
.checkout-verification-form[b-e5p0lmoelz] {
    display: flex;
    flex-direction: column;
    gap: var(--sp-label-control, 8px);
    width: 100%;
}

/* `.t-label` on the element carries the design's label type; this adds only the
   line-height the base rule leaves to context. */
.checkout-verification-label[b-e5p0lmoelz] {
    line-height: var(--lh-compact, 1.35);
}

/* Wide letter-spacing and a large type size so a six-digit code read off a phone is unambiguous. The trailing
   letter-spacing pushes the last glyph off-centre, so the text is nudged back by half a step to keep the digits
   optically centred in the field. This is the prototype's `.code-row .input` treatment (52x60, --t-24, 800) on
   ONE field rather than four boxes — see the note at the top of the .razor for why the four do not port. */
.checkout-verification-input[b-e5p0lmoelz] {
    width: 100%;
    max-width: 16rem;
    min-height: 56px;
    padding: var(--sp-3, 12px) var(--sp-4, 16px);
    font-size: var(--t-24, 1.5rem);
    font-weight: 600;
    letter-spacing: 0.4rem;
    text-indent: 0.4rem;
    text-align: center;
    border: 1px solid var(--hairline-strong, var(--hairline, rgba(44, 62, 80, 0.38)));
    border-radius: var(--radius-sm, 8px);
    background: var(--surface-2, #fff);
    color: var(--ink-1, inherit);
}

/* A visible, non-colour-only focus ring: a code field is the one control on this page, and a keyboard or
   screen-magnifier user must be able to see where they are without relying on hue alone. */
.checkout-verification-input:focus-visible[b-e5p0lmoelz] {
    outline: 2px solid var(--accent, #1F6E9C);
    outline-offset: 2px;
    border-color: var(--accent, #1F6E9C);
}

.checkout-verification-help[b-e5p0lmoelz] {
    margin: 0;
    /* The field -> helper relationship is closer than field -> next thing; naming it keeps that true after an edit. */
    margin-top: calc(var(--sp-control-help, 8px) - var(--sp-label-control, 8px));
}

/* The design's `.btn .btn-primary`, stated locally for the one reason it cannot
   be TmaActionLink: redeeming the code re-issues the auth cookie, so this must be
   a real <button type="submit"> inside a plain HTML POST, and TmaActionLink emits
   `type="button"`. `--btn-h` is the design's ONE button height. */
.checkout-verification-submit[b-e5p0lmoelz] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: fit-content;
    min-height: var(--btn-h, 44px);
    margin-top: var(--sp-3, 12px);
    padding-inline: var(--sp-5, 24px);
    font-size: var(--t-16, 1rem);
    font-weight: 700;
    line-height: var(--lh-compact, 1.35);
    border: 0;
    border-radius: var(--radius-pill, 999px);
    background: var(--accent-strong, #1F6E9C);
    color: var(--accent-on-strong, #fff);
    box-shadow: var(--elev-1, none);
    font-family: inherit;
    cursor: pointer;
}

.checkout-verification-submit:focus-visible[b-e5p0lmoelz],
.checkout-verification-textbtn:focus-visible[b-e5p0lmoelz] {
    outline: 2px solid var(--accent, #1F6E9C);
    outline-offset: 2px;
}

/* The design's tertiary role. The resend and password actions are secondary by
   weight and must align FLUSH with the label and field above them — MudBlazor's
   text-button padding indented them ~16px, which is what made the row look
   accidentally offset. The touch target is restored with height, not padding. */
.checkout-verification-textbtn[b-e5p0lmoelz] {
    display: inline-flex;
    align-items: center;
    min-height: var(--btn-h, 44px);
    padding-inline: 0;
    font-size: var(--t-16, 1rem);
    font-weight: 600;
    background: transparent;
    border: 0;
    color: var(--accent-fg, #1F6E9C);
    font-family: inherit;
    cursor: pointer;
}

.checkout-verification-resend[b-e5p0lmoelz] {
    margin: 0;
}

/* NEW.2: the lede above the inline password form — it has to read as an instruction ("do this to unlock
   Tools"), not another status line, so it is body-2 weight rather than the alert's bold safe/warning colours. */
.checkout-verification-password-lede[b-e5p0lmoelz] {
    width: 100%;
    margin: 0;
    color: var(--ink-2, inherit);
}

.checkout-verification-footnote[b-e5p0lmoelz] {
    color: var(--ink-3, inherit);
}

.checkout-verification-inline-link[b-e5p0lmoelz] {
    color: var(--accent, #1F6E9C);
    text-decoration: underline;
}
/* /Components/Shared/PlanCadenceToggle.razor.rz.scp.css */
/* Owner ruling 2026-08-14 (corrected same day): each savings badge pins to the TOP-RIGHT corner of
   its own tab button — the MudBadge-overlap look — by anchoring inside the MudToggleItem it
   describes. Per-button anchoring is what makes the badge layout-proof: whatever the toggle row
   does at any width (row, wrap, stack), the anchor IS the button. Scoped here so app.css gains
   zero lines; colors ride the design tokens so both themes resolve. The wrap's top padding gives
   the raised chip headroom; overflow stays visible the whole way up so no ancestor clips it. */

.plan-cadence-toggle-wrap[b-qj17vn72l9] {
    padding-top: 0.6rem;
}

.plan-cadence-toggle-wrap[b-qj17vn72l9]  .plan-builder-cadence {
    overflow: visible;
}

.plan-cadence-toggle-wrap[b-qj17vn72l9]  .plan-builder-cadence .mud-toggle-item {
    overflow: visible;
    position: relative;
}

.plan-cadence-toggle-wrap[b-qj17vn72l9]  .cadence-save-chip {
    background: var(--public-surface);
    border: 1px solid var(--mud-palette-primary);
    border-radius: 999px;
    box-shadow: 0 2px 6px rgba(16, 33, 43, 0.18);
    color: var(--mud-palette-primary);
    display: inline-flex;
    align-items: center;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.1;
    padding: 0.1rem 0.5rem;
    pointer-events: none;
    position: absolute;
    right: 0;
    top: 0;
    transform: translate(20%, -55%);
    white-space: nowrap;
    z-index: 1;
}
/* /Components/Shared/PlanSelectorCard.razor.rz.scp.css */
/* NEW.2 (2026-08-14 UX audit): plan selector tabs + the "see what's included" toggle on the ONE
   populated plan card. Scoped to this component so the pricing top-section restructure adds zero
   app.css growth. Mobile-first: tabs stack full-width at 375px and sit side by side from 768px up
   (1280 inherits the 768 row layout — nothing changes wider than one more content column). Colors
   ride the design tokens (--mud-palette-primary / --tma-border / --public-text) so both light and
   dark themes resolve correctly without a separate dark override. */

.plan-selector[b-p1gx9w6qca] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 0.85rem;
}

.plan-selector-tab[b-p1gx9w6qca] {
    background: transparent;
    border: 1px solid var(--tma-border);
    border-radius: 8px;
    color: var(--public-text);
    cursor: pointer;
    font-weight: 600;
    padding: 0.6rem 0.9rem;
    text-align: left;
}

.plan-selector-tab.is-selected[b-p1gx9w6qca] {
    border-color: var(--mud-palette-primary);
    box-shadow: 0 0 0 1px var(--mud-palette-primary);
    color: var(--mud-palette-primary);
}

.plan-picker-see-included[b-p1gx9w6qca] {
    background: transparent;
    border: none;
    color: var(--mud-palette-primary);
    cursor: pointer;
    font-weight: 600;
    justify-self: start;
    padding: 0;
    text-decoration: underline;
}

@media (min-width: 48rem) {
    .plan-selector[b-p1gx9w6qca] {
        flex-direction: row;
    }

    .plan-selector-tab[b-p1gx9w6qca] {
        flex: 1 1 0;
        text-align: center;
    }
}
/* /Components/Shared/QrTemplateDesigner.razor.rz.scp.css */
/* F-553 (NEW.1): designer toolbar / block-toolbar chrome onto the card/token vocabulary. Both selectors are
   layout-only in app.css (flex/gap, no colour literals) so there is nothing to override here — this purely ADDS a
   card surface behind the button rows. Neither selector participates in qr-template-designer.js's drag/resize math
   (it reads only .qr-designer-canvas's own bounding rect via [data-qr-drag]/[data-qr-resize]/[data-qr-block-index],
   none of which live in the toolbar); see QrTemplateDesignerCanvas.razor.cs + the JS module for that boundary. The
   canvas/workspace/ruler/block/grid geometry classes are untouched here — this file never selects them. */

.qr-designer-toolbar[b-umwk24dodl] {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    padding: var(--sp-3);
}

.qr-designer-block-toolbar[b-umwk24dodl] {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
    padding: var(--sp-2);
}
/* /Components/Shared/QrTemplateDesignerCanvas.razor.rz.scp.css */
/* F-553 (NEW.1): the ONE safe skin touch on the canvas component. qr-template-designer.js reads only
   .qr-designer-canvas's own getBoundingClientRect() (see reportMove()) and a set of data-attributes
   ([data-qr-drag], [data-qr-resize], [data-qr-block-index]) — it never reads a CSS colour, so an outline-colour-only
   override cannot perturb the drag/resize math. `outline` is also never part of the CSS box model (it does not
   affect layout or a bounding rect), which is what makes this safe independent of the interop read.

   Deliberately NOT touched here (left for a lane with live-browser verification): .qr-designer-block's dashed
   placement border and .is-selected's glow carry FB-122 contrast history (near-white text tuned for visibility
   against arbitrary/dark print-stock skins) that this lane cannot re-verify without a browser — recolouring them
   blind risks a real contrast regression the geometry suites cannot catch (they assert markup/inline-style, never
   computed colour). Filed as remaining scope, not silently dropped. */

.qr-designer-canvas:focus-visible[b-spahj0f5yn] {
    outline-color: var(--accent-strong);
}
/* /Components/Shared/QrTemplateDesignerPropertiesPanel.razor.rz.scp.css */
/* F-553 (NEW.1): properties panel card onto the design system's card/token vocabulary. `.qr-designer-properties`
   is a MudPaper Elevation="0" root this component renders directly, so the scoped selector (no ::deep needed)
   matches it. Chrome only — the panel never renders a canvas/block/ruler element, so there is no geometry class in
   this file's reach at all. The native colour-swatch input gets a matching hairline ring; its intrinsic width/
   height are left to the browser (untouched). */

.qr-designer-properties[b-iwrpq2f4ry] {
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius);
    box-shadow: var(--elev-1);
}

.qr-designer-color-input[b-iwrpq2f4ry] {
    border: 1px solid var(--hairline);
    border-radius: var(--radius-sm);
}
/* /Components/Shared/SupportTicketForm.razor.rz.scp.css */
/* NEW.5 (owner report 2026-08-14): Mud's outlined label shrinks only via a C#-toggled class, which
   needs a live circuit — a keystroke typed before the circuit attaches, or an autofill (neither
   fires a C# event), leaves it sitting on the text. app.css has no headroom left under its enforced
   public-surface cap (scripts/audit-public-surface.mjs), so this scoped ::deep fallback reproduces
   Mud's own shrink transform via two native browser states needing no circuit at all: :focus-within
   (floats from the field's very first keystroke) and :autofill (via :has(), the only way to reach
   the sibling label from the input's own pseudo-class). ::deep is required because MudBlazor renders
   this markup itself, several component boundaries below this form's own scope (through
   MudTextField / MudSelect / TmaEmailField / TmaPhoneField). Keyed off .contact-form-card — the
   FormClass default every caller (Contact, SupportCenter) shares. */
/* The bot decoy (see the markup in SupportTicketForm.razor). Moved out of the viewport rather than hidden:
   `display:none` / `visibility:hidden` / `hidden` are all states a form filler can cheaply test for and skip,
   whereas an off-screen field reads to it as an ordinary one. Carries no colour of its own, so the theme
   conformance sweep has nothing to hold — it is never painted. */
.support-form-decoy[b-dof5uckymp] {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.contact-form-card[b-dof5uckymp]  .mud-input-control-input-container:focus-within .mud-input-label-outlined,
.contact-form-card[b-dof5uckymp]  .mud-input-control-input-container:has(.mud-input-slot:autofill) .mud-input-label-outlined {
    transform: translate(14px, -6px) scale(0.75);
    max-width: calc((100% - 14px) / .75);
}
