/* Admin-console page-scoped styles. app.css sits just under the public-surface size budget, so admin-only
   blocks land here (loaded after app.css, same mobile-first authoring rules as its FB-92 block: base rules
   target 375px, ONLY min-width queries layer wider layouts on, everything contained per FB-86). */

/* FB-91 governance inbox mobile-first — start */
/* The guided governance workspace's unified inbox, authored mobile-first like app.css's FB-92 block: base rules
   target 375px — the count chips wrap, each row stacks its summary and detail into one column, and the expanded
   detail's context panel sits ABOVE the decision affordances — and min-width queries lay the context beside the
   decisions once there's width. Everything stays inside the clipped admin canvas (FB-86 containment rule):
   max-width: 100% / min-width: 0 down the chain. Scoped to the governance-inbox-*/governance-term-context
   classes only. Layout only — no decision-flow changes. */
.governance-inbox-chips,
.governance-inbox-list,
.governance-inbox-row,
.governance-inbox-row-heading,
.governance-inbox-detail,
.governance-inbox-detail-grid,
.governance-inbox-decision,
.governance-term-context {
    max-width: 100%;
    min-width: 0;
}

.governance-inbox-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

.governance-inbox-row {
    padding: 1rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
}

/* Base = 375px: icon + heading share the first line; the Decide toggle drops to its own full-width 44px row. */
.governance-inbox-row-summary {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.75rem;
    align-items: start;
}

.governance-inbox-row-toggle.mud-button-root {
    min-height: 44px;
    grid-column: 1 / -1;
}

.governance-inbox-row-heading .mud-typography-h6 {
    overflow-wrap: anywhere;
}

.governance-inbox-detail {
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
}

.governance-inbox-detail-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
    align-items: start;
}

.governance-term-context {
    padding: 0.75rem;
    border-radius: 8px;
    background: var(--mud-palette-background-gray, rgba(0, 0, 0, 0.04));
}

@media (min-width: 768px) {
    /* The toggle returns to the summary line once there's width for a third column. */
    .governance-inbox-row-summary {
        grid-template-columns: auto minmax(0, 1fr) auto;
    }

    .governance-inbox-row-toggle.mud-button-root {
        grid-column: auto;
    }
}

@media (min-width: 1100px) {
    /* Desktop: the per-term context sits BESIDE the decision affordances. */
    .governance-inbox-detail-grid {
        grid-template-columns: minmax(15rem, 0.8fr) minmax(0, 1.7fr);
    }
}
/* FB-91 governance inbox mobile-first — end */

/* FB-99 review-surface bulk mode mobile-first — start */
/* Bulk mode (FB-95 V63.2): the pending inbox folded into signature-group batch cards. Authored mobile-first like the
   blocks above — base rules target 375px so the member table stacks/scrolls inside its own .descriptor-review-scroll-x
   container (FB-99: never a page-wide horizontal scroll), the batch header wraps, and the confirm overlay is a
   full-width sheet — and only min-width queries relax it. Everything stays inside the clipped admin canvas
   (FB-86 containment rule): max-width: 100% / min-width: 0 down the chain. Layout only. */
.descriptor-bulk-list,
.descriptor-bulk-card,
.descriptor-bulk-report,
.descriptor-batch-card,
.descriptor-batch-head,
.descriptor-batch-members,
.descriptor-batch-actions {
    max-width: 100%;
    min-width: 0;
}

.descriptor-bulk-progress {
    margin-bottom: 1rem;
}

/* V64.2 group paging: the loaded-vs-total readout and the "Load more groups" control under the batch list. */
.descriptor-bulk-readout {
    margin-bottom: 0.5rem;
}

.descriptor-bulk-load-more {
    display: flex;
    justify-content: center;
    margin-top: 1rem;
}

/* V64.2 member virtualization: the member table needs a bounded scroll viewport for <Virtualize> to window its rows
   (a group can hold hundreds — the operator cluster thousands). Cap the height and scroll INSIDE the card, keeping the
   FB-99 no-page-wide-scroll containment. */
.descriptor-batch-members {
    max-height: 60vh;
    overflow-y: auto;
}

