/* ==========================================================================
   Loyalty.Web — shared UI foundation (WEB-F5, ADR-037 §22–§24).
   Platform UI only (NOT restaurant branding). Own CSS, no framework, no external font/CDN/image.
   Mobile-first: base rules are the 320 px layout; two min-width breakpoints refine it:
     40rem (640 px)  — tablet: roomier spacing, side-by-side session bar
     64rem (1024 px) — desktop: admin gets a left navigation column, content max-widths apply
   All values come from the tokens below; components never hard-code colours.
   ========================================================================== */

/* ---------- 1. Design tokens ---------- */
:root {
    /* Typography: system stack (no web font) until the licensed RIWORD WOFF2 files exist (D-03). Components read ONLY these tokens, so the official families are added later by
       prepending them here (plus the font declaration in a separate file), never by editing a component. */
    --font-display: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
    --text-xs: 0.8125rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;
    --leading-tight: 1.25;
    --leading-base: 1.5;
    --weight-regular: 400;
    --weight-medium: 500;
    --weight-bold: 600;

    /* Spacing scale (rem). */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.5rem;
    --space-6: 2rem;
    --space-7: 3rem;

    /* Shape. */
    --radius-sm: 0.25rem;
    --radius-md: 0.5rem;
    --radius-lg: 0.75rem;
    --border-width: 1px;
    --target-min: 2.75rem; /* 44 px minimum touch target */

    /* Layout widths. */
    --width-form: 26rem;
    --width-content: 72rem;
    --width-wide: 100rem; /* RCM-F7.1: master/list pages (opt-in via .master-wide); still capped on very large monitors */
    --width-nav: 16rem; /* UI-F2: admin sidebar */
    --riword-logo-horizontal-height: 2.5rem; /* logo sizes are tokens; the official SVGs keep their aspect ratio (width: auto) */
    --riword-logo-mark-height: 2.5rem;

    /* Surfaces and text (neutral platform palette). */
    --color-bg: #f5f6f8;
    --color-surface: #ffffff;
    --color-surface-alt: #eceef2;
    --color-border: #cfd4dc;
    --color-border-strong: #6b7380; /* form-control borders: >= 3:1 against the surface */
    --color-text: #1a1e26;
    --color-text-muted: #4a5260;


    /* RIWORD platform palette (UI-F1, D-02). Official brand colours: blue, cyan, yellow, gray. NAVY / NAVY-DEEP are DERIVED UI COLORS, not official brand colours.
       Cyan and yellow fail 4.5:1 on light surfaces: decorative / accent use only, never text. */
    --riword-blue: #1556ee;
    --riword-blue-hover: #0f43c0; /* derived: darker blue for hover */
    --riword-cyan: #01a2c6;
    --riword-yellow: #f4c800;
    --riword-gray: #575c6f;
    --riword-navy: #0b1b3a; /* DERIVED UI COLOR */
    --riword-navy-deep: #06214f; /* DERIVED UI COLOR */
    --riword-primary: var(--riword-blue); /* platform controls (buttons, picker) */
    --riword-primary-hover: var(--riword-blue-hover);

    /* ISOLATION: --color-primary / --color-primary-hover are the FALLBACKS of the restaurant card CSS (var(--cp-primary, var(--color-primary)), var(--customer-brand-accent, ...)).
       They keep their pre-RIWORD value so a restaurant card without an explicit theme never changes; platform controls use --riword-primary instead. */
    --color-primary: #1d4ed8;
    --color-primary-hover: #1e40af;
    --color-on-primary: #ffffff;
    --color-focus: #1556ee; /* = --riword-blue; literal because the contrast test reads hex values (RiwordIdentityTests keeps them in sync) */
    --color-link: #1556ee; /* = --riword-blue */
    --color-on-dark: #ffffff; /* text on a dark restaurant brand colour (NX-F6) */
    --color-on-light: #000000; /* text on a light restaurant brand colour (NX-F6) */

    /* Semantic states (text on its own background >= 4.5:1). */
    --color-success-bg: #dcfce7;
    --color-success-text: #14532d;
    --color-success-border: #86efac;
    --color-warning-bg: #fef3c7;
    --color-warning-text: #713f12;
    --color-warning-border: #fcd34d;
    --color-error-bg: #fee2e2;
    --color-error-text: #7f1d1d;
    --color-error-border: #fca5a5;
    --color-info-bg: #dbeafe;
    --color-info-text: #1e3a8a;
    --color-info-border: #93c5fd;

    /* Elevation only where it clarifies a layer. */
    --shadow-panel: 0 1px 2px rgb(16 24 40 / 0.08);
    --color-backdrop: rgb(11 27 58 / 0.5); /* drawer overlay (derived from --riword-navy) */
}

/* ---------- 2. Base ---------- */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

body {
    margin: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-base);
    overflow-wrap: break-word; /* long emails / references never force horizontal scrolling */
}

img,
svg {
    max-width: 100%;
    height: auto;
}

h1, h2, h3 {
    line-height: var(--leading-tight);
    margin: 0 0 var(--space-3);
}

h1 { font-size: var(--text-2xl); font-weight: var(--weight-bold); }
h2 { font-size: var(--text-xl); font-weight: var(--weight-bold); }
h3 { font-size: var(--text-lg); font-weight: var(--weight-medium); }

p { margin: 0 0 var(--space-3); }

a { color: var(--color-link); text-underline-offset: 0.15em; }
a:hover { text-decoration-thickness: 2px; }

code { font-family: var(--font-mono); font-size: var(--text-sm); }

.muted { color: var(--color-text-muted); }
.wrap { overflow-wrap: anywhere; }

/* Programmatic focus on headings/main (skip link, FocusOnNavigate) needs no ring; interactive controls always get one. */
h1:focus,
main:focus {
    outline: none;
}

:focus-visible {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
}

/* ---------- 3. Skip link ---------- */
.skip-link {
    position: absolute;
    left: var(--space-3);
    top: var(--space-3);
    padding: var(--space-2) var(--space-4);
    background: var(--color-surface);
    color: var(--color-link);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    transform: translateY(-200%);
    z-index: 2000;
}

.skip-link:focus {
    transform: none;
}

/* ---------- 4. Buttons ---------- */
.btn,
button {
    font: inherit;
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--target-min);
    max-width: 100%; /* a button never pushes its container (or the page) wider than the viewport */
    padding: var(--space-2) var(--space-5);
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-md);
    font-weight: var(--weight-medium);
    text-align: center;
    text-decoration: none;
    white-space: normal;
    overflow-wrap: anywhere;
    cursor: pointer;
}

.btn--primary { background: var(--riword-primary); color: var(--color-on-primary); }
.btn--primary:hover { background: var(--riword-primary-hover); }

.btn--secondary {
    background: var(--color-surface);
    color: var(--riword-primary);
    border-color: var(--riword-primary);
}
.btn--secondary:hover { background: var(--color-info-bg); }

.btn--quiet {
    background: transparent;
    color: var(--color-link);
    border-color: var(--color-border-strong);
    padding: var(--space-2) var(--space-4);
}
.btn--quiet:hover { background: var(--color-surface-alt); }

button:disabled,
.btn[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.65;
}

/* Native submit buttons without a .btn class still keep a usable target. */
button[type="submit"]:not(.btn) {
    min-height: var(--target-min);
}

/* ---------- 5. Forms ---------- */
.stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.field {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.field label,
legend {
    font-weight: var(--weight-medium);
}

.field__hint {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="date"],
input[type="datetime-local"],
input[type="time"],
input[type="number"],
input[type="search"],
input[type="tel"],
input[type="url"],
select,
textarea {
    width: 100%;
    max-width: 100%;
    min-height: var(--target-min);
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
}

textarea { resize: vertical; } /* user resizing never widens the page */

input[type="file"] {
    max-width: 100%; /* the native picker's intrinsic width never exceeds its container */
    font: inherit;
}

input:disabled {
    background: var(--color-surface-alt);
    color: var(--color-text-muted);
    cursor: not-allowed;
}

fieldset {
    margin: 0;
    padding: 0;
    border: 0;
    min-width: 0; /* lets long labels wrap inside the viewport */
}

.choice-group legend {
    padding: 0;
    margin-bottom: var(--space-2);
}

.choice {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    min-height: var(--target-min);
    padding: var(--space-2) var(--space-3);
    margin-bottom: var(--space-2);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
}

.choice input[type="radio"],
.choice input[type="checkbox"] {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    margin: 0.35rem 0 0;
}

.choice label {
    flex: 1;
    min-width: 0;
    padding: var(--space-1) 0;
    font-weight: var(--weight-regular);
}

/* Blazor validation classes (kept for future EditForm screens). */
.validation-message { color: var(--color-error-text); }

/* ---------- 6. Feedback: alerts, empty state, badges ---------- */
.alert {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    border: var(--border-width) solid;
    border-radius: var(--radius-md);
}

.alert--info { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--color-info-border); }
.alert--success { background: var(--color-success-bg); color: var(--color-success-text); border-color: var(--color-success-border); }
.alert--warning { background: var(--color-warning-bg); color: var(--color-warning-text); border-color: var(--color-warning-border); }
.alert--error { background: var(--color-error-bg); color: var(--color-error-text); border-color: var(--color-error-border); }

.empty-state {
    padding: var(--space-5) var(--space-4);
    text-align: center;
    background: var(--color-surface);
    border: var(--border-width) dashed var(--color-border-strong);
    border-radius: var(--radius-md);
    color: var(--color-text-muted);
}

.empty-state__message { margin: 0; }

.badge {
    display: inline-block;
    padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    border: var(--border-width) solid var(--color-border);
    background: var(--color-surface-alt);
    color: var(--color-text);
    font-size: var(--text-xs);
    font-weight: var(--weight-medium);
}

.badge--success { background: var(--color-success-bg); color: var(--color-success-text); border-color: var(--color-success-border); }
.badge--warning { background: var(--color-warning-bg); color: var(--color-warning-text); border-color: var(--color-warning-border); }

/* ---------- 7. Panel + page header ---------- */
.panel {
    padding: var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-panel);
}

.panel__heading { margin-bottom: var(--space-3); }

