/* ============================================
   DESIGN TOKENS - Shared CSS variables
   Used by Portal, Admin, and Backend.
   Load this first; templates may override with SITE/theme values.

   Figma token mapping (school theme packs):
   - Academic Authority: Primary-Base #0D173B -> --school-primary / palette.primary
   - Digital Lavender:   Primary-Base #7C7CE4 -> --school-primary
   - Modern Sage:        Primary-Deep #2D4739 -> --school-primary
   - Surface-Bg / Neutral-Text: see palette.dashboard_bg, palette.text
   - Shared states: Success #22C55E, Warning #F59E0B, Error #EF4444, Disabled #9CA3AF
   - See docs/THEME_COMPONENT_KITS.md and docs/THEME_ACCESSIBILITY.md
   ============================================ */

:root {
  /* ============================================================
     APPLE SEMANTIC SURFACES (v2 theme system, added 2026-05-12)
     ------------------------------------------------------------
     Role-named tokens — every shell, page, and component should
     consume these (not raw hex, not --portal-* / --admin-content-*).
     Old names below are kept as aliases for back-compat; they now
     resolve through the semantic layer, so a single edit here
     cascades platform-wide.

     Layered elevation grammar (Apple HIG):
       --surface-bg       outermost canvas (body)
       --surface-canvas   inner content shell (.page-wrap, .cp-main)
       --surface-elevated cards, panels lifted off canvas
       --surface-popover  dropdowns/menus with backdrop-filter
       --surface-overlay  hover/active tint mixed into any surface

     Text grammar:
       --text-primary | --text-secondary | --text-tertiary | --text-muted

     Hairlines + elevations follow Apple's 0.5px / soft-shadow recipe.
     ============================================================ */
  --surface-bg: #f5f5f7;
  --surface-canvas: #fbfbfd;        /* off-white so elevated cards visibly tone-lift */
  --surface-elevated: #ffffff;
  --surface-popover: color-mix(in oklab, #ffffff 92%, transparent);
  /* Hover/active overlay — color-mixed with brand accent so hover faintly carries
     brand character instead of being flat black. Falls back to neutral. */
  --surface-overlay: color-mix(in oklab, var(--school-primary, #4f46e5) 5%, transparent);
  --surface-overlay-strong: color-mix(in oklab, var(--school-primary, #4f46e5) 10%, transparent);
  --surface-sunken: #ebebef;
  --hairline: rgba(0, 0, 0, 0.08);
  --hairline-strong: rgba(0, 0, 0, 0.14);
  --text-primary: #1d1d1f;
  --text-secondary: #424245;
  --text-tertiary: #6e6e73;
  /* Pass 10 / WCAG 2.2 AA: muted was #86868b → ratio 3.57:1 on --surface-canvas.
     Tightened to #6c6c70 so even small-text consumers pass 4.5:1 (computed 4.97:1).
     Visual distinction from --text-tertiary preserved by the surrounding font-weight
     and surface contrast, not by lightness — the AA floor wins over hierarchy nuance. */
  --text-muted: #6c6c70;
  --elev-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 1px rgba(15, 23, 42, 0.04);
  --elev-2: 0 4px 12px rgba(15, 23, 42, 0.08), 0 1px 3px rgba(15, 23, 42, 0.06);
  /* v3.58.x (2026-05-22): --elev-3 0.12 -> 0.18 flipped after coordinated audit (docs/generated/elev3_audit/index.html). Visual-weight bump aligned to v8 200x preview. */
  --elev-3: 0 18px 48px rgba(15, 23, 42, 0.18), 0 4px 12px rgba(15, 23, 42, 0.08);
  --material-blur: saturate(180%) blur(20px);
  --material-blur-strong: saturate(180%) blur(28px);
  --radius-pill: 999px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
  /* v3.57.13 preview-parity audit: bumped 20px -> 22px to match v8 200x
     preview. 11 consumer sites; 2 are token-redefinitions
     (design-system-unified.css sets `var(--lux-radius-xl, 1rem)` and loads
     AFTER design-tokens.css in all 4 shells, so it masks this value on
     portal/cp/base/admin; rmc-warm-bright-school.css sets 24px locally).
     Consumer fallbacks (`20px`, `1rem`, `1.25rem`) don't bet on the exact
     value — safe nudge. SAFE-TO-FLIP. */
  --radius-xl: 22px;
  /* Motion vocabulary — three tiers, plus Apple-style entry/exit easings.
     `motion-spring` is for entry (frosted popovers, drawer open, toast in).
     `motion-decel` is for exits and decay. All consumers should use these names
     — never inline `transition: all 0.2s ease`. */
  --motion-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --motion-normal: 220ms cubic-bezier(0.4, 0, 0.2, 1);
  /* v3.57.13 preview-parity audit: 360ms cubic-bezier(0.22, 1, 0.36, 1)
     -> 420ms cubic-bezier(0.22, 0.61, 0.36, 1) to match v8 200x preview.
     Strong evidence preview is intended target: rmc-cp-200x.css:32 already
     hardcodes the preview value as its fallback (`var(--motion-slow,
     420ms cubic-bezier(0.22, 0.61, 0.36, 1))`). 4 consumers; the bezier
     change is from a sharper-ended ease-out to a more conservative
     emphasized ease-out. SAFE-TO-FLIP. */
  --motion-slow: 420ms cubic-bezier(0.22, 0.61, 0.36, 1);
  --motion-spring: 420ms cubic-bezier(0.34, 1.56, 0.64, 1);
  --motion-decel: 260ms cubic-bezier(0.2, 0.8, 0.2, 1);

  /* Brand gradient — single-accent luminous (Linear / Vercel feel) rather than the
     old indigo→emerald two-color gradient. `--brand-gradient-end` defaults to
     indigo-deeper; tenants can override via SITE.brand_gradient_end to e.g. a 30%
     darker shade of their primary so the header still feels luminous. */
  --brand-gradient-start: var(--school-primary);
  --brand-gradient-end: var(--color-indigo-800, #3730a3);
  --brand-gradient-angle: 135deg;
  --brand-gradient: linear-gradient(var(--brand-gradient-angle), var(--brand-gradient-start), var(--brand-gradient-end));

  /* Brand (overridden by SITE.primary_color / accent_color in base/portal/backend templates).
     Platform default: indigo + emerald — recessive enough to not fight tenant brand overrides,
     vibrant enough to feel modern. Tenants set their own via SITE_PRIMARY_COLOR / SITE_ACCENT_COLOR. */
  --school-primary: #4f46e5;
  --school-accent: #10b981;
  --school-primary-light: rgba(79, 70, 229, 0.14);
  --school-accent-light: rgba(16, 185, 129, 0.12);

  /* Admin content area (forms, lists). Refined dark uses softer slate, not navy.
     Previous overrides via admin-content-readability.css / admin-dark-readability.css retired
     2026-05-12 — values folded into the token defaults below.
     v2 theme system (2026-05-12): aliased through Apple semantic surfaces so a single
     edit to --surface-* cascades into admin too. Specific values below are fallbacks. */
  --admin-content-bg: var(--surface-canvas, #ffffff);
  --admin-content-surface: var(--surface-elevated, #ffffff);
  --admin-content-text: var(--text-primary, #0f172a);
  --admin-content-text-muted: var(--text-secondary, #475569);
  --admin-content-border: var(--hairline, rgba(15, 23, 42, 0.12));
  --admin-content-card-bg: var(--surface-elevated, #ffffff);
  --admin-content-accent: #0ea5e9;
  --admin-content-accent-alt: #38bdf8;
  --admin-content-accent-fg: #ffffff;
  --admin-content-thead-bg: #f1f5f9;
  --admin-content-danger: #dc2626;

  /* Admin surface (overridden by SITE.admin_sidebar_* in admin base_site).
     Defaults tuned for WCAG-friendly readability. admin_sidebar_enhanced.css was retired
     2026-05-12 (zero template load); per-theme overrides now live in backend-themes.css. */
  --admin-accent: var(--school-primary);
  --admin-accent-light: var(--school-primary-light);
  --admin-sidebar-bg: #0f172a;
  --admin-sidebar-surface: #1e293b;
  --admin-sidebar-border: #334155;
  --admin-sidebar-text: #f1f5f9;
  --admin-sidebar-text-muted: #94a3b8;
  --admin-sidebar-heading: #e2e8f0;
  --admin-sidebar-hover-bg: #1e293b;
  --admin-sidebar-active-bg: #1e293b;
  --admin-sidebar-active-border: #38bdf8;
  --admin-sidebar-badge-bg: #334155;
  --admin-sidebar-badge-text: #f1f5f9;
  /* Lively child block (no black); per-theme overrides now live in backend-themes.css. */
  --admin-sidebar-child-bg: linear-gradient(160deg, #334155 0%, #475569 100%);
  --admin-sidebar-child-border: rgba(148, 163, 184, 0.35);

  /* Portal (light defaults; dark overrides in portal-theme-modes.css).
     v2 theme system (2026-05-12): aliased through Apple semantic surfaces. The body
     now sits on the off-white --surface-bg so the white inner shell visibly rises out
     of the canvas (fixes the "everything is white, content hides" complaint). */
  --portal-bg: var(--surface-bg, #f5f5f7);
  --portal-font: Inter, system-ui, sans-serif;
  --portal-text: var(--text-primary, #111827);
  --portal-text-muted: var(--text-tertiary, #6c757d);
  --portal-border: var(--hairline, rgba(15, 23, 42, 0.08));
  --portal-border-strong: var(--hairline-strong, rgba(15, 23, 42, 0.15));
  --portal-shadow: var(--elev-1, 0 8px 22px rgba(0, 0, 0, 0.08));
  --portal-shadow-hover: var(--elev-3, 0 20px 40px rgba(15, 23, 42, 0.2));
  --portal-nav-pill: #495057;
  --portal-nav-pill-hover: var(--school-primary);
  /* Portal brand spine — school-primary mixes (replaces legacy indigo rgba literals). */
  --portal-brand-mix-50: color-mix(
    in srgb,
    var(--school-primary, var(--color-primary, #4f46e5)) 50%,
    transparent
  );
  --portal-brand-mix-22: color-mix(
    in srgb,
    var(--school-primary, var(--color-primary, #4f46e5)) 22%,
    transparent
  );
  --portal-brand-mix-14: color-mix(
    in srgb,
    var(--school-primary, var(--color-primary, #4f46e5)) 14%,
    transparent
  );
  --portal-brand-mix-12-accent: color-mix(
    in srgb,
    var(--school-accent, var(--color-secondary, #764ba2)) 12%,
    transparent
  );
  --portal-brand-mix-10: color-mix(
    in srgb,
    var(--school-primary, var(--color-primary, #4f46e5)) 10%,
    transparent
  );
  --portal-brand-mix-08: color-mix(
    in srgb,
    var(--school-primary, var(--color-primary, #4f46e5)) 8%,
    transparent
  );
  --portal-nav-pill-bg-hover: var(--portal-brand-mix-08);
  --portal-nav-pill-bg-active: var(--school-primary-light);

  /* Backend console (theme files override) */
  --backend-surface: #1a1f2e;
  --backend-surface-alt: #252b3b;
  --backend-text: #e5e7eb;
  --backend-border: rgba(255, 255, 255, 0.08);

  /* Header & footer – always visible regardless of themepack.
     Portal/backend headers: use --header-brand-bg (topbar), --header-brand-fg (text).
     Footer: use --footer-bg, --footer-text, --footer-border.
     Admin sidebar logo: --admin-sidebar-logo-bg ensures logo has contrasting container. */
  /* v2 Phase J (2026-05-12): single-accent luminous gradient — no longer two-color.
     Tenants can override --brand-gradient-end via SITE.brand_gradient_end to keep
     the luminous feel with their own brand. Old two-color gradient was the
     mid-2010s SaaS tell; this is Linear / Vercel / Stripe. */
  --header-brand-bg: var(--brand-gradient);
  /* Pass 10 / WCAG 2.2 AA refresh 2026-05-14: header foreground stays slate-50,
     overlay strength bumped 0.25 → 0.35 so the effective bg luminance lands the
     contrast ratio at ~4.7:1 against the emerald end of the gradient (was ~4.0:1).
     The accompanying overlay is applied by the header rule in patterns.css. */
  --header-brand-fg: #f8fafc;
  --header-brand-overlay: rgba(15, 23, 42, 0.35);
  --header-brand-logo-bg: rgba(255, 255, 255, 0.2);
  --footer-bg: linear-gradient(180deg, rgba(6, 12, 34, 0.92), rgba(4, 10, 28, 0.95));
  --footer-text: #e2e8f0;
  /* Pass 10: slate-400 → slate-500 for AA contrast (4.5:1) on light footer surfaces. */
  --footer-text-muted: #64748b;
  --footer-border: rgba(148, 163, 184, 0.2);
  --admin-sidebar-logo-bg: rgba(0, 0, 0, 0.25);
  --admin-sidebar-logo-fg: #ffffff;

  /* Common spacing – single source (4px base). Other sheets use --spacing-* or --token-space-* from here. */
  --token-space-xs: 0.25rem;   /* 4px */
  --token-space-sm: 0.5rem;    /* 8px */
  --token-space-md: 1rem;      /* 16px */
  --token-space-lg: 1.5rem;    /* 24px */
  --token-space-xl: 2rem;      /* 32px */
  --token-space-2xl: 3rem;     /* 48px */
  --token-space-3xl: 4rem;     /* 64px */
  /* Aliases for design-system-unified and phase7 compatibility */
  --spacing-xs: var(--token-space-xs);
  --spacing-sm: var(--token-space-sm);
  --spacing-md: var(--token-space-md);
  --spacing-lg: var(--token-space-lg);
  --spacing-xl: var(--token-space-xl);
  --spacing-2xl: var(--token-space-2xl);
  --spacing-3xl: var(--token-space-3xl);
  --token-radius-sm: 8px;
  --token-radius-md: 12px;
  --token-radius-lg: 16px;
  --token-radius-xl: 20px;
  --token-radius-2xl: 24px;

  /* Border-width scale — Apple HIG-aligned. Default is hairline; strong is reserved for
     focus rings / active emphasis. Anything thicker is a design violation. Replaces ad-hoc
     `border: 2px` literals in admin/index.html, visual_workflow_designer.html, etc.
     Tenant themes never need to override these — they are purely structural. */
  --token-border-width-hairline: 0.5px;
  --token-border-width-subtle: 1px;
  --token-border-width-strong: 2px;
  --border-width-hairline: var(--token-border-width-hairline);
  --border-width-subtle: var(--token-border-width-subtle);
  --border-width-strong: var(--token-border-width-strong);

  /* Sidebar-width scale — admin shell + portal sidebar widths. `default` matches the
     280px convention in portal-base-shell.css (`--portal-sidebar-width`).
     `compact` is the collapsed/icon-only state; `wide` is for dense-data admin contexts.
     Tenant themes never need to override these — they are purely layout chrome. */
  --token-sidebar-width-compact: 240px;
  --token-sidebar-width-default: 280px;
  --token-sidebar-width-wide: 320px;
  --sidebar-width-compact: var(--token-sidebar-width-compact);
  --sidebar-width-default: var(--token-sidebar-width-default);
  --sidebar-width-wide: var(--token-sidebar-width-wide);

  /* Shell canvas rhythm — tight horizontal inset so dashboards use the full main column
     between sidebar rails (operator control plane + tenant portal + manager admin). */
  --rmc-shell-max-width: none;
  --rmc-shell-pad-x: clamp(10px, 0.75vw, 14px);
  --rmc-shell-pad-y: clamp(8px, 0.9vw, 14px);
  --rmc-shell-gutter: clamp(6px, 0.45vw, 10px);
  --rmc-shell-rhythm-y: clamp(8px, 0.9vw, 14px);

  /* ========== Phase 2 — semantic design system (--ds-*) ==========
     Single grammar for cards, surfaces, alerts, chips. Alias platform/luxury/tokens.
     Components: design-system-phase2-enforcement.css + card-grammar / form-system / table-system. */
  --ds-font-sans: var(--portal-font);
  --ds-text: var(--admin-content-text);
  --ds-text-muted: var(--admin-content-text-muted);
  --ds-surface: var(--admin-content-bg);
  --ds-surface-raised: var(--admin-content-surface);
  --ds-surface-muted: var(--surface-bg-muted);
  --ds-border: var(--admin-content-border);
  --ds-border-strong: var(--portal-border-strong);
  --ds-shadow-sm: var(--shell-elevation-1);
  --ds-shadow-md: var(--shell-elevation-2);
  --ds-shadow-lg: var(--shell-elevation-3);
  --ds-radius-sm: var(--token-radius-sm);
  --ds-radius-md: var(--token-radius-md);
  --ds-radius-lg: var(--token-radius-lg);
  --ds-radius-xl: var(--token-radius-xl);
  --ds-focus: var(--focus-ring-color);
  /* Semantic states — Apple HIG (system green/orange/red/blue). Refined 2026-05-12.
     Previous values were Tailwind's saturated mid-shades which read "candy" in dense
     UIs; HIG values are tuned for legibility on neutral surfaces and match what
     macOS/iOS users intuit. Tenant overrides via SITE.success_color etc. still win. */
  --ds-success: #28a745;
  --ds-success-bg: rgba(52, 199, 89, 0.12);
  --ds-warning: #f0883e;
  --ds-warning-bg: rgba(255, 149, 0, 0.14);
  --ds-danger: #e5484d;
  --ds-danger-bg: rgba(255, 59, 48, 0.12);
  --ds-info: #0a84ff;
  --ds-info-bg: rgba(10, 132, 255, 0.12);
  /* Pass 8 Wave 2 — canonical form tokens. Used by components/form_field.html and the
     `.form-system` body class. Previously every template re-rolled `text-danger small`
     (118 sites), `text-muted small` (54 sites), and hardcoded asterisk markers — the
     audit's three form inconsistencies all flowed from missing tokens here. */
  --form-required-color: var(--ds-danger);
  --form-error-color: var(--ds-danger);
  --form-error-bg: var(--ds-danger-bg);
  --form-help-color: rgba(15, 23, 42, 0.6);
  --form-section-rule-color: rgba(15, 23, 42, 0.08);
  --ds-motion-content: var(--motion-normal);
  /* Decorative motion: luxury sheet may override --luxury-motion-* after load */
  --ds-motion-decorative: 600ms ease-out;

  /* Dashboard tokens (radius, spacing, shadow, type scale) – used by backend/admin/parent/teacher dashboards.
     Premium feel: platform-high-end.css overrides with --platform-* tokens where loaded. */
  --dashboard-space-unit: 8px;
  --dashboard-card-radius: 14px;
  --dashboard-card-shadow: 0 12px 28px rgba(15, 23, 42, 0.08), 0 0 0 1px rgba(15, 23, 42, 0.04);
  --dashboard-card-border: 1px solid rgba(15, 23, 42, 0.08);
  --dashboard-gap-sm: 12px;
  --dashboard-gap-md: 16px;
  --dashboard-gap-lg: 24px;
  --dashboard-title-size: 1.5rem;
  --dashboard-section-size: 1.125rem;
  --dashboard-card-title-size: 1rem;

  /* Teacher dashboard Today's Overview cards (optional; theme pack can override) */
  --teacher-warning-bg: #d97706;
  --teacher-warning-border: #b45309;
  --teacher-warning-alt-bg: #ea580c;
  --teacher-warning-alt-border: #c2410c;

  /* Parent dashboard Today at a Glance card tints (optional) */
  --parent-glance-messages-bg: rgba(79, 70, 229, 0.08);
  --parent-glance-messages-border: rgba(79, 70, 229, 0.22);
  --parent-glance-followup-bg: rgba(253, 126, 20, 0.1);
  --parent-glance-followup-border: rgba(253, 126, 20, 0.25);
  --parent-glance-outstanding-bg: rgba(220, 53, 69, 0.08);
  --parent-glance-outstanding-border: rgba(220, 53, 69, 0.2);
  --parent-glance-good-bg: rgba(25, 135, 84, 0.1);
  --parent-glance-good-border: rgba(25, 135, 84, 0.2);

  /* Fluid typography (clamp: min, preferred, max) – smooth scaling, no rigid breakpoint jumps */
  --text-xs: clamp(0.7rem, 1.5vw, 0.75rem);
  --text-sm: clamp(0.8rem, 1.8vw, 0.875rem);
  --text-base: clamp(0.9rem, 2vw, 1rem);
  --text-lg: clamp(1rem, 2.2vw, 1.125rem);
  --text-xl: clamp(1.1rem, 2.5vw, 1.25rem);
  --text-2xl: clamp(1.25rem, 3vw, 1.5rem);
  --text-3xl: clamp(1.4rem, 4vw, 1.875rem);
  --text-hero: clamp(1.2rem, 2.6vw, 1.8rem);

  /* Phase 5.3: H1–H4 type scale – use for semantic headings; prefer over display/fw-bold overrides */
  --heading-h1: clamp(1.5rem, 3.5vw, 2rem);   /* ~24–32px */
  --heading-h2: clamp(1.25rem, 2.8vw, 1.5rem); /* ~20–24px */
  --heading-h3: clamp(1.125rem, 2.2vw, 1.25rem); /* ~18px */
  --heading-h4: 1rem;                           /* 16px */

  /* Experience architecture: full typography scale (Display, Section, Table, Micro, Metric, Mono) */
  --type-display: clamp(2rem, 5vw, 3rem);
  --type-hero: clamp(1.5rem, 3.5vw, 2.25rem);
  --type-section: clamp(1.125rem, 2.5vw, 1.375rem);
  --type-body: clamp(0.9rem, 2vw, 1rem);
  --type-body-secondary: clamp(0.8rem, 1.8vw, 0.9375rem);
  --type-table: clamp(0.8rem, 1.6vw, 0.875rem);
  --type-micro: 0.75rem;
  --type-metric: clamp(1.25rem, 2.5vw, 1.5rem);
  --type-mono: 0.875em/1.4 ui-monospace, "Cascadia Code", "SF Mono", monospace;

  /* Shell elevations and surface backgrounds (surface-aware themes override per plane) */
  --shell-elevation-1: 0 2px 8px rgba(15, 23, 42, 0.06);
  --shell-elevation-2: 0 4px 16px rgba(15, 23, 42, 0.08);
  --shell-elevation-3: 0 12px 28px rgba(15, 23, 42, 0.1);
  --surface-bg-base: #ffffff;
  --surface-bg-subtle: #f8fafc;
  --surface-bg-muted: #f1f5f9;

  /* Color-base scale: neutral palette for Studio OS and unified shells (SOT §8.0).
     Use var(--color-base-N) for rail, canvas, cards, borders; dark theme overrides in theme files. */
  --color-base-0: #ffffff;
  --color-base-50: #f8fafc;
  --color-base-100: #f1f5f9;
  --color-base-200: #e2e8f0;
  --color-base-300: #cbd5e1;
  --color-base-350: #b8c4d0;
  --color-base-400: #94a3b8;
  --color-base-500: #64748b;
  --color-base-600: #475569;
  --color-base-700: #334155;
  --color-base-800: #1e293b;
  --color-base-900: #0f172a;
  --color-base-950: #020617;
  --color-primary-50: #eff6ff;
  --color-primary-100: #dbeafe;
  --color-primary-300: #93c5fd;
  --color-primary-400: #60a5fa;
  --color-primary-500: #3b82f6;
  --color-primary-600: #2563eb;
  --color-primary-700: #1d4ed8;
  --color-primary-900: #1e3a8a;

  /* Indigo scale — platform brand chrome variants (admin sidebar, focus rings, decorative
     gradients in backend chrome). Stays platform-fixed by design: the "recessive palette"
     decision means admin chrome does NOT respond to tenant brand overrides — only the
     tenant-facing portal does. For tenant-overridable brand surfaces use --school-primary
     (which defaults to --color-indigo-600). */
  --color-indigo-100: #c7d2fe;
  --color-indigo-300: #a5b4fc;
  --color-indigo-400: #818cf8;
  --color-indigo-500: #6366f1;
  --color-indigo-600: #4f46e5;
  --color-indigo-700: #4338ca;
  --color-indigo-800: #3730a3;

  /* Alert text-on-tint scale — text shades inside alert chips/badges, separated by surface
     theme so we don't ship a #fcd34d-on-amber-tint blob inline in every theme override.
     `*-on-dark` = readable on dark backgrounds; `*-on-light` = readable on light backgrounds. */
  --alert-text-success-on-dark: #86efac;
  --alert-text-warning-on-dark: #fcd34d;
  --alert-text-danger-on-dark: #fca5a5;
  --alert-text-info-on-dark: #7dd3fc;
  --alert-text-success-on-light: #166534;
  --alert-text-warning-on-light: #92400e;
  --alert-text-danger-on-light: #991b1b;
  --alert-text-info-on-light: #0369a1;

  /* Link text on dark theme (for non-button, non-nav anchors inside admin chrome) */
  --link-text-on-dark: #93c5fd;
  --link-text-on-dark-hover: #bfdbfe;

  /* Text-on-brand — readable foreground for text rendered on top of --school-primary,
     --school-accent, or any saturated brand surface. Defaults to white (works against
     dark indigo/emerald). Tenants with light/pastel brand colors should override
     to a dark value via SiteSettings so contrast stays AA. */
  --text-on-brand: #ffffff;

  /* Amber scale — used for warning chrome distinct from --ds-warning (amber-600).
     400 = soft warning highlights, 500 = alert-warning borders, 700 = dark-theme warning text. */
  --color-amber-400: #fbbf24;
  --color-amber-500: #f59e0b;
  --color-amber-600: #d97706;
  --color-amber-700: #b45309;

  /* Status palette — full primitives for chart fills, progress bars, status badges.
     Distinct from --ds-{success,danger,info} semantic tokens which alias the platform
     defaults but may shift per theme; these primitives are stable Tailwind ladder steps. */
  --color-emerald-400: #34d399;
  --color-emerald-600: #059669;
  --color-green-500: #22c55e;
  --color-red-400: #f87171;
  --color-red-500: #ef4444;
  --color-red-600: #dc2626;
  --color-orange-400: #fb923c;
  --color-orange-500: #f97316;
  --color-sky-400: #38bdf8;
  --color-sky-500: #0ea5e9;
  --color-cyan-500: #06b6d4;
  --color-cyan-600: #0891b2;
  --color-teal-500: #14b8a6;

  /* Indigo-900 extends the indigo scale (used for deep brand text + hover ink). */
  --color-indigo-900: #312e81;

  /* Soft pastel tints — used as icon-chip backgrounds and faint surface tints.
     These could be derived via color-mix() but are pinned to specific hex for
     consistent rendering across older browsers that lack oklab color-mix. */
  --tint-indigo-soft: #f7f4ff;
  --tint-blue-soft: #eef4ff;
  --tint-sky-soft: #edf8ff;
  --tint-gray-soft: #f1f3f5;
  --tint-gray-warm: #e9ecef;

  /* Tailwind gray-800 — distinct from --color-base-800 (slate-800); used by
     manager-aesthetic-polish rail links for warmer neutral text. */
  --color-gray-800: #1f2937;

  /* Emerald-500 — fills the gap between --color-emerald-400 and --color-emerald-600
     in the emerald ladder. Matches --school-accent default. */
  --color-emerald-500: #10b981;

  /* Teal-300 — extends the teal scale alongside --color-teal-500; used as a
     decorative sky/teal accent on dark control-plane surfaces. */
  --color-teal-300: #5eead4;

  /* Emerald ladder extensions — used by status badges and the wizard step
     indicator's "complete" state. v3.17 (2026-05-17). */
  --color-emerald-50: #d1fae5;
  --color-emerald-700: #047857;

  /* Amber ladder for warning surfaces (badge tint + ink). v3.17. */
  --color-amber-50: #fef3c7;
  --color-amber-700: #b45309;

  /* Status-color semantic tokens. Light-mode defaults; light/dark variants
     follow the same naming so consuming rules don't need theme-conditional
     overrides. Used by .omig-domain__badge, .rmc-wizard-steps__item.is-complete,
     and any other status chip the platform adds. v3.17. */
  --success-bg: rgba(16, 185, 129, 0.10);
  --success-fg: var(--color-emerald-700, #047857);
  --warning-bg: rgba(245, 158, 11, 0.12);
  --warning-fg: var(--color-amber-700, #b45309);

  /* Accent semantics — the muted "tinted brand" backgrounds used by chips and
     pill banners (Apple Settings-style). Surface stays neutral; the chip carries
     a faint accent. text-accent picks up the school primary so tenants override
     it via the brand cascade. v3.17. */
  --surface-accent-subtle: color-mix(in srgb, var(--school-primary, #4f46e5) 8%, transparent);
  --text-accent: var(--school-primary, #4f46e5);

  /* Pure easing curve — separate from --motion-* which carry duration. Used
     by .ovendor-tile hover and similar single-property transitions. v3.17. */
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);

  /* Control-plane ink scale — extremely dark blue-blacks used as the operator
     surface canvas and as text-on-gold for the manager + /super/ shells. These
     sit below --color-base-950 in luminosity and carry slight cool/warm shifts
     for layered atmospherics (header < sidebar < canvas). */
  --cp-ink-abyss: #06090e;        /* ultra-dark canvas (control-plane-ultra hero bg) */
  --cp-ink-deep: #0a0c10;          /* text-on-gold for gold-buttoned primary actions */
  --cp-ink-canvas: #0b0e14;        /* operator dark ground (platform-navy default) */
  --cp-ink-sidebar: #0b1220;       /* manager sidebar bg (aesthetic-polish) */
  --cp-ink-action: #0a1729;        /* text-on-sky-gradient for hero primary action */

  /* Control-plane neutrals (light text + muted text on cp-ink-* surfaces). */
  --cp-text-ultra: #e8eef6;        /* primary text on ultra-dark cp surfaces */
  --cp-text-muted-ultra: #a8b8d4;  /* muted/secondary text on ultra-dark cp surfaces (WCAG bump v2) */

  /* Cool slate tints (3xx-ish range) used by cp-hero/panel meta text.
     Distinct from --color-base-* because they are warmer and trade neutrality
     for a faint blue lift consistent with the cp navy palette. */
  --cp-slate-cool-400: #9fb1cb;    /* cp-muted (default body muted) */
  --cp-slate-cool-300: #a8bdd8;    /* table thead text */
  --cp-slate-cool-200: #b6c8e0;    /* hero stat subtitle */

  /* Soft canvas off-white — non-pure-white page bg behind cards (Aesthetic Pass A). */
  --surface-canvas-soft: #f6f7fb;

  /* Control-plane sky/blue pastels — link text, eyebrows, chip text, gradient stops.
     All used on dark cp surfaces; chosen so AA contrast holds against --cp-ink-*. */
  --cp-sky-100: #e7eefc;           /* default cp-text (hero copy on dark) */
  --cp-sky-150: #d9eeff;           /* subtle link / workstream text */
  --cp-sky-175: #d7e7fb;           /* panel-stat label */
  --cp-sky-185: #d7e4f7;           /* status-badge-neutral text */
  --cp-sky-200: #cce6ff;           /* section-link text */
  --cp-sky-300: #9bd9ff;           /* eyebrow label */
  --cp-sky-350: #8fd6ff;           /* workstream-cta text */
  --cp-sky-400: #8ebdff;           /* hero primary-action gradient end */
  --cp-sky-450: #76d5ff;           /* hero primary-action gradient start */
  --cp-sky-500: #77c6ff;           /* cp-accent (anchor for sky pastels) */

  /* Control-plane status pastels — readable foreground for status chips/badges
     rendered on dark cp surfaces; mirrors --alert-text-*-on-dark family but
     uses the manager's saturated palette instead of muted Tailwind shades. */
  --cp-success-300: #96edc4;       /* status-badge success text */
  --cp-success-350: #9af0ca;       /* chip success text */
  --cp-success-500: #31c48d;       /* cp-success (border + emphasis) */
  --cp-warning-300: #ffe3a8;       /* status-badge warning text */
  --cp-warning-350: #ffe0a3;       /* chip warning text */
  --cp-warning-450: #ffd166;       /* cp-accent-2 (hero accent) */
  --cp-warning-500: #ffbf47;       /* cp-warning (border + emphasis) */
  --cp-danger-300: #ffc0c0;        /* status-badge danger text */
  --cp-danger-350: #ffb5b5;        /* chip danger text */
  --cp-danger-500: #ff6b6b;        /* cp-danger (border + emphasis) */

  /* Control-plane gold gradient stops — used for primary-action gradient on
     manager + admin login (control-plane-ultra). Three stops form the gradient. */
  --cp-gold-500: #e8c454;          /* gradient hover top */
  --cp-gold-600: #e0bc48;          /* gradient default top */
  --cp-gold-700: #c9a02c;          /* gradient default bottom (darkest) */

  /* Studio OS layout tokens (fluid; SOT §8.0.6 responsive) */
  --studio-rail-width: minmax(min(12rem, 100%), 16rem);
  --studio-right-width: minmax(min(14rem, 100%), 18rem);
  --studio-gap: clamp(0.75rem, 2vw, 1.5rem);
  --studio-font-base: clamp(0.8125rem, 1.5vw + 0.5rem, 0.9375rem);
  --studio-font-heading: clamp(0.9375rem, 1.2vw + 0.6rem, 1.125rem);
  /* Hero/display typography: marketing and product share one design system (CONTROL_PLANE §4, MARKETING_FRONT_PLACEHOLDER Design tokens) */
  --studio-font-display: clamp(2rem, 4vw, 3.25rem);
  --studio-radius: 0.5rem;
  --studio-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);

  /* Table densities (compact / comfortable / spacious) */
  --table-density-compact: 0.35rem 0.5rem;
  --table-density-comfortable: 0.5rem 0.75rem;
  --table-density-spacious: 0.75rem 1rem;

  /* Chart tokens */
  --chart-stroke-default: 1.5px;
  --chart-legend-text: var(--text-sm);
  /* Pass 10: chart axes render on light surfaces; slate-500 meets AA. */
  --chart-axis-muted: #64748b;

  /* Graph node badges (consumed by package-dependency-graph.js for SVG node fills) */
  --graph-node-info-bg: var(--color-sky-50, #e0f2fe);
  --graph-node-info-border: var(--color-sky-600, #0284c7);
  --graph-node-warning-bg: var(--color-amber-100, #fef3c7);
  --graph-node-warning-border: var(--color-amber-600, #d97706);
  --graph-node-success-bg: var(--color-emerald-50, #ecfdf5);
  --graph-node-success-border: var(--color-emerald-600, #059669);

  /* Keyboard hint chips (kbd element style injected by keyboard_shortcuts-1.js) */
  --kbd-color: var(--color-base-900);
  --kbd-bg: var(--color-base-50);
  --kbd-border: var(--color-base-300);
  --kbd-border-bottom: var(--color-base-400);

  /* Signature pad (portal__signature_sign.js) — overridable for dark-mode signature surfaces */
  --signature-canvas-bg: var(--color-base-0);
  --signature-canvas-ink: var(--color-base-900);

  /* Motion — Apple-tier curves live in the v2.26 quiet-luxury layer at the
     end of this file. The duplicates that used to live here (150/250/350ms
     plain `ease`) silently clobbered the cubic-bezier values at L70-72 and
     are deleted as of v2.26 quiet-luxury wave (2026-05-15). */

  /* Content-based breakpoints (use in media queries: max-width: var(--bp-mobile) etc.) */
  --bp-narrow: 360px;
  --bp-content-sm: 480px;
  --bp-content-sm-max: 479px;   /* below 480 */
  --bp-content-md: 640px;
  --bp-extra-narrow: 575px;     /* e.g. hide secondary nav */
  --bp-mobile: 768px;           /* common mobile/tablet split */
  --bp-mobile-max: 767px;       /* below 768 */
  --bp-content-lg: 832px;
  --bp-tablet: 991px;           /* common tablet/desktop split */
  --bp-below-wide: 1023px;      /* below 1024 */
  --bp-wide: 1024px;
  --bp-max: 1280px;

  /* Focus ring: high-contrast in both themes (override in theme files if needed) */
  --focus-ring-color: var(--school-primary);
  --focus-ring-offset: 2px;

  /* Overlay / surface text: ensure readable on both themes when used in modals, dropdowns */
  --overlay-bg: rgba(255, 255, 255, 0.98);
  --overlay-text: #0f172a;
  --overlay-text-muted: #64748b;

  /* Unified content surface: use for cards, panels, dropdowns (alias for admin-content-bg when same) */
  --admin-surface: #ffffff;
  /* Aliases for components for text/border on main content (theme-everywhere-dark.css retired 2026-05-12 — was a temporary bridge) */
  --admin-text: #0f172a;
  --admin-border: rgba(15, 23, 42, 0.12);

  /* Semantic role/stat colors for dashboards (admin stats, charts, badges) – theme-aware */
  --stat-admin: #6366f1;
  --stat-student: #0ea5e9;
  --stat-teacher: #10b981;
  --stat-parent: var(--admin-text);
  --stat-accent: var(--admin-content-accent);

  /* Theme-proof visibility (Light + Dark): stroke-like outline, backplate, safe mid-tones.
     Use for labels, badges, and critical UI that must stay legible when system theme switches. */
  --theme-proof-stroke-light: 0 0 1px #fff, 0 0 2px #fff, 0 1px 2px rgba(0,0,0,0.4);
  --theme-proof-stroke-dark: 0 0 1px #000, 0 0 2px #000, 0 1px 2px rgba(255,255,255,0.15);
  --theme-proof-backplate: rgba(128, 128, 128, 0.5);
  --theme-proof-backplate-light: rgba(255, 255, 255, 0.85);
  --theme-proof-backplate-dark: rgba(0, 0, 0, 0.5);
  --theme-proof-shadow-soft: 0 2px 8px rgba(0, 0, 0, 0.12);
  --theme-proof-shadow-soft-dark: 0 2px 12px rgba(0, 0, 0, 0.4);
  /* Safe mid-tones: visible on both #000 and #fff (avoid pure black/white for un-outlined text) */
  --theme-proof-muted: #64748b;
  --theme-proof-accent: #0ea5e9;

  /* Meta theme-color (mobile browser chrome) — no raw hex in JS */
  --meta-theme-color-light: var(--color-base-0);
  --meta-theme-color-dark: var(--color-base-900);

  /* === v8 200x preview parity (v3.57.11) =======================
     Tokens added to align the live shell with the canonical v8
     200x preview's :root {} block (see rmc-shell-preview-v8-200x.html
     lines 14-59). Source-of-truth declarations live here in :root,
     which scan_off_token_colors honors as a theme-scope exemption.
     ============================================================ */
  /* Status / semantic colors (no equivalents previously declared in :root). */
  --warning: #f59e0b;
  --danger: #ef4444;
  --success: #22c55e;
  /* Manager control-plane dark chrome (header/sidebar are dark on manager).
     Required by control_plane_skeleton.html consumers; the v8 200x preview
     depends on the full namespace for the dark header + sidebar. */
  --cp-chrome-bg: #07091a;
  --cp-chrome-bg-deep: #04060f;
  --cp-chrome-surface: #0f1530;
  --cp-chrome-surface-2: #131a35;
  --cp-chrome-hairline: rgba(255, 255, 255, 0.08);
  --cp-chrome-hairline-strong: rgba(255, 255, 255, 0.14);
  --cp-chrome-text: #f1f5f9;
  --cp-chrome-text-muted: #94a3b8;
  --cp-chrome-text-faint: #64748b;
}

/* Phase 9: Visible keyboard focus – use tokens so theme can override */
:root *:focus {
  outline: none; /* remove default; :focus-visible provides replacement */
}
:root *:focus-visible {
  outline: 2px solid var(--focus-ring-color);
  outline-offset: var(--focus-ring-offset);
}

/* Dark theme: one place for all token overrides. Applies to portal (data-theme/data-bs-theme) and backend/admin (body.portal-backend-dark).
   v2 (2026-05-12): Apple semantic surface tokens override first, then admin/portal aliases inherit.
   v3 (2026-05-18): data-theme contract — see docs/THEME_SYSTEM.md §0. data-theme now always
   carries the EFFECTIVE theme, so the old `data-theme="system" + data-resolved-theme="dark"`
   compound is no longer needed and has been retired. */
html[data-theme="dark"],
html[data-resolved-theme="dark"],
html[data-bs-theme="dark"],
body.portal-backend-dark {
  /* Apple semantic surfaces — dark */
  --surface-bg: #000000;
  --surface-canvas: #1c1c1e;
  --surface-elevated: #2c2c2e;
  --surface-popover: color-mix(in oklab, #2c2c2e 88%, transparent);
  --surface-overlay: rgba(255, 255, 255, 0.06);
  --surface-sunken: #0a0a0c;
  --hairline: rgba(255, 255, 255, 0.10);
  --hairline-strong: rgba(255, 255, 255, 0.16);
  --text-primary: #f5f5f7;
  --text-secondary: #ebebf5;
  --text-tertiary: #aeaeb2;
  --text-muted: #8e8e93;
  --elev-1: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 1px rgba(0, 0, 0, 0.3);
  --elev-2: 0 4px 12px rgba(0, 0, 0, 0.45), 0 1px 3px rgba(0, 0, 0, 0.3);
  --elev-3: 0 20px 40px rgba(0, 0, 0, 0.6), 0 6px 12px rgba(0, 0, 0, 0.4);

  /* Admin content area — kept as fallbacks; primary route is through semantic surfaces above */
  --admin-content-bg: var(--surface-canvas, #0f172a);
  --admin-content-surface: var(--surface-elevated, #1e293b);
  --admin-content-text: var(--text-primary, #f1f5f9);
  /* Pass 10: backend content panels are light-surface; slate-500 for AA. */
  --admin-content-text-muted: var(--text-tertiary, #64748b);
  --admin-content-border: var(--hairline, rgba(148, 163, 184, 0.25));
  --admin-content-card-bg: var(--surface-elevated, #1e293b);
  --admin-content-thead-bg: #334155;
  --admin-content-accent-fg: var(--text-primary, #f1f5f9);
  --admin-surface: var(--surface-elevated, #1e293b);

  /* Portal */
  --portal-bg: var(--surface-bg, #0f172a);
  --portal-text: var(--text-primary, #e2e8f0);
  /* Pass 10: portal text is on light surfaces; slate-500 meets AA. */
  --portal-text-muted: var(--text-tertiary, #64748b);
  --portal-border: var(--hairline, rgba(148, 163, 184, 0.2));
  --portal-border-strong: var(--hairline-strong, rgba(148, 163, 184, 0.35));

  --admin-text: #f1f5f9;
  --admin-border: rgba(148, 163, 184, 0.25);

  /* v3.17 (2026-05-17) — status / accent token overrides for dark surfaces.
     Brighter fg (200-step instead of 700-step) so chips stay legible against
     the near-black backdrop; tints stay at the same alpha so the surface
     tint reads as the same intent across light + dark. */
  --success-bg: rgba(16, 185, 129, 0.18);
  --success-fg: #6ee7b7;
  --warning-bg: rgba(245, 158, 11, 0.22);
  --warning-fg: #fcd34d;
  --surface-accent-subtle: color-mix(in srgb, var(--school-primary, #818cf8) 18%, transparent);
  --text-accent: #a5b4fc;

  /* Overlay / modals / dropdowns */
  --overlay-bg: #1e293b;
  --overlay-text: #e2e8f0;
  --overlay-text-muted: #94a3b8;

  /* Dashboard tokens – dark (premium elevation) */
  --dashboard-card-shadow: 0 12px 28px rgba(0, 0, 0, 0.35), 0 0 0 1px rgba(255, 255, 255, 0.06);
  --dashboard-card-border: 1px solid rgba(148, 163, 184, 0.2);

  /* Semantic role/stat colors – dark (slightly lighter for contrast on dark bg) */
  --stat-admin: #818cf8;
  --stat-student: #38bdf8;
  --stat-teacher: #34d399;
  --stat-parent: var(--admin-text);

  /* Theme-proof: dark mode uses light stroke and darker backplate */
  --theme-proof-stroke-light: 0 0 1px #000, 0 0 2px #000, 0 1px 2px rgba(255,255,255,0.2);
  --theme-proof-stroke-dark: 0 0 1px #fff, 0 0 2px #fff, 0 1px 2px rgba(0,0,0,0.3);
  --theme-proof-backplate: rgba(0, 0, 0, 0.45);
  --theme-proof-shadow-soft: 0 2px 12px rgba(0, 0, 0, 0.4);

  /* Phase 2 — semantic DS tokens (after admin/portal dark vars above) */
  --ds-text: var(--admin-content-text);
  --ds-text-muted: var(--admin-content-text-muted);
  --ds-surface: var(--admin-content-bg);
  --ds-surface-raised: var(--admin-content-surface);
  --ds-surface-muted: var(--admin-content-thead-bg);
  --ds-border: var(--admin-content-border);
  --ds-border-strong: var(--portal-border-strong);
  --ds-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.35);
  --ds-shadow-md: 0 8px 24px rgba(0, 0, 0, 0.35);
  --ds-shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.45);
  --ds-success: #4ade80;
  --ds-success-bg: rgba(34, 197, 94, 0.18);
  --ds-warning: #fbbf24;
  --ds-warning-bg: rgba(245, 158, 11, 0.2);
  --ds-danger: #f87171;
  --ds-danger-bg: rgba(239, 68, 68, 0.18);
  --ds-info: #60a5fa;
  --ds-info-bg: rgba(59, 130, 246, 0.2);
}


/* ============================================================
   v2 theme system — Warm Graphite neutral palette (tenant opt-in).
   Activated via <html data-rmc-neutral="warm"> or <body data-rmc-neutral="warm">,
   which the base templates emit when SITE.neutral_palette == "warm".
   Reads as Notion / Anthropic / paper — more character than cool slate while
   staying recessive so tenant brand colors still own the foreground.
   ============================================================ */
html[data-rmc-neutral="warm"],
body[data-rmc-neutral="warm"] {
  --surface-bg: #fafaf9;          /* stone-50 */
  --surface-canvas: #ffffff;
  --surface-elevated: #ffffff;
  --surface-popover: color-mix(in oklab, #ffffff 92%, transparent);
  --surface-overlay: rgba(28, 25, 23, 0.04);
  --surface-sunken: #f5f5f4;       /* stone-100 */
  --hairline: rgba(28, 25, 23, 0.08);
  --hairline-strong: rgba(28, 25, 23, 0.14);
  --text-primary: #1c1917;         /* stone-900 */
  --text-secondary: #44403c;       /* stone-700 */
  --text-tertiary: #57534e;        /* stone-600 — was stone-500 #78716c (3.99:1 on #fafaf9). 7.65:1 AA pass. */
  --text-muted: #6b6660;           /* WCAG AA: 5.04:1 on #fafaf9. Was stone-400 #a8a29e (2.62:1, FAIL). */
}
html[data-rmc-neutral="warm"][data-theme="dark"],
html[data-rmc-neutral="warm"][data-resolved-theme="dark"],
body[data-rmc-neutral="warm"].portal-backend-dark {
  --surface-bg: #0c0a09;            /* stone-950 */
  --surface-canvas: #1c1917;        /* stone-900 */
  --surface-elevated: #292524;      /* stone-800 */
  --surface-popover: color-mix(in oklab, #292524 88%, transparent);
  --surface-overlay: rgba(245, 245, 244, 0.06);
  --surface-sunken: #0c0a09;
  --hairline: rgba(245, 245, 244, 0.10);
  --hairline-strong: rgba(245, 245, 244, 0.16);
  --text-primary: #fafaf9;
  --text-secondary: #e7e5e4;
  --text-tertiary: #d6d3d1;        /* stone-300 — was stone-400 #a8a29e (5.18:1). 10.55:1 AA pass. */
  --text-muted: #a8a29e;           /* stone-400 — was stone-500 #78716c (3.39:1, FAIL). 5.18:1 AA pass on #0c0a09. */
}

/* ============================================================
   v3 theme system — pre-JS fallback for system preference.
   The JS bootstrap (theme-preference-bootstrap.js) runs synchronously
   in <head>, so by first paint `data-theme` already carries the
   resolved value and the `html[data-theme="dark"]` block above fires.
   Under the v3 contract `data-theme` is never the literal "system",
   so the prior `@media (prefers-color-scheme: dark) html[data-theme="system"]`
   fallback became unreachable and was removed (2026-05-18).
   ============================================================ */

/* Smooth theme transitions — Apple-fluid, applied only to non-decorative props
   so charts and animations are not affected. Skipped when user requests reduced motion. */
@media (prefers-reduced-motion: no-preference) {
  html, body {
    transition: background-color var(--motion-normal), color var(--motion-normal);
  }
  .card, .page-wrap, .dropdown-menu, .navbar, .topbar, .footer, .cp-main, .admin-content {
    transition: background-color var(--motion-normal), border-color var(--motion-normal),
                color var(--motion-normal), box-shadow var(--motion-normal);
  }
}


/* Dark themes: logo container slightly lighter than sidebar so dark logos visible.
   Light themes: logo container slightly darker so light/white logos visible. */
body.portal-backend-cream #nav-sidebar .admin-sidebar-logo-wrap,
body.portal-backend-lavender #nav-sidebar .admin-sidebar-logo-wrap,
body.portal-backend-sand #nav-sidebar .admin-sidebar-logo-wrap,
body.portal-backend-snow #nav-sidebar .admin-sidebar-logo-wrap,
body.portal-backend-light #nav-sidebar .admin-sidebar-logo-wrap {
  --admin-sidebar-logo-bg: rgba(0, 0, 0, 0.12);
  --admin-sidebar-logo-fg: #1e293b;
}

/* Focus ring for keyboard and a11y – use school primary */
button:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
a:focus-visible {
  outline: 2px solid var(--school-primary);
  outline-offset: 2px;
}

/* Tables: use design tokens so lists stay readable in light/dark (Phase 4.2). */
.table thead th {
  background: var(--admin-content-thead-bg);
  color: var(--admin-content-text);
  border-bottom-color: var(--admin-content-border);
}
.table td {
  color: var(--admin-content-text);
}
.table-border-color {
  border-color: var(--admin-content-border);
}

/* ============================================
   APPLE-TIER POLISH (platform-wide)
   Layered shadows, motion easing, micro-interactions, refined focus rings,
   typographic refinements (tabular numerals, optical letter-spacing). One
   place, opt-in via standard tags/classes. Tokens here are additive — they
   do not replace existing --shell-elevation / --motion-* tokens.
   ============================================ */
:root {
  /* Easing curves
     - apple: ease-out-quart, the workhorse for most enter/exit and hover transitions
     - apple-in: for elements leaving the screen
     - apple-spring: gentle overshoot for affordances that should feel tactile
     - apple-snap: short and sharp for press-down/release */
  --ease-apple:        cubic-bezier(0.32, 0.72, 0, 1);
  --ease-apple-in:     cubic-bezier(0.4, 0, 1, 1);
  --ease-apple-spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
  --ease-apple-snap:   cubic-bezier(0.65, 0, 0.35, 1);

  /* Duration scale — three speeds; never longer for chrome (decorative may go to 600ms via --ds-motion-decorative). */
  --dur-fast: 150ms;
  --dur-base: 240ms;
  --dur-slow: 400ms;

  /* Layered shadow elevation. Each layer combines a hairline + a soft drop.
     Use these on cards, popovers, dropdowns, modals — NOT on form inputs. */
  --apple-hairline:       0 0 0 1px rgba(15, 23, 42, 0.05);
  --apple-elev-1:         0 0 0 1px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.04);
  --apple-elev-2:         0 0 0 1px rgba(15, 23, 42, 0.05), 0 4px 12px -2px rgba(15, 23, 42, 0.08), 0 2px 4px -1px rgba(15, 23, 42, 0.04);
  --apple-elev-3:         0 0 0 1px rgba(15, 23, 42, 0.06), 0 12px 32px -4px rgba(15, 23, 42, 0.10), 0 4px 8px -2px rgba(15, 23, 42, 0.05);
  --apple-elev-4:         0 0 0 1px rgba(15, 23, 42, 0.06), 0 24px 48px -8px rgba(15, 23, 42, 0.16), 0 8px 16px -4px rgba(15, 23, 42, 0.06);
  --apple-elev-modal:     0 0 0 1px rgba(15, 23, 42, 0.08), 0 32px 64px -12px rgba(15, 23, 42, 0.25), 0 12px 24px -8px rgba(15, 23, 42, 0.10);

  /* Focus ring — Apple uses a colored outline with a soft glow halo.
     Single token reused for buttons, inputs, links, custom widgets. */
  --apple-focus-ring: 0 0 0 2px var(--surface-bg-base, #fff), 0 0 0 4px color-mix(in oklab, var(--school-primary) 60%, transparent), 0 0 0 7px color-mix(in oklab, var(--school-primary) 18%, transparent);

  /* Material — frosted/glass surface for popovers and floating bars (light mode). */
  --apple-material:       saturate(180%) blur(20px);
  --apple-material-bg:    rgba(255, 255, 255, 0.72);
  --apple-material-border:rgba(15, 23, 42, 0.08);

  /* Letter-spacing scale — tighter on display, looser on uppercase chips/eyebrows. */
  --tracking-display: -0.025em;
  --tracking-heading: -0.015em;
  --tracking-body:    -0.005em;
  --tracking-eyebrow: 0.06em;
  --tracking-mono:    0;
}

html[data-theme="dark"],
html[data-bs-theme="dark"],
body.portal-backend-dark {
  --apple-hairline:       0 0 0 1px rgba(148, 163, 184, 0.16);
  --apple-elev-1:         0 0 0 1px rgba(148, 163, 184, 0.14), 0 1px 2px rgba(0, 0, 0, 0.30);
  --apple-elev-2:         0 0 0 1px rgba(148, 163, 184, 0.16), 0 4px 12px -2px rgba(0, 0, 0, 0.40), 0 2px 4px -1px rgba(0, 0, 0, 0.30);
  --apple-elev-3:         0 0 0 1px rgba(148, 163, 184, 0.20), 0 12px 32px -4px rgba(0, 0, 0, 0.45), 0 4px 8px -2px rgba(0, 0, 0, 0.30);
  --apple-elev-4:         0 0 0 1px rgba(148, 163, 184, 0.22), 0 24px 48px -8px rgba(0, 0, 0, 0.55), 0 8px 16px -4px rgba(0, 0, 0, 0.35);
  --apple-elev-modal:     0 0 0 1px rgba(148, 163, 184, 0.28), 0 32px 64px -12px rgba(0, 0, 0, 0.65), 0 12px 24px -8px rgba(0, 0, 0, 0.40);
  --apple-focus-ring:     0 0 0 2px #0f172a, 0 0 0 4px color-mix(in oklab, var(--school-primary) 70%, transparent), 0 0 0 7px color-mix(in oklab, var(--school-primary) 22%, transparent);
  --apple-material-bg:    rgba(15, 23, 42, 0.72);
  --apple-material-border:rgba(148, 163, 184, 0.16);
}

/* Body baseline — antialiased text + Inter font features (cv11 = slashed zero, ss03 = stylistic set). */
body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "cv11", "ss03", "cv02";
  letter-spacing: var(--tracking-body);
  text-rendering: optimizeLegibility;
}

/* Display headings: tighter tracking, optical sharpness. Bootstrap h1/h2 already heavy; we just tune tracking. */
h1, .h1, .display-1, .display-2, .display-3 { letter-spacing: var(--tracking-display); }
h2, .h2 { letter-spacing: var(--tracking-heading); }
h3, .h3, h4, .h4 { letter-spacing: var(--tracking-heading); }

/* Tabular numerals on data surfaces — aligned columns for KPIs, tables, metrics. */
.table td, .table th,
[data-numeric], .ds-metric, .kpi-value, .stat-value {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum", "cv11";
}

/* Eyebrow / chip / overline helper grammar (does not override; opt-in via class). */
/* LAY-2: single source for the operator-report / cp-evidence reading measure.
   Previously 52/56/58rem inline caps were scattered across ~10 report partials.
   Set to the widest prior value so no report page narrows; change here to widen
   reports platform-wide (the manager control-plane shell already forces these
   full-width via #cp-main-content .cp-evidence-page { max-width:none !important }). */
:root { --rmc-report-measure: 58rem; }

.eyebrow, .ds-eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--admin-content-text-muted);
}

/* Per-page personality is applied ONLY to eyebrows inside a page header
   (.page-header / .rmc-page-header-glow), which sit on light/neutral
   premium surfaces — so the deep personality eyebrow color is always
   contrast-safe. Arbitrary .eyebrow labels elsewhere (which may live on
   colored / dark / brand backgrounds the contrast scanner can't resolve
   through var()) keep the muted token. The dark glow-header keeps its own
   .rmc-page-header-glow--dark .rmc-page-eyebrow override. */
.page-header .eyebrow,
.page-header .ds-eyebrow {
  color: var(--personality-eyebrow, var(--admin-content-text-muted));
}

/* Buttons — Apple-tier micro-interactions. Applies to .btn (Bootstrap) and bare <button>. */
.btn,
button:not(.btn-link):not(.btn-close):not([class*="btn-outline-light"]):not([data-no-polish]) {
  transition:
    background-color var(--dur-fast) var(--ease-apple),
    border-color var(--dur-fast) var(--ease-apple),
    color var(--dur-fast) var(--ease-apple),
    box-shadow var(--dur-base) var(--ease-apple),
    transform var(--dur-fast) var(--ease-apple-snap),
    filter var(--dur-fast) var(--ease-apple);
}
.btn:hover,
button:not(.btn-link):not(.btn-close):not([data-no-polish]):hover {
  filter: brightness(1.04) saturate(1.03);
}
.btn:active,
button:not(.btn-link):not(.btn-close):not([data-no-polish]):active {
  transform: scale(0.98);
  filter: brightness(0.98);
  transition-duration: 80ms;
}
.btn:disabled,
.btn.disabled,
button:disabled {
  filter: none;
  transform: none;
  opacity: 0.55;
}

/* Primary button: layered shadow + slightly stronger lift on hover. */
.btn-primary,
.btn-success,
.btn-danger,
.btn-warning,
.btn-info {
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.12);
  border-color: transparent;
}
.btn-primary:hover,
.btn-success:hover,
.btn-danger:hover,
.btn-warning:hover,
.btn-info:hover {
  box-shadow: 0 6px 16px -2px color-mix(in oklab, var(--bs-primary, var(--school-primary)) 35%, transparent), 0 2px 4px rgba(15, 23, 42, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.14);
}

/* Cards — hairline + soft elevation, breathable padding by default.
   Bootstrap .card already gets these via Bootstrap theme; we layer Apple polish. */
.card,
.ds-card,
.dashboard-card,
[data-card] {
  border-color: transparent;
  box-shadow: var(--apple-elev-1);
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.card[data-interactive="1"]:hover,
.ds-card[data-interactive="1"]:hover,
.dashboard-card[data-interactive="1"]:hover,
[data-card][data-interactive="1"]:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}

/* Dropdowns, popovers, modals — material elevation. */
.dropdown-menu {
  border: none;
  box-shadow: var(--apple-elev-3);
  border-radius: var(--token-radius-md);
}
.modal-content {
  border: none;
  box-shadow: var(--apple-elev-modal);
  border-radius: var(--token-radius-lg);
}
.popover, .tooltip-inner {
  box-shadow: var(--apple-elev-2);
}

/* Inputs — quiet focus state, refined hairline. */
.form-control,
.form-select {
  transition: border-color var(--dur-fast) var(--ease-apple), box-shadow var(--dur-fast) var(--ease-apple), background-color var(--dur-fast) var(--ease-apple);
}
.form-control:focus,
.form-select:focus,
.form-check-input:focus {
  border-color: color-mix(in oklab, var(--school-primary) 60%, var(--admin-content-border));
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent);
}

/* Refined platform-wide focus ring (overrides the simple 2px solid above with the layered glow). */
*:focus-visible {
  outline: none;
  box-shadow: var(--apple-focus-ring);
  border-radius: inherit;
}
.form-control:focus-visible,
.form-select:focus-visible {
  /* Inputs already have an internal focus state; don't double-ring. */
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent);
}

/* Links — quiet underline-on-hover, brand color. */
a:not(.btn):not(.nav-link):not(.dropdown-item) {
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  transition: color var(--dur-fast) var(--ease-apple);
}
a:not(.btn):not(.nav-link):not(.dropdown-item):hover {
  color: color-mix(in oklab, var(--school-primary) 78%, #000);
}

/* Reduced motion — honor OS preference. */
@media (prefers-reduced-motion: reduce) {
  .btn, .card, .dashboard-card, .form-control, .form-select, .dropdown-menu, .modal-content, a:not(.btn) {
    transition: none !important;
    animation: none !important;
  }
  .btn:active { transform: none !important; }
}

/* Skip link — Apple-style: hidden until focus, then floats with material. */
.skip-link {
  position: absolute;
  top: 8px;
  left: 8px;
  background: var(--apple-material-bg);
  color: var(--admin-content-text);
  border: 1px solid var(--apple-material-border);
  border-radius: var(--token-radius-md);
  padding: 8px 14px;
  font-weight: 600;
  font-size: 0.875rem;
  text-decoration: none;
  transform: translateY(-150%);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease-apple-spring), opacity var(--dur-fast) var(--ease-apple);
  backdrop-filter: var(--apple-material);
  -webkit-backdrop-filter: var(--apple-material);
  z-index: 9999;
}
.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
  opacity: 1;
}

/* ============================================
   NAVIGATION & FLOW POLISH
   Wayfinding components — breadcrumbs, sidebar nav, page header, skeletons,
   empty states, toasts, tooltips, HTMX progress, page transitions, modal.
   Layered onto existing partials' classes so component files don't need edits.
   ============================================ */

/* Breadcrumbs — chevron separators + refined hierarchy. Targets
   templates/partials/breadcrumbs.html (.breadcrumb / .breadcrumb-item). */
.breadcrumb {
  --bs-breadcrumb-divider: '';
  font-size: 0.875rem;
  letter-spacing: var(--tracking-body);
  padding: 0;
  margin: 0;
}
.breadcrumb-item {
  display: inline-flex;
  align-items: center;
  color: var(--admin-content-text-muted);
}
.breadcrumb-item + .breadcrumb-item { padding-left: 0; }
.breadcrumb-item + .breadcrumb-item::before {
  content: '';
  display: inline-block;
  width: 14px;
  height: 14px;
  margin: 0 8px;
  background-color: var(--admin-content-text-muted);
  opacity: 0.5;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='currentColor' d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill='currentColor' d='M9 6l6 6-6 6'/></svg>") center / contain no-repeat;
  padding: 0;
}
.breadcrumb-item a {
  color: var(--admin-content-text-muted);
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease-apple);
  border-radius: 4px;
  padding: 2px 4px;
  margin: -2px -4px;
}
.breadcrumb-item a:hover {
  color: var(--school-primary);
}
.breadcrumb-item.active {
  color: var(--admin-content-text);
  font-weight: 600;
}

/* Sidebar nav — works for portal sidebar, control plane sidebar, generic .nav-pills.
   Active state uses a sliding accent rail instead of just background. Shared by
   templates/partials/portal_sidebar.html and templates/partials/control_plane_sidebar.html. */
.portal-sidebar .nav-link,
.control-plane-sidebar .nav-link,
[data-rmc-shell-root="portal"] .nav-pills .nav-link,
[data-rmc-shell-root="control-plane-skeleton"] .nav-pills .nav-link,
[data-shell-layout] aside .nav-link {
  position: relative;
  border-radius: 10px;
  padding: 9px 14px;
  font-weight: 500;
  letter-spacing: var(--tracking-body);
  display: flex;
  align-items: center;
  gap: 12px;
  transition:
    background-color var(--dur-fast) var(--ease-apple),
    color var(--dur-fast) var(--ease-apple),
    transform var(--dur-fast) var(--ease-apple-snap);
}
.portal-sidebar .nav-link::before,
.control-plane-sidebar .nav-link::before,
[data-rmc-shell-root="portal"] .nav-pills .nav-link::before,
[data-rmc-shell-root="control-plane-skeleton"] .nav-pills .nav-link::before,
[data-shell-layout] aside .nav-link::before {
  content: '';
  position: absolute;
  left: 0;
  top: 50%;
  height: 0;
  width: 3px;
  background: var(--school-primary);
  border-radius: 0 3px 3px 0;
  transform: translateY(-50%);
  transition: height var(--dur-base) var(--ease-apple);
}
.portal-sidebar .nav-link:hover,
.control-plane-sidebar .nav-link:hover,
[data-rmc-shell-root="portal"] .nav-pills .nav-link:hover,
[data-shell-layout] aside .nav-link:hover {
  background: color-mix(in oklab, var(--school-primary) 6%, transparent);
}
.portal-sidebar .nav-link:active,
.control-plane-sidebar .nav-link:active,
[data-shell-layout] aside .nav-link:active {
  transform: scale(0.98);
}
.portal-sidebar .nav-link.active,
.control-plane-sidebar .nav-link.active,
[data-rmc-shell-root="portal"] .nav-pills .nav-link.active,
[data-rmc-shell-root="control-plane-skeleton"] .nav-pills .nav-link.active,
[data-shell-layout] aside .nav-link.active {
  background: var(--school-primary-light);
  color: var(--school-primary);
  font-weight: 600;
}
.portal-sidebar .nav-link.active::before,
.control-plane-sidebar .nav-link.active::before,
[data-rmc-shell-root="portal"] .nav-pills .nav-link.active::before,
[data-rmc-shell-root="control-plane-skeleton"] .nav-pills .nav-link.active::before,
[data-shell-layout] aside .nav-link.active::before {
  height: 60%;
}

/* Sidebar section eyebrows (collapsible group headings) */
.portal-sidebar .nav-section-title,
.control-plane-sidebar .nav-section-title,
[data-shell-layout] aside .nav-section-title {
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--admin-content-text-muted);
  padding: 16px 14px 6px;
  margin: 0;
}

/* Page header — stronger hierarchy. Targets templates/components/page_header.html (.page-header). */
.page-header {
  padding-bottom: 18px;
  margin-bottom: 24px !important;
  border-bottom: 1px solid var(--admin-content-border);
}
.page-header > div:first-child h1,
.page-header > div:first-child .h1,
.page-header > div:first-child .h2 {
  letter-spacing: var(--tracking-display);
  font-weight: 700;
  margin-bottom: 4px;
}
.page-header .text-muted {
  font-size: 0.95rem;
  letter-spacing: var(--tracking-body);
}

/* Skeleton loader — Apple shimmer (gradient sweep, not opacity pulse).
   Targets templates/components/skeleton_loader.html (.skeleton, .skeleton-text). */
.skeleton {
  background: linear-gradient(
    90deg,
    color-mix(in oklab, var(--admin-content-border) 30%, transparent) 25%,
    color-mix(in oklab, var(--admin-content-border) 60%, transparent) 50%,
    color-mix(in oklab, var(--admin-content-border) 30%, transparent) 75%
  );
  background-size: 200% 100%;
  border-radius: 6px;
  animation: skeletonShimmer 1.6s var(--ease-apple) infinite;
}
.skeleton-text {
  height: 12px;
  margin-bottom: 10px;
  border-radius: 4px;
}
.skeleton-text.short { width: 60%; }
.skeleton-circle { border-radius: 50%; }
.skeleton-block { height: 80px; border-radius: var(--token-radius-md); }
@keyframes skeletonShimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}
.skeleton-loader {
  padding: 4px 0;
}

/* Retired 2026-05-14 (v2.6 verification sweep): .page-family-empty-state
   rule block deleted along with the template it targeted
   (templates/partials/page_families/empty_state.html, deleted in v2.6).
   Empty-state grammar now lives entirely under .rmc-empty (+ size variants
   .rmc-empty--inline / .rmc-empty--row / .rmc-empty--compact) defined in
   rmc-long-page-grammar.css. ~28 lines removed. */

/* Toast container — top-right, frosted material, slide-in.
   Targets templates/components/toast_notifications.html (#toast-container, .toast). */
.toast-container {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 1080;
  display: flex;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;
  max-width: min(420px, calc(100vw - 32px));
}
.toast-container .toast,
.toast-container > * {
  pointer-events: auto;
  background: var(--apple-material-bg);
  -webkit-backdrop-filter: var(--apple-material);
          backdrop-filter: var(--apple-material);
  border: 1px solid var(--apple-material-border);
  border-radius: var(--token-radius-md);
  box-shadow: var(--apple-elev-3);
  color: var(--admin-content-text);
  padding: 12px 14px;
  animation: toastSlideIn 360ms var(--ease-apple-spring) both;
  font-size: 0.9rem;
  letter-spacing: var(--tracking-body);
}
@keyframes toastSlideIn {
  from { transform: translateX(110%); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.toast.hiding,
.toast-container > .hiding {
  animation: toastSlideOut 220ms var(--ease-apple-in) forwards;
}
@keyframes toastSlideOut {
  to { transform: translateX(110%); opacity: 0; }
}

/* Tooltip refinement — frosted material instead of flat fill. Targets [data-tooltip]
   and Bootstrap .tooltip. The custom system in tooltips.css already provides core. */
[data-tooltip]::after,
.runmycampus-tooltip-bubble {
  background: var(--apple-material-bg) !important;
  -webkit-backdrop-filter: var(--apple-material);
          backdrop-filter: var(--apple-material);
  border: 1px solid var(--apple-material-border) !important;
  box-shadow: var(--apple-elev-2) !important;
  font-weight: 500;
  letter-spacing: var(--tracking-body);
  color: var(--admin-content-text) !important;
}
.tooltip-inner {
  background: var(--admin-content-text);
  color: var(--admin-content-bg);
  font-weight: 500;
  letter-spacing: var(--tracking-body);
  padding: 6px 10px;
  border-radius: 6px;
  font-size: 0.8125rem;
}
.bs-tooltip-top .tooltip-arrow::before { border-top-color: var(--admin-content-text); }
.bs-tooltip-bottom .tooltip-arrow::before { border-bottom-color: var(--admin-content-text); }
.bs-tooltip-start .tooltip-arrow::before { border-left-color: var(--admin-content-text); }
.bs-tooltip-end .tooltip-arrow::before { border-right-color: var(--admin-content-text); }

/* HTMX progress indicator — thin gradient bar at top of viewport during loads.
   Use class .htmx-progress (auto-applied by htmx during requests) on the body, OR
   render a fixed bar via the [data-htmx-progress] element. */
.htmx-progress-bar,
[data-htmx-progress] {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--school-primary), color-mix(in oklab, var(--school-primary) 70%, var(--school-accent)), transparent);
  background-size: 50% 100%;
  background-repeat: no-repeat;
  z-index: 9998;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity var(--dur-fast) var(--ease-apple), transform var(--dur-fast) var(--ease-apple);
  pointer-events: none;
}
.htmx-request .htmx-progress-bar,
.htmx-request[data-htmx-progress],
body.htmx-request .htmx-progress-bar,
[data-htmx-progress].active {
  opacity: 1;
  transform: translateY(0);
  animation: htmxProgressSlide 1.2s var(--ease-apple) infinite;
}
@keyframes htmxProgressSlide {
  0%   { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

/* HTMX inline indicator (per-element spinner inside button etc.) — Apple-style fade. */
.htmx-indicator {
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-apple);
}
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
}

/* Page transition — subtle fade-in for main content area on every page load.
   Targets [data-rmc-shell-main], main#main-content, .page-wrap. Lightweight; respects
   reduced motion. */
@keyframes pageEnter {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
[data-rmc-shell-main],
main#main-content > .page-wrap,
.rmc-shell-content-grid {
  animation: pageEnter 320ms var(--ease-apple) both;
}
@media (prefers-reduced-motion: reduce) {
  [data-rmc-shell-main],
  main#main-content > .page-wrap,
  .rmc-shell-content-grid,
  .skeleton,
  .toast-container .toast {
    animation: none !important;
  }
}

/* Command palette modal polish — Apple Spotlight feel. Targets the JS-driven palette
   from static/js/command-palette.js. The script renders an overlay with these IDs. */
#command-palette-overlay,
.command-palette-overlay,
[data-rmc-command-palette-overlay] {
  position: fixed;
  inset: 0;
  background: color-mix(in oklab, var(--color-base-900) 28%, transparent);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  z-index: 1090;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
  animation: cpOverlayIn var(--dur-base) var(--ease-apple) both;
}
@keyframes cpOverlayIn { from { opacity: 0; } to { opacity: 1; } }
#command-palette-modal,
.command-palette-modal,
[data-rmc-command-palette-modal] {
  width: min(640px, calc(100vw - 32px));
  background: var(--admin-content-bg);
  border-radius: 18px;
  box-shadow: var(--apple-elev-modal);
  overflow: hidden;
  animation: cpModalIn 280ms var(--ease-apple-spring) both;
}
@keyframes cpModalIn {
  from { transform: translateY(-12px) scale(0.97); opacity: 0; }
  to   { transform: translateY(0) scale(1);        opacity: 1; }
}
.command-palette-input,
[data-rmc-command-palette-input] {
  width: 100%;
  border: none;
  background: transparent;
  padding: 18px 22px;
  font-size: 1.0625rem;
  letter-spacing: var(--tracking-body);
  outline: none;
  border-bottom: 1px solid var(--admin-content-border);
}
.command-palette-input:focus,
[data-rmc-command-palette-input]:focus { box-shadow: none; }
.command-palette-results,
[data-rmc-command-palette-results] {
  max-height: 56vh;
  overflow-y: auto;
  padding: 6px;
}
.command-palette-results .result-item,
.command-palette-results > a,
.command-palette-results > button {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 10px;
  color: var(--admin-content-text);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease-apple);
  font-weight: 500;
}
.command-palette-results .result-item:hover,
.command-palette-results .result-item.is-selected,
.command-palette-results > a.is-selected,
.command-palette-results > button.is-selected {
  background: color-mix(in oklab, var(--school-primary) 8%, transparent);
}
.command-palette-results .result-item.is-selected {
  color: var(--school-primary);
}
.command-palette-footer {
  border-top: 1px solid var(--admin-content-border);
  padding: 10px 16px;
  font-size: 0.8125rem;
  color: var(--admin-content-text-muted);
  display: flex;
  justify-content: space-between;
  letter-spacing: var(--tracking-body);
}

/* <kbd> styling — refined keycap for shortcut hints. */
kbd, .kbd {
  background: var(--admin-content-thead-bg);
  color: var(--admin-content-text);
  border: 1px solid var(--admin-content-border);
  border-bottom-width: 2px;
  border-radius: 5px;
  padding: 2px 6px;
  font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
  font-size: 0.78em;
  font-weight: 600;
  line-height: 1;
  vertical-align: middle;
  box-shadow: 0 1px 0 rgba(15, 23, 42, 0.04);
}

/* Modal backdrop — frosted blur (was solid black). */
.modal-backdrop.show {
  background: color-mix(in oklab, var(--color-base-900) 36%, transparent);
  -webkit-backdrop-filter: blur(6px);
          backdrop-filter: blur(6px);
  opacity: 1;
}

/* Offcanvas (drawers) — same elevation language as modals. */
.offcanvas {
  border: none;
  box-shadow: var(--apple-elev-modal);
}
.offcanvas-start, .offcanvas-end { border-radius: 0; }
.offcanvas-header { border-bottom: 1px solid var(--admin-content-border); padding: 18px 22px; }
.offcanvas-header .offcanvas-title { font-weight: 700; letter-spacing: var(--tracking-heading); }

/* Statement header (top app bar) — slightly elevated, smooth scroll-aware shadow.
   Adds depth on scroll; main statement-header.css has the base. */
.statement-header {
  transition: box-shadow var(--dur-base) var(--ease-apple), backdrop-filter var(--dur-base) var(--ease-apple);
}
.statement-header.is-scrolled,
body.is-scrolled .statement-header {
  box-shadow: var(--apple-elev-2);
}

/* ============================================
   WIZARD / ONBOARDING POLISH
   First-impression surfaces — schools/onboard_wizard.html, teacher/student
   onboarding_wizard.html, siteconfig/onboarding.html. Layers Apple-tier polish
   onto existing class hooks (.wizard-step, .wizard-progress-bar,
   [data-shell-page="onboarding-wizard"], [data-rmc-onboarding-hint]).
   ============================================ */

/* Wizard root — generous max-width, breathable padding */
.wizard-container,
[data-shell-page="onboarding-wizard"],
[data-rmc-onboarding-page="1"] {
  max-width: 880px;
  margin: 0 auto;
  padding: 32px 20px 64px;
}

/* Step indicator — horizontal track with numbered circles + connecting line */
.wizard-progress {
  margin: 0 0 32px;
}
.wizard-steps {
  display: flex;
  gap: 0;
  align-items: flex-start;
  position: relative;
  margin: 0 0 18px;
}
.wizard-steps::before {
  /* Connecting hairline behind the circles (full-width, behind everything) */
  content: '';
  position: absolute;
  top: 16px;
  left: calc(100% / var(--wizard-step-count, 4) / 2);
  right: calc(100% / var(--wizard-step-count, 4) / 2);
  height: 1px;
  background: var(--admin-content-border);
  z-index: 0;
}
.wizard-step {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  position: relative;
  z-index: 1;
  cursor: default;
}
.wizard-step-number {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--surface-bg-base);
  color: var(--admin-content-text-muted);
  border: 1px solid var(--admin-content-border);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
  margin-bottom: 8px;
  transition:
    background var(--dur-base) var(--ease-apple),
    color var(--dur-base) var(--ease-apple),
    border-color var(--dur-base) var(--ease-apple),
    transform var(--dur-base) var(--ease-apple-spring),
    box-shadow var(--dur-base) var(--ease-apple);
}
.wizard-step.active .wizard-step-number {
  background: var(--school-primary);
  color: #fff;
  border-color: var(--school-primary);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent);
}
.wizard-step.completed .wizard-step-number {
  background: var(--school-accent);
  color: #fff;
  border-color: var(--school-accent);
}
.wizard-step.completed .wizard-step-number i {
  font-size: 1rem;
}
.wizard-step-label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--admin-content-text-muted);
  letter-spacing: var(--tracking-body);
  transition: color var(--dur-fast) var(--ease-apple);
  max-width: 11ch;
}
.wizard-step.active .wizard-step-label,
.wizard-step.completed .wizard-step-label {
  color: var(--admin-content-text);
  font-weight: 600;
}

/* Progress bar — slim, brand-gradient fill, smooth animation */
.wizard-progress-bar {
  height: 4px;
  background: var(--admin-content-border);
  border-radius: 999px;
  overflow: hidden;
}
.wizard-progress-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--school-primary), color-mix(in oklab, var(--school-primary) 70%, var(--school-accent)));
  border-radius: 999px;
  transition: width 600ms var(--ease-apple);
}

/* Step content — card with hairline + soft elevation */
.wizard-step-content {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-lg);
  padding: 28px 32px;
  box-shadow: var(--apple-elev-1);
  margin-top: 24px;
}
.wizard-step-title {
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  margin: 0 0 6px;
  color: var(--admin-content-text);
}
.wizard-step-description {
  font-size: 1rem;
  color: var(--admin-content-text-muted);
  margin: 0 0 24px;
  line-height: 1.55;
  letter-spacing: var(--tracking-body);
  max-width: 60ch;
}

/* Onboarding hint banner — refined "guided tip" with brand-tinted left rule */
.alert.alert-light[data-rmc-onboarding-hint],
[data-rmc-onboarding-hint] {
  background: color-mix(in oklab, var(--school-primary) 4%, var(--admin-content-bg));
  border: none;
  border-left: 3px solid var(--school-primary);
  border-radius: 8px;
  padding: 12px 16px;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--admin-content-text);
  letter-spacing: var(--tracking-body);
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.alert.alert-light[data-rmc-onboarding-hint] strong,
[data-rmc-onboarding-hint] strong {
  color: var(--school-primary);
  font-weight: 600;
}

/* Schools onboard wizard step pill — replace flat .badge.bg-secondary with refined chip */
[data-shell-page="onboarding-wizard"] .badge.bg-secondary {
  background: var(--school-primary-light) !important;
  color: var(--school-primary) !important;
  font-weight: 600;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  font-size: 0.7rem;
  padding: 4px 10px;
  border-radius: 999px;
}

/* Onboarding hero typography — titles slightly larger, tighter */
[data-shell-page="onboarding-wizard"] h1,
[data-rmc-onboarding-page="1"] h1,
.wizard-container h1 {
  font-size: clamp(1.75rem, 2.5vw, 2.25rem);
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  margin-bottom: 8px;
}
[data-shell-page="onboarding-wizard"] h1 + .text-muted,
[data-rmc-onboarding-page="1"] h1 + .text-muted,
.wizard-container h1 + .text-muted {
  font-size: 1rem;
  letter-spacing: var(--tracking-body);
  max-width: 60ch;
}

/* Apple-class data-quality meter (used in siteconfig/onboarding.html) — refined hairline + radius */
.apple-class-data-quality-meter,
[id^="meter-"] {
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-1);
  border: none;
}

/* Wizard form field labels — proper hierarchy */
.wizard-step-content .form-label,
[data-shell-page="onboarding-wizard"] .form-label {
  font-size: 0.875rem;
  font-weight: 500;
  letter-spacing: var(--tracking-body);
  margin-bottom: 6px;
  color: var(--admin-content-text);
}

/* Wizard footer action row — sticky-feeling button cluster with spacing */
.wizard-step-content .d-flex.flex-wrap.gap-2,
[data-shell-page="onboarding-wizard"] form > .d-flex {
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--admin-content-border);
}
.wizard-step-content .btn-primary,
[data-shell-page="onboarding-wizard"] .btn-primary {
  padding: 10px 22px;
  font-weight: 600;
}

/* ============================================
   PLATFORM-WIDE COMPONENT GRAMMAR
   Apple-tier polish for every remaining Bootstrap + bespoke RMC pattern
   that hasn't been addressed above. This is the catch-all layer that
   ensures pages outside the polished base shells still inherit the system.
   Targets exact class names from Bootstrap 5 and common RMC bespoke patterns.
   ============================================ */

/* ----- LIST GROUPS ----- */
.list-group {
  border-radius: var(--token-radius-md);
  overflow: hidden;
  border: 1px solid var(--admin-content-border);
  background: var(--admin-content-bg);
}
.list-group-item {
  border: none;
  border-bottom: 1px solid var(--admin-content-border);
  padding: 12px 16px;
  font-size: 0.9rem;
  letter-spacing: var(--tracking-body);
  background: transparent;
  color: var(--admin-content-text);
  transition: background var(--dur-fast) var(--ease-apple);
}
.list-group-item:last-child { border-bottom: none; }
.list-group-item-action:hover,
.list-group-item-action:focus {
  background: color-mix(in oklab, var(--school-primary) 4%, transparent);
  color: var(--admin-content-text);
}
.list-group-item.active {
  background: var(--school-primary-light);
  color: var(--school-primary);
  border-color: transparent;
  font-weight: 600;
}
.list-group-flush .list-group-item {
  border-radius: 0;
  border-left: 0;
  border-right: 0;
}
.list-group-flush .list-group-item:first-child { border-top: 0; }
.list-group-flush .list-group-item:last-child { border-bottom: 0; }

/* ----- NAV TABS / PILLS (refined; sliding underline on tabs) ----- */
.nav-tabs {
  border-bottom: 1px solid var(--admin-content-border);
  gap: 4px;
}
.nav-tabs .nav-link {
  border: none;
  border-bottom: 2px solid transparent;
  border-radius: 8px 8px 0 0;
  padding: 10px 16px;
  font-weight: 500;
  letter-spacing: var(--tracking-body);
  color: var(--admin-content-text-muted);
  transition: color var(--dur-fast) var(--ease-apple), border-color var(--dur-base) var(--ease-apple), background var(--dur-fast) var(--ease-apple);
  margin-bottom: -1px;
}
.nav-tabs .nav-link:hover {
  background: color-mix(in oklab, var(--school-primary) 4%, transparent);
  color: var(--admin-content-text);
  border-color: transparent;
}
.nav-tabs .nav-link.active,
.nav-tabs .nav-item.show .nav-link {
  background: transparent;
  color: var(--school-primary);
  border-bottom-color: var(--school-primary);
  font-weight: 600;
}

.nav-pills .nav-link {
  border-radius: 8px;
  padding: 8px 14px;
  font-weight: 500;
  color: var(--admin-content-text-muted);
  transition: background var(--dur-fast) var(--ease-apple), color var(--dur-fast) var(--ease-apple), transform var(--dur-fast) var(--ease-apple-snap);
}
.nav-pills .nav-link:hover { background: color-mix(in oklab, var(--school-primary) 6%, transparent); color: var(--admin-content-text); }
.nav-pills .nav-link:active { transform: scale(0.98); }
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link {
  background: var(--school-primary);
  color: #fff;
  box-shadow: 0 4px 12px color-mix(in oklab, var(--school-primary) 30%, transparent);
}

/* ----- ALERTS (all variants) ----- */
.alert {
  border: none;
  border-left: 3px solid currentColor;
  border-radius: var(--token-radius-md);
  padding: 14px 16px;
  font-size: 0.92rem;
  letter-spacing: var(--tracking-body);
  line-height: 1.55;
}
.alert-primary    { background: color-mix(in oklab, var(--school-primary) 6%, var(--admin-content-bg)); color: var(--admin-content-text); border-left-color: var(--school-primary); }
.alert-success    { background: color-mix(in oklab, var(--ds-success) 8%, var(--admin-content-bg));   color: var(--admin-content-text); border-left-color: var(--ds-success); }
.alert-warning    { background: color-mix(in oklab, var(--ds-warning) 8%, var(--admin-content-bg));   color: var(--admin-content-text); border-left-color: var(--ds-warning); }
.alert-danger     { background: color-mix(in oklab, var(--ds-danger) 6%, var(--admin-content-bg));    color: var(--admin-content-text); border-left-color: var(--ds-danger); }
.alert-info       { background: color-mix(in oklab, var(--ds-info) 6%, var(--admin-content-bg));      color: var(--admin-content-text); border-left-color: var(--ds-info); }
.alert-light      { background: var(--surface-bg-subtle);                                              color: var(--admin-content-text); border-left-color: var(--admin-content-border); }
.alert-dark       { background: var(--color-base-900);                                                 color: #fff;                       border-left-color: var(--color-base-800); }
.alert-secondary  { background: var(--color-base-100);                                                 color: var(--admin-content-text); border-left-color: var(--color-base-400); }
.alert .alert-link { font-weight: 600; color: inherit; text-decoration: underline; }

/* ----- BADGES (all variants — refined pill, slightly more padding) ----- */
.badge,
.text-bg-primary, .text-bg-success, .text-bg-warning, .text-bg-danger,
.text-bg-info, .text-bg-light, .text-bg-dark, .text-bg-secondary {
  font-weight: 500;
  letter-spacing: 0.005em;
  padding: 4px 10px;
  border-radius: 999px;
}
.badge.bg-primary,   .badge.text-bg-primary   { background: var(--school-primary) !important; color: #fff; }
.badge.bg-success,   .badge.text-bg-success   { background: var(--ds-success) !important;    color: #fff; }
.badge.bg-warning,   .badge.text-bg-warning   { background: var(--ds-warning) !important;    color: #fff; }
.badge.bg-danger,    .badge.text-bg-danger    { background: var(--ds-danger) !important;     color: #fff; }
.badge.bg-info,      .badge.text-bg-info      { background: var(--ds-info) !important;       color: #fff; }
.badge.bg-secondary, .badge.text-bg-secondary { background: var(--color-base-500) !important; color: #fff; }
/* Soft badge variants (data-tone) — for less-shouty status chips */
.badge[data-tone="soft-primary"] { background: var(--school-primary-light); color: var(--school-primary); }
.badge[data-tone="soft-success"] { background: color-mix(in oklab, var(--ds-success) 14%, transparent); color: var(--ds-success); }
.badge[data-tone="soft-warning"] { background: color-mix(in oklab, var(--ds-warning) 14%, transparent); color: var(--ds-warning); }
.badge[data-tone="soft-danger"]  { background: color-mix(in oklab, var(--ds-danger) 14%, transparent);  color: var(--ds-danger); }
.badge[data-tone="soft-info"]    { background: color-mix(in oklab, var(--ds-info) 14%, transparent);    color: var(--ds-info); }

/* ----- PROGRESS (refined bar w/ brand fill) ----- */
.progress {
  height: 6px;
  background: var(--admin-content-border);
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar {
  background: linear-gradient(90deg, var(--school-primary), color-mix(in oklab, var(--school-primary) 70%, var(--school-accent)));
  transition: width 600ms var(--ease-apple);
  box-shadow: 0 0 0 1px color-mix(in oklab, var(--school-primary) 30%, transparent) inset;
}
.progress-bar.bg-success { background: var(--ds-success); }
.progress-bar.bg-warning { background: var(--ds-warning); }
.progress-bar.bg-danger  { background: var(--ds-danger); }

/* ----- ACCORDION (refined chrome) ----- */
.accordion-item {
  border: 1px solid var(--admin-content-border);
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  margin-bottom: 6px;
  overflow: hidden;
}
.accordion-button {
  background: transparent;
  color: var(--admin-content-text);
  font-weight: 600;
  letter-spacing: var(--tracking-body);
  padding: 14px 16px;
  border: none;
  box-shadow: none !important;
  transition: background var(--dur-fast) var(--ease-apple);
}
.accordion-button:hover { background: color-mix(in oklab, var(--school-primary) 4%, transparent); }
.accordion-button:not(.collapsed) {
  background: color-mix(in oklab, var(--school-primary) 6%, transparent);
  color: var(--school-primary);
}
.accordion-button::after {
  width: 14px; height: 14px;
  background-size: 14px;
  transition: transform var(--dur-base) var(--ease-apple);
}
.accordion-body {
  padding: 14px 16px 18px;
  color: var(--admin-content-text-muted);
  font-size: 0.92rem;
  line-height: 1.6;
  letter-spacing: var(--tracking-body);
}

/* ----- INPUT GROUP (refined with focus ring across the whole group) ----- */
.input-group { border-radius: 10px; }
.input-group > .form-control,
.input-group > .form-select {
  border-color: var(--admin-content-border);
}
.input-group-text {
  background: var(--surface-bg-subtle);
  border-color: var(--admin-content-border);
  color: var(--admin-content-text-muted);
  font-weight: 500;
  font-size: 0.9rem;
}
.input-group:focus-within {
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent);
  border-radius: 10px;
}
.input-group:focus-within > .form-control,
.input-group:focus-within > .form-select {
  border-color: color-mix(in oklab, var(--school-primary) 60%, var(--admin-content-border));
  box-shadow: none;
}

/* ----- PAGINATION ----- */
.pagination { gap: 4px; }
.page-item { margin: 0; }
.page-link {
  border: 1px solid var(--admin-content-border);
  border-radius: 8px !important;
  color: var(--admin-content-text);
  font-weight: 500;
  font-size: 0.875rem;
  padding: 6px 12px;
  background: var(--admin-content-bg);
  transition: background var(--dur-fast) var(--ease-apple), color var(--dur-fast) var(--ease-apple), border-color var(--dur-fast) var(--ease-apple);
}
.page-link:hover {
  background: color-mix(in oklab, var(--school-primary) 6%, transparent);
  color: var(--school-primary);
  border-color: color-mix(in oklab, var(--school-primary) 40%, var(--admin-content-border));
}
.page-item.active .page-link {
  background: var(--school-primary);
  border-color: var(--school-primary);
  color: #fff;
}
.page-item.disabled .page-link {
  opacity: 0.5;
  background: transparent;
  border-color: var(--admin-content-border);
}

/* ----- FORM SWITCHES, CHECKS, FLOATING LABELS, RANGE ----- */
.form-check-input {
  border-color: var(--admin-content-border);
  width: 1.1em; height: 1.1em;
  transition: background-color var(--dur-fast) var(--ease-apple), border-color var(--dur-fast) var(--ease-apple), box-shadow var(--dur-fast) var(--ease-apple);
}
.form-check-input:checked {
  background-color: var(--school-primary);
  border-color: var(--school-primary);
}
.form-check-input:focus { box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent); }

.form-switch .form-check-input {
  width: 2.4em; height: 1.3em;
  background-color: var(--color-base-300);
  border: none;
}
.form-switch .form-check-input:checked {
  background-color: var(--school-primary);
}

.form-floating > label {
  color: var(--admin-content-text-muted);
  letter-spacing: var(--tracking-body);
  padding: 14px 14px;
}
.form-floating > .form-control:focus ~ label,
.form-floating > .form-control:not(:placeholder-shown) ~ label,
.form-floating > .form-select ~ label {
  color: var(--school-primary);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: var(--tracking-eyebrow);
  text-transform: uppercase;
  transform: scale(1) translateY(-0.5rem) translateX(0.15rem);
  opacity: 1;
  background: var(--admin-content-bg);
  padding: 0 6px;
  height: auto;
}

.form-range::-webkit-slider-thumb {
  background: var(--school-primary);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.15), 0 0 0 4px color-mix(in oklab, var(--school-primary) 20%, transparent);
}
.form-range::-moz-range-thumb {
  background: var(--school-primary);
}

/* ----- BUTTON GROUPS ----- */
.btn-group .btn { border-radius: 10px; }
.btn-group > .btn:not(:last-child):not(.dropdown-toggle),
.btn-group > .btn-group:not(:last-child) > .btn {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.btn-group > .btn:not(:first-child),
.btn-group > .btn-group:not(:first-child) > .btn {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-left: -1px;
}

/* ----- SPINNERS ----- */
.spinner-border {
  border-color: color-mix(in oklab, var(--school-primary) 28%, transparent);
  border-right-color: var(--school-primary);
  width: 1.25rem; height: 1.25rem;
  border-width: 0.18em;
}
.spinner-border-sm { width: 1rem; height: 1rem; border-width: 0.16em; }
.spinner-grow { background: var(--school-primary); }

/* Bootstrap-Icon spinner — `.bi.spinning` rotates an icon, replacing FA's `fa-spin`.
   Use on any icon: `<i class="bi bi-arrow-repeat spinning"></i>`. */
.bi.spinning,
i.spinning,
[class*="bi-"].spinning {
  display: inline-block;
  animation: rmcSpin 1s linear infinite;
}
@keyframes rmcSpin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .bi.spinning, i.spinning, [class*="bi-"].spinning { animation: none; }
}

/* ----- BOOTSTRAP PLACEHOLDER (loading) — match our skeleton shimmer ----- */
.placeholder {
  background: linear-gradient(
    90deg,
    color-mix(in oklab, var(--admin-content-border) 30%, transparent) 25%,
    color-mix(in oklab, var(--admin-content-border) 60%, transparent) 50%,
    color-mix(in oklab, var(--admin-content-border) 30%, transparent) 75%
  );
  background-size: 200% 100%;
  animation: skeletonShimmer 1.6s var(--ease-apple) infinite;
  border-radius: 4px;
  opacity: 1;
}

/* ----- BESPOKE RMC CARDS — common patterns across the codebase ----- */
.stat-card,
.metric-card,
.info-card,
.profile-card,
.summary-card,
.kpi-card,
.action-card,
.feature-card,
.tile-card {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 18px 20px;
  box-shadow: var(--apple-elev-1);
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
  border: none;
}
.stat-card[data-interactive="1"]:hover,
.metric-card[data-interactive="1"]:hover,
.info-card[data-interactive="1"]:hover,
.profile-card[data-interactive="1"]:hover,
.summary-card[data-interactive="1"]:hover,
.action-card[data-interactive="1"]:hover,
.feature-card[data-interactive="1"]:hover,
.tile-card[data-interactive="1"]:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}

/* Stat / KPI value + label hierarchy */
.stat-value, .metric-value, .kpi-value {
  font-size: 1.85rem;
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
.stat-label, .metric-label, .kpi-label {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  color: var(--admin-content-text-muted);
}

/* ----- LIST UTILITY: data list (dt/dd) ----- */
dl.data-list,
.data-list dl {
  display: grid;
  grid-template-columns: minmax(8rem, 30%) 1fr;
  gap: 6px 14px;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
}
dl.data-list dt,
.data-list dt {
  color: var(--admin-content-text-muted);
  font-weight: 500;
  letter-spacing: var(--tracking-body);
}
dl.data-list dd,
.data-list dd {
  color: var(--admin-content-text);
  font-weight: 600;
  margin: 0;
}

/* ----- HORIZONTAL RULES, BLOCKQUOTES, CODE ----- */
hr {
  border: none;
  border-top: 1px solid var(--admin-content-border);
  margin: 18px 0;
  opacity: 1;
}
blockquote {
  border-left: 3px solid var(--school-primary);
  padding: 6px 16px;
  margin: 14px 0;
  color: var(--admin-content-text);
  font-style: italic;
  background: color-mix(in oklab, var(--school-primary) 3%, transparent);
  border-radius: 0 8px 8px 0;
}
code:not(pre code) {
  background: var(--surface-bg-subtle);
  color: var(--admin-content-text);
  padding: 1px 6px;
  border-radius: 4px;
  font-size: 0.85em;
  font-family: ui-monospace, "SF Mono", "Cascadia Code", monospace;
  border: 1px solid var(--admin-content-border);
}
pre {
  background: var(--surface-bg-subtle);
  border: 1px solid var(--admin-content-border);
  border-radius: var(--token-radius-md);
  padding: 14px 16px;
  font-size: 0.85em;
  line-height: 1.55;
  color: var(--admin-content-text);
  overflow-x: auto;
}

/* ----- DETAILS / SUMMARY (collapsibles) ----- */
details {
  border: 1px solid var(--admin-content-border);
  border-radius: var(--token-radius-md);
  background: var(--admin-content-bg);
  margin-bottom: 8px;
  overflow: hidden;
}
details > summary {
  padding: 12px 16px;
  cursor: pointer;
  font-weight: 600;
  letter-spacing: var(--tracking-body);
  color: var(--admin-content-text);
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  transition: background var(--dur-fast) var(--ease-apple);
}
details > summary::-webkit-details-marker { display: none; }
details > summary::after {
  content: '';
  width: 14px; height: 14px;
  background: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3cpath fill='currentColor' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z'/%3e%3c/svg%3e") center/contain no-repeat;
          mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3e%3cpath fill='currentColor' d='M16.59 8.59L12 13.17 7.41 8.59 6 10l6 6 6-6z'/%3e%3c/svg%3e") center/contain no-repeat;
  opacity: 0.6;
  transition: transform var(--dur-base) var(--ease-apple);
}
details[open] > summary::after { transform: rotate(180deg); }
details > summary:hover { background: color-mix(in oklab, var(--school-primary) 4%, transparent); }
details > div,
details > p,
details > ul,
details > ol { padding: 0 16px 14px; margin-top: 0; }

/* ----- AUTH SHELL -----
   Targets every auth template pattern in this codebase: .auth-shell, .auth-landing,
   .login-page, .signup-page, .login-split, [data-shell-page="auth"], body.auth-page. */
.auth-shell,
.auth-landing,
.login-page,
.signup-page,
body.auth-page,
[data-shell-page="auth"] {
  min-height: 100vh;
  padding: 32px 20px;
  background:
    radial-gradient(ellipse 80% 50% at 50% 0%, color-mix(in oklab, var(--school-primary) 8%, transparent), transparent 60%),
    var(--surface-bg-subtle);
}
/* Two-pane wallpaper variant (auth/login.html .login-split) */
.login-split {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 1fr;
}
@media (max-width: 900px) {
  .login-split { grid-template-columns: 1fr; }
  .login-split__left { display: none; }
}
.login-split__left {
  background-size: cover;
  background-position: center;
  position: relative;
}
.login-split__left::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(135deg, color-mix(in oklab, var(--school-primary) 32%, transparent) 0%, transparent 70%);
}
.login-split__right {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  background: var(--surface-bg-subtle);
}

/* Hero brand cluster (logo + name + subtext) — used in auth/login.html */
.auth-hero {
  max-width: 980px;
  margin: 0 auto 28px;
  padding: 0 8px;
}
.hero-brand {
  display: flex;
  align-items: center;
  gap: 14px;
}
.hero-logo {
  width: 56px;
  height: 56px;
  border-radius: 14px;
  background: linear-gradient(135deg, var(--school-primary), color-mix(in oklab, var(--school-primary) 70%, var(--school-accent)));
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 1.4rem;
  flex-shrink: 0;
  box-shadow: var(--apple-elev-1);
}
.hero-brand strong {
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: var(--tracking-heading);
  display: block;
  line-height: 1.25;
}
.hero-brand small {
  display: block;
  color: var(--admin-content-text-muted);
  font-size: 0.85rem;
  margin-top: 2px;
}

.auth-breadcrumb {
  max-width: 980px;
  margin: 0 auto 14px;
  padding: 0 8px;
}

/* Card variants — login-card, signup-card, info-card, admin-login-card */
.auth-card,
.login-card,
.signup-card,
.info-card,
.admin-login-card,
[data-shell-page="auth"] .card {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-2);
  padding: 32px 28px;
  border: none;
}
.admin-login-card {
  max-width: 420px;
  margin: 0 auto;
}
.auth-card h1,
.auth-card .h1,
.login-card h1,
.signup-card h1,
.admin-login-title {
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  margin: 0 0 6px;
}
.admin-login-subtitle,
.auth-card .auth-sub,
.login-card .text-muted:first-of-type {
  font-size: 0.95rem;
  color: var(--admin-content-text-muted);
  margin-bottom: 22px;
  line-height: 1.55;
}
.admin-login-brand .brand-name {
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: var(--tracking-heading);
  margin-bottom: 18px;
}
.auth-card .btn-primary,
.login-card .btn-primary,
.signup-card .btn-primary,
.admin-login-card .btn-primary {
  width: 100%;
  padding: 11px 14px;
  font-weight: 600;
}

/* Password show/hide toggle (auth onboarding + account forms) */
.rmc-password-field .input-group .form-control {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
.rmc-password-field__toggle {
  border-color: var(--hairline);
  color: var(--text-secondary);
  transition: color var(--dur-fast) var(--ease-apple),
    background-color var(--dur-fast) var(--ease-apple);
}
.rmc-password-field__toggle:hover,
.rmc-password-field__toggle:focus-visible {
  color: var(--text-primary);
  background: var(--surface-bg-subtle);
}
.rmc-password-field--sm .rmc-password-field__toggle {
  padding: 0.25rem 0.5rem;
  font-size: var(--type-size-caption);
}
.rmc-password-field__help--portal-muted {
  font-size: var(--type-size-caption);
  line-height: 1.5;
  color: var(--admin-content-text-muted);
  margin-top: 6px;
}

/* Quick-link chips on the family/admin info side (auth/login.html .quick-link) */
.quick-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--school-primary) 8%, transparent);
  color: var(--school-primary);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
  letter-spacing: var(--tracking-body);
  transition: background var(--dur-fast) var(--ease-apple), color var(--dur-fast) var(--ease-apple);
}
.quick-link:hover {
  background: var(--school-primary);
  color: #fff;
}
.quick-link.quick-link-muted {
  background: var(--surface-bg-subtle);
  color: var(--admin-content-text-muted);
}
.quick-link.quick-link-muted:hover {
  background: var(--admin-content-text-muted);
  color: #fff;
}

/* ----- ERROR PAGE SHELL -----
   Targets: 404.html, 500.html, 403.html, errors/*.html — common .error-page hooks. */
.error-page,
[data-shell-page="error"],
body.error-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  text-align: center;
  background:
    radial-gradient(ellipse 80% 50% at 50% 0%, color-mix(in oklab, var(--school-primary) 6%, transparent), transparent 60%),
    var(--surface-bg-subtle);
}
.error-page .error-code,
.error-code-display {
  font-size: clamp(4rem, 12vw, 7rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  color: var(--school-primary);
  line-height: 1;
  margin-bottom: 8px;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(135deg, var(--school-primary), color-mix(in oklab, var(--school-primary) 65%, var(--school-accent)));
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
}
.error-page h1,
.error-page .error-title {
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  margin: 4px 0 8px;
}
.error-page p,
.error-page .error-message {
  color: var(--admin-content-text-muted);
  max-width: 56ch;
  margin: 0 auto 20px;
  line-height: 1.6;
  font-size: 1rem;
}
.error-page .error-actions {
  display: inline-flex;
  gap: 10px;
  flex-wrap: wrap;
  justify-content: center;
}

/* Maintenance-mode operator preview: same shell as .error-page, scoped class
   so the staff-only maintenance preview body partial keeps a stable hook
   for scan_undefined_css_classes. The class itself adds no rules of its own
   beyond what .error-page already provides; it's a named anchor for the
   surface inventory (data-shell-surface="maintenance-preview"). */
.rmc-maintenance-preview {
  /* Inherits .error-page layout; reserved hook for future scoped styling. */
}

[hx-swap-oob="true"],
[data-hx-swap-oob],
.htmx-swapping,
.htmx-settling {
  transition: opacity var(--dur-fast) var(--ease-apple);
}
.htmx-swapping { opacity: 0.6; }
.htmx-added { animation: pageEnter 280ms var(--ease-apple) both; }

/* ----- SCROLLBARS (refined; respects dark mode) ----- */
* {
  scrollbar-width: thin;
  scrollbar-color: color-mix(in oklab, var(--admin-content-text-muted) 30%, transparent) transparent;
}
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: color-mix(in oklab, var(--admin-content-text-muted) 28%, transparent);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover {
  background: color-mix(in oklab, var(--admin-content-text-muted) 50%, transparent);
  background-clip: padding-box;
  border: 2px solid transparent;
}

/* ----- SELECTION (text highlight) ----- */
::selection {
  background: color-mix(in oklab, var(--school-primary) 22%, transparent);
  color: var(--admin-content-text);
}

/* ----- TEXT-* utility colors bound to tokens (so .text-primary etc. follow brand) ----- */
.text-primary    { color: var(--school-primary) !important; }
.text-success    { color: var(--ds-success) !important; }
.text-warning    { color: var(--ds-warning) !important; }
.text-danger     { color: var(--ds-danger) !important; }
.text-info       { color: var(--ds-info) !important; }
.text-muted      { color: var(--admin-content-text-muted) !important; }
.bg-primary      { background-color: var(--school-primary) !important; }
.bg-primary-subtle { background-color: var(--school-primary-light) !important; }
.bg-success-subtle { background-color: color-mix(in oklab, var(--ds-success) 10%, transparent) !important; }
.bg-warning-subtle { background-color: color-mix(in oklab, var(--ds-warning) 10%, transparent) !important; }
.bg-danger-subtle  { background-color: color-mix(in oklab, var(--ds-danger) 8%, transparent) !important; }
.border-primary  { border-color: var(--school-primary) !important; }

/* ----- IMAGE / AVATAR PRIMITIVES (.avatar / .av classes) ----- */
.avatar,
.av {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--school-primary), color-mix(in oklab, var(--school-primary) 70%, var(--school-accent)));
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 0.82rem;
  flex-shrink: 0;
  letter-spacing: 0;
}
.avatar-sm { width: 28px; height: 28px; font-size: 0.72rem; }
.avatar-lg { width: 56px; height: 56px; font-size: 1.1rem; }
.avatar-xl { width: 80px; height: 80px; font-size: 1.5rem; }

/* ----- CONFIRM DIALOG (bespoke .confirm-dialog pattern) ----- */
.confirm-dialog,
[data-rmc-confirm-dialog] {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-modal);
  padding: 24px 28px;
  max-width: 440px;
  border: none;
}
.confirm-dialog h3,
.confirm-dialog .confirm-title {
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: var(--tracking-heading);
  margin: 0 0 6px;
}
.confirm-dialog p,
.confirm-dialog .confirm-message {
  color: var(--admin-content-text-muted);
  font-size: 0.95rem;
  margin: 0 0 18px;
  line-height: 1.55;
}
.confirm-dialog .confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* ----- CHARTS: ensure default chart colors derive from tokens ---
   (chart-rules.css governs chart-specific visuals; these provide token defaults
   for libraries that read from CSS-vars or inline style.)
   Bound to school cascade so Chart.js (`buildThemePalette` reads `getComputedStyle`)
   and any other chart library picks up tenant brand automatically. */
:root {
  --chart-color-1: var(--school-primary);
  --chart-color-2: var(--school-accent);
  --chart-color-3: #38bdf8; /* sky */
  --chart-color-4: #a78bfa; /* violet */
  --chart-color-5: var(--ds-warning);
  --chart-color-6: var(--ds-danger);
  --chart-color-7: #14b8a6; /* teal */
  --chart-color-8: #ec4899; /* pink */
  --chart-grid:    var(--admin-content-border);
  --chart-axis:    var(--admin-content-text-muted);

  /* Dashboard chart tokens — read by static/js/dashboard-charts-shared.js
     (buildThemePalette). Previously had hardcoded fallbacks; now bound to school cascade. */
  --dashboard-theme-primary: var(--school-primary);
  --dashboard-theme-accent:  var(--school-accent);
  --brand-primary:           var(--school-primary);
  --brand-accent:            var(--school-accent);
  --brand-success:           var(--ds-success);
  --brand-warning:           var(--ds-warning);
  --brand-danger:            var(--ds-danger);
  --brand-info:              var(--ds-info);
}

/* ----- FILE INPUT (refined) ----- */
.form-control[type="file"] {
  padding: 6px 10px;
  font-size: 0.9rem;
}
.form-control[type="file"]::file-selector-button {
  background: var(--surface-bg-subtle);
  color: var(--admin-content-text);
  border: 1px solid var(--admin-content-border);
  border-radius: 6px;
  padding: 4px 12px;
  margin-right: 12px;
  font-weight: 500;
  transition: background var(--dur-fast) var(--ease-apple), color var(--dur-fast) var(--ease-apple);
}
.form-control[type="file"]::file-selector-button:hover {
  background: var(--school-primary);
  color: #fff;
  border-color: var(--school-primary);
}

/* ----- TIMELINE PATTERN (.timeline / .activity-feed extension) ----- */
.timeline,
.activity-feed {
  position: relative;
}
.timeline > .timeline-item,
.activity-feed > .item {
  position: relative;
  padding-left: 28px;
}
.timeline > .timeline-item::before,
.activity-feed > .item::before {
  content: '';
  position: absolute;
  left: 12px;
  top: 28px;
  bottom: -12px;
  width: 1px;
  background: var(--admin-content-border);
}
.timeline > .timeline-item:last-child::before,
.activity-feed > .item:last-child::before { display: none; }

/* ----- MAINTENANCE / OFFLINE PAGE ----- */
.maintenance-shell,
.offline-shell,
[data-shell-page="maintenance"],
[data-shell-page="offline"] {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px;
  text-align: center;
  background: var(--surface-bg-subtle);
}
.maintenance-shell .maint-mark,
.offline-shell .maint-mark {
  width: 64px;
  height: 64px;
  border-radius: 18px;
  background: var(--school-primary-light);
  color: var(--school-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  margin-bottom: 18px;
}

/* ============================================
   GLOBAL .card POLISH (Bootstrap default + .shadow-sm/.shadow variants)
   Highest-leverage rule in the entire system: polishes hundreds of existing
   `.card.shadow-sm` / `.card.shadow` / `.card border-0 shadow-sm` usages.
   Template authors don't need to change anything — every Bootstrap card in
   the codebase becomes Apple-tier automatically.
   ============================================ */
.card,
.card.shadow-sm,
.card.shadow {
  background: var(--admin-content-bg);
  border: 1px solid var(--admin-content-border);
  border-radius: var(--token-radius-md);
  box-shadow: var(--apple-elev-1);
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.card.shadow-sm { box-shadow: var(--apple-elev-1); }
.card.shadow    { box-shadow: var(--apple-elev-2); }
.card.shadow-lg { box-shadow: var(--apple-elev-3); }
.card.border-0  { border: none !important; }

.card[data-interactive="1"]:hover,
.card.is-interactive:hover,
a.card:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}
.card-header {
  background: var(--admin-content-bg);
  border-bottom: 1px solid var(--admin-content-border);
  padding: 14px 18px;
  font-weight: 600;
  letter-spacing: var(--tracking-body);
}
.card-header.bg-transparent {
  background: transparent;
  border-bottom: 1px solid var(--admin-content-border);
}
/* Old Bootstrap `card-header bg-primary text-white` patterns — soften so they don't
   look like 2018 dashboards. Branded background but desaturated. */
.card-header.bg-primary,
.card-header.bg-success,
.card-header.bg-warning,
.card-header.bg-danger,
.card-header.bg-info {
  border-bottom: none;
  border-radius: var(--token-radius-md) var(--token-radius-md) 0 0;
}
.card-body { padding: 18px 20px; }
.card-footer {
  background: var(--surface-bg-subtle);
  border-top: 1px solid var(--admin-content-border);
  padding: 12px 18px;
  font-size: 0.88rem;
  color: var(--admin-content-text-muted);
}

/* ============================================
   HIGH-FREQUENCY BESPOKE CLASS COVERAGE
   Catches the top RMC class names used across the codebase that don't
   already inherit from `.card` / `.kpi` / Bootstrap. This is the single
   highest-leverage layer — polishes 500+ existing template usages with
   no template changes. Names + counts from the platform audit (top 60).
   ============================================ */

/* Universal panel surface — cp-panel (129×), proof-panel (62×), v2-panel (31×),
   tdm-panel (14×), de-panel (9×), security-panel (6×), pinned-panel (6×),
   bento-panel (5×), studio-panel (5×), cp-panel-stat (5×). */
.bento-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
  gap: var(--space-4, 1rem);
  align-items: stretch;
}

.bento-grid > * {
  min-width: 0;
}

.cp-panel,
.proof-panel,
.v2-panel,
.tdm-panel,
.de-panel,
.security-panel,
.pinned-panel,
.bento-panel,
.studio-panel,
.cp-panel-stat {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 18px 20px;
  box-shadow: var(--apple-elev-1);
  border: none;
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.cp-panel[data-interactive="1"]:hover,
.proof-panel[data-interactive="1"]:hover,
.v2-panel[data-interactive="1"]:hover,
.tdm-panel[data-interactive="1"]:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}

/* Universal card surface — content-card (49×), overview-card (38×), strip-card (36×),
   dashboard-card (33×), cp-card (30×), summary-card (22×), proof-card (21×),
   ds-card (20×), segment-card (16×), app-card (13×), hub-card (12×),
   health-card (10×), queue-card (9×), rail-card (7×), preview-card (7×),
   chart-card (6×), action-card (6×), footer-card (6×), data-card (6×),
   security-card (×), table-card (×), platform-card (×), module-card (×),
   accordion-card (×), workflow-card (×), user-card (×), parent-glance-card (×).
   Pulls from the same .card-x pattern. */
.content-card,
.overview-card,
.strip-card,
.dashboard-card,
.cp-card,
.summary-card,
.proof-card,
.ds-card,
.segment-card,
.app-card,
.hub-card,
.health-card,
.queue-card,
.rail-card,
.preview-card,
.chart-card,
.action-card,
.footer-card,
.data-card,
.security-card,
.table-card,
.platform-card,
.module-card,
.accordion-card,
.workflow-card,
.user-card,
.glance-card,
.parent-glance-card,
.glance-cell,
.fees-card,
.adm-card,
.product-metric,
.results-summary-card,
.list-card,
.hub-action-card,
.org-chart-card,
.module-card,
.footprint-card,
.cp-footprint-card,
.cp-stack-card,
.cp-table-card,
.cp-search-results-panel {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 18px 20px;
  box-shadow: var(--apple-elev-1);
  border: none;
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.content-card[data-interactive="1"]:hover,
.overview-card[data-interactive="1"]:hover,
.dashboard-card[data-interactive="1"]:hover,
.cp-card[data-interactive="1"]:hover,
.summary-card[data-interactive="1"]:hover,
.proof-card[data-interactive="1"]:hover,
.app-card[data-interactive="1"]:hover,
.hub-card[data-interactive="1"]:hover,
.health-card[data-interactive="1"]:hover,
.action-card[data-interactive="1"]:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}

/* Universal chip / pill — proof-chip (39×), cp-chip (37×), status-chip (29×),
   nas-chip (15×), pack-pill (8×), pain-chip (6×), preview-chip (4×),
   nav-pill (81× — but excluded; nav pills are sidebar-handled), summary-chip (×),
   telemetry-chip (×), trust-pill (×), status-pill (×), intent-pill (×), metric-pill (×),
   cpoh-tile (×), cp-outcome-pill (×), backend-intent-pill (×). */
.proof-chip,
.cp-chip,
.status-chip,
.nas-chip,
.pack-pill,
.pain-chip,
.preview-chip,
.summary-chip,
.telemetry-chip,
.trust-pill,
.status-pill,
.intent-pill,
.metric-pill,
.cpoh-tile,
.cp-outcome-pill,
.backend-intent-pill,
.admin-telemetry-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.005em;
  background: var(--surface-bg-subtle);
  color: var(--admin-content-text);
  border: 1px solid var(--admin-content-border);
  transition: background var(--dur-fast) var(--ease-apple), color var(--dur-fast) var(--ease-apple);
}
.proof-chip[data-tone="primary"],
.cp-chip[data-tone="primary"],
.status-chip[data-tone="primary"],
.status-pill[data-tone="primary"] {
  background: var(--school-primary-light);
  color: var(--school-primary);
  border-color: transparent;
}
.proof-chip[data-tone="success"],
.cp-chip[data-tone="success"],
.status-chip[data-tone="success"],
.status-pill[data-tone="success"] {
  background: color-mix(in oklab, var(--ds-success) 14%, transparent);
  color: var(--ds-success);
  border-color: transparent;
}
.proof-chip[data-tone="warning"],
.cp-chip[data-tone="warning"],
.status-chip[data-tone="warning"],
.status-pill[data-tone="warning"] {
  background: color-mix(in oklab, var(--ds-warning) 14%, transparent);
  color: var(--ds-warning);
  border-color: transparent;
}
.proof-chip[data-tone="danger"],
.cp-chip[data-tone="danger"],
.status-chip[data-tone="danger"],
.status-pill[data-tone="danger"] {
  background: color-mix(in oklab, var(--ds-danger) 14%, transparent);
  color: var(--ds-danger);
  border-color: transparent;
}

/* Universal stat tile — tdm-stat (16×), hero-stat (12×), admin-stat (7×),
   security-stat (6×), wcx-metric (4×), rmc-wcx-metric (4×), cp-panel-stat,
   global-stat, child-metric, etc. */
.tdm-stat,
.hero-stat,
.admin-stat,
.security-stat,
.wcx-metric,
.rmc-wcx-metric,
.proof-metric,
.product-metric,
.acx-metric,
.rmc-acx-metric,
.global-stat,
.child-metric,
.de-metric,
.v2-metric,
.cp-stack-metric,
.mkt-global-stat {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 16px 18px;
  box-shadow: var(--apple-elev-1);
  border: none;
}
.tdm-stat .stat-value,
.hero-stat .stat-value,
.admin-stat .stat-value,
.security-stat .stat-value,
.tdm-stat strong,
.hero-stat strong,
.admin-stat strong,
.security-stat strong {
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: var(--tracking-display);
  font-variant-numeric: tabular-nums;
  display: block;
  line-height: 1.1;
  color: var(--admin-content-text);
}

/* Universal row layouts — list-row (18×), md-row (17×), stack-row (10×),
   action-row (6×), cp-action-row (5×), meta-row (5×). */
.list-row,
.md-row,
.stack-row,
.action-row,
.cp-action-row,
.meta-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border-radius: 8px;
  transition: background var(--dur-fast) var(--ease-apple);
}
.list-row:hover,
.md-row:hover,
.stack-row:hover { background: color-mix(in oklab, var(--school-primary) 4%, transparent); }
.list-row + .list-row,
.md-row + .md-row,
.stack-row + .stack-row { border-top: 1px solid var(--admin-content-border); }

/* Tile / weather-widget / glance — visible bg, restrained shadow */
.weather-widget,
.badge-tile {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 14px 16px;
  box-shadow: var(--apple-elev-1);
  border: none;
}

/* Filter row (page-family-filter-row + plain card.bg-light variants) — refined chrome */
.page-family-filter-row,
.card.card-body.bg-light {
  background: var(--surface-bg-subtle) !important;
  border: none !important;
  border-radius: var(--token-radius-md);
  padding: 12px 14px !important;
  margin-bottom: 14px;
  box-shadow: 0 0 0 1px var(--admin-content-border);
}

/* Table extensions — table-zebra, table-sticky-head (custom Bootstrap extensions) */
.table-zebra tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--admin-content-text) 2%, transparent);
}
.table-sticky-head thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-bg-subtle);
  box-shadow: 0 1px 0 var(--admin-content-border);
}

/* Step indicator (used in evals/grade_import wizard) — fixes the broken bare classes.
   Uses CSS counters so numbering works whether or not the template provides data-step. */
.step-indicator {
  display: flex;
  align-items: flex-start;
  gap: 0;
  margin: 12px 0 28px;
  position: relative;
  counter-reset: step;
}
.step-indicator .step {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  position: relative;
  counter-increment: step;
  padding: 0 6px;
}
.step-indicator .step::before {
  content: counter(step);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--admin-content-bg);
  border: 1px solid var(--admin-content-border);
  color: var(--admin-content-text-muted);
  font-weight: 600;
  font-size: 0.88rem;
  margin-bottom: 8px;
  font-variant-numeric: tabular-nums;
  position: relative;
  z-index: 1;
  transition:
    background var(--dur-base) var(--ease-apple),
    color var(--dur-base) var(--ease-apple),
    border-color var(--dur-base) var(--ease-apple),
    box-shadow var(--dur-base) var(--ease-apple-spring);
}
.step-indicator .step[data-step]::before { content: attr(data-step); }
.step-indicator .step.is-active::before,
.step-indicator .step.active::before {
  background: var(--school-primary);
  color: #fff;
  border-color: var(--school-primary);
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--school-primary) 18%, transparent);
}
.step-indicator .step.is-complete::before,
.step-indicator .step.completed::before {
  background: var(--school-accent);
  color: #fff;
  border-color: var(--school-accent);
  content: '✓';
}
.step-indicator .step + .step::after {
  content: '';
  position: absolute;
  top: 16px;
  right: 50%;
  width: 100%;
  height: 1px;
  background: var(--admin-content-border);
  z-index: 0;
}
.step-indicator .step.is-complete + .step::after,
.step-indicator .step.completed + .step::after {
  background: var(--school-accent);
}
/* Step labels — Apple typography */
.step-indicator .step h6,
.step-indicator .step .step-title {
  font-size: 0.85rem;
  font-weight: 600;
  margin: 0 0 2px;
  letter-spacing: var(--tracking-body);
  color: var(--admin-content-text);
}
.step-indicator .step.active h6,
.step-indicator .step.is-active h6,
.step-indicator .step.active .step-title,
.step-indicator .step.is-active .step-title {
  color: var(--school-primary);
}
.step-indicator .step small,
.step-indicator .step .step-sub {
  font-size: 0.75rem;
  color: var(--admin-content-text-muted);
}

/* Dropzone (cdn-loaded library used in evals/grade_import_upload_v2.html) — Apple-tier polish */
.dropzone {
  background: var(--admin-content-bg) !important;
  border: 2px dashed var(--admin-content-border) !important;
  border-radius: var(--token-radius-md) !important;
  min-height: 200px !important;
  padding: 32px !important;
  transition: border-color var(--dur-base) var(--ease-apple), background var(--dur-base) var(--ease-apple);
}
.dropzone.dz-drag-hover {
  border-color: var(--school-primary) !important;
  background: color-mix(in oklab, var(--school-primary) 4%, var(--admin-content-bg)) !important;
}
.dropzone .dz-message {
  color: var(--admin-content-text-muted) !important;
  font-size: 0.95rem !important;
  letter-spacing: var(--tracking-body);
}
.dropzone .dz-preview .dz-image {
  border-radius: var(--token-radius-sm) !important;
}
.dropzone .dz-preview {
  margin: 8px !important;
}

/* Drawers — Apple-class quick-profile drawer + cp-context-drawer */
.rmc-acx-drawer,
.cp-context-drawer {
  background: var(--admin-content-bg);
  box-shadow: var(--apple-elev-modal);
  border: none;
}
.rmc-acx-drawer__handle {
  width: 36px;
  height: 4px;
  background: var(--admin-content-border);
  border-radius: 2px;
  margin: 8px auto;
}
.rmc-acx-drawer__header,
.cp-context-drawer .offcanvas-header {
  border-bottom: 1px solid var(--admin-content-border);
  padding: 16px 20px;
}

/* "Apple-class" / "World-class" / "RMC-OS" surface — three parallel namespaces;
   bind to one shared surface to remove duplicate styling (visual unification). */
.rmc-wcx-surface,
.rmc-acx-surface,
.world-class-surface,
.apple-class-surface,
.rmc-os-surface,
[data-world-class-trust-page="1"] .rmc-wcx-surface,
[data-apple-class-trust-page="1"] .rmc-wcx-surface {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-1);
  border: none;
}

/* Three-namespace consolidation: matching subcomponents.
   Components (page hero, summary strip, status strip, glass panel, metric card,
   product moment, risk blocker, status pill, page header) all share styling. */
.world-class-page-hero,
.apple-class-page-hero,
.rmc-os-page-header {
  padding: 28px 32px;
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-1);
  margin-bottom: 24px;
}
.world-class-summary-strip,
.apple-class-summary-strip,
.rmc-os-status-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  padding: 14px 18px;
  background: var(--surface-bg-subtle);
  border-radius: var(--token-radius-md);
  border: 1px solid var(--admin-content-border);
  font-size: 0.9rem;
  letter-spacing: var(--tracking-body);
}
.apple-class-glass-panel,
.world-class-glass-panel {
  background: var(--apple-material-bg);
  -webkit-backdrop-filter: var(--apple-material);
          backdrop-filter: var(--apple-material);
  border: 1px solid var(--apple-material-border);
  border-radius: var(--token-radius-lg);
  box-shadow: var(--apple-elev-2);
  padding: 20px;
}
.apple-class-metric-card,
.world-class-metric-card,
.world-class-product-moment-card,
.world-class-risk-blocker-card {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  box-shadow: var(--apple-elev-1);
  padding: 18px 20px;
  border: none;
  transition: box-shadow var(--dur-base) var(--ease-apple), transform var(--dur-base) var(--ease-apple);
}
.world-class-product-moment-card:hover,
.world-class-risk-blocker-card:hover,
.apple-class-metric-card[data-interactive="1"]:hover {
  box-shadow: var(--apple-elev-3);
  transform: translateY(-1px);
}
.apple-class-status-pill,
.world-class-status-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.78rem;
  font-weight: 500;
  background: var(--surface-bg-subtle);
  color: var(--admin-content-text);
  border: 1px solid var(--admin-content-border);
}
.apple-class-data-quality-meter {
  background: var(--admin-content-bg);
  border-radius: var(--token-radius-md);
  padding: 16px 18px;
  box-shadow: var(--apple-elev-1);
  border: none;
}

/* ============================================
   MOBILE / TOUCH POLISH
   Better touch targets, mobile-specific spacing, sidebar offcanvas refinement,
   table-on-mobile readability. Activates on narrow widths.
   ============================================ */

/* Touch target minimum 44px on coarse pointer (touch devices) */
@media (pointer: coarse) {
  .btn:not(.btn-link):not(.btn-sm):not(.btn-close),
  .nav-link,
  .dropdown-item,
  .form-check-input,
  a.list-group-item-action,
  .pagination .page-link {
    min-height: 44px;
  }
  .form-control,
  .form-select { min-height: 44px; }
  .btn-sm { min-height: 36px; }
  /* Increase tap area on icon-only buttons via padding */
  button[aria-label]:not(.btn-close),
  .btn[aria-label]:not(.btn-close):not(.btn-sm) {
    padding: 0.55rem 0.75rem;
  }
}

/* Mobile spacing — content padding reduced, gap tightened */
@media (max-width: 640px) {
  .preview-section,
  .card-x,
  .content-card,
  .cp-panel,
  .cp-card,
  .proof-panel,
  .dashboard-card,
  .summary-card { padding: 14px 16px; border-radius: var(--token-radius-md); }
  .auth-card,
  .login-card,
  .signup-card,
  .admin-login-card { padding: 24px 20px; border-radius: var(--token-radius-md); }
  .page-header { padding-bottom: 12px; margin-bottom: 16px !important; }
  main.main { padding: 16px; }
  .modal-dialog { margin: 10px; }
  .modal-content { border-radius: var(--token-radius-lg); }
}

/* Mobile tables — wrap in scrolling container; cells more breathable */
@media (max-width: 700px) {
  .table-responsive {
    border-radius: var(--token-radius-md);
    background: var(--admin-content-bg);
    box-shadow: var(--apple-elev-1);
  }
  .table thead th { font-size: 0.7rem; padding: 8px 10px; }
  .table tbody td { font-size: 0.88rem; padding: 10px; }
}

/* Mobile-specific KPI grid — 2 col instead of 4, refined value sizing */
@media (max-width: 640px) {
  .kpi { padding: 14px; }
  .kpi .value { font-size: 1.4rem; }
}

/* Mobile sidebar (offcanvas) — full-width drawer with refined header */
@media (max-width: 991px) {
  .offcanvas-start, .offcanvas-end {
    max-width: 320px;
    width: 88vw;
  }
}

/* Mobile auth — full-width card on small screens */
@media (max-width: 480px) {
  .auth-shell, .login-page, .signup-page, .auth-landing { padding: 16px; }
  .auth-card, .login-card, .signup-card, .admin-login-card { box-shadow: none; padding: 22px 18px; }
}

/* Mobile error pages — tighter */
@media (max-width: 640px) {
  .error-page { padding: 20px; }
  .error-code-display { font-size: clamp(3.5rem, 18vw, 5rem); }
}

/* ============================================
   ACCESSIBILITY DEEP PASS
   Focus order helpers, skip links, reduced motion enforcement, contrast helpers.
   ============================================ */

/* Skip-link visible on focus — already exists, but reinforce stacking + text */
.skip-link:focus,
.mkt-skip-link:focus,
[class*="skip-link"]:focus {
  z-index: 10000 !important;
  clip: auto !important;
  width: auto !important;
  height: auto !important;
  margin: 0 !important;
  position: fixed !important;
  top: 12px !important;
  left: 12px !important;
}

/* Reduced motion — kill all decorative motion */
@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;
  }
  .skeleton, .placeholder { animation: none !important; }
  .htmx-progress-bar, [data-htmx-progress] { animation: none !important; }
}

/* High contrast mode (Windows) — preserve outlines + button borders */
@media (forced-colors: active) {
  .btn { border: 1px solid ButtonBorder !important; }
  .card-x, .cp-panel, .content-card, .dashboard-card { border: 1px solid CanvasText; }
  .badge { border: 1px solid currentColor; }
}

/* Visible focus on interactive cards (keyboard nav into card stack) */
.card[tabindex],
.card-x[tabindex],
.content-card[tabindex],
.cp-panel[tabindex],
[data-interactive="1"][tabindex] {
  cursor: pointer;
}
.card[tabindex]:focus-visible,
.card-x[tabindex]:focus-visible,
.content-card[tabindex]:focus-visible,
.cp-panel[tabindex]:focus-visible,
[data-interactive="1"][tabindex]:focus-visible {
  outline: none;
  box-shadow: var(--apple-focus-ring);
}

/* Aria-busy: visually indicate during async loads */
[aria-busy="true"] {
  pointer-events: none;
  opacity: 0.7;
  transition: opacity var(--dur-base) var(--ease-apple);
}

/* Visually-hidden — accessible-only text. Use Bootstrap's .visually-hidden too;
   this is a defensive copy. */
.visually-hidden,
.sr-only {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Required-field marker via aria-required */
[aria-required="true"] + .form-label::after,
.form-label[data-required]::after {
  content: '*';
  color: var(--ds-danger);
  margin-left: 4px;
  font-weight: 700;
}

/* Disabled fields — clear visual signal */
:disabled,
[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.5;
}


/* ============================================================
   v2.4 Apple-tier polish layer (2026-05-12)
   Typography features, body vignette, refined focus ring,
   reduced-transparency honor, scroll-aware header, density modes.
   ============================================================ */

/* Typography — opt into Inter's OpenType features + optical sizing where the
   variable font ships them. Tabular + lining numerics by default so columns of
   numbers align across the whole platform without per-component overrides. */
html, body {
  font-feature-settings: "cv11" 1, "ss01" 1, "ss03" 1, "cv05" 1;
  font-variant-numeric: lining-nums tabular-nums;
  font-optical-sizing: auto;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Size-aware letter-spacing — tighter as type gets bigger (Apple HIG). */
h1, .h1, .display, .display-1, .display-2, .display-3,
.page-h1, .rmc-section-header__title {
  letter-spacing: -0.018em;
}
h2, .h2 { letter-spacing: -0.014em; }
h3, .h3 { letter-spacing: -0.01em; }
h4, .h4 { letter-spacing: -0.006em; }
.small, small, .text-tertiary, .text-muted, kbd, code { letter-spacing: 0.003em; }

/* Numeric-heavy cells: explicitly tabular + lining. Belt-and-suspenders alongside
   the global html/body rule above for legacy components that re-declare font. */
.num, td.num, th.num, .currency, .stat-value, .rmc-kpi-trend__value,
.rmc-data-table .num, .gradebook-table .num,
.toast-notification .num, [data-rmc-tabular-nums] {
  font-variant-numeric: lining-nums tabular-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}

/* ===== Body vignette — subtle radial fade that says "premium" without showing
   off. Applied via ::before so it's behind everything but doesn't intercept
   pointer events. Disabled on print + reduced-transparency. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background:
    radial-gradient(
      ellipse 120% 80% at 50% 0%,
      color-mix(in oklab, var(--school-primary, #4f46e5) 4%, transparent),
      transparent 65%
    ),
    radial-gradient(
      ellipse 80% 60% at 100% 100%,
      color-mix(in oklab, var(--school-accent, #10b981) 3%, transparent),
      transparent 60%
    );
  opacity: 0.8;
}
@media print {
  body::before { display: none; }
}

/* ===== Refined focus ring (Apple HIG): 3px solid accent + 2px offset +
   element-shape-matching radius (uses currentColor as fallback). Replaces the
   default browser dotted line + the older Bootstrap blue glow. */
button:focus-visible,
[role="button"]:focus-visible,
a:focus-visible,
.btn:focus-visible,
.form-control:focus-visible,
.form-select:focus-visible,
.form-check-input:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--focus-ring-color, var(--school-primary));
  outline-offset: 2px;
  box-shadow: 0 0 0 5px color-mix(in oklab, var(--school-primary, #4f46e5) 18%, transparent);
}
/* Keyboard-only — don't show ring for mouse clicks */
:focus:not(:focus-visible) { outline: none; box-shadow: none; }

/* ===== Honor prefers-reduced-transparency (Vision OS / accessibility setting).
   When the user opts out of transparency we drop backdrop-filter and replace
   semi-transparent surfaces with solid ones. */
@media (prefers-reduced-transparency: reduce) {
  *, *::before, *::after {
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
  }
  :root {
    --surface-popover: var(--surface-elevated);
    --material-blur: none;
    --material-blur-strong: none;
  }
  .rmc-cmdk__backdrop { background: color-mix(in oklab, var(--surface-bg) 95%, transparent); }
}

/* ===== Scroll-aware header — when document is scrolled the topbar shrinks +
   gains a frosted backdrop. Triggered by JS adding .is-scrolled on <html>. */
html.is-scrolled .topbar.topbar-sticky,
html.is-scrolled .cp-navbar,
html.is-scrolled .admin-cp-navbar-unified {
  -webkit-backdrop-filter: var(--material-blur-strong, saturate(180%) blur(28px));
  backdrop-filter: var(--material-blur-strong, saturate(180%) blur(28px));
  background: color-mix(in oklab, var(--header-brand-bg) 92%, transparent);
  box-shadow: 0 1px 0 var(--hairline);
  transition: backdrop-filter var(--motion-fast), background var(--motion-fast),
              box-shadow var(--motion-fast);
}
html.is-scrolled .topbar.topbar-sticky #portalHeader > .container-fluid,
html.is-scrolled .cp-navbar > .container-fluid,
html.is-scrolled .admin-cp-navbar-unified > .container-fluid {
  padding-top: 0.35rem;
  padding-bottom: 0.35rem;
  transition: padding var(--motion-fast);
}

/* ===== Density modes — user-pickable platform-wide rhythm. Defaults to
   "comfortable"; tenants can ship "compact" for dense workflows (Finance ops,
   data-entry teachers) or "spacious" (read-heavy parents). Set via
   <html data-rmc-density="compact|comfortable|spacious">. */
:root {
  --density-row-padding-y: 0.65rem;
  --density-card-padding: clamp(0.875rem, 1vw + 0.5rem, 1.25rem);
  --density-card-gap: 1rem;
  --density-form-row-gap: 0.85rem;
}
html[data-rmc-density="compact"] {
  --density-row-padding-y: 0.35rem;
  --density-card-padding: 0.75rem;
  --density-card-gap: 0.65rem;
  --density-form-row-gap: 0.55rem;
}
html[data-rmc-density="spacious"] {
  --density-row-padding-y: 0.95rem;
  --density-card-padding: 1.5rem;
  --density-card-gap: 1.5rem;
  --density-form-row-gap: 1.25rem;
}
/* Adopt the density tokens on the components that benefit most. */
html[data-rmc-density="compact"] .rmc-data-table thead th,
html[data-rmc-density="compact"] .rmc-data-table tbody td,
html[data-rmc-density="compact"] .gradebook-table thead th,
html[data-rmc-density="compact"] .gradebook-table tbody td {
  padding-top: var(--density-row-padding-y);
  padding-bottom: var(--density-row-padding-y);
}
html[data-rmc-density="compact"] .card .card-body { padding: var(--density-card-padding); }
html[data-rmc-density="spacious"] .rmc-data-table thead th,
html[data-rmc-density="spacious"] .rmc-data-table tbody td {
  padding-top: var(--density-row-padding-y);
  padding-bottom: var(--density-row-padding-y);
}

/* ===== Reusable segmented control. Generalized from .rmc-theme-toggle-row so
   any group of mutually-exclusive options can adopt the Apple HIG pill grammar. */
.rmc-segmented {
  display: inline-flex;
  padding: 0.15rem;
  gap: 0.1rem;
  background: var(--surface-overlay);
  border-radius: var(--radius-pill, 999px);
  border: var(--border-width-hairline, 0.5px) solid var(--hairline);
}
.rmc-segmented__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.35rem 0.85rem;
  border-radius: var(--radius-pill);
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-secondary);
  border: 0;
  background: transparent;
  text-decoration: none;
  transition: background var(--motion-fast), color var(--motion-fast), transform var(--motion-fast);
  min-height: 32px;
  cursor: pointer;
}
.rmc-segmented__btn:hover {
  background: var(--surface-overlay-strong, var(--surface-overlay));
  color: var(--text-primary);
}
.rmc-segmented__btn.is-active,
.rmc-segmented__btn.active,
.rmc-segmented__btn[aria-pressed="true"],
.rmc-segmented__btn[aria-selected="true"] {
  background: var(--surface-elevated);
  color: var(--text-primary);
  box-shadow: var(--elev-1);
}
.rmc-segmented__btn:active { transform: scale(0.97); }

/* v2.63 Wave A1: scrollable variant for tab bars that may overflow narrow
   viewports (e.g. Feature control's 9+ category tabs). Pill grammar
   unchanged; container becomes a horizontal scroller with hidden bars and
   inertial momentum on touch. Prevents the tab bar from wrapping into 2-3
   rows on mobile, which would re-introduce the height problem the tabs
   were supposed to fix. */
.rmc-segmented--scrollable {
  display: flex;
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  max-width: 100%;
}
.rmc-segmented--scrollable::-webkit-scrollbar { height: 4px; }
.rmc-segmented--scrollable::-webkit-scrollbar-thumb {
  background: var(--hairline);
  border-radius: var(--radius-pill, 999px);
}
.rmc-segmented--scrollable .rmc-segmented__btn { flex: 0 0 auto; }

/* ===== v2 carried-forward (2026-05-12): adaptive logo swap. Apply
   `.rmc-logo-adaptive` to any element that uses the tenant's logo as a
   background-image (header logo block, login mark, email signature preview,
   etc.). The element picks up --site-logo-url by default; when
   [data-resolved-theme="dark"] is on <html> and a dark variant is configured,
   the cascade swaps to --site-logo-dark-url. Both vars are set on <html> by
   theme-preference-bootstrap.js, sourced from <meta> tags written by the
   siteconfig context processor. */
.rmc-logo-adaptive {
  background-image: var(--site-logo-url, none);
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  transition: background-image var(--motion-fast, 150ms) ease;
}
html[data-resolved-theme="dark"] .rmc-logo-adaptive {
  background-image: var(--site-logo-dark-url, var(--site-logo-url, none));
}
/* For <img class="rmc-logo-adaptive-img" data-logo-light-src="…"
   data-logo-dark-src="…">, rmc-shell-polish.js swaps the src attribute in
   response to data-resolved-theme changes so semantic alt-text + sizing intact. */

/* ===== v2.6 (2026-05-12) · 10X v4.02.x (2026-06-06): Top-of-page progress bar.
   Apple-style bar for HTMX swaps, cross-doc navigation, and arbitrary async
   work. Mounted once to <body> by rmc-page-progress.js; fill driven by `--p`
   custom prop; `data-state` ∈ idle|loading|done|error, `data-error` flips the
   palette to the danger token. 10X adds: a glowing comet head at the leading
   edge, a layered indeterminate sweep, a visible error flash, a success bloom,
   and a configurable height (`--rmc-page-progress-height`). Honors
   prefers-reduced-motion (no shimmer/comet) + prefers-reduced-transparency. */
.rmc-page-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--rmc-page-progress-height, 3px);
  z-index: 9999;
  pointer-events: none;
  background: transparent;
  --p: 0%;
  /* Brand-aware palette, resolved once so every layer stays in sync. */
  --rmc-pp-color: var(--school-primary, #4f46e5);
  --rmc-pp-color-2: color-mix(in oklab, var(--school-primary, #4f46e5) 62%, var(--school-accent, #10b981));
}

body.control-plane-shell .rmc-page-progress,
body.admin-manager-shell .rmc-page-progress {
  /* v4.02.x: pin to the true viewport top (like the marketing page) rather than
     below the header — the owner wants the load line at the very top, not mid-page.
     Keep the elevated z-index so it rides above the pinned cockpit header. */
  top: 0;
  z-index: 10050;
}
/* When a danger flash is requested the whole bar swaps to the error palette. */
.rmc-page-progress[data-error] {
  --rmc-pp-color: var(--danger, #ef4444);
  --rmc-pp-color-2: color-mix(in oklab, var(--danger, #ef4444) 78%, #000);
}
.rmc-page-progress__fill {
  height: 100%;
  width: var(--p);
  background: linear-gradient(90deg, var(--rmc-pp-color), var(--rmc-pp-color-2));
  box-shadow: 0 0 10px color-mix(in oklab, var(--rmc-pp-color) 60%, transparent),
              0 0 3px color-mix(in oklab, var(--rmc-pp-color) 82%, transparent);
  transition: width var(--motion-default, 220ms) var(--ease-standard, ease-out),
              opacity var(--motion-default, 220ms) ease;
  position: relative;
  overflow: visible; /* let the comet head bleed past the fill edge */
  border-top-right-radius: 999px;
  border-bottom-right-radius: 999px;
}
/* Comet head — a bright, blurred dot riding the leading edge of the fill. */
.rmc-page-progress[data-state="loading"] .rmc-page-progress__fill::before {
  content: "";
  position: absolute;
  top: 50%;
  right: 0;
  width: calc(var(--rmc-page-progress-height, 3px) * 6);
  height: calc(var(--rmc-page-progress-height, 3px) * 6);
  transform: translateY(-50%) translateX(40%);
  border-radius: 50%;
  background: radial-gradient(
    circle,
    color-mix(in oklab, var(--rmc-pp-color) 90%, #fff) 0%,
    color-mix(in oklab, var(--rmc-pp-color) 70%, transparent) 45%,
    transparent 72%
  );
  opacity: 0.9;
  pointer-events: none;
}
/* Layered moving sweep for the indeterminate climb. */
.rmc-page-progress[data-state="loading"] .rmc-page-progress__fill::after {
  content: "";
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  background: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.55) 50%,
    transparent 100%
  );
  animation: rmc-page-progress-shimmer 1.25s linear infinite;
}
@keyframes rmc-page-progress-shimmer {
  from { transform: translateX(-100%); }
  to { transform: translateX(100%); }
}
/* Completion: a quick success bloom (brightness + glow) before the fade. */
.rmc-page-progress[data-state="done"] .rmc-page-progress__fill {
  transition: width var(--motion-fast, 180ms) var(--ease-standard, ease-out),
    opacity var(--motion-default, 220ms) ease 90ms,
    filter 160ms ease;
  filter: brightness(1.12) saturate(1.1);
  opacity: 0;
}
/* Error flash: brief pulse on the danger palette, then fade. */
.rmc-page-progress[data-error] .rmc-page-progress__fill {
  animation: rmc-page-progress-error 560ms ease both;
}
@keyframes rmc-page-progress-error {
  0% { opacity: 1; transform: translateX(0); }
  18% { transform: translateX(-2px); }
  36% { transform: translateX(2px); }
  54% { transform: translateX(-1px); }
  72% { transform: translateX(0); opacity: 1; }
  100% { opacity: 0; }
}
.rmc-page-progress[data-state="idle"] .rmc-page-progress__fill {
  opacity: 0;
  filter: none;
  transition: opacity 120ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .rmc-page-progress[data-state="loading"] .rmc-page-progress__fill::after { animation: none; }
  .rmc-page-progress[data-state="loading"] .rmc-page-progress__fill::before { display: none; }
  .rmc-page-progress[data-error] .rmc-page-progress__fill { animation: none; }
  .rmc-page-progress[data-state="done"] .rmc-page-progress__fill { filter: none; }
}
/* Honor prefers-reduced-transparency by dropping the glow + comet. */
@media (prefers-reduced-transparency: reduce) {
  .rmc-page-progress__fill { box-shadow: none; }
  .rmc-page-progress .rmc-page-progress__fill::before { display: none; }
}

/* ===== v2.6 (2026-05-12): Safe-area insets — iOS notch / Android nav bar.
   Paired with `viewport-fit=cover` on the viewport meta. Padding utilities for
   surfaces that touch screen edges (sticky topbar, bottom sheets, FABs). */
:root {
  --safe-area-inset-top: env(safe-area-inset-top, 0px);
  --safe-area-inset-right: env(safe-area-inset-right, 0px);
  --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);
  --safe-area-inset-left: env(safe-area-inset-left, 0px);
}
.rmc-safe-pt { padding-top: max(var(--safe-area-inset-top), 0.5rem); }
.rmc-safe-pb { padding-bottom: max(var(--safe-area-inset-bottom), 0.5rem); }
.rmc-safe-px { padding-left: max(var(--safe-area-inset-left), 0.5rem); padding-right: max(var(--safe-area-inset-right), 0.5rem); }
.rmc-safe-mb { margin-bottom: var(--safe-area-inset-bottom); }
/* Sticky topbars consume notch padding so content doesn't fall under the bar. */
.topbar.topbar-sticky,
.cp-navbar,
.admin-cp-navbar-unified,
.mkt-header {
  padding-top: max(var(--safe-area-inset-top), 0px);
}

/* ===== v2.6 (2026-05-12): Bottom sheet primitive.
   Mobile-first dialog that slides up from the bottom edge. Drag-handle on top,
   swipe-to-dismiss via rmc-bottom-sheet.js. Honors safe-area on Android nav
   bars + iOS home indicator. Falls back to centered modal on >=md screens.

   Markup:
     <dialog class="rmc-sheet" id="example">
       <div class="rmc-sheet__handle" aria-hidden="true"></div>
       <header class="rmc-sheet__header">
         <h3 class="rmc-sheet__title">Title</h3>
         <button class="rmc-sheet__close" aria-label="Close" data-rmc-sheet-close>&times;</button>
       </header>
       <div class="rmc-sheet__body">…</div>
     </dialog>

   Open with: document.getElementById("example").showModal(); */
.rmc-sheet[open] {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  max-width: 100%;
  max-height: 90vh;
  margin: 0;
  padding: 0;
  border: 0;
  border-top-left-radius: 1.25rem;
  border-top-right-radius: 1.25rem;
  background: var(--surface-elevated, #ffffff);
  color: var(--text-primary, inherit);
  box-shadow: 0 -20px 60px -20px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding-bottom: max(var(--safe-area-inset-bottom), 0.5rem);
  animation: rmc-sheet-up 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.rmc-sheet::backdrop {
  background: rgba(0, 0, 0, 0.4);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  animation: rmc-sheet-fade 200ms ease;
}
@keyframes rmc-sheet-up {
  from { transform: translateY(100%); }
  to { transform: translateY(0); }
}
@keyframes rmc-sheet-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}
.rmc-sheet__handle {
  width: 36px;
  height: 4px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--text-secondary, #6b7280) 30%, transparent);
  margin: 0.5rem auto 0.25rem;
  cursor: grab;
  flex: 0 0 auto;
}
.rmc-sheet__handle:active { cursor: grabbing; }
.rmc-sheet__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 1rem 0.75rem;
  border-bottom: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.08));
  flex: 0 0 auto;
}
.rmc-sheet__title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-primary);
  letter-spacing: -0.005em;
}
.rmc-sheet__close {
  appearance: none;
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  font-size: 1.5rem;
  line-height: 1;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  cursor: pointer;
  transition: background var(--motion-fast, 150ms) ease;
}
.rmc-sheet__close:hover { background: var(--surface-overlay-strong, rgba(0, 0, 0, 0.06)); color: var(--text-primary); }
.rmc-sheet__body {
  padding: 0.75rem 1rem 1rem;
  overflow-y: auto;
  flex: 1 1 auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
.rmc-sheet[data-dragging="1"] { transition: transform 0ms !important; animation: none; }
/* On wider screens, slide up becomes a centered modal. */
@media (min-width: 768px) {
  .rmc-sheet[open] {
    inset: 50% auto auto 50%;
    transform: translate(-50%, -50%);
    border-radius: 1rem;
    width: min(560px, calc(100% - 2rem));
    max-height: 80vh;
    animation: rmc-sheet-pop 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  @keyframes rmc-sheet-pop {
    from { opacity: 0; transform: translate(-50%, -45%) scale(0.96); }
    to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  }
}
@media (prefers-reduced-motion: reduce) {
  .rmc-sheet[open] { animation: none !important; }
  .rmc-sheet::backdrop { animation: none !important; }
}

/* ===== 10X v4.02.x (2026-06-06): Sheet / modal primitive — premium upgrade.
   Fully additive over the v2.6 base above. Adds: refined material (layered
   elevation + hairline ring + saturated backdrop), desktop size variants
   (sm/md/lg/xl/full), a structured header (eyebrow + subtitle + leading icon),
   a sticky action footer, a right-edge side-drawer variant, mobile snap
   detents, and body scroll-lock. No markup change is required for existing
   consumers — they inherit the richer base automatically. JS lives in
   rmc-bottom-sheet.js (focus wiring, scroll-lock, snap, public RMCSheet API). */

/* Richer material — overrides the base box-shadow with a layered elevation and
   adds a hairline ring + saturated backdrop. Same specificity as `.rmc-sheet
   [open]`, later in source order, so it wins cleanly. */
.rmc-sheet[open] {
  box-shadow: var(--elev-3, 0 18px 48px rgba(15, 23, 42, 0.18)),
              0 -1px 0 var(--hairline, rgba(0, 0, 0, 0.06)) inset;
  background: var(--surface-popover, var(--surface-elevated, #ffffff));
  -webkit-backdrop-filter: var(--material-blur, saturate(180%) blur(20px));
  backdrop-filter: var(--material-blur, saturate(180%) blur(20px));
}
.rmc-sheet::backdrop {
  background: color-mix(in oklab, var(--cp-chrome-bg-deep, #04060f) 52%, transparent);
  -webkit-backdrop-filter: saturate(140%) blur(6px);
  backdrop-filter: saturate(140%) blur(6px);
}

/* Drag handle: bigger touch affordance + brand-tinted on grab. */
.rmc-sheet__handle {
  width: 40px;
  height: 5px;
  transition: background var(--motion-fast, 150ms) ease, width var(--motion-fast, 150ms) ease;
}
.rmc-sheet__handle:hover,
.rmc-sheet[data-dragging="1"] .rmc-sheet__handle {
  background: color-mix(in oklab, var(--school-primary, #4f46e5) 55%, transparent);
  width: 52px;
}

/* Structured header grammar: leading icon + (eyebrow / title / subtitle) stack. */
.rmc-sheet__header { align-items: flex-start; padding-top: 0.75rem; }
.rmc-sheet__title-group { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; flex: 1 1 auto; }
.rmc-sheet__eyebrow {
  font-size: var(--type-size-12, 0.72rem);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--school-primary, #4f46e5);
  line-height: 1.1;
}
.rmc-sheet__subtitle {
  margin: 0;
  font-size: var(--type-size-13, 0.82rem);
  color: var(--text-secondary, #6b7280);
  line-height: 1.35;
}
.rmc-sheet__icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  margin-right: 0.25rem;
  border-radius: var(--radius-md, 12px);
  background: var(--surface-overlay, color-mix(in oklab, var(--school-primary, #4f46e5) 8%, transparent));
  color: var(--school-primary, #4f46e5);
  font-size: 1.15rem;
}
/* Bigger, squarer close target (44px touch min) with a calmer rest state. */
.rmc-sheet__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2.25rem;
  min-height: 2.25rem;
  font-size: 1.4rem;
  flex: 0 0 auto;
}
.rmc-sheet__close:focus-visible {
  outline: 2px solid var(--school-primary, #4f46e5);
  outline-offset: 2px;
}

/* Sticky action footer — pinned to the bottom of the sheet above the safe area. */
.rmc-sheet__footer {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.5rem;
  flex-wrap: wrap;
  padding: 0.75rem 1rem;
  padding-bottom: max(var(--safe-area-inset-bottom), 0.75rem);
  border-top: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.08));
  background: var(--surface-elevated, #ffffff);
  position: sticky;
  bottom: 0;
}
.rmc-sheet__footer--split { justify-content: space-between; }

/* Desktop size variants — width only changes on the centered-modal breakpoint. */
@media (min-width: 768px) {
  .rmc-sheet--sm[open]   { width: min(420px, calc(100% - 2rem)); }
  .rmc-sheet--md[open]   { width: min(560px, calc(100% - 2rem)); }
  .rmc-sheet--lg[open]   { width: min(720px, calc(100% - 2rem)); }
  .rmc-sheet--xl[open]   { width: min(920px, calc(100% - 2rem)); max-height: 86vh; }
  .rmc-sheet--full[open] {
    inset: 1.5rem;
    transform: none;
    width: auto;
    max-width: none;
    max-height: none;
    border-radius: var(--radius-xl, 22px);
    animation: rmc-sheet-pop 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }

  /* Right-edge side drawer (Linear / Things-style detail panel). */
  .rmc-sheet--side[open],
  .rmc-sheet--side-end[open] {
    inset: 0 0 0 auto;
    transform: none;
    width: min(480px, calc(100% - 3rem));
    max-width: none;
    max-height: none;
    height: 100%;
    border-radius: var(--radius-xl, 22px) 0 0 var(--radius-xl, 22px);
    animation: rmc-sheet-slide-in 300ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .rmc-sheet--side.rmc-sheet--lg[open],
  .rmc-sheet--side-end.rmc-sheet--lg[open] { width: min(640px, calc(100% - 3rem)); }
  @keyframes rmc-sheet-slide-in {
    from { opacity: 0; transform: translateX(100%); }
    to { opacity: 1; transform: translateX(0); }
  }
  .rmc-sheet--side .rmc-sheet__handle { display: none; }
}

/* Mobile snap detents — open at a partial height, drag up to expand to full.
   `--rmc-sheet-snap` controls the resting height; rmc-bottom-sheet.js toggles
   `data-expanded` on drag-up / handle-tap. */
@media (max-width: 767.98px) {
  .rmc-sheet--snap[open] {
    max-height: var(--rmc-sheet-snap, 58vh);
    transition: max-height 320ms cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .rmc-sheet--snap[open][data-expanded="1"] { max-height: 92vh; }
}

/* Body scroll-lock applied by rmc-bottom-sheet.js while any sheet is open. */
html.rmc-sheet-scroll-lock,
html.rmc-sheet-scroll-lock body { overflow: hidden; }

@media (prefers-reduced-motion: reduce) {
  .rmc-sheet--side[open],
  .rmc-sheet--side-end[open],
  .rmc-sheet--full[open] { animation: none !important; }
  .rmc-sheet--snap[open] { transition: none !important; }
}
@media (prefers-reduced-transparency: reduce) {
  .rmc-sheet[open] {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--surface-elevated, #ffffff);
  }
  .rmc-sheet::backdrop { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ===== v2.6 (2026-05-12): Keyboard cheat sheet — Linear-style `?` overlay.
   Renders inside .rmc-sheet (bottom-sheet on mobile, modal on >=md). The list
   is built by rmc-kbd-cheatsheet.js from the window.RMCShortcuts registry. */
.rmc-kbd-cheatsheet--platform {
  max-width: min(96vw, 72rem);
  width: 100%;
}

.rmc-kbd-cheatsheet__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
  gap: 1.25rem 1.5rem;
  align-items: start;
}

.rmc-kbd-cheatsheet__column {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 0;
}

.rmc-kbd-cheatsheet__body {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.rmc-kbd-cheatsheet__header {
  flex-wrap: wrap;
  gap: 0.75rem;
}

.rmc-kbd-cheatsheet__header-main {
  flex: 1 1 12rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.rmc-kbd-cheatsheet__header .rmc-sheet__title {
  font-size: 1.25rem;
  margin: 0;
}

.rmc-kbd-cheatsheet__filter {
  width: 100%;
  max-width: 20rem;
  padding: 0.4rem 0.65rem;
  font-size: 0.875rem;
  border-radius: 0.5rem;
  border: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.12));
  background: var(--surface-elevated, #fff);
  color: var(--text-primary);
}

.rmc-kbd-cheatsheet__row {
  flex-wrap: wrap;
}

.rmc-kbd-cheatsheet__footer {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  padding: 0.75rem 1.25rem 1rem;
  border-top: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.08));
  font-size: 0.875rem;
  color: var(--text-secondary);
}

.rmc-kbd-cheatsheet__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  cursor: pointer;
  user-select: none;
}

.rmc-kbd-cheatsheet__row--disabled {
  opacity: 0.55;
}

.rmc-kbd-cheatsheet__row--disabled .rmc-kbd {
  opacity: 0.7;
}

.rmc-kbd-cheatsheet__unavailable {
  flex: 1 1 100%;
  font-size: 0.72rem;
  color: var(--text-tertiary, var(--text-secondary));
  margin-top: 0.15rem;
}

.rmc-kbd-cheatsheet__pin {
  position: fixed;
  right: max(1rem, env(safe-area-inset-right, 0px));
  bottom: max(1rem, env(safe-area-inset-bottom, 0px));
  z-index: 1040;
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 999px;
  border: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.12));
  background: var(--surface-elevated, #fff);
  color: var(--text-primary);
  font-weight: 700;
  font-size: 1.1rem;
  box-shadow: var(--elev-2, 0 8px 24px rgba(0, 0, 0, 0.12));
  cursor: pointer;
}

.rmc-kbd-cheatsheet__pin:hover {
  background: var(--surface-canvas, #f5f5f7);
}

@media (max-width: 640px) {
  .rmc-kbd-cheatsheet__grid {
    grid-template-columns: 1fr;
  }
}
.rmc-kbd-cheatsheet__group {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.rmc-kbd-cheatsheet__group-title {
  margin: 0;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-tertiary, var(--text-secondary, #6b7280));
}
.rmc-kbd-cheatsheet__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.rmc-kbd-cheatsheet__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.5rem 0.65rem;
  border-radius: 0.5rem;
  background: var(--surface-canvas, #fbfbfd);
  border: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.06));
}
.rmc-kbd-cheatsheet__label {
  font-size: 0.93rem;
  color: var(--text-primary);
}
.rmc-kbd-cheatsheet__keys {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  flex-shrink: 0;
}
.rmc-kbd-cheatsheet__plus {
  font-size: 0.7rem;
  color: var(--text-tertiary, var(--text-secondary));
  letter-spacing: 0.02em;
  padding: 0 0.15rem;
}
.rmc-kbd {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.6rem;
  height: 1.55rem;
  padding: 0 0.35rem;
  font-family: var(--font-stack, "Inter"), -apple-system, "SF Pro Text", sans-serif;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-primary);
  background: var(--surface-elevated, #ffffff);
  border: var(--border-width-hairline, 0.5px) solid var(--hairline, rgba(0, 0, 0, 0.08));
  border-bottom-width: 1.5px;
  border-radius: 0.35rem;
  box-shadow: 0 1px 0 color-mix(in oklab, var(--hairline) 60%, transparent);
  font-variant-numeric: tabular-nums;
}

/* ===== v2 carried-forward (2026-05-12): View Transitions API.
   Chromium 126+ and Safari Tech Preview support cross-document view
   transitions natively when `@view-transition { navigation: auto }` is set.
   Other browsers just navigate instantly — graceful fallback by default.
   We honor prefers-reduced-motion and skip transitions for users who opt out.
   Named regions (topbar, main-content) glide through the transition so the
   shell feels continuous, the way native apps do. */
@view-transition {
  navigation: auto;
}
::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: 280ms;
  animation-timing-function: var(--motion-decel, cubic-bezier(0.2, 0.8, 0.2, 1));
}
::view-transition-old(root) { animation-name: rmc-vt-fade-out; }
::view-transition-new(root) { animation-name: rmc-vt-fade-in; }
@keyframes rmc-vt-fade-out {
  to { opacity: 0; transform: translateY(-4px); }
}
@keyframes rmc-vt-fade-in {
  from { opacity: 0; transform: translateY(4px); }
}
/* Persistent regions: name them so the browser cross-fades the new instance
   over the old instead of fading both out. One element per page may carry a
   given view-transition-name. */
.rmc-vt-topbar,
.topbar.topbar-sticky,
.cp-navbar,
.admin-cp-navbar-unified,
.mkt-header {
  view-transition-name: rmc-topbar;
}
.rmc-vt-main,
main#main-content {
  view-transition-name: rmc-main;
}
::view-transition-old(rmc-topbar),
::view-transition-new(rmc-topbar) {
  animation-duration: 150ms;
  animation-name: none;
  /* No motion — the topbar should appear continuous. Default opacity x-fade. */
}
::view-transition-old(rmc-main),
::view-transition-new(rmc-main) {
  animation-duration: 280ms;
  animation-timing-function: var(--motion-decel, cubic-bezier(0.2, 0.8, 0.2, 1));
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root),
  ::view-transition-old(rmc-topbar),
  ::view-transition-new(rmc-topbar),
  ::view-transition-old(rmc-main),
  ::view-transition-new(rmc-main) {
    animation-duration: 1ms !important;
    animation-name: none !important;
  }
}

/* ============================================================
 * Migration Cloud — mapping wizard polish (Phase U6 +)
 * ============================================================ */
.rmc-mapping__header { margin-bottom: var(--space-md, 12px); }

.rmc-mapping__table {
  --rmc-mapping-row-pad: var(--space-sm, 8px);
}

.rmc-mapping__row {
  cursor: grab;
  transition: background-color 160ms var(--motion-decel, cubic-bezier(0.2, 0.8, 0.2, 1)),
              transform 160ms var(--motion-decel, cubic-bezier(0.2, 0.8, 0.2, 1));
}
.rmc-mapping__row:hover {
  background-color: color-mix(in srgb, var(--primary, #6366f1) 4%, var(--surface-canvas, #fbfbfd));
}
.rmc-mapping__row--dragging {
  opacity: 0.55;
  cursor: grabbing;
}
.rmc-mapping__row--drop-target {
  outline: 2px dashed var(--primary, #6366f1);
  outline-offset: -2px;
  background-color: color-mix(in srgb, var(--primary, #6366f1) 8%, transparent);
}
.rmc-mapping__row--accepted {
  background-color: color-mix(in srgb, var(--accent-emerald, #10b981) 10%, transparent);
}
.rmc-mapping__row--overridden {
  background-color: color-mix(in srgb, var(--accent-amber, #f59e0b) 10%, transparent);
}

.rmc-mapping__handle {
  display: inline-block;
  margin-right: 6px;
  color: var(--text-muted, #94a3b8);
  cursor: grab;
  font-family: var(--font-mono, monospace);
}

.rmc-pill--confidence {
  font-variant-numeric: tabular-nums;
  min-width: 3.25rem;
  text-align: center;
}
.rmc-pill--success {
  background-color: color-mix(in srgb, var(--accent-emerald, #10b981) 18%, transparent);
  color: var(--accent-emerald, #047857);
}
.rmc-pill--warning {
  background-color: color-mix(in srgb, var(--accent-amber, #f59e0b) 18%, transparent);
  color: var(--accent-amber, #b45309);
}
.rmc-pill--danger {
  background-color: color-mix(in srgb, var(--accent-rose, #f43f5e) 18%, transparent);
  color: var(--accent-rose, #be123c);
}

.rmc-mapping__method-tag {
  font-size: 0.75rem;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
  color: var(--text-muted, #64748b);
}

.rmc-mapping__actions {
  display: flex;
  gap: 6px;
  align-items: center;
  flex-wrap: wrap;
}
.rmc-mapping__actions-col { width: 1%; white-space: nowrap; /* horizontal-overflow-risk-allow: actions-column-fixed-width-icon-buttons */ }

.rmc-mapping__explain {
  display: inline-block;
  margin-left: 4px;
  font-size: 0.75rem;
}
.rmc-mapping__explain summary { cursor: pointer; color: var(--text-muted, #64748b); }
.rmc-mapping__explain p { margin: 4px 0 0; max-width: 28rem; }

.rmc-mapping__status {
  margin-top: var(--space-md, 12px);
  min-height: 1.5rem;
  font-size: 0.875rem;
}
.rmc-mapping__status[data-tone="success"] { color: var(--accent-emerald, #047857); }
.rmc-mapping__status[data-tone="error"]   { color: var(--accent-rose, #be123c); }

.rmc-btn--xs {
  padding: 2px 8px;
  font-size: 0.75rem;
  line-height: 1.4;
}

/* ========================================================================== */
/* v2.26 Apple HIG quiet-luxury layer (2026-05-15)                            */
/* ========================================================================== */
/* Effortless, intentional, emotionally engaging. Adds the missing primitives
   that Apple HIG leans on: named motion curves, discrete durations, an
   eight-step type ramp with tracking-by-size, breath-scale negative space,
   44pt tactile floor, retina hairlines, and a scroll-reveal grammar. Layered
   on top of the v2.X foundation. Every primitive respects
   prefers-reduced-motion and prefers-reduced-transparency. Tenant brand still
   wins via the cascade. */

:root {
  /* Apple motion curves. Named for intent, not just the bezier. */
  --ease-curtain:       cubic-bezier(0.22, 1, 0.36, 1);
  --ease-cinematic:     cubic-bezier(0.16, 1, 0.3, 1);
  --ease-emphasis-out:  cubic-bezier(0.34, 1.2, 0.64, 1);
  --ease-emphasis-in:   cubic-bezier(0.6, 0, 0.78, 0);
  --ease-quiet:         cubic-bezier(0.32, 0.72, 0, 1);

  /* Apple duration scale. Pair with an ease curve via shorthand or transition. */
  --dur-instant:    100ms;
  --dur-quick:      200ms;
  --dur-swift:      300ms;
  --dur-curtain:    600ms;
  --dur-cinematic:  1200ms;

  /* Apple HIG type ramp v2. Eight roles: display to eyebrow. Each pairs
     size x line-height x tracking per HIG optical-size guidance. */
  --type-size-display:      clamp(3rem, 6vw + 1rem, 5rem);
  --type-size-headline-xl:  clamp(2.25rem, 4.5vw + 0.5rem, 3.5rem);
  --type-size-headline-l:   clamp(1.75rem, 3.5vw + 0.25rem, 2.5rem);
  --type-size-headline-m:   clamp(1.375rem, 2.5vw, 1.75rem);
  --type-size-body-l:       clamp(1.0625rem, 1.2vw + 0.5rem, 1.1875rem);
  --type-size-body:         1rem;
  --type-size-caption:      0.8125rem;
  --type-size-eyebrow:      0.75rem;
  --type-size-micro:        0.65rem;   /* dashboard metadata, table micro-labels */

  --type-lh-display:        1.04;
  --type-lh-headline-xl:    1.08;
  --type-lh-headline-l:     1.12;
  --type-lh-headline-m:     1.2;
  --type-lh-body-l:         1.5;
  --type-lh-body:           1.55;
  --type-lh-caption:        1.4;
  --type-lh-eyebrow:        1.2;

  --type-tr-display:        -0.022em;
  --type-tr-headline-xl:    -0.018em;
  --type-tr-headline-l:     -0.014em;
  --type-tr-headline-m:     -0.01em;
  --type-tr-body-l:         -0.003em;
  --type-tr-body:           0em;
  --type-tr-caption:        0.005em;
  --type-tr-eyebrow:        0.12em;

  /* Breath scale (between-section negative space). */
  --space-breath-xs:  3rem;
  --space-breath-sm:  4.5rem;
  --space-breath-md:  6rem;
  --space-breath-lg:  9rem;
  --space-breath-xl:  13rem;

  /* 44pt tactile floor (HIG hit target). */
  --tactile-min:          44px;
  --tactile-comfortable:  48px;
  --tactile-generous:     56px;

  /* Reveal grammar (paired with rmc-reveal.js). */
  --reveal-distance:   24px;
  --reveal-duration:   var(--dur-curtain);
  --reveal-ease:       var(--ease-curtain);
  --reveal-stagger:    90ms;
}

/* Type ramp classes */
.rmc-type-display,
.rmc-type-headline-xl,
.rmc-type-headline-l,
.rmc-type-headline-m,
.rmc-type-body-l,
.rmc-type-body,
.rmc-type-caption,
.rmc-type-eyebrow {
  font-family: var(--portal-font, Inter, system-ui, -apple-system, "SF Pro Text", sans-serif);
  font-optical-sizing: auto;
  text-wrap: balance;
}
.rmc-type-display     { font-size: var(--type-size-display);     line-height: var(--type-lh-display);     letter-spacing: var(--type-tr-display);     font-weight: 700; }
.rmc-type-headline-xl { font-size: var(--type-size-headline-xl); line-height: var(--type-lh-headline-xl); letter-spacing: var(--type-tr-headline-xl); font-weight: 700; }
.rmc-type-headline-l  { font-size: var(--type-size-headline-l);  line-height: var(--type-lh-headline-l);  letter-spacing: var(--type-tr-headline-l);  font-weight: 700; }
.rmc-type-headline-m  { font-size: var(--type-size-headline-m);  line-height: var(--type-lh-headline-m);  letter-spacing: var(--type-tr-headline-m);  font-weight: 600; }
.rmc-type-body-l      { font-size: var(--type-size-body-l);      line-height: var(--type-lh-body-l);      letter-spacing: var(--type-tr-body-l);      font-weight: 400; }
.rmc-type-body        { font-size: var(--type-size-body);        line-height: var(--type-lh-body);        letter-spacing: var(--type-tr-body);        font-weight: 400; }
.rmc-type-caption     { font-size: var(--type-size-caption);     line-height: var(--type-lh-caption);     letter-spacing: var(--type-tr-caption);     font-weight: 500; color: var(--text-tertiary, var(--text-muted)); }
.rmc-type-eyebrow     { font-size: var(--type-size-eyebrow);     line-height: var(--type-lh-eyebrow);     letter-spacing: var(--type-tr-eyebrow);     font-weight: 600; text-transform: uppercase; color: var(--text-tertiary, var(--text-muted)); }

/* Tactile floor utilities */
.rmc-tactile-44,
.rmc-tactile-44 > button,
.rmc-tactile-44 > a {
  min-block-size:  var(--tactile-min);
  min-inline-size: var(--tactile-min);
}
.rmc-tactile-48 { min-block-size: var(--tactile-comfortable); min-inline-size: var(--tactile-comfortable); }
.rmc-tactile-56 { min-block-size: var(--tactile-generous);    min-inline-size: var(--tactile-generous); }

/* Breath utilities (between-section padding). */
.rmc-breath-xs { padding-block: var(--space-breath-xs); }
.rmc-breath-sm { padding-block: var(--space-breath-sm); }
.rmc-breath-md { padding-block: var(--space-breath-md); }
.rmc-breath-lg { padding-block: var(--space-breath-lg); }
.rmc-breath-xl { padding-block: var(--space-breath-xl); }

/* Scroll reveal grammar (paired with static/js/rmc-reveal.js).
   Hidden state is opt-in via html[data-rmc-reveal-armed], set synchronously at
   the top of rmc-reveal.js. If that script fails to load, the flag is never
   set, opacity stays at 1, and content is visible — the rmc-reveal class
   becomes a no-op instead of a permanent invisibility trap. */
html[data-rmc-reveal-armed] .rmc-reveal {
  opacity: 0;
  transform: translate3d(0, var(--reveal-distance), 0);
  transition:
    opacity var(--reveal-duration) var(--reveal-ease),
    transform var(--reveal-duration) var(--reveal-ease);
  will-change: opacity, transform;
  pointer-events: none;
}
html[data-rmc-reveal-armed] .rmc-reveal.is-revealed {
  opacity: 1;
  transform: translate3d(0, 0, 0);
  pointer-events: auto;
}
html[data-rmc-reveal-armed] .rmc-reveal-stagger > .rmc-reveal {
  transition-delay: calc(var(--reveal-index, 0) * var(--reveal-stagger));
}
html[data-rmc-reveal-armed] .rmc-reveal--from-left  { transform: translate3d(calc(-1 * var(--reveal-distance)), 0, 0); }
html[data-rmc-reveal-armed] .rmc-reveal--from-right { transform: translate3d(var(--reveal-distance), 0, 0); }
html[data-rmc-reveal-armed] .rmc-reveal--from-left.is-revealed,
html[data-rmc-reveal-armed] .rmc-reveal--from-right.is-revealed { transform: translate3d(0, 0, 0); }
html[data-rmc-reveal-armed] .rmc-reveal--scale {
  opacity: 0;
  transform: scale(0.96);
  transition:
    opacity var(--reveal-duration) var(--reveal-ease),
    transform var(--reveal-duration) var(--ease-emphasis-out);
  pointer-events: none;
}
html[data-rmc-reveal-armed] .rmc-reveal--scale.is-revealed {
  opacity: 1;
  transform: scale(1);
  pointer-events: auto;
}

/* Accessibility: respect reduced motion. */
@media (prefers-reduced-motion: reduce) {
  html[data-rmc-reveal-armed] .rmc-reveal,
  html[data-rmc-reveal-armed] .rmc-reveal--scale,
  html[data-rmc-reveal-armed] .rmc-reveal--from-left,
  html[data-rmc-reveal-armed] .rmc-reveal--from-right {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
    pointer-events: auto !important;
  }
  html[data-rmc-reveal-armed] .rmc-reveal-stagger > .rmc-reveal { transition-delay: 0ms !important; }
}

/* Hairline divider grammar (retina-aware). */
.rmc-hairline,
.rmc-hairline-top,
.rmc-hairline-bottom { border: 0 solid var(--hairline); }
.rmc-hairline        { border-block: 1px solid var(--hairline); }
.rmc-hairline-top    { border-block-start: 1px solid var(--hairline); }
.rmc-hairline-bottom { border-block-end: 1px solid var(--hairline); }
@media (min-resolution: 2dppx) {
  .rmc-hairline        { border-block-width: 0.5px; }
  .rmc-hairline-top    { border-block-start-width: 0.5px; }
  .rmc-hairline-bottom { border-block-end-width: 0.5px; }
}

/* Hero arrival pattern: pair .rmc-arrival on a wrapper with child .rmc-reveal
   to get a velvet-curtain hero entrance — eyebrow, title, body, CTA. */
.rmc-arrival > .rmc-reveal:nth-child(1) { --reveal-index: 0; }
.rmc-arrival > .rmc-reveal:nth-child(2) { --reveal-index: 1; }
.rmc-arrival > .rmc-reveal:nth-child(3) { --reveal-index: 2; }
.rmc-arrival > .rmc-reveal:nth-child(4) { --reveal-index: 3; }
.rmc-arrival > .rmc-reveal:nth-child(5) { --reveal-index: 4; }
.rmc-arrival > .rmc-reveal:nth-child(6) { --reveal-index: 5; }
.rmc-arrival > .rmc-reveal:nth-child(n+7) { --reveal-index: 6; }

/* ========================================================================== */
/* v2.29 SVG illustration + decoration library (2026-05-15)                   */
/* ========================================================================== */
/* Apple-tier line-art for empty states + chapter dividers. SVGs use
   currentColor for strokes so the parent text color tints them, plus
   --rmc-illustration-accent for the single accent stroke/fill. */
.rmc-illustration {
  display: inline-block;
  max-inline-size: 180px;
  inline-size: 100%;
  block-size: auto;
  color: var(--text-tertiary, var(--text-muted));
  --rmc-illustration-accent: var(--brand-accent, #C1573A);
}
.rmc-empty__illustration-slot {
  display: flex;
  align-items: center;
  justify-content: center;
  min-block-size: 120px;
  margin-block-end: 1.25rem;
}
.rmc-empty__illustration-slot .rmc-illustration {
  max-inline-size: 200px;
}
/* Inherit the editorial accent on marketing surfaces. */
[data-mkt-edition="editorial"] .rmc-illustration,
.marketing-surface .rmc-illustration {
  --rmc-illustration-accent: var(--mkt-edt-accent, #C1573A);
}
/* Dividers + corner ornaments sit tighter than full-block illustrations. */
.rmc-illustration--divider-serif,
.rmc-illustration--divider-lined,
.rmc-illustration--divider-flourish {
  display: block;
  max-inline-size: 320px;
  margin-inline: auto;
  margin-block: var(--space-breath-sm, 4.5rem);
  color: var(--text-tertiary, var(--hairline-strong));
}
.rmc-illustration--corner-ornament {
  position: absolute;
  inline-size: 40px;
  block-size: 40px;
  pointer-events: none;
  opacity: 0.7;
}
.rmc-illustration--corner-ornament[data-corner="tl"] { inset-block-start: 12px; inset-inline-start: 12px; }
.rmc-illustration--corner-ornament[data-corner="tr"] { inset-block-start: 12px; inset-inline-end: 12px; transform: scaleX(-1); }
.rmc-illustration--corner-ornament[data-corner="bl"] { inset-block-end: 12px; inset-inline-start: 12px; transform: scaleY(-1); }
.rmc-illustration--corner-ornament[data-corner="br"] { inset-block-end: 12px; inset-inline-end: 12px; transform: scale(-1, -1); }

/* ========================================================================== */
/* v2.32 Marketing hero figure (2026-05-15)                                   */
/* ========================================================================== */
/* Editorial framing for the generated hero compositions. Each page opts in
   via {% include "components/marketing_hero_image.html" with hero_slug="..." %}.
   The figure: rounded corners, soft shadow, hairline border, single terracotta
   accent dot, scale-reveal on first paint. */
.rmc-hero-figure {
  position: relative;
  display: block;
  margin: 0;
  border-radius: 1.5rem;
  overflow: hidden;
  background: var(--surface-elevated, var(--cream-deep, #ECE4D8));
  border: 1px solid var(--hairline);
  box-shadow:
    0 1px 2px rgba(28, 25, 23, 0.04),
    0 12px 32px -16px rgba(28, 25, 23, 0.12);
  isolation: isolate;
}
.rmc-hero-figure picture,
.rmc-hero-figure img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  aspect-ratio: 16 / 10;
  object-fit: cover;
}
.rmc-hero-figure__accent {
  position: absolute;
  inset-block-end: 18px;
  inset-inline-start: 18px;
  inline-size: 12px;
  block-size: 12px;
  border-radius: 50%;
  background: var(--brand-accent, #C1573A);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--brand-accent, #C1573A) 18%, transparent);
}
/* On retina displays, sharpen the border + soften the shadow further. */
@media (min-resolution: 2dppx) {
  .rmc-hero-figure { border-width: 0.5px; }
}
/* Tenant brand wash overlay — page can opt in by adding .rmc-hero-figure--tinted */
.rmc-hero-figure--tinted::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--brand-primary, #4f46e5) 12%, transparent),
    transparent 60%
  );
  pointer-events: none;
  mix-blend-mode: multiply;
  z-index: 1;
}

/* ========================================================================== */
/* v2.33 Platform-wide contrast + layout repair layer (2026-05-15)            */
/* ========================================================================== */
/* Driven by the manager-dashboard dissection screenshots. Three classes of
   bug that touched dozens of templates each are repaired with global CSS
   rather than 209 template edits:
     1. text-white-50 / text-white-25 / text-muted on dark surfaces fail WCAG
     2. content-max-960 class is referenced 25x but was never defined
     3. The harsh indigo→emerald active pill gradient (manager-aesthetic-polish.css)
        is overridden here with a quieter single-tint + brand-tinted hairline
   No template touches — overrides cascade through the existing class names. */

/* ---- Contrast repair on dark chrome only (not #cp-main-content light canvas) --- */
[data-theme="dark"] .text-white-50,
[data-bs-theme="dark"] .text-white-50,
[data-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-white-50,
[data-bs-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-white-50 {
  color: var(--text-tertiary, #aeaeb2) !important;
  opacity: 1 !important;
}
[data-theme="dark"] .text-white-25,
[data-bs-theme="dark"] .text-white-25,
[data-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-white-25,
[data-bs-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-white-25 {
  color: var(--text-muted, #8e8e93) !important;
  opacity: 1 !important;
}
[data-theme="dark"] .text-muted,
[data-bs-theme="dark"] .text-muted,
[data-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-muted,
[data-bs-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col, .cp-primary-nav, .rmc-control-plane-chrome) .text-muted {
  color: var(--text-tertiary, #aeaeb2) !important;
}
[data-theme="dark"] :is(h1, h2, h3, h4, h5, h6, p, span, small, a, button).opacity-50,
[data-theme="dark"] :is(h1, h2, h3, h4, h5, h6, p, span, small, a, button).opacity-75,
[data-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col) :is(h1, h2, h3, h4, h5, h6, p, span, small, a, button).opacity-75,
[data-bs-theme="dark"] :is(.cp-navbar, .cp-sidebar-col, #cp-sidebar-col) :is(h1, h2, h3, h4, h5, h6, p, span, small, a, button).opacity-75 {
  opacity: 1;
}

/* ---- content-max-960: fill the empty middle column ---------------------- */
/* This class was referenced in 25 manager / siteconfig templates but never
   defined — so the inner content fell back to no max-width, leaving a visible
   empty band on wide screens. We give it a sane Apple-tier reading-width cap
   (1440px) + center it so the page actually fills its column. */
.content-max-960 {
  max-inline-size: min(1440px, 100%);
  margin-inline: auto;
}
/* Old shorter cap as an opt-in for genuinely long-form reading surfaces. */
.content-max-narrow {
  max-inline-size: min(960px, 100%);
  margin-inline: auto;
}

/* Dashboard shells: bleed wide layouts to sidebar-adjacent rails (not reading opt-ins). */
:is(
    body.control-plane-shell,
    body.admin-manager-shell,
    body.portal-body-with-layout,
    body.backend-shell,
    body.base-document-shell
  )
  :is(.content-max-960, .content-max-1200, .cp-page) {
  max-inline-size: 100%;
  margin-inline: 0;
}

/* ---- Quieter primary-nav active pill ------------------------------------ */
/* Replaces the harsh indigo→emerald gradient from manager-aesthetic-polish.css
   with a single brand-tinted wash + hairline ring. Reads as "this surface is
   selected" without yelling. Only applies on dark control-plane surfaces;
   light surfaces keep the original gradient (where it doesn't visually shout). */
[data-theme="dark"] .cp-primary-nav__pill--active,
[data-theme="dark"] .cp-primary-nav__pill[aria-current="page"],
.control-plane-shell .cp-primary-nav__pill--active,
.control-plane-shell .cp-primary-nav__pill[aria-current="page"],
.cp-surface .cp-primary-nav__pill--active,
.cp-surface .cp-primary-nav__pill[aria-current="page"] {
  background: color-mix(in srgb, var(--school-primary, #4f46e5) 14%, transparent);
  border-color: color-mix(in srgb, var(--school-primary, #4f46e5) 32%, transparent);
  color: var(--color-base-0, #ffffff);
  font-weight: 600;
  box-shadow:
    inset 0 0 0 0.5px color-mix(in srgb, var(--school-primary, #4f46e5) 45%, transparent),
    0 1px 0 rgba(255, 255, 255, 0.04) inset;
}
[data-theme="dark"] .cp-primary-nav__pill--active:hover,
.control-plane-shell .cp-primary-nav__pill--active:hover,
.cp-surface .cp-primary-nav__pill--active:hover {
  background: color-mix(in srgb, var(--school-primary, #4f46e5) 22%, transparent);
  filter: none;
}

/* ============================================================
   .rmc-empty-state BEM (v4.01.06, 2026-05-31)
   ------------------------------------------------------------
   Canonical empty-state primitive. Consumed by
   templates/components/rmc_empty_state.html (SOT) AND by raw-
   <td colspan> codemod sites where including a full partial
   adds unwanted vertical chrome. The verifier
   `LUX_EMPTY_STATE_RE` matches both `rmc-empty` and
   `rmc-empty-state` so legacy callers keep working.
   Retires: cp_empty.html, tp_empty.html,
            world_class_empty_state.html,
            dashboard_empty_state.html (scheduled v4.02.0).
   ============================================================ */
.rmc-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 2.5rem 1.5rem;
  border-radius: var(--lux-radius, 12px);
  background: var(--surface-elevated, var(--lux-canvas-elev));
  border: 1px solid var(--hairline, var(--lux-border-thin));
  gap: 0.75rem;
}
.rmc-empty-state__icon {
  font-size: 2.5rem;
  color: var(--text-secondary);
  opacity: 0.6;
}
.rmc-empty-state__title {
  font-weight: 600;
  font-size: 1.05rem;
  color: var(--text-primary);
  margin: 0;
}
.rmc-empty-state__body {
  color: var(--text-secondary);
  margin: 0;
  max-width: 32rem;
}
.rmc-empty-state__cta {
  margin-top: 0.5rem;
}
.rmc-empty-state--row {
  padding: 1rem;
}  /* For inside <td colspan="N"> contexts */