.descriptor-bulk-report {
    margin-bottom: 1rem;
    padding: 0.75rem;
    border-radius: 8px;
    background: var(--mud-palette-background-gray, rgba(0, 0, 0, 0.04));
}

/* DG3.3 reason groups: the batch outcome renders one collapsible group per reason (count + heading), replacing the flat
   per-row wall. The header is a full-width, tappable toggle; the rows sit indented under it and hide when collapsed. */
.descriptor-bulk-report-group {
    border-top: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.08));
    padding: 0.25rem 0;
}

.descriptor-bulk-report-group:first-of-type {
    border-top: none;
}

.descriptor-bulk-report-group-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.4rem 0;
    background: none;
    border: none;
    cursor: pointer;
    text-align: left;
    color: inherit;
    font: inherit;
}

.descriptor-bulk-report-group-count {
    font-weight: 600;
    min-width: 2ch;
}

.descriptor-bulk-report-group-reason {
    overflow-wrap: anywhere;
}

.descriptor-bulk-report-group-rows {
    padding-left: 1.75rem;
}

.descriptor-bulk-report-row {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0.15rem;
    padding: 0.35rem 0;
}

.descriptor-bulk-report-failed {
    color: var(--mud-palette-error-text, #b00020);
}

/* DG3.4: a "needs a source" group is re-actionable, not a failure — warning tone, distinct from the error-red failures. */
.descriptor-bulk-report-needs-source {
    color: var(--mud-palette-warning-text, #b26a00);
}

.descriptor-bulk-list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 1rem;
}

.descriptor-batch-card {
    padding: 1rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.12));
    border-radius: 8px;
}

.descriptor-batch-head {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 0.5rem;
    align-items: center;
    margin-bottom: 0.75rem;
}

.descriptor-batch-header {
    overflow-wrap: anywhere;
}

/* V64.4: the signature info affordance sits at the end of the header row — a quiet, tappable target that explains
   why the rows are grouped and what each header segment means. */
.descriptor-batch-signature-tip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
}

.descriptor-batch-signature-info {
    cursor: help;
}

/* V64.4: the "what will happen" sentence beneath the confirm overlay's exact counts. */
.descriptor-bulk-confirm-effect {
    overflow-wrap: anywhere;
    opacity: 0.85;
}

/* The member table is contained in its own horizontal-scroll wrapper — below the breakpoint it scrolls INSIDE the
   card, never pushing the shell past the admin canvas. */
.descriptor-batch-members {
    overflow-x: auto;
}

.descriptor-batch-members table {
    width: 100%;
    border-collapse: collapse;
}

.descriptor-batch-members th,
.descriptor-batch-members td {
    padding: 0.4rem 0.5rem;
    text-align: left;
    vertical-align: top;
}

.descriptor-batch-members input[type="checkbox"] {
    width: 22px;
    height: 22px;
    min-width: 22px;
    min-height: 22px;
}

.descriptor-batch-excluded {
    opacity: 0.6;
}

.descriptor-batch-actions {
    margin-top: 0.75rem;
}

.descriptor-batch-apply.mud-button-root {
    min-height: 44px;
    width: 100%;
}

/* Base = 375px: the confirm step is a full-bleed bottom sheet with 44px actions. */
.descriptor-bulk-confirm-overlay {
    position: fixed;
    inset: 0;
    z-index: 1400;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(0, 0, 0, 0.4);
}

.descriptor-bulk-confirm {
    width: 100%;
    max-width: 32rem;
    padding: 1.25rem;
    display: grid;
    gap: 0.75rem;
}

.descriptor-bulk-confirm-counts {
    overflow-wrap: anywhere;
}

.descriptor-bulk-confirm-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
}

.descriptor-bulk-confirm-actions .mud-button-root {
    min-height: 44px;
}

@media (min-width: 768px) {
    /* Once there's width the batch actions sit inline and the confirm sheet centers as a dialog. */
    .descriptor-batch-apply.mud-button-root {
        width: auto;
    }

    .descriptor-bulk-confirm-overlay {
        align-items: center;
    }
}
/* FB-99 review-surface bulk mode mobile-first — end */