.page-header { margin-bottom: var(--space-4); }
.page-header h1 { margin-bottom: var(--space-2); font-family: var(--font-display); }
.page-header__description { margin: 0; color: var(--color-text-muted); }

/* ---------- 8. Public / authentication shell ---------- */
.public-shell {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

.public-shell__header {
    padding: var(--space-3) var(--space-4);
}

.public-shell__main {
    flex: 1;
    width: 100%;
    padding: var(--space-4);
}

.auth-card {
    width: 100%;
    max-width: var(--width-form); /* forms never stretch across large displays */
    margin: 0 auto;
}

.brand {
    display: inline-flex;
    align-items: center;
    min-height: var(--target-min);
    color: var(--color-text);
    font-size: var(--text-xl);
    font-weight: var(--weight-bold);
    text-decoration: none;
}

/* UI-F1: RIWORD logo (TEMPORARY raster assets; the shell sizes them by height, the width follows the intrinsic ratio). */
.brand--logo { min-width: 0; }

.riword-logo { display: block; width: auto; max-width: 100%; }
.riword-logo--mark { height: var(--riword-logo-mark-height); }
.riword-logo--horizontal { height: var(--riword-logo-horizontal-height); }

.gsi-slot {
    min-height: var(--target-min);
    max-width: 100%;
    overflow: hidden;
}

/* UI-F3: public shell footer, plain authentication panel and the public landing (RIWORD platform only; restaurant branding is untouched). */
.public-shell__footer {
    padding: var(--space-4);
    text-align: center;
}

.auth-card--plain { padding: var(--space-2) 0; }
.auth-card--plain .btn[type="submit"],
.auth-card--plain button[type="submit"] { width: 100%; }

.auth-divider {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-5) 0;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

.auth-divider::before,
.auth-divider::after {
    content: "";
    flex: 1;
    border-top: var(--border-width) solid var(--color-border);
}

.auth-alt__heading { font-size: var(--text-base); margin: 0; }
.auth-alt__intro { font-size: var(--text-sm); margin: 0; }

.landing {
    width: 100%;
    max-width: var(--width-content);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
}

.landing__hero {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    padding-top: var(--space-4);
}

.landing__hero h1 { font-size: var(--text-3xl); }
.landing__lead { font-size: var(--text-lg); margin-bottom: var(--space-3); }

.landing__cta {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-top: var(--space-5);
}

/* Brand composition of the hero (visual only): three independent tiles — official RIWORD isotipo on blue, horizontal logo on yellow, white logo on cyan — that overlap slightly.
   Everything is a percentage of one square box (aspect-ratio reserves the space: no layout shift) so the artwork scales uniformly and is never cut or stretched. Colours are the platform tokens. */
.landing__art {
    position: relative;
    width: 100%;
    max-width: 24rem;
    margin: 0 auto;
    aspect-ratio: 1 / 1;
}

.landing__tile {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    border: 0.25rem solid var(--color-bg);
    box-shadow: 0 0.0625rem 0.125rem color-mix(in srgb, var(--riword-navy) 14%, transparent);
    overflow: hidden;
}

.landing__tile .riword-logo { max-width: none; width: auto; }
.landing__tile--blue { left: 0; top: 0; width: 48%; aspect-ratio: 1 / 1; background: var(--riword-blue); z-index: 1; }
.landing__tile--blue .riword-logo { height: 66%; }
.landing__tile--yellow { right: 0; top: 30%; width: 62%; aspect-ratio: 16 / 9; background: var(--riword-yellow); z-index: 2; }
.landing__tile--yellow .riword-logo { width: 74%; height: auto; }
.landing__tile--cyan { left: 6%; bottom: 0; width: 72%; aspect-ratio: 16 / 9; background: var(--riword-cyan); z-index: 3; }
.landing__tile--cyan .riword-logo { width: 74%; height: auto; }

.landing__section h2 { margin-bottom: var(--space-4); }

.landing__steps,
.landing__advantages {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-4);
}

.landing__steps li {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
}

.landing__step-number {
    flex: none;
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--riword-primary);
    color: var(--color-on-primary);
    font-weight: var(--weight-bold);
    font-size: var(--text-sm);
}

.landing__advantages li {
    padding-left: var(--space-4);
    border-left: 3px solid var(--riword-cyan);
}

/* ---------- 9. Application shells (admin + customer) ---------- */
.shell {
    min-height: 100vh;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "header" "nav" "main";
}

/* Customer shell: since M14-F5 it has a customer-wide navigation row, so it uses the base "header" "nav" "main" template. */
.shell--customer {
    grid-template-rows: auto auto 1fr auto;
    grid-template-areas: "header" "nav" "main" "footer";
}

.shell__footer {
    grid-area: footer;
    padding: var(--space-3) var(--space-4);
    text-align: center;
}

/* UI-F1 (D-04): discreet platform credit; the restaurant stays the dominant brand. */
.powered-by {
    margin: 0;
    font-size: var(--text-xs);
    color: var(--color-text-muted);
}

.shell--customer .nav-list {
    max-width: 40rem; /* aligned with the single customer content column */
    margin: 0 auto;
}

.shell__header {
    grid-area: header;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
}

.shell__session {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    width: 100%; /* mobile: the session bar takes its own row under the brand */
    min-width: 0;
    max-width: 100%;
}

/* Flex items default to min-width: auto (their unbreakable min-content): a long e-mail or restaurant name would otherwise force the whole
   page wider than a phone viewport (M15 responsive remediation). They may shrink and break anywhere instead. */
.shell__header > *,
.shell__session > * {
    min-width: 0;
    max-width: 100%;
}

.shell__context,
.shell__user {
    overflow-wrap: anywhere;
}

.shell__session form { margin: 0; }

.shell__nav {
    grid-area: nav;
    background: var(--color-surface);
    border-bottom: var(--border-width) solid var(--color-border);
}

.nav-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin: 0;
    padding: var(--space-2) var(--space-3);
    list-style: none;
}

.nav-link {
    gap: var(--space-2);
    display: flex;
    align-items: center;
    min-height: var(--target-min);
    padding: var(--space-2) var(--space-3); /* phones: more entries per wrapped row; tablet+ restores the wider padding */
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
}

.nav-link:hover { background: var(--color-surface-alt); }

/* UI-F1: decorative monochrome navigation icon (inline SVG sprite, currentColor, uniform stroke). */
.nav-icon {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.nav-link[aria-current="page"] {
    background: var(--color-info-bg);
    color: var(--color-info-text);
    font-weight: var(--weight-bold);
}

.shell__main {
    grid-area: main;
    min-width: 0;
    width: 100%;
    max-width: var(--width-content);
    margin: 0 auto;
    padding: var(--space-4);
}

.shell--customer .shell__main {
    max-width: 40rem; /* customer content is a single mobile-style column, even on large displays */
}

/* ---------- 9b. Admin shell (UI-F2) ----------
   Base (< 64rem): compact topbar (menu button, isotipo, restaurant context) over the content; the sidebar is a native-popover drawer. >= 64rem: sidebar + topbar (section 11). */
.shell--admin {
    grid-template-rows: auto auto 1fr;
    grid-template-areas: "header" "sidebar" "main";
}

.shell--admin .shell__header {
    gap: var(--space-2) var(--space-3);
    padding: var(--space-2) var(--space-3);
}

.shell__menu-button {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex: none;
}

.shell__brand-compact { flex: none; }

/* The account lives in the drawer below 64rem and in the topbar from it: exactly one is displayed. */
.shell--admin .shell__header .shell__session { display: none; }

/* Restaurant context (replaces the former "Cambiar restaurante" navigation entry). */
.shell--admin .shell__context {
    display: flex;
    flex: 1 1 100%; /* phones: the context takes its own row; tablet restores one row */
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    min-width: 0;
}

.shell-context__text {
    display: flex;
    flex-direction: column;
    min-width: 0;
    line-height: var(--leading-tight);
}

.shell-context__label { font-size: var(--text-xs); }
.shell-context__name { overflow-wrap: anywhere; }

.shell-context__action {
    display: inline-flex;
    align-items: center;
    flex: none;
    min-height: var(--target-min);
    padding: 0 var(--space-2);
}

/* A warning appears only when there is a context problem (SUPERADMIN with no restaurant selected). */
.shell-context--warning {
    padding: 0 var(--space-3);
    background: var(--color-warning-bg);
    color: var(--color-warning-text);
    border: var(--border-width) solid var(--color-warning-border);
    border-radius: var(--radius-md);
}

.shell-context--warning .shell-context__action { color: var(--color-warning-text); }

.account-block {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2) var(--space-4);
    min-width: 0;
}

.account-block form { margin: 0; }
.shell__role { font-size: var(--text-sm); font-weight: var(--weight-medium); }

.shell__sidebar-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
}

.shell--admin .shell__nav {
    flex: 1;
    padding: 0 var(--space-3) var(--space-3);
    background: transparent;
    border: 0;
}

.shell--admin .nav-list {
    flex-direction: column;
    flex-wrap: nowrap;
    padding: 0;
}

.nav-group { margin-top: var(--space-4); }

.nav-group__label {
    margin: 0 0 var(--space-1);
    padding: 0 var(--space-3);
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--riword-gray);
}

.shell__sidebar-account {
    padding: var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
}

.shell__sidebar-account .account-block {
    flex-direction: column;
    align-items: flex-start;
}

/* The drawer: only where the Popover API exists. Without it the sidebar simply stays in the page flow (the menu buttons are hidden), a usable fallback. */
@supports selector(:popover-open) {
    .shell__sidebar {
        margin: 0;
        inset: 0 auto 0 0;
        width: min(20rem, 85vw);
        height: 100vh;
        height: 100dvh;
        max-height: none;
        padding: 0;
        border: 0;
        overflow-y: auto;
        background: var(--color-surface);
        color: var(--color-text);
        box-shadow: var(--shadow-panel);
    }

    .shell__sidebar:popover-open {
        display: flex;
        flex-direction: column;
    }

    .shell__sidebar::backdrop { background: var(--color-backdrop); }
}

@supports not selector(:popover-open) {
    .shell__menu-button,
    .shell__menu-close { display: none; }
}

/* ---------- RCM-F6: master restaurant list (tokens only; mobile-first; semantic table, KPIs, filters, pager) ---------- */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.page-title-row { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-3); }
.page-title-row .page-header { margin-bottom: var(--space-2); }

/* KPIs: two compact groups; each indicator is a link that applies its filter. */
.kpi-groups { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-bottom: var(--space-4); }
.kpi-group { flex: 1 1 14rem; min-width: 0; }
.kpi-group__title { margin: 0 0 var(--space-2); font-size: var(--text-sm); font-weight: var(--weight-bold); color: var(--color-text-muted); }
.kpi-group__items { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2); }
.kpi {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-height: var(--target-min);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
}
a.kpi:hover { background: var(--color-surface-alt); }
.kpi--active { border-color: var(--riword-primary); box-shadow: inset 0 0 0 1px var(--riword-primary); background: var(--color-info-bg); }
.kpi__count { font-size: var(--text-xl); font-weight: var(--weight-bold); line-height: var(--leading-tight); }
.kpi__label { font-size: var(--text-sm); color: var(--color-text-muted); }
.kpi--attention .kpi__count { color: var(--color-warning-text); }

/* Filters: the search is always visible; the rest folds behind a native checkbox toggle on a phone (no script). */
.filters { display: grid; gap: var(--space-3); }
.filters__search { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-2); align-items: end; }
.filters__toggle { position: absolute; opacity: 0; width: 1px; height: 1px; }
.filters__toggle:focus-visible + .filters__toggle-label { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.filters__toggle-label { justify-self: start; }
.filters__body { display: none; gap: var(--space-3); grid-template-columns: minmax(0, 1fr); }
.filters__toggle:checked ~ .filters__body { display: grid; }
.filters__more > summary { cursor: pointer; min-height: var(--target-min); padding: var(--space-2) 0; font-weight: var(--weight-medium); }
.filters__dates { display: grid; gap: var(--space-3); grid-template-columns: minmax(0, 1fr); }

.results-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2); margin: var(--space-3) 0; }
.results-bar p { margin: 0; }
.page-size { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; font-size: var(--text-sm); }
.page-size a, .page-size strong { display: inline-flex; align-items: center; justify-content: center; min-width: var(--target-min); min-height: var(--target-min); }

/* The table, phone first: no compressed table — the head stays for assistive technology and each row is a compact stacked block. */
.data-table-wrap { width: 100%; }
.data-table { width: 100%; border-spacing: 0; font-size: var(--text-sm); }
.data-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }
.data-table, .data-table tbody { display: block; }
.data-table tbody tr {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--space-3);
    row-gap: var(--space-1);
    padding: var(--space-3) 0;
    border-bottom: var(--border-width) solid var(--color-border);
}
.data-table tbody th, .data-table tbody td { display: block; padding: 0; border: 0; text-align: left; overflow-wrap: anywhere; }
.data-table tbody th { grid-column: 1; grid-row: 1; font-size: var(--text-base); font-weight: var(--weight-bold); }
.data-table__cutoff { grid-column: 1; grid-row: 2; }
.data-table__flags { grid-column: 1; }
.data-table__action { grid-column: 2; grid-row: 1 / span 3; align-self: center; text-align: right; white-space: nowrap; }
.data-table__normal, .data-table__aux, .col-wide, .col-desktop { display: none !important; }
.data-table__state { display: block; }
.data-table__aux { color: var(--color-text-muted); font-size: var(--text-xs); }
.sort-link { color: inherit; text-decoration: none; display: inline-flex; align-items: center; min-height: var(--target-min); }
.sort-link:hover { text-decoration: underline; }

.pager { margin-top: var(--space-4); }
.pager__list { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); list-style: none; margin: 0; padding: 0; }
.pager__current { background: var(--riword-primary); color: var(--color-on-primary); }
.pager__gap { padding: 0 var(--space-1); }


/* ---------- 10b. Master/list pattern (RCM-F7.1) ----------
   An administrative master (wide, compact, data-oriented) is opted into by ONE wrapper, `.master-wide`, placed as the direct child of the shell main. Every rule of this pattern is scoped to it,
   so the narrow admin pages (detail, forms) keep the standard content width; the breakpoint parts live in sections 10 and 11 (RCM-F7.1 markers). Same tokens as the rest of RIWORD. */
.shell__main:has(> .master-wide) { max-width: var(--width-wide); }

/* Header: title and description on the left, the primary call to action on the right, on the same master width as everything below. */
.master-wide .page-title-row--master { align-items: center; gap: var(--space-2) var(--space-4); margin-bottom: var(--space-4); }
.master-wide .page-title-row--master .page-header { margin-bottom: 0; }
.master-wide .page-title-row--master .page-header h1 { margin-bottom: var(--space-1); font-size: var(--text-2xl); }
.master-wide .page-title-row--master .btn { flex: none; }

/* KPIs: one compact strip. Base/tablet: the groups wrap in order (Cartera takes the larger share); desktop: Atención takes only what it needs and the five Cartera tiles share one row. */
.master-wide .kpi-groups { gap: var(--space-3) var(--space-5); margin-bottom: var(--space-4); padding: var(--space-3) var(--space-4); background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-panel); }
.master-wide .kpi-group--attention { flex: 1 1 12rem; }
.master-wide .kpi-group--portfolio { flex: 3 1 24rem; }
.master-wide .kpi-group__title { margin-bottom: var(--space-1); font-size: var(--text-xs); font-weight: var(--weight-bold); text-transform: uppercase; letter-spacing: 0.04em; }
.master-wide .kpi { border-color: transparent; background: transparent; padding: var(--space-2) var(--space-3); gap: 0; }
.master-wide a.kpi:hover { background: var(--color-surface-alt); }
.master-wide .kpi--active { border-color: var(--riword-primary); background: var(--color-info-bg); }
.master-wide .kpi__count { font-size: var(--text-2xl); font-variant-numeric: tabular-nums; }
.master-wide .kpi__label { font-size: var(--text-xs); }

/* Toolbar: search and filters as a compact management bar (search row + one filters row; the advanced dates stay folded until "Más filtros"). */
.master-wide .master-toolbar { padding: var(--space-3) var(--space-4); }
.master-wide .filters { gap: var(--space-2); }

/* Results toolbar: secondary line right above the table. */
.master-wide .results-bar { margin: var(--space-4) 0 var(--space-2); font-size: var(--text-sm); }

/* Table: the protagonist. A surface of its own; roomy rows; soft separators; the restaurant name leads; secondary data recedes; normal states are plain text. */
.master-wide .data-table-wrap { background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); box-shadow: var(--shadow-panel); overflow: hidden; }
.master-wide .data-table tbody tr { padding: var(--space-3) var(--space-4); }
.master-wide .data-table tbody tr:last-child { border-bottom: 0; }
.master-wide .data-table tbody th { color: var(--color-text); }
.master-wide .data-table__action .btn--secondary { background: transparent; border-color: var(--color-border); padding-left: var(--space-4); padding-right: var(--space-4); }
.master-wide .data-table__action .btn--secondary:hover { background: var(--color-info-bg); border-color: var(--riword-primary); }

/* ---------- 10. Tablet (>= 640 px) ---------- */
/* ---------- 9c. Card workspace layout (CW-F1.1, ADR-059) ----------
   Explicit breakpoints (the two existing ones) instead of auto-fit. Declared BEFORE the breakpoint blocks and prefixed with .card-ws so they win over the generic .panel / .summary-list rules.
   Phone: summary 2 columns, operations and purchase pair stacked. >= 40rem: summary 3 columns, purchase pair 2 columns. >= 64rem (admin sidebar 16rem): summary in one row, Visit (3fr) + Rewards (2fr). */
.card-ws > .card-ws-summary { padding: var(--space-3) var(--space-4); }
.card-ws .card-ws-summary__list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-4); }
.card-ws .card-ws-summary__list dt { font-size: var(--text-xs); }
.card-ws > .card-ws-ops { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; }
.card-ws > .card-ws-ops:empty { display: none; }
.card-ws-ops > * { margin: 0; min-width: 0; }
.card-ws .card-ws-pair { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3) var(--space-4); }
.card-ws-pair > * { min-width: 0; }

/* ---------- 9d. Layout primitives (UX-F1, ADR-060) ----------
   Reusable composition classes of the RIWORD design system. They are INERT until a page uses them (UX-F1 migrates no page) and they never change .panel, .stack, .field or the existing .btn / .badge.
   Cascade contract: every BASE rule of this section is declared here, before the two breakpoint blocks below; the 40rem / 64rem refinements live INSIDE those blocks, in a "UX-F1" group. Nothing
   after this section redeclares a base rule of these primitives. Padding modifiers use a compound selector (.panel.panel--x) so they beat the generic .panel padding of the 40rem block whatever the order.
   Tokens only; the two canonical breakpoints (40rem, 64rem) only. */

/* Page stack: the explicit owner of the vertical space between large sections (16 px phone, 24 px from 40rem). Direct children carry no margin of their own. */
.page-stack { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.page-stack > * { margin: 0; min-width: 0; }

/* Panel grid: ONE column by default; two columns from 64rem (equal, or --split 3fr/2fr). A lone child spans the whole row. DOM order = visual order (no order / grid-area). */
.panel-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); align-items: start; min-width: 0; }
.panel-grid > * { margin: 0; min-width: 0; }
.panel-grid > :only-child { grid-column: 1 / -1; }

/* Density modifiers of .panel (compound selector: not a second panel, and independent of the source order of the generic padding). */
.panel.panel--summary,
.panel.panel--compact { padding: var(--space-3) var(--space-4); }
.panel.panel--compact .panel__heading { margin-bottom: var(--space-2); }
.panel--summary .summary-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: var(--space-2) var(--space-4); }
.panel--summary .summary-list dt { font-size: var(--text-xs); }

/* Field grids: INTERNAL to a form / panel (never page columns). One column on a phone; content-driven columns from 40rem. */
.filter-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3); align-items: end; min-width: 0; }
.filter-grid > * { min-width: 0; }
.filter-grid__actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.form-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-3) var(--space-4); align-items: start; min-width: 0; }
.form-grid > * { min-width: 0; }
.form-grid__full { grid-column: 1 / -1; }