/* DG3.2 catalog source provenance mobile-first — start */
/* The catalog browse card lists a term's REAL sources and demotes the canon-verification stamp to an event line.
   Base rules target 375px: the source rows wrap and break long URLs so nothing pushes the card past the clipped
   admin canvas (FB-86 containment); the stamp line reads as a quiet verified-by/when caption. Scoped to the
   descriptor-source-* classes only; no max-width query needed — the rules hold at 768/1280 unchanged. */
.descriptor-source-list {
    padding: 0;
    max-width: 100%;
    min-width: 0;
}
.descriptor-source-item {
    overflow-wrap: anywhere;
    word-break: break-word;
}
.descriptor-source-stamp {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    opacity: 0.75;
}
/* DG3.2 catalog source provenance mobile-first — end */

/* FB-91 descriptor library mobile-first — start */
/* The category/connection library pages (V61.4 decomposition of AdminDescriptorCategories/-Relationships),
   authored mobile-first like the FB-92 block in app.css: base rules target 375px — metrics, cards, and the
   filter/form panels stack to one full-width column with 44px touch targets — and only min-width queries layer
   the desktop grids back on. Everything stays inside the clipped admin canvas (FB-86 containment rule):
   max-width: 100% / min-width: 0 down the chain. Scoped to the descriptor-library-* classes only. */
.descriptor-library-section,
.descriptor-library-section .admin-metric-grid,
.descriptor-library-section .admin-workspace-grid,
.descriptor-library-section .admin-workspace-card,
.descriptor-library-section .admin-workspace-card > *,
.descriptor-library-section .tool-access-filter-panel {
    max-width: 100%;
    min-width: 0;
}

/* Base = 375px: metrics, library cards, and the filter/form panels all stack to one full-width column. */
.descriptor-library-metric-grid.admin-metric-grid,
.descriptor-library-card-grid.admin-workspace-grid,
.descriptor-library-filter-panel.tool-access-filter-panel {
    grid-template-columns: 1fr;
}

.descriptor-library-filter-panel .tool-access-filter-summary {
    min-width: 0;
}

/* A long category or relationship title breaks instead of forcing its card wider than the viewport. */
.descriptor-library-section .admin-workspace-card .mud-typography-h6 {
    overflow-wrap: anywhere;
}

/* 44px touch floor on the card review/save actions and the workspace back-links. */
.descriptor-library-section .descriptor-review-actions .mud-button-root,
.descriptor-library-section .descriptor-library-filter-panel .mud-button-root {
    min-height: 44px;
}

.descriptor-library-term-link {
    display: inline-block;
    padding: 0.5rem 0;
}

/* DG3.5 Explorer: a store-mismatch row (a descriptor in only one store) gets a left accent so the health chip
   isn't the only signal, and the caption lines wrap instead of forcing the card wider than a 375px viewport. */
.descriptor-explorer-row--mismatch {
    border-left: 3px solid var(--mud-palette-warning);
}

.descriptor-explorer-aliases,
.descriptor-explorer-sources {
    overflow-wrap: anywhere;
}

/* DG3.6 Explorer where-used pane: the FB-91 context panel folded under an ops-backed row (linked menu items +
   recipe usage). Full-width under the card content and contained at 375px so it never forces the card wider. */
.descriptor-explorer-where-used {
    margin-top: 0.75rem;
    min-width: 0;
}