/* Action row: primary / secondary / quiet actions that wrap safely. Buttons keep their own 44 px target; a bare link gets one too. */
.action-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); min-width: 0; }
.action-row > * { margin: 0; min-width: 0; }
.action-row > a:not(.btn) { display: inline-flex; align-items: center; min-height: var(--target-min); }
.action-row--end { justify-content: flex-end; }

/* Disclosure: styles the NATIVE <details>/<summary> (keyboard, screen reader and the native marker are untouched; no script). */
.disclosure { min-width: 0; background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); }
.disclosure > summary { min-height: var(--target-min); padding: var(--space-3) var(--space-4); cursor: pointer; font-weight: var(--weight-medium); color: var(--color-link); list-style-position: inside; }
.disclosure[open] > summary { border-bottom: var(--border-width) solid var(--color-border); }
.disclosure__body { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; padding: var(--space-4); }

/* Semantic additions to the existing .badge / .btn (declared after both). A badge always carries its text; the danger button is outlined, never a solid red fill, and its label states the action. */
.badge--info { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--color-info-border); }
.badge--error { background: var(--color-error-bg); color: var(--color-error-text); border-color: var(--color-error-border); }
.btn--danger { background: var(--color-surface); color: var(--color-error-text); border-color: var(--color-error-text); }
.btn--danger:hover { background: var(--color-error-bg); }

/* Segmented control (UX-F3.2B, ADR-061 OD-UX-10): a row of equal NAVIGATION links (<nav class="segmented"> with <a class="segmented__item">) for choosing what a page shows. The current one carries
   aria-current="page" and is told apart WITHOUT colour: bold label, a bar under it and the text of its state. --active and --empty add a second cue each (a primary border / a dashed border) and every
   item states its status in words in .segmented__state. Reusable: no page or module name. Columns fill the row and wrap when the labels no longer fit (no breakpoint). */
.segmented { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); gap: var(--space-2); min-width: 0; margin: 0; padding: 0; }
.segmented__item { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-1); min-width: 0; min-height: var(--target-min); padding: var(--space-2) var(--space-3); text-align: center; text-decoration: none; color: var(--color-link); background: var(--color-surface); border: var(--border-width) solid var(--color-border-strong); border-radius: var(--radius-md); overflow-wrap: anywhere; }
.segmented__item:hover { background: var(--color-surface-alt); }
.segmented__item--active { border-color: var(--riword-primary); }
.segmented__item--empty { border-style: dashed; }
.segmented__item[aria-current="page"] { background: var(--color-info-bg); color: var(--color-info-text); border-color: var(--riword-primary); box-shadow: inset 0 calc(var(--space-1) * -1) 0 var(--riword-primary); }
.segmented__label { font-weight: var(--weight-bold); }
.segmented__state { font-size: var(--text-xs); color: var(--color-text-muted); }
.segmented__item[aria-current="page"] .segmented__state { color: var(--color-info-text); }

@media (min-width: 40rem) {
    /* UX-F1 (ADR-060): tablet refinements of the section 9d primitives. */
    .page-stack { gap: var(--space-5); }
    .panel-grid { gap: var(--space-5); }
    .filter-grid { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
    .form-grid { grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); }
    /* UX-F3.1.2 (ADR-060 §21): a short lead control + a wide one (about 1/3 + 2/3). Compound selector so it wins over .form-grid whatever the order; phones inherit the single column. */
    .form-grid.form-grid--split { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
    .disclosure__body { padding: var(--space-4) var(--space-5) var(--space-5); }

    .card-ws .card-ws-summary__list { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .card-ws .card-ws-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* CARD-CUSTOMIZATION-F3: the icon dialog is centered from 40rem (more specific than the phone-first base rule further down). */
    .icon-picker .icon-dialog:modal {
        width: min(46rem, calc(100% - 2rem));
        height: auto;
        max-height: min(42rem, calc(100% - 2rem));
        margin: auto;
        border: var(--border-width) solid var(--color-border-strong);
        border-radius: var(--radius-lg);
    }

    /* RCM-F6 master list (tablet) */
    .filters__search { max-width: 40rem; }
    .filters__toggle-label { display: none; }
    .filters__body { display: grid; grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); align-items: end; }
    .filters__more { grid-column: 1 / -1; }
    .filters__dates { grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr)); }
    .kpi-group__items { grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr)); }

    .data-table thead { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
    .data-table { display: table; }
    .data-table tbody { display: table-row-group; }
    .data-table tbody tr { display: table-row; padding: 0; border-bottom: 0; }
    .data-table th, .data-table td { padding: var(--space-2) var(--space-3); text-align: left; vertical-align: top; border-bottom: var(--border-width) solid var(--color-border); overflow-wrap: anywhere; }
    .data-table tbody th, .data-table tbody td { display: table-cell; padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
    .data-table tbody th { font-size: var(--text-sm); }
    .data-table thead th { background: var(--color-surface-alt); font-weight: var(--weight-bold); white-space: nowrap; }
    .data-table tbody tr:hover { background: var(--color-surface-alt); }
    .data-table__normal, .data-table__aux { display: table-cell !important; }
    .data-table__aux { display: block !important; }
    .col-wide { display: table-cell !important; }
    .data-table__action { text-align: right; }
    .summary-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }

    h1 { font-size: var(--text-3xl); }

    .public-shell__main,
    .shell__main { padding: var(--space-5); }

    .panel { padding: var(--space-5); }

    .shell__session {
        width: auto;
        margin-left: auto; /* brand left, session actions right */
    }

    .btn { padding-left: var(--space-6); padding-right: var(--space-6); }
    .landing__cta { flex-direction: row; flex-wrap: wrap; }
    .landing__steps,
    .landing__advantages { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .btn--quiet { padding-left: var(--space-4); padding-right: var(--space-4); }

    .nav-link { padding-left: var(--space-4); padding-right: var(--space-4); }

    /* RCM-F7.1 master/list — tablet: the toolbar becomes one wrapping row of selects, the advanced dates two per row, the table rows a flat roomy grid. */
    .master-wide .filters__search { max-width: none; }
    .master-wide .filters__body { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2) var(--space-3); }
    .master-wide .filters__body > .field { flex: 1 1 10rem; min-width: 0; }
    .master-wide .filters__more { flex: 0 0 auto; order: 1; align-self: center; }
    .master-wide .filters__more[open] { flex-basis: 100%; order: 3; }
    .master-wide .filters__body > #clear-filters { order: 2; }
    .master-wide .filters__dates { grid-template-columns: repeat(2, minmax(0, 1fr)); padding-bottom: var(--space-1); }
    .master-wide .data-table tbody tr { padding: 0; }
    .master-wide .data-table th, .master-wide .data-table td { padding: var(--space-3) var(--space-4); vertical-align: middle; }
    .master-wide .data-table tbody th, .master-wide .data-table tbody td { padding: var(--space-3) var(--space-4); vertical-align: middle; }
    .master-wide .data-table thead th { padding-top: var(--space-2); padding-bottom: var(--space-2); font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.04em; color: var(--color-text-muted); }
    .master-wide .data-table tbody tr:last-child th, .master-wide .data-table tbody tr:last-child td { border-bottom: 0; }
    .master-wide .data-table tbody th { font-size: var(--text-base); }
    .master-wide .data-table tbody td { color: var(--color-text-muted); }
    .master-wide .data-table tbody td.data-table__cutoff, .master-wide .data-table tbody td.data-table__flags { color: var(--color-text); }
    .master-wide .data-table__cutoff > span:first-child { font-weight: var(--weight-medium); font-variant-numeric: tabular-nums; }

    .shell--admin .shell__context { flex: 1 1 0; }

    /* REPORTS-DASH-F1 (section 11b) — tablet: filter actions beside the fields, 2 period figures per row, 3 snapshot figures, the CSV menu as a popover. */
    .reports-dash .filters__actions { flex: 0 0 auto; }
    .reports-dash .kpi-group__items--period { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .reports-dash .kpi-group__items--snapshot { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .download-menu { position: relative; width: auto; flex: none; }
    .download-menu__list { position: absolute; z-index: 20; top: 100%; right: 0; min-width: 18rem; }

    /* AUDIT-DASH-F1 (section 11c) — tablet: a real table (instant, action, entity, actor, result), the stacked-row labels off, filter actions beside the fields. */
    .audit-dash .filters__actions { flex: 0 0 auto; }
    .audit-dash .audit-table .audit-entity::before, .audit-dash .audit-table .audit-actor::before { content: none; }
    .audit-dash .audit-table .data-table tbody td.audit-when { color: var(--color-text); white-space: nowrap; font-size: var(--text-sm); }
    .audit-dash .audit-table .data-table tbody td.audit-result, .audit-dash .audit-table .data-table tbody td.audit-actor { justify-self: auto; white-space: nowrap; }
    .audit-dash .audit-table .data-table tbody th.audit-action { font-size: var(--text-sm); }

    /* F4.8-F: the custom stamp view side by side (image + actions) */
    .icon-custom .custom-stage {
        grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
        justify-items: stretch;
    }

    .icon-custom .custom-stage__body {
        width: auto;
    }

    .icon-custom .custom-stage__image {
        max-width: 11rem;
    }

    .icon-custom .custom-stage__actions .btn {
        flex: 0 0 auto;
    }

    .icon-custom .custom-upload__pick {
        width: auto;
    }
}

/* ---------- 11. Desktop (>= 1024 px) ---------- */
@media (min-width: 64rem) {
    /* UX-F1 (ADR-060): desktop refinements of the section 9d primitives (admin content is ~48rem here: the sidebar takes 16rem). */
    .panel-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .panel-grid--split { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }

    .card-ws .card-ws-summary__list { grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr)); }
    .card-ws > .card-ws-ops { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
    .card-ws > .card-ws-ops > :only-child { grid-column: 1 / -1; }
    /* RCM-F6 master list (desktop) */
    .col-desktop { display: table-cell !important; }
    .landing__hero { flex-direction: row; align-items: center; gap: var(--space-7); }
    .landing__hero-text { flex: 1 1 0; }
    .landing__art { flex: 1 1 0; max-width: 28rem; }
    .landing__hero h1 { font-size: 2.5rem; }
    /* Admin: the sidebar (lockup + grouped navigation) becomes a sticky left column beside the topbar and the content, which keeps a readable max width. */
    .shell--admin {
        grid-template-columns: var(--width-nav) minmax(0, 1fr);
        grid-template-rows: auto 1fr;
        grid-template-areas: "sidebar header" "sidebar main";
    }

    .shell--admin .shell__header {
        flex-wrap: nowrap;
        padding: var(--space-2) var(--space-6);
    }

    .shell--admin .shell__header .shell__session {
        display: flex;
        width: auto;
        margin-left: auto;
    }

    .shell__menu-button,
    .shell__menu-close,
    .shell__brand-compact,
    .shell__sidebar-account { display: none; }

    .shell__sidebar {
        grid-area: sidebar;
        display: flex;
        flex-direction: column;
        position: sticky;
        inset: auto;
        top: 0;
        align-self: start;
        width: auto;
        height: 100vh;
        overflow-y: auto;
        box-shadow: none;
        border-right: var(--border-width) solid var(--color-border);
        background: var(--color-surface);
    }

    .shell--admin .shell__main {
        margin: 0;
        padding: var(--space-6);
    }

    /* BRANDING-F2C: the card preview stays in view next to the controls. */
    .theme-editor {
        grid-template-columns: minmax(0, 1fr) minmax(16rem, 24rem);
        align-items: start;
    }

    .theme-editor__preview {
        order: 2;
        position: sticky;
        top: var(--space-4);
    }

    .theme-editor__controls {
        order: 1;
    }

    /* RCM-F7.1 master/list — desktop: capped content centred in the column on very large monitors; KPI strip in one row; four aligned advanced dates. */
    .shell--admin .shell__main:has(> .master-wide) { margin-inline: auto; }
    .master-wide .kpi-groups { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: stretch; flex-wrap: nowrap; }
    .master-wide .kpi-group--portfolio { padding-left: var(--space-5); border-left: var(--border-width) solid var(--color-border); }
    .master-wide .kpi-group--attention .kpi-group__items { grid-template-columns: repeat(2, minmax(7.5rem, 9rem)); }
    .master-wide .kpi-group--portfolio .kpi-group__items { grid-template-columns: repeat(5, minmax(0, 1fr)); }
    .master-wide .filters__dates { grid-template-columns: repeat(4, minmax(0, 1fr)); }

    /* REPORTS-DASH-F1 (section 11b) — desktop: both KPI groups side by side in one row (four period figures, three snapshot figures); the panels on a two-column grid. These follow the master rules above on purpose. */
    .reports-dash .kpi-groups--report { grid-template-columns: minmax(0, 4fr) minmax(0, 3fr); gap: var(--space-4); }
    .reports-dash .kpi-group__items--period { grid-template-columns: repeat(4, minmax(0, 1fr)); }
    .reports-dash .kpi-group__items--snapshot { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .report-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .report-grid__item--wide { grid-column: 1 / -1; }
}

/* ---------- 11b. Reports dashboard (REPORTS-DASH-F1, ADR-054) ----------
   Presentation of /admin/reports on the master-wide pattern (10b). Same tokens, same two breakpoints: the tablet and desktop parts live inside sections 10 and 11 (REPORTS-DASH-F1 markers); every rule is scoped to `.reports-dash` or to a component class of this slice,
   so no other page changes. The desktop rules follow the master ones on purpose: they refine them for the PERIOD / SNAPSHOT KPI groups. */
.reports-dash .report-toolbar { margin-bottom: var(--space-3); }
.reports-dash .filters__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.reports-dash .report-context { margin: var(--space-2) 0 0; font-size: var(--text-sm); font-variant-numeric: tabular-nums; }

/* KPI groups: «En el periodo» (the period figures) and «Instantánea actual» (today's state; tinted and captioned so it never reads as a period figure). */
.reports-dash .kpi-group { flex: 1 1 100%; } /* phone and tablet: the two groups stack; desktop turns the container into a two-column grid */
.reports-dash .kpi-group__context { display: inline-block; margin-left: var(--space-2); font-weight: var(--weight-regular); text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.reports-dash .kpi-group--snapshot { padding: var(--space-3); background: var(--color-surface-alt); border-radius: var(--radius-md); }
.reports-dash .kpi-group__hint { margin: var(--space-2) 0 0; font-size: var(--text-xs); color: var(--color-text-muted); }
.reports-dash .kpi__note { font-size: var(--text-xs); color: var(--color-text-muted); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.reports-dash .kpi__label { overflow-wrap: anywhere; }

/* The definitions of every indicator: one discreet disclosure. */
.report-definitions { margin: 0 0 var(--space-4); font-size: var(--text-sm); }
.report-definitions > summary { display: flex; align-items: center; min-height: var(--target-min); cursor: pointer; font-weight: var(--weight-medium); color: var(--color-link); }
.report-definitions__list { margin: 0; padding: var(--space-3) var(--space-4); background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); }
.report-definitions__list dt { margin-top: var(--space-2); font-weight: var(--weight-bold); }
.report-definitions__list dt:first-child { margin-top: 0; }
.report-definitions__list dd { margin: 0; color: var(--color-text-muted); }

/* The panels that F2 will redesign keep their content; here they only share the wide grid. */
.report-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
.report-grid__item { min-width: 0; }
.report-grid .panel { height: 100%; margin: 0; }
.report-grid .branch-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: var(--space-3); }
.report-grid .branch-item { padding: var(--space-3); }
.report-grid .branch-item__header { margin-bottom: var(--space-2); font-size: var(--text-base); }

/* ---------- 11c. Audit dashboard (AUDIT-DASH-F1, ADR-054) ----------
   Presentation of /admin/audit on the master-wide pattern (10b): a compact filter bar and ONE dense semantic table. Same tokens, same two breakpoints (the tablet part lives inside section 10, marked AUDIT-DASH-F1);
   every rule is scoped to `.audit-dash`, so no other page changes. Phone first: no horizontal table — each event is a compact stacked block (action and result, then the instant, then entity and actor). */
.audit-dash .audit-toolbar { margin-bottom: var(--space-3); }
.audit-dash .filters__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.audit-dash .audit-context { margin: var(--space-2) 0 0; font-size: var(--text-sm); }
.audit-dash .audit-summary { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: 0 0 var(--space-2); font-size: var(--text-sm); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.audit-dash .audit-summary__label { font-weight: var(--weight-bold); }
.audit-dash .audit-pager { margin-top: var(--space-4); }

.audit-table .data-table tbody tr.audit-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "action result" "when when" "entity actor";
    align-items: center;
}
.audit-table .data-table tbody th.audit-action { grid-area: action; font-size: var(--text-base); }
.audit-table .data-table tbody td.audit-result { grid-area: result; justify-self: end; }
.audit-table .data-table tbody td.audit-when { grid-area: when; font-size: var(--text-xs); color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
.audit-table .data-table tbody td.audit-entity { grid-area: entity; color: var(--color-text-muted); }
.audit-table .data-table tbody td.audit-actor { grid-area: actor; justify-self: end; }
.audit-table .audit-entity::before, .audit-table .audit-actor::before { content: attr(data-label) ": "; font-size: var(--text-xs); color: var(--color-text-muted); }
.audit-table .audit-row--denied { box-shadow: inset 3px 0 0 var(--color-error-border); }

/* The action leads; its display group is a secondary outlined tag (always text, never a colour code). */
.audit-action__name { font-weight: var(--weight-bold); overflow-wrap: anywhere; }
.audit-group { display: inline-block; margin-left: var(--space-2); padding: 0 var(--space-2); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: var(--weight-regular); color: var(--color-text-muted); white-space: nowrap; vertical-align: middle; }

/* Actor: «Sistema» is a dashed tag with a gear; a person is plain text. Result: «Correcto» is discreet; «Denegado» is a bordered, bold tag with a cross. Glyphs are decoration: the words carry the meaning. */
.audit-actor__tag--system { display: inline-block; padding: 0 var(--space-2); border: var(--border-width) dashed var(--color-border-strong); border-radius: var(--radius-sm); font-size: var(--text-xs); }
.audit-actor__tag--system::before { content: "\2699\00a0"; }
.audit-result__tag--success { font-size: var(--text-xs); color: var(--color-text-muted); }
.audit-result__tag--success::before { content: "\2713\00a0"; }
.audit-result__tag--denied { display: inline-block; padding: 0 var(--space-2); border: var(--border-width) solid var(--color-error-border); border-radius: var(--radius-sm); background: var(--color-error-bg); color: var(--color-error-text); font-size: var(--text-xs); font-weight: var(--weight-bold); }
.audit-result__tag--denied::before { content: "\2715\00a0"; }
/* end 11c */

/* CSV menu (native details/summary; closed by default; links keep their URLs). Phone: in the flow at full width; tablet and up: a popover under the button. */
.download-menu { width: 100%; }
.download-menu__summary { display: flex; align-items: center; justify-content: center; list-style: none; }
.download-menu__summary::-webkit-details-marker { display: none; }
.download-menu__summary::after { content: "▾"; content: "▾" / ""; margin-left: var(--space-2); }
.download-menu[open] > .download-menu__summary { background: var(--color-info-bg); }
.download-menu__list { display: grid; margin: var(--space-2) 0 0; padding: var(--space-2); list-style: none; background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-md); box-shadow: var(--shadow-panel); }
.download-menu__link { display: flex; align-items: center; min-height: var(--target-min); padding: 0 var(--space-3); border-radius: var(--radius-sm); color: var(--color-link); text-decoration: none; overflow-wrap: anywhere; }
.download-menu__link:hover { background: var(--color-surface-alt); text-decoration: underline; }

/* ---------- 12. Motion ---------- */
@media (prefers-reduced-motion: no-preference) {
    .btn,
    .nav-link,
    .skip-link {
        transition: background-color 120ms ease-out, transform 120ms ease-out;
    }
}

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}

/* ---------- 13. Blazor framework hooks ---------- */
.blazor-error-boundary {
    padding: var(--space-4);
    background: var(--color-error-text);
    color: var(--color-on-primary);
}

.blazor-error-boundary::after {
    content: "Ocurrió un error inesperado.";
}

/* ---------- M14-F1: customer restaurant list (tokens only) ---------- */
.restaurant-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.restaurant-list__item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-3);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
}

.restaurant-list__link {
    display: inline-flex;
    align-items: center;
    min-height: var(--target-min);
    flex: 1;
    min-width: 0;
    font-weight: var(--weight-medium);
}

.restaurant-list__link--off {
    color: var(--color-text-muted);
}

/* ---------- M14-F2: customer card + points summary (tokens only; PLATFORM UI, not the Wallet pass) ---------- */
.summary-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}

.summary-list {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.summary-list__row { min-width: 0; }
.summary-list dt { color: var(--color-text-muted); font-size: var(--text-sm); }
.summary-list dd { margin: 0; font-weight: var(--weight-medium); overflow-wrap: anywhere; }

.summary-list__balance {
    font-size: var(--text-3xl);
    font-weight: var(--weight-bold);
    line-height: var(--leading-tight);
}

.summary-list__number { font-family: var(--font-mono); font-size: var(--text-lg); letter-spacing: 0.02em; }

/* PC-M15-10: same-origin preview of the restaurant's OWN logo (Google Wallet masks logos to a circle; shown square here). */
.logo-preview {
    display: block;
    width: 6rem;
    height: 6rem;
    object-fit: contain;
    background: var(--color-surface-alt);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
}

/* M15-F7C: the registration QR, inline SVG that scales with the column (never wider than the viewport) and keeps its quiet zone. */
.registration-qr { margin: 0 0 var(--space-4); }
.registration-qr svg {
    display: block;
    width: 100%;
    max-width: 18rem;
    height: auto;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
}

/* ---------- M14-F3: restaurant sections + transaction history (tokens only; no new breakpoint) ---------- */
.restaurant-nav { margin: 0 0 var(--space-4); }
.restaurant-nav .nav-list { padding: 0; }

.history-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
}

.history-item {
    display: flex;
    flex-wrap: wrap; /* type, delta and date wrap onto new lines at 320 px instead of scrolling */
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
    padding: var(--space-3) 0;
    border-bottom: var(--border-width) solid var(--color-border);
    min-width: 0;
}

.history-item:last-child { border-bottom: 0; }
.history-item__type { flex: 1 1 8rem; min-width: 0; font-weight: var(--weight-medium); overflow-wrap: anywhere; }
.history-item__points { font-weight: var(--weight-bold); font-variant-numeric: tabular-nums; white-space: nowrap; }
.history-item__unit { font-weight: var(--weight-regular); color: var(--color-text-muted); font-size: var(--text-sm); }
.history-item__date { flex-basis: 100%; color: var(--color-text-muted); font-size: var(--text-sm); overflow-wrap: anywhere; }

.history-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
}


/* ---------- M14-F4: rewards + redemption (tokens only; no new breakpoint) ---------- */
.rewards-balance { margin-bottom: var(--space-4); }

.reward-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.reward-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-1);
    padding: var(--space-4) 0;
    border-bottom: var(--border-width) solid var(--color-border);
    min-width: 0;
}

.reward-item:first-child { padding-top: 0; }
.reward-item:last-child { border-bottom: 0; padding-bottom: 0; }
.reward-item p { margin: 0; }
.reward-item .btn { margin-top: var(--space-2); }
.reward-item__name { margin: 0; font-size: var(--text-lg); max-width: 100%; }
.reward-item__cost { font-weight: var(--weight-bold); font-variant-numeric: tabular-nums; }
.reward-item__status { font-weight: var(--weight-medium); color: var(--color-warning-text); }

.reward-actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-3);
    margin-top: var(--space-4);
}

.redemption-code {
    font-family: var(--font-mono);
    font-size: var(--text-2xl);
    font-weight: var(--weight-bold);
    letter-spacing: 0.08em;
    overflow-wrap: anywhere;
}

/* ---------- M14-F5: customer redemption history (tokens only; no new breakpoint) ---------- */
.redemption-list {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.redemption-item {
    padding: var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    min-width: 0;
}

.redemption-item__reward { margin: 0 0 var(--space-1); font-size: var(--text-lg); }
.redemption-item__restaurant { margin: 0 0 var(--space-3); color: var(--color-text-muted); }
.redemption-item__restaurant a { display: inline-flex; align-items: center; min-height: var(--target-min); }
.redemption-item p:last-child { margin-bottom: 0; }

/* ---------- M14-F6: Wallet action (own control, NOT Google's branded button; tokens only) ---------- */
.wallet-action {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    margin-top: var(--space-4);
}

.wallet-action p { margin: 0; }
.wallet-action .btn { max-width: 100%; white-space: normal; }

/* ---------- GW-COMM-F4: admin communications history (tokens only; same shape as .redemption-list) ---------- */
.communication-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.communication-item {
    padding: var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    min-width: 0;
}

.communication-item__header { margin: 0 0 var(--space-1); font-size: var(--text-lg); }
.communication-item__body { margin: 0 0 var(--space-3); color: var(--color-text-muted); }

/* ---------- M15-F2/F3: admin branch and reward lists (tokens only; same shape as .communication-list) ---------- */
.branch-list,
.reward-admin-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.branch-item,
.reward-admin-item {
    padding: var(--space-4);
    background: var(--color-surface);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    min-width: 0;
}

.branch-item__header,
.reward-admin-item__header { margin: 0 0 var(--space-3); font-size: var(--text-lg); }
.branch-item__actions,
.reward-admin-item__actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-3); }

/* ---------- NX-F1F: plan and subscription administration (tokens only; cards, never tables) ---------- */
.choice__body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.choice__body p { margin: 0; }
.actions { display: flex; flex-wrap: wrap; gap: var(--space-2); } /* stacks on narrow screens */
.subscription-section details > summary { cursor: pointer; min-height: var(--target-min); padding: var(--space-2) 0; font-weight: var(--weight-medium); }

/* NX-F6C + BRANDING-F2D: the branded header of a restaurant's customer pages. The theme arrives only as the validated --customer-brand-* custom properties of this element
   (or of the loyalty card that contains it); without them it keeps the platform look. */
.brand-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem;
    padding: 1rem;
    border-radius: 0.5rem;
    background: var(--customer-brand-background, transparent);
    color: var(--customer-brand-text, inherit);
}

.brand-header--in-card {
    padding: 0 0 var(--space-3);
    border-radius: 0;
    background: none;
    color: inherit;
    border-bottom: var(--border-width) solid var(--customer-brand-secondary, var(--color-border));
}

.brand-header__logo {
    flex: none;
    width: 3rem;
    height: 3rem;
    object-fit: contain;
    background: var(--color-surface);
    border-radius: 50%;
}

.brand-header h1 {
    margin: 0;
    overflow-wrap: anywhere;
    color: var(--customer-brand-primary, inherit);
}

/* ---------- BRANDING-F2C: visual theme editor ----------
   The restaurant's colors are DATA: they only ever arrive as the validated custom properties --cp-* on .card-preview (ThemePresentation.Style) and as --swatch / --chip on
   the palette and the current-color chip. Everything else here uses the platform tokens, so no restaurant color can restyle the administration chrome. */
.icon-sprite {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

.theme-editor {
    display: grid;
    gap: var(--space-5);
    min-width: 0;
}

.theme-editor__preview,
.theme-editor__controls {
    min-width: 0;
}

/* Below the desktop breakpoint the controls come first and the preview follows (the preview stays first in the source). */
.theme-editor__preview--after {
    order: 2;
}

.theme-editor__controls {
    order: 1;
}

.card-preview {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    max-width: 22rem;
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--cp-bg, var(--color-surface));
    color: var(--cp-text, var(--color-text));
}

.card-preview__head {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding-bottom: var(--space-3);
    border-bottom: var(--border-width) solid var(--cp-secondary, var(--color-border-strong));
}

.card-preview__logo {
    flex: none;
    width: 2.5rem;
    height: 2.5rem;
    object-fit: contain;
    border-radius: 50%;
}

.card-preview__logo--empty {
    border: 2px dashed var(--cp-secondary, var(--color-border-strong));
}

.card-preview__name {
    min-width: 0;
    font-weight: var(--weight-bold);
    font-size: var(--text-lg);
    color: var(--cp-primary, var(--color-primary));
    overflow-wrap: anywhere;
}

.card-preview__stamps {
    display: grid;
    grid-template-columns: repeat(var(--cp-cols, 5), minmax(0, 1fr));
    gap: var(--space-2);
}

.card-preview__stamp {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    border-radius: 50%;
}

.card-preview__stamp--earned {
    color: var(--cp-stamp, var(--color-success-text));
    border: 2px solid var(--cp-stamp, var(--color-success-text));
}

.card-preview__stamp--pending {
    color: var(--cp-secondary, var(--color-border-strong));
    border: 2px dashed var(--cp-secondary, var(--color-border-strong));
    opacity: 0.75;
}

.card-preview__glyph {
    width: 62%;
    height: 62%;
}

/* CARD-CUSTOMIZATION-F4.6-C: the preview holds the catalog glyph (svg) and the custom-mask glyph side by side and toggles them with [hidden]. A class that sets display (the mask glyph) beats the
   browser's [hidden] rule, and [hidden] is not honored at all on an svg, so the guard is explicit and covers both. */
.card-preview [hidden] {
    display: none;
}

.card-preview__glyph--small {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
    color: var(--cp-primary, var(--color-primary));
}

.card-preview__balance {
    margin: 0;
    font-size: var(--text-3xl);
    font-weight: var(--weight-bold);
}

.card-preview__caption {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    font-size: var(--text-sm);
}

.card-preview__bar {
    height: 0.5rem;
    overflow: hidden;
    border: var(--border-width) solid var(--cp-secondary, var(--color-border-strong));
    border-radius: var(--radius-sm);
}

.card-preview__bar > span {
    display: block;
    height: 100%;
    background: var(--cp-accent, var(--color-primary));
}

.theme-color {
    display: grid;
    gap: var(--space-2);
    min-width: 0;
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.theme-color__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-2);
}

.theme-color__head label {
    font-weight: var(--weight-bold);
}

.theme-color .field__hint {
    margin: 0;
}

.theme-color__row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

.theme-color input.theme-color__hex {
    width: 7.5rem;
    flex: none;
    font-family: var(--font-mono);
    text-transform: uppercase;
}

.theme-color__reset {
    margin-left: auto;
}

.theme-color__default {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.theme-color__default-chip {
    flex: none;
    width: 0.875rem;
    height: 0.875rem;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-sm);
    background: var(--chip, var(--color-surface-alt));
}

.theme-color__default code {
    font-family: var(--font-mono);
}

.theme-editor__controls .stack > .theme-color,
.theme-editor__controls .stack > .icon-picker {
    min-width: 0;
    margin: 0;
    padding: 0;
    border: 0;
}

/* CARD-CUSTOMIZATION-F4.6-C: the color-control rules F3 (ba8105b) dropped by mistake, restored verbatim from ba8105b~1: native picker, chip, state badge, palette grid and swatches. */
.theme-color input.theme-color__picker {
    flex: none;
    width: var(--target-min);
    height: var(--target-min);
    padding: 0;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    cursor: pointer;
}

.theme-color__chip {
    flex: none;
    width: 2rem;
    height: 2rem;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--chip, var(--color-surface-alt));
}

.theme-color__state {
    padding: 0 var(--space-2);
    border-radius: var(--radius-sm);
    background: var(--color-surface-alt);
    font-size: var(--text-sm);
    color: var(--color-text-muted);
}

.theme-color__palette {
    display: grid;
    grid-template-columns: repeat(6, 2rem);
    justify-content: start;
    gap: var(--space-2);
}

.theme-color__palette[hidden],
.theme-color input[hidden] {
    display: none;
}

.swatch {
    position: relative;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--swatch, var(--color-surface-alt));
    cursor: pointer;
}

.swatch:hover {
    border-color: var(--color-text);
    transform: scale(1.08);
}

.swatch:focus-visible {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
}

/* Selected: a ring AND a check mark (white tick on a dark disc), so the selection never depends on the swatch color alone. */
.swatch[aria-pressed="true"] {
    border-color: var(--color-text);
    box-shadow: 0 0 0 2px var(--color-surface), 0 0 0 4px var(--color-text);
}

.swatch[aria-pressed="true"]::after {
    content: "\2713";
    position: absolute;
    inset: 50% auto auto 50%;
    display: grid;
    place-items: center;
    width: 1.1rem;
    height: 1.1rem;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 0.75rem;
    line-height: 1;
}

/* The JS-only controls and the filtered-out options stay hidden whatever display their own class sets. */
.icon-picker [hidden] {
    display: none;
}

/* ---------- CARD-CUSTOMIZATION-F3: the icon selector (current icon + «Cambiar icono» + native dialog; tokens only; mobile-first, breakpoints 40rem) ---------- */
.icon-current {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.icon-current__glyph {
    flex: none;
    width: 2.25rem;
    height: 2.25rem;
}

.icon-current__text {
    display: flex;
    flex: 1 1 8rem;
    flex-direction: column;
    min-width: 0;
    overflow-wrap: anywhere;
}

.icon-current__change {
    flex: none;
}

.icon-dialog {
    padding: 0;
    border: 0;
    background: var(--color-surface);
    color: var(--color-text);
}

.icon-dialog::backdrop {
    background: var(--color-backdrop);
}

/* Without script the dialog is not a dialog: it is shown inline and every option stays a plain radio. */
.icon-dialog:not(:modal) {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
}

@media (scripting: none) {
    .icon-dialog:not([open]) {
        display: block;
    }
}

/* Opened (script): full screen on a phone, a centered dialog from 40rem. */
.icon-dialog:modal {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: none;
    height: 100%;
    max-height: none;
    margin: 0;
    overflow: hidden;
}

.icon-dialog__panel {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    min-height: 0;
}

.icon-dialog__header {
    display: flex;
    flex: none;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
    border-bottom: var(--border-width) solid var(--color-border);
}

.icon-dialog__title {
    margin: 0;
    font-size: var(--text-lg);
}

.icon-dialog__close {
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: var(--target-min);
    height: var(--target-min);
    padding: 0;
    border: var(--border-width) solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text);
    cursor: pointer;
}

.icon-dialog__close:hover {
    background: var(--color-surface-alt);
}

/* Search, categories and the grid scroll together, so a short screen never squeezes the grid out. */
.icon-dialog__scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: var(--space-3) var(--space-4);
}

.icon-dialog__tools {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
}

.icon-dialog__search {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    font-weight: var(--weight-medium);
}

.icon-dialog__search input {
    width: 100%;
    min-height: var(--target-min);
    padding: var(--space-2) var(--space-3);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
}

.icon-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.icon-chip {
    min-height: 2.25rem;
    padding: var(--space-1) var(--space-3);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-size: var(--text-sm);
    cursor: pointer;
}

.icon-chip:hover {
    background: var(--color-info-bg);
}

/* The pressed category is told by a heavier border and weight, not by color alone. */
.icon-chip[aria-pressed="true"] {
    border-color: var(--riword-primary);
    outline: 2px solid var(--riword-primary);
    background: var(--color-info-bg);
    font-weight: var(--weight-bold);
}

.icon-chip:focus-visible {
    outline: 3px solid var(--color-focus);
}

.icon-dialog__count {
    margin: 0;
}

.icon-dialog__empty {
    margin: var(--space-3) 0 0;
}

.icon-picker__default {
    margin-bottom: var(--space-3);
}

.icon-dialog__footer {
    display: flex;
    flex: none;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-top: var(--border-width) solid var(--color-border);
    background: var(--color-surface);
}

.icon-dialog__footer .btn {
    flex: 1 1 8rem;
}

.icon-picker__options {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(5.25rem, 1fr));
    gap: var(--space-2);
}

.icon-option {
    display: block;
    cursor: pointer;
}

.icon-option input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
}

.icon-option__body {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-1);
    height: 100%;
    min-width: 0;
    padding: var(--space-2);
    border: var(--border-width) solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    font-size: var(--text-sm);
    text-align: center;
    overflow-wrap: anywhere;
}

.icon-option__body--wide {
    flex-direction: row;
    justify-content: center;
}

.icon-option__glyph {
    width: 1.75rem;
    height: 1.75rem;
}

.icon-option input:checked + .icon-option__body {
    border-color: var(--riword-primary);
    outline: 2px solid var(--riword-primary);
    background: var(--color-info-bg);
    font-weight: var(--weight-medium);
}

/* The selected option also carries a check mark (and a visually hidden «Seleccionado»), so the state never depends on color alone. */
.icon-option input:checked + .icon-option__body::after {
    content: "\2713";
    position: absolute;
    top: 0.1rem;
    right: 0.3rem;
    color: var(--riword-primary);
    font-weight: var(--weight-bold);
    line-height: 1;
}

.icon-option input:not(:checked) + .icon-option__body .icon-option__mark {
    display: none;
}

.icon-option input:focus-visible + .icon-option__body {
    outline: 3px solid var(--color-focus);
}

/* ---------- CARD-CUSTOMIZATION-F4.5: the «Personalizado» view of the icon selector (tokens only; same patterns as the F3 selector) ---------- */
/* A custom icon is a silhouette (the normalized PNG) used as a CSS mask over the current color, so it takes the stamp / text colors exactly like a catalog glyph. */
/* CARD-CUSTOMIZATION-F4.6-C: a mask element without its --ri-mask paints NOTHING (a fully transparent image), never a solid block of currentColor. */
:root {
    --ri-mask-none: linear-gradient(transparent, transparent);
}

.icon-mask {
    display: inline-block;
    flex: none;
    background-color: currentColor;
    -webkit-mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
    mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
}

/* The preview glyph of a custom icon: the same silhouette mask, tinted by the stamp / accent color of its own container exactly like a catalog glyph. */
.card-preview__glyph--mask {
    display: block;
    background-color: currentColor;
    -webkit-mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
    mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
}

.icon-tabs {
    display: flex;
    flex: none;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4) 0;
    border-bottom: var(--border-width) solid var(--color-border);
}

.icon-tab {
    min-height: var(--target-min);
    padding: var(--space-1) var(--space-4);
    border: var(--border-width) solid transparent;
    border-bottom: 0;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    background: transparent;
    color: var(--color-text);
    font: inherit;
    cursor: pointer;
}

.icon-tab:hover {
    background: var(--color-info-bg);
}

/* The active view is told by a heavier border and weight as well as the color. */
.icon-tab[aria-selected="true"] {
    border-color: var(--color-border-strong);
    border-bottom: 3px solid var(--riword-primary);
    background: var(--color-surface);
    font-weight: var(--weight-bold);
}

.icon-tab:focus-visible {
    outline: 3px solid var(--color-focus);
}

.icon-view__title {
    margin: 0 0 var(--space-2);
    font-size: var(--text-lg);
}

/* With the script the tabs name the views; without it the two views are stacked and need their own headings. */
.theme-editor[data-ready="true"] .icon-view__title {
    display: none;
}

.icon-custom {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.icon-custom > * {
    margin-top: 0;
    margin-bottom: 0;
}

.icon-custom__options {
    display: grid;
    gap: var(--space-2);
}

.icon-option--custom .icon-option__body {
    flex-wrap: wrap;
    justify-content: flex-start;
    gap: var(--space-2) var(--space-3);
    text-align: left;
}

.icon-option--custom .icon-option__glyph {
    width: 2.5rem;
    height: 2.5rem;
    color: var(--riword-primary);
}

/* «Preparado, aún no seleccionado»: a visible text, hidden as soon as the option is the checked one. */
.icon-option__badge {
    flex: 1 1 100%;
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

.icon-option input:checked + .icon-option__body .icon-option__badge {
    display: none;
}

.icon-custom__upload {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.icon-custom__upload input[type="file"] {
    max-width: 100%;
}

.icon-custom__remove {
    padding: var(--space-3);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
}

.icon-custom__remove summary {
    min-height: var(--target-min);
    display: flex;
    align-items: center;
    cursor: pointer;
    font-weight: var(--weight-medium);
}

.icon-custom__remove summary:focus-visible {
    outline: 3px solid var(--color-focus);
}

.icon-custom__status:empty {
    display: none;
}

.theme-contrast {
    margin: 0;
    padding-left: var(--space-5);
    font-size: var(--text-sm);
}

.theme-contrast li[hidden] {
    display: none;
}

.theme-contrast[data-state="ok"] {
    color: var(--color-success-text);
}

.theme-contrast [data-level="warning"] {
    color: var(--color-warning-text);
}

.theme-contrast [data-level="blocking"] {
    color: var(--color-error-text);
    font-weight: var(--weight-medium);
}

/* ---------- BRANDING-F2D: the customer's branded loyalty card ----------
   ONE isolated area: the card element carries the --customer-brand-* custom properties (canonical colors only, ThemePresentation.CustomerStyle). Navigation, the Wallet/card panel, the
   privacy panel and every alert keep the platform tokens, so a restaurant theme can never reduce their readability. */
.customer-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
    margin-bottom: var(--space-4);
    padding: var(--space-4);
    border: var(--border-width) solid var(--customer-brand-secondary, var(--color-border));
    border-radius: var(--radius-lg);
    background: var(--customer-brand-background, var(--color-surface));
    color: var(--customer-brand-text, var(--color-text));
}

.customer-card__body {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    min-width: 0;
}

.customer-card__heading {
    margin: 0;
    font-size: var(--text-lg);
    color: var(--customer-brand-primary, inherit);
}

.customer-card .summary-list dt {
    color: var(--customer-brand-text, var(--color-text-muted));
}

.customer-card .summary-list__balance {
    color: var(--customer-brand-primary, inherit);
}

.customer-card__progress {
    width: 100%;
    height: 0.75rem;
    accent-color: var(--customer-brand-accent, var(--color-primary));
}

/* The stamp card: as many positions as the goal, wrapping to the width available (no horizontal scrolling for any supported goal). */
.stamp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(2.75rem, 1fr));
    gap: var(--space-2);
    min-width: 0;
}

.stamp-grid__stamp {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 0;
    aspect-ratio: 1;
    border-radius: 50%;
}

.stamp-grid__stamp--earned {
    color: var(--customer-brand-stamp, var(--color-success-text));
    border: 2px solid currentColor;
}

.stamp-grid__stamp--pending {
    color: var(--customer-brand-secondary, var(--color-border-strong));
    border: 2px dashed currentColor;
    opacity: 0.75;
}

.stamp-grid__glyph {
    width: 62%;
    height: 62%;
}

/* CARD-CUSTOMIZATION-F4.5.1: a custom icon is the program's silhouette used as a mask over the stamp's own color (earned / pending), exactly like a catalog glyph. */
.stamp-grid__glyph--mask {
    display: block;
    background-color: currentColor;
    -webkit-mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
    mask: var(--ri-mask, var(--ri-mask-none)) center / contain no-repeat;
}

/* ---------- DD-V1-VISIT-01: "Registrar visita" counter (number field, optional camera) ---------- */
/* The 12-digit number is the primary action: a large, easy-to-hit field and button on every device. */
.counter-number input {
    font-size: var(--text-xl, 1.5rem);
    min-height: 3.5rem;
    letter-spacing: 0.08em;
}

.counter-number .btn,
.btn--large {
    min-height: 3.5rem;
    font-size: var(--text-lg, 1.125rem);
}

/* The camera is optional: the panel is revealed by counter-scan.js; [hidden] must beat the display of .btn. */
.scan-panel[hidden],
.scan-panel [hidden] {
    display: none;
}

/* UX-F2 (ADR-060): while the camera panel is still [hidden] (no script, or no camera support) it takes no grid cell, so the barcode panel that follows it fills the whole row instead of half of it.
   A sibling selector, not :has(): once counter-scan.js removes [hidden] the rule stops matching and the two panels sit side by side. */
.panel-grid > .scan-panel[hidden] + * {
    grid-column: 1 / -1;
}

.scan-panel video {
    width: 100%;
    max-width: 28rem;
    border-radius: var(--radius-md);
    background: var(--color-surface-alt);
}

/* ---------- CARD-CUSTOMIZATION-F4.8-E (ADR-057): the FULL-COLOR custom stamp image ----------
   It is an ordinary image (the canonical, immutable file served by /media/stamp-images): its own colors, never a mask and never tinted by the stamp color. No display is set on the
   image classes, so the [hidden] attribute keeps working. The earned stamp shows it as it is; a pending stamp shows the SAME image subdued (grayscale + reduced opacity) inside the
   dashed ring, so earned / pending never depend on color alone. object-fit keeps the aspect ratio: no stretching, a transparent PNG stays transparent. */
.stamp-grid__image,
.card-preview__glyph--image,
.icon-current__image {
    object-fit: contain;
}

.stamp-grid__image {
    width: 62%;
    height: 62%;
}

.stamp-grid__stamp--pending .stamp-grid__image,
.card-preview__stamp--pending .card-preview__glyph--image {
    filter: grayscale(1);
    opacity: 0.4;
}

/* ---------- CARD-CUSTOMIZATION-F4.8-F: the «Personalizado» view (Subir → Usar → Guardar) ----------
   Existing tokens only. The header stays visible even when the dialog tabs name the views; every state is also written in words (never by color alone); the image classes set no display, so the
   [hidden] guard of .icon-picker keeps working. A narrow screen stacks everything in one column. */
.theme-editor[data-ready="true"] .icon-custom .icon-view__title {
    display: block;
}

.custom-steps {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2) var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}

.custom-steps__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--text-sm);
}

.custom-steps__mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border: 2px solid currentColor;
    border-radius: 50%;
    font-weight: 600;
    font-size: var(--text-sm);
    background: var(--color-surface);
}

.custom-steps__item[data-state="current"] {
    color: var(--riword-primary);
    font-weight: 600;
}

.custom-steps__item[data-state="current"] .custom-steps__mark {
    border-style: double;
    border-width: 4px;
}

.custom-steps__item[data-state="done"] {
    color: var(--color-success-text);
}

.custom-steps__item[data-state="done"] .custom-steps__mark {
    border-color: var(--color-success-text);
    background: var(--color-success-text);
    color: var(--color-surface);
}

.custom-stage {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: var(--space-4);
    align-items: start;
    padding: var(--space-4);
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
}

.custom-stage[data-state="prepared"],
.custom-stage[data-state="selected"] {
    border-width: 2px;
    border-color: var(--riword-primary);
}

.custom-stage[data-state="selected"] {
    border-style: solid;
}

.custom-stage[data-state="prepared"] {
    border-style: dashed;
}

.custom-stage__media {
    display: flex;
    justify-content: center;
}

.custom-stage__image {
    margin-inline: auto;
    width: 100%;
    max-width: 11rem;
    height: auto;
    aspect-ratio: 1;
    object-fit: contain;
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--riword-primary);
}

.custom-stage__body {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.custom-stage__body > * {
    margin: 0;
}

.custom-stage__title {
    font-size: var(--text-lg);
}

.custom-stage__status {
    font-weight: 600;
}

.custom-stage__actions .btn {
    flex: 1 1 100%;
}

.custom-upload__pick {
    width: 100%;
}

.custom-stage__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

/* «Usar este sello»: a real radio inside a button-looking label (works without script); with the script a button does the same and the radio label is only the «in use» mark. */
.custom-use {
    position: relative;
    cursor: pointer;
}

.custom-use input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    opacity: 0;
}

.custom-use:focus-within {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
}

.custom-use__on {
    display: none;
}

.custom-use input:checked ~ .custom-use__on {
    display: inline;
}

.custom-use input:checked ~ .custom-use__off {
    display: none;
}

.theme-editor[data-ready="true"] .custom-use input:not(:checked) ~ .custom-use__off {
    display: none;
}

.theme-editor[data-ready="true"] .custom-use:not(:has(input:checked)) {
    display: none;
}

.theme-editor[data-ready="true"] .custom-use:has(input:checked) {
    background: var(--color-surface);
    color: var(--color-success-text);
    border: 2px solid currentColor;
    cursor: default;
}

.custom-stage[data-state="selected"] [data-role="icon-use"],
.custom-stage[data-state="current"] [data-role="icon-use"] {
    display: none;
}

.custom-upload {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.custom-upload__surface {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-5, var(--space-4));
    border: 2px dashed var(--color-border-strong, var(--color-border));
    border-radius: var(--radius-md);
    background: var(--color-surface);
    text-align: center;
}

.custom-upload__surface[data-dragging="true"] {
    border-style: solid;
    border-color: var(--riword-primary);
}

.custom-upload[data-compact="true"] .custom-upload__surface {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    padding: var(--space-3);
}

.custom-upload[data-compact="true"] .custom-upload__glyph {
    display: none;
}

.custom-upload__surface > p {
    margin: 0;
}

.custom-upload__glyph {
    color: var(--riword-primary);
}

.custom-upload__pick {
    cursor: pointer;
}

.custom-upload__input {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    opacity: 0;
    overflow: hidden;
}

.custom-upload__input:focus-visible + .custom-upload__name,
.custom-upload__surface:focus-within .custom-upload__pick {
    outline: 3px solid var(--color-focus);
    outline-offset: 2px;
}

.custom-upload__name {
    max-width: 100%;
    overflow-wrap: anywhere;
    font-size: var(--text-sm);
}

.custom-upload__name:empty {
    display: none;
}

.theme-editor[data-autoupload="true"] .custom-upload__submit {
    display: none;
}

/* ---------- CW-F1 (ADR-059): card workspace structure ----------
   Presentation only. CW-F1.1: the layout rules (summary, operations zone, purchase pair) live in section 9c below and in the two existing breakpoint blocks. */
.card-ws { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.card-ws > * { margin: 0; min-width: 0; }
.card-ws-actions { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-3); align-items: flex-start; }
.card-ws-actions form { margin: 0; }
.card-ws-admin { background: var(--color-surface); border: var(--border-width) solid var(--color-border); border-radius: var(--radius-lg); }
.card-ws-admin__summary { display: flex; align-items: center; min-height: var(--target-min); padding: var(--space-2) var(--space-4); cursor: pointer; font-weight: var(--weight-medium); color: var(--color-link); }
.card-ws-admin__summary:focus-visible { outline: 3px solid var(--color-focus, currentColor); outline-offset: 2px; }
.card-ws-admin__body { display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-2) var(--space-4) var(--space-4); }
.card-ws-admin__section { display: flex; flex-direction: column; gap: var(--space-3); min-width: 0; }
.card-ws__subheading { margin: 0; font-size: var(--text-lg); }