@media (min-width: 640px) {
    /* Layer the shared multi-column grids back on once there's width to spare. */
    .descriptor-library-metric-grid.admin-metric-grid {
        grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    }

    .descriptor-library-card-grid.admin-workspace-grid {
        grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    }

    .descriptor-library-filter-panel.tool-access-filter-panel {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1100px) {
    /* The filter/form panels return to the full desktop row. */
    .descriptor-library-filter-panel.tool-access-filter-panel {
        grid-template-columns: minmax(16rem, 1.4fr) minmax(12rem, 0.8fr) minmax(12rem, 0.8fr) auto;
    }
}
/* FB-91 descriptor library mobile-first — end */

/* FB-93 admin area sweep mobile-first — start */
/* The area-wide sweep. The admin table pages' MudTables already self-contain (MudBlazor's .mud-table-container
   scrolls horizontally and the default Xs breakpoint stacks rows on phones), so these page-scoped rules repair
   only the regions the audit found escaping a 375px viewport: billing's fixed three-/two-column card grids and
   the white-glove intake internals (a field grid fixed at three columns and an account-link command row whose
   14rem-plus-button template outgrows a phone). Authored mobile-first like the blocks above: base rules target
   375px, ONLY min-width queries layer the desktop columns back on, and everything stays inside the clipped
   admin canvas (FB-86 containment): max-width: 100% / min-width: 0 down the chain. Scoped to the
   admin-billing-console / admin-white-glove-console page classes only. Layout only — no behavior changes. */
.admin-billing-console .admin-list-card,
.admin-billing-console .admin-list-card > .mud-table,
.admin-white-glove-console .admin-intake-card,
.admin-white-glove-console .admin-intake-card > .mud-table {
    max-width: 100%;
    min-width: 0;
}

/* Base = 375px: billing's roadmap/function card grids stack to one readable column. */
.admin-billing-console .admin-roadmap-grid,
.admin-billing-console .admin-function-grid {
    grid-template-columns: 1fr;
}

/* Base = 375px: the intake field grid stacks, and the account-link command row stacks its select over its
   button instead of holding the desktop minmax(14rem, 1fr) auto template. */
.admin-white-glove-console .support-ticket-field-grid,
.admin-white-glove-console .operational-link-command {
    grid-template-columns: minmax(0, 1fr);
}

/* The intake heading wraps its status pill under the title instead of pushing past the card edge. */
.admin-white-glove-console .admin-intake-head {
    flex-wrap: wrap;
}

/* Long shared-folder/website values, hashes, and file names break instead of forcing the card wide. */
.admin-white-glove-console .support-ticket-field,
.admin-white-glove-console .intake-file-table .mud-table-cell {
    overflow-wrap: anywhere;
}

@media (min-width: 640px) {
    /* Layer the two-across layouts back on once there's width to spare. */
    .admin-billing-console .admin-roadmap-grid,
    .admin-white-glove-console .support-ticket-field-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .admin-white-glove-console .operational-link-command {
        grid-template-columns: minmax(14rem, 1fr) auto;
    }
}

@media (min-width: 960px) {
    /* Full desktop column counts. */
    .admin-billing-console .admin-function-grid,
    .admin-white-glove-console .support-ticket-field-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
/* FB-93 admin area sweep mobile-first — end */

/* FB-95 review-desk focus mode + keyboard mobile-first — start */
/* The V63.3 Review Desk shell: a Bulk ↔ Focus mode switch, Focus mode's always-in-view decision bar (a sticky
   bottom sheet on phone, a fixed side rail on desktop — the reviewer never scrolls to reach Verify), the roving
   keyboard focus ring shared by both modes, and the `?` keyboard-help overlay. Authored mobile-first like the blocks
   above: base rules target 375px and ONLY min-width queries layer the desktop rail on; everything stays inside the
   clipped admin canvas (FB-86 containment) with 44px touch targets. Scoped to the descriptor-review-desk /
   descriptor-focus-* / descriptor-key-help-* classes only. */
.descriptor-review-desk,
.descriptor-focus-shell,
.descriptor-focus-stage,
.descriptor-focus-card,
.descriptor-focus-card > * {
    max-width: 100%;
    min-width: 0;
}

/* The mode switch reads as a two-tab segmented control; the buttons hold a 44px touch floor. */
.descriptor-review-mode-switch {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.descriptor-review-mode-switch .mud-button-root {
    min-height: 44px;
}

/* The focus shell (and each roving-focused card) shows a clear ring so keyboard position is never ambiguous. */
.descriptor-focus-shell:focus,
.descriptor-focus-shell:focus-visible {
    outline: 2px solid var(--mud-palette-primary, #594ae2);
    outline-offset: 2px;
    border-radius: 8px;
}

.descriptor-batch-card-focused {
    outline: 2px solid var(--mud-palette-primary, #594ae2);
    outline-offset: 2px;
}

.descriptor-focus-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
}

.descriptor-focus-filter {
    flex: 1 1 8rem;
    min-width: 0;
    min-height: 44px;
    padding: 0 0.75rem;
    border: 1px solid var(--mud-palette-lines-inputs, rgba(0, 0, 0, 0.3));
    border-radius: 8px;
    font: inherit;
}

/* Base = 375px: the card stacks above a sticky bottom action bar (bottom-sheet feel) so Verify is always reachable
   without scrolling the page. */
.descriptor-focus-stage {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.descriptor-focus-card-head {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
}

.descriptor-focus-term {
    overflow-wrap: anywhere;
}

.descriptor-focus-actionbar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.5rem 0;
    background: var(--mud-palette-surface, #fff);
}

.descriptor-focus-actionbar .mud-button-root {
    flex: 1 1 auto;
    min-height: 44px;
}

/* The `?` help overlay, the group-verify confirm, and the V64.4 "how governance works" explainer dim the surface and
   sheet up from the bottom on phone. */
.descriptor-key-help-overlay,
.descriptor-gov-help-overlay,
.descriptor-focus-confirm-overlay {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.45);
}

.descriptor-key-help,
.descriptor-gov-help,
.descriptor-focus-confirm {
    width: 100%;
    max-width: 30rem;
    padding: 1rem;
    border-radius: 12px;
}

/* The explainer runs longer than the keyboard list — cap its height and scroll inside the sheet on a short screen. */
.descriptor-gov-help {
    max-height: 85vh;
    overflow-y: auto;
}

.descriptor-key-help-head,
.descriptor-gov-help-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* V64.4 explainer body: stacked heading/body points and a per-kind "what am I deciding" list. */
.descriptor-gov-help-points {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin: 0.5rem 0;
}

.descriptor-gov-help-kinds {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin: 0.5rem 0 0;
}

.descriptor-gov-help-kind-label {
    font-weight: 600;
}

.descriptor-gov-help-kind-desc {
    margin: 0.1rem 0 0;
    opacity: 0.85;
}

.descriptor-key-help-list {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    margin: 0.5rem 0;
}

.descriptor-key-help-row {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
}

.descriptor-key-help-kbd {
    flex: 0 0 5rem;
    padding: 0.15rem 0.4rem;
    border: 1px solid var(--mud-palette-lines-default, rgba(0, 0, 0, 0.2));
    border-radius: 6px;
    font-family: ui-monospace, monospace;
    text-align: center;
}

.descriptor-focus-confirm-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: flex-end;
    margin-top: 0.75rem;
}

.descriptor-focus-confirm-actions .mud-button-root {
    min-height: 44px;
}

@media (min-width: 768px) {
    /* Once there's width, Focus mode's action bar becomes a fixed side rail beside the card — always in view without
       ever covering the row content — and the overlays center as dialogs. */
    .descriptor-focus-stage {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(13rem, 17rem);
        align-items: start;
        gap: 1rem;
    }

    .descriptor-focus-actionbar {
        position: sticky;
        top: 1rem;
        bottom: auto;
        flex-direction: column;
        padding: 0;
        background: transparent;
    }

    .descriptor-key-help-overlay,
    .descriptor-gov-help-overlay,
    .descriptor-focus-confirm-overlay {
        align-items: center;
    }
}
/* FB-95 review-desk focus mode + keyboard mobile-first — end */

/* UI2.5 — show-once staff PIN display: the spaced-out, heavy plaintext styling that was an inline Style on
   the MudText, moved to a page-scoped class so the typography stays MudText Typo-driven. */
.employee-pin-display {
    letter-spacing: .3em;
    font-weight: 800;
}

/* V69.5 bolt-on switchboard — mobile-first. The two environment panels stack on a phone and sit side by side
   from the tablet breakpoint up: staging and production are independent decisions, so they are never presented
   as one control, at any width. */
.feature-switch-row__envs {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    margin-top: .75rem;
}

.feature-switch-env {
    flex: 1 1 0;
    padding: .75rem;
    border: 1px solid var(--mud-palette-lines-default);
    border-radius: var(--mud-default-borderradius);
}

/* The environment THIS host serves — the one whose "live" state is the reader's own. */
.feature-switch-env--current {
    border-color: var(--mud-palette-info);
}

.feature-switch-env__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 2rem;
}

.feature-switch-env__commitment {
    margin: .5rem 0;
}

/* 44px minimum touch targets: these controls suspend and retract live features — a mis-tap is expensive. */
.feature-switch-env .feature-switch-action,
.feature-switch-env .feature-switch-toggle {
    min-height: 44px;
}

.feature-switch-env .feature-switch-action {
    margin-top: .5rem;
    margin-right: .5rem;
}

@media (min-width: 768px) {
    .feature-switch-row__envs {
        flex-direction: row;
    }
}

/* UW.1 QR builder/designer — these rules live here because app.css sits at its enforced byte cap
   (audit-public-surface.mjs); admin.css loads globally right after it, so equal-specificity rules below win. */

/* Unlabelled minor ruler ticks: quarter-inch / half-centimetre short lines between the numbered marks,
   positioned by the same inline percent stops the numbered ticks use. */
.qr-designer-ruler-tick--minor {
    background: rgba(8, 16, 29, 0.35);
}

.qr-designer-ruler--top .qr-designer-ruler-tick--minor {
    bottom: 0;
    height: 0.26rem;
    width: 1px;
}

.qr-designer-ruler--left .qr-designer-ruler-tick--minor {
    height: 1px;
    right: 0;
    width: 0.26rem;
}

/* The custom designer's visual-style skin: the same .qr-template-surface the stock preview paints its six
   styles on, laid absolute UNDER the positioned blocks with the stock padding zeroed — blocks keep their
   percent-of-CANVAS coordinate contract, so the skin must never become their offset or padded box. */
.qr-designer-canvas > .qr-template-surface {
    inset: 0;
    padding: 0;
    position: absolute;
}

/* Spiral text consumes the template-level styling like every other preset field: SVG glyphs paint with fill
   (not color), so the paint follows currentColor and the same inline color:… token restyles the on-path text. */
.qr-template-language-spiral-text {
    color: var(--qr-template-style-ink);
    fill: currentColor;
}

/* FB-71 dark-mode chrome overrides — start
   Scope: body.theme-dark, set by TmaThemeProviderHost (body, not the shell div, so dialogs/popovers
   that render outside the layout are covered). ONLY the UNPAIRED rules live here — app.css chrome text
   whose fixed light-mode color sits on a Mud-themed surface that flips dark (the two drawers, dialog
   copy). Self-paired panels (the public marketing shell, the local-menus surface, the white admin
   cards) set BOTH their background and text and stay deliberately light — legible in either mode —
   so they are intentionally not re-themed here. These rules live in admin.css because app.css sits
   at its enforced byte cap (audit-public-surface.mjs); admin.css loads globally right after it. */
body.theme-dark .app-drawer,
body.theme-dark .admin-nav-drawer {
    color: var(--mud-palette-drawer-text, #ffffff);
}

body.theme-dark .admin-drawer-audience-title {
    border-top-color: var(--mud-palette-divider, #486178);
    color: var(--mud-palette-secondary, #33cccc);
}

/* The tool-status hints render directly on the drawer surface; their light-mode greens/ambers land
   near-invisible on the dark drawer, so they re-resolve through the palette's dark-legible accents. */
body.theme-dark .tool-nav-status.is-enabled {
    color: var(--mud-palette-success, #33cccc);
}

body.theme-dark .tool-nav-status.is-coming-soon {
    color: var(--mud-palette-warning, #f0b45c);
}

body.theme-dark .tool-nav-status.is-hidden {
    color: var(--mud-palette-text-disabled, #8ca2b4);
}

/* Checkout hand-off copy sits on a bare MudPaper (themed surface) but pinned the light-ink vars. */
body.theme-dark .checkout-account-handoff-copy .mud-typography-subtitle1 {
    color: var(--mud-palette-text-primary, #ffffff);
}

body.theme-dark .checkout-account-handoff-copy .mud-typography-body2 {
    color: var(--mud-palette-text-secondary, #c1cfdd);
}
/* FB-71 dark-mode chrome overrides — end */

/* FB-69 wallboard editor (WB.3) — start
   The editor's live preview reuses the TV display's block COMPONENTS (WallboardScreenBlocks) at reduced scale.
   The display styles itself inline in its own self-contained document (vh-based TV typography), so those rules
   never reach an admin page; this section restates the wb-* skin at pane scale, scoped under .wb-preview-frame
   so nothing leaks to the display or the rest of the console. */
.wb-preview-frame {
    background: #0b1020;
    color: #f4f6fb;
    border-radius: var(--mud-default-borderradius, 8px);
    padding: .75rem;
    overflow: hidden;
    width: 100%;
    max-width: 520px;
}

.wb-preview-frame .wb-blocks {
    display: flex;
    flex-direction: row;
    gap: .5rem;
    height: 100%;
    min-height: 0;
}

.wb-preview-frame.wb-portrait .wb-blocks {
    flex-direction: column;
}

.wb-preview-frame .wb-block {
    flex: 1 1 0;
    min-width: 0;
    min-height: 0;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.wb-preview-frame .wb-block--soldout {
    align-items: center;
    justify-content: center;
    text-align: center;
}

.wb-preview-frame .wb-count {
    font-size: 2.6rem;
    font-weight: 900;
    line-height: 1;
}

.wb-preview-frame .wb-count.is-clear { color: #4ade80; }

.wb-preview-frame .wb-count.has-items { color: #f87171; }

.wb-preview-frame .wb-label {
    font-size: .8rem;
    font-weight: 700;
    color: #cbd5f5;
}

.wb-preview-frame .wb-menu-name,
.wb-preview-frame .wb-matrix-name {
    font-size: 1rem;
    font-weight: 900;
    margin: 0 0 .25rem;
    overflow-wrap: anywhere;
}

.wb-preview-frame .wb-section-name {
    font-size: .7rem;
    text-transform: uppercase;
    letter-spacing: .14em;
    color: #8ea2c8;
    margin: .5rem 0 .2rem;
}

.wb-preview-frame .wb-menu-items {
    list-style: none;
    margin: 0;
    padding: 0;
}

.wb-preview-frame .wb-menu-item { margin: 0 0 .35rem; }

.wb-preview-frame .wb-item-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: .5rem;
}

.wb-preview-frame .wb-item-name {
    font-size: .8rem;
    font-weight: 700;
    overflow-wrap: anywhere;
}

.wb-preview-frame .wb-item-price {
    font-size: .8rem;
    font-weight: 700;
    color: #4ade80;
    white-space: nowrap;
}

.wb-preview-frame .wb-item-desc {
    display: block;
    font-size: .7rem;
    color: #cbd5f5;
    overflow-wrap: anywhere;
}

.wb-preview-frame .wb-matrix-grid {
    border-collapse: collapse;
    width: 100%;
    font-size: .6rem;
}

.wb-preview-frame .wb-matrix-grid th,
.wb-preview-frame .wb-matrix-grid td {
    border: 1px solid #2b3a5e;
    padding: .15rem .25rem;
    text-align: center;
}

.wb-preview-frame .wb-matrix-grid th.wb-matrix-item {
    text-align: left;
    overflow-wrap: anywhere;
}

.wb-preview-frame .wb-cell-C,
.wb-preview-frame .wb-cell-R {
    font-weight: 700;
    color: #f87171;
}

.wb-preview-frame .wb-cell-M { color: #fbbf24; }

.wb-preview-frame .wb-cell-NC {
    font-style: italic;
    color: #fbbf24;
}

.wb-preview-frame .wb-matrix-legend {
    font-size: .6rem;
    color: #8ea2c8;
}

.wb-preview-frame .wb-unavailable {
    font-size: .85rem;
    color: #8ea2c8;
    margin: auto;
    text-align: center;
}

/* The editor's block cards: plain divs (native drag events bind directly), styled to sit with the Mud console. */
.wb-editor-block {
    border: 1px solid var(--mud-palette-lines-default, #ddd);
    border-radius: var(--mud-default-borderradius, 8px);
    padding: .75rem;
    margin-top: .5rem;
    background: var(--mud-palette-surface, #fff);
    cursor: grab;
}

.wb-editor-block.is-dragging {
    opacity: .6;
}
/* FB-69 wallboard editor (WB.3) — end */

/* FB-117 menu-embed snippet (WB.6): the copy-paste code block on the menu builder. Mobile-first — the
   snippet wraps instead of forcing horizontal scroll at 375px, and stays a readable code block wider up. */
.tma-embed-snippet {
    white-space: pre-wrap;
    word-break: break-all;
    font-size: .8rem;
    line-height: 1.4;
    padding: .75rem;
    border: 1px solid var(--mud-palette-lines-default, #ddd);
    border-radius: var(--mud-default-borderradius, 8px);
    background: var(--mud-palette-background-gray, #f5f5f5);
    max-width: 100%;
    overflow-x: auto;
}

/* F-169 order-queue card chips — start */
/* An order's situation on the queue board is TWO chips, not one: the front-of-house status and — only where
   the track applies — the kitchen ticket. Mobile-first: at 375px the pair wraps under the order reference
   instead of pushing the card into horizontal scroll, and a long reference breaks rather than widening it. No
   max-width query: the rules hold unchanged at 768/1280. Emphasis is deliberately never colour-only — the two
   open states also carry weight here, and an icon plus a label in the markup — because the board is read across
   a pass under service pressure. Colours stay MudBlazor palette slots (the TmaBrand ramp) in the markup; no raw
   hex here. Admin-only surface, so this lives in admin.css — app.css is at its enforced public-surface byte cap
   (F-191). */
.order-queue-card-chips {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    align-items: center;
    gap: 0.25rem;
    min-width: 0;
    max-width: 100%;
}

.order-queue-card-reference {
    min-width: 0;
    overflow-wrap: anywhere;
}

/* Requested and Needs Edit are the only states waiting on a human. Requested is the filled chip; this lifts
   BOTH above the settled chips by weight, so Needs Edit still outranks Accepted/Complete/Rejected without
   being filled like a brand-new order nobody has looked at. */
.order-queue-status-chip--action {
    font-weight: 600;
}

.order-queue-status-chip--action.mud-chip-outlined {
    border-width: 2px;
}

.order-queue-kitchen-chip {
    max-width: 100%;
}
/* F-169 order-queue card chips — end */

/* F-173 order page (own-page order view + prev/next) — start */
/* The order now opens on its own route, so the walk bar and the decision buttons are the two things that have to
   work under a thumb mid-service. Mobile-first and unconditional: every rule below holds at 375, 768 and 1280 —
   there is no max-width gate that could drop the touch floor on a tablet. Everything wraps rather than widening,
   because a decision an operator has to scroll SIDEWAYS to reach is a decision they will not take. Admin-only
   surface, so this lives in admin.css: app.css is at its enforced public-surface byte cap (F-191). */
.order-detail-nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    max-width: 100%;
}

.order-detail-nav-cycle {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    max-width: 100%;
}

/* The walk bar AND every decision clear the 44px touch floor (docs/05 section 4 - WCAG 2.5.5) via min-height,
   never a fixed height, which would fight the label centering. The back link is included deliberately: measured
   at 375px it renders 42px on MudBlazor's text-button padding alone, which is under the floor. */
.order-detail-nav .mud-button-root,
.order-detail-cycle-button,
.order-detail-actions .mud-button-root {
    min-height: 44px;
}

.order-detail-position {
    min-width: 0;
    white-space: nowrap;
}

.order-detail-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
    max-width: 100%;
}

/* The seating picker shares the action row; it grows on a wide screen and drops to its own line on a phone
   instead of pushing the Confirm button off the edge. */
.order-detail-actions .mud-input-control {
    flex: 1 1 12rem;
    min-width: 0;
}

.order-detail-panel {
    min-width: 0;
    max-width: 100%;
    overflow-wrap: anywhere;
}

/* The queue card is a link now (it opens the order page), so it answers the keyboard and says so visibly. */
.order-queue-card:focus-visible {
    outline: 2px solid var(--mud-palette-primary);
    outline-offset: 2px;
}
/* F-173 order page (own-page order view + prev/next) — end */