/* ============================================================
   Shared admin-page chrome.

   Page head + form primitives used across /admins, /roles, /profile.
   Kept in one file (loaded from App.razor) so scoped .razor.css files
   only need to carry the actually-page-specific bits.

   Everything resolves through the shared theme tokens (--color-*,
   --space-*, --radius-*, --shadow-*, --font-*) imported with app.css
   from the MAUI design system.
   ============================================================ */

/* ============================================================
   Foundation — Silk Pastel design tokens

   One easing curve for the whole console; refined silk shadows;
   the "silk thread" hairline used in exactly three places (top-bar
   divider, sidebar promo top edge, and reserved for future use).
   These tokens cascade through every theme because they reference
   the existing --color-* variables, never raw hex.
   ============================================================ */

:root {
    /* Fill the gaps in the space scale shipped by the MAUI client's
       compiled Tailwind (app.css defines 1/2/3/4/5/6/8/10 only). The
       admin chrome and form-card padding reference 7, 9, 11, 12 —
       without these definitions the resulting `padding` shorthands
       become invalid and collapse to zero, which is what made every
       Edit page lose its internal padding entirely. */
    --space-7:  2.25rem;
    --space-9:  3rem;
    --space-11: 4rem;
    --space-12: 4.5rem;

    --ease-silk: cubic-bezier(0.23, 1, 0.32, 1);
    --transition-silk-fast: 180ms var(--ease-silk);
    --transition-silk:      300ms var(--ease-silk);
    --transition-silk-slow: 480ms var(--ease-silk);

    --radius-card-xl:  1.75rem;   /* 28px — bento, chart, activity */
    --radius-card-2xl: 2rem;      /* 32px — form-card, glass-card hero */
    --radius-tile:     0.875rem;  /* 14px — icon tiles inside cards */

    /* Triple-layered, low-opacity ambient-occlusion shadow.
       Per Silk & Pastel: diffused not directional — light is
       everywhere, never from one source. */
    --shadow-silk-rest:
        0 1px 2px rgba(15, 12, 30, 0.02),
        0 10px 40px rgba(15, 12, 30, 0.03);
    --shadow-silk-lift:
        0 2px 6px rgba(15, 12, 30, 0.03),
        0 20px 50px rgba(15, 12, 30, 0.05);
    --shadow-silk-hero:
        0 30px 80px -20px rgba(15, 12, 30, 0.18),
        0 8px 24px -8px rgba(15, 12, 30, 0.09);

    /* Silk-edge — the 1px white stroke around glass surfaces.
       Per the design system: "catches the light, defines the
       silk edge." 40% on rest, 80% on hover. */
    --silk-edge:        rgba(255, 255, 255, 0.4);
    --silk-edge-strong: rgba(255, 255, 255, 0.8);

    --silk-thread-v: linear-gradient(to bottom,
        transparent 0%,
        color-mix(in oklab, var(--color-outline-variant) 70%, transparent) 28%,
        color-mix(in oklab, var(--color-outline-variant) 70%, transparent) 72%,
        transparent 100%);
    --silk-thread-h: linear-gradient(to right,
        transparent 0%,
        color-mix(in oklab, var(--color-outline-variant) 70%, transparent) 28%,
        color-mix(in oklab, var(--color-outline-variant) 70%, transparent) 72%,
        transparent 100%);
}

/* ============================================================
   Body atmosphere — twin radial overlays in primary + tertiary
   tints. Sits behind everything via z-index: -1 so cards float on
   top. Theme-aware because it references --color-primary /
   --color-tertiary. Dark themes still get a faint glow because the
   6-7% mix of primary on near-black surfaces reads as a halo, not
   white wash. Pointer-events: none keeps it click-through.
   ============================================================ */

body {
    position: relative;
    isolation: isolate;
}

/* Twin pastel orbs in opposing corners — the signature Silk &
   Pastel atmosphere. The lavender bloom at top-left and the
   mint bloom at bottom-right "simulate light hitting silk."
   Larger and more saturated than the previous version so the
   pastel quality actually reads on first paint. The secondary
   ::after layer is a faint top-right peach kiss for warmth. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -2;
    background:
        radial-gradient(ellipse 70% 55% at 12% -5%,
            color-mix(in oklab, var(--color-primary) 18%, transparent),
            transparent 55%),
        radial-gradient(ellipse 60% 55% at 90% 105%,
            color-mix(in oklab, var(--color-secondary) 14%, transparent),
            transparent 55%);
    pointer-events: none;
}
body::after {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background:
        radial-gradient(ellipse 35% 30% at 95% 8%,
            color-mix(in oklab, var(--color-tertiary-container) 60%, transparent),
            transparent 60%);
    pointer-events: none;
}

/* ============================================================
   .glass-card — reusable frosted surface utility. Use it where
   you want a card that floats on the body atmosphere. The
   color-mix base is the lowest theme surface (white on light,
   near-black on dark) so it inherits theme correctness; the
   backdrop-filter creates the "behind" depth. Don't sprinkle it
   on every card — backdrop-filter is GPU-expensive at scale.
   Typical use: dashboard chart card, dashboard quick-actions
   card, form-cards on long edit pages. Lists of N items should
   use plain .card so the page paints fast.
   ============================================================ */

.glass-card {
    background: rgba(255, 255, 255, 0.7);
    backdrop-filter: blur(24px) saturate(150%);
    -webkit-backdrop-filter: blur(24px) saturate(150%);
    border: 1px solid var(--silk-edge);
    box-shadow: var(--shadow-silk-rest);
    border-radius: var(--radius-card-xl);
    transition:
        border-color var(--transition-silk),
        box-shadow var(--transition-silk),
        transform var(--transition-silk);
}
.glass-card:hover {
    border-color: var(--silk-edge-strong);
    box-shadow: var(--shadow-silk-lift);
}

/* Dark theme override — backdrop-filter on near-black surface needs
   a different base. Falls back if anyone toggles to a *-dark theme. */
:root[data-theme*="-dark"] .glass-card {
    background: color-mix(in oklab, var(--color-surface-container-lowest) 70%, transparent);
    border-color: color-mix(in oklab, white 8%, transparent);
}
:root[data-theme*="-dark"] .glass-card:hover {
    border-color: color-mix(in oklab, white 16%, transparent);
}

/* Universal card-lift refinement. Every list-page card already uses
   .card.card-lift; bumping this rule restyles them all without
   touching their .razor markup. Smaller translate (1px → 2px) +
   shadow swap + faint primary border tint on hover. */
.card-lift {
    transition: transform var(--transition-silk),
                box-shadow var(--transition-silk),
                border-color var(--transition-silk);
}
.card-lift:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-silk-lift);
    border-color: color-mix(in oklab, var(--color-primary) 22%, var(--color-outline-variant));
}

/* Reduced-motion override — strip transforms + transitions, but keep
   color/state changes so the UI still communicates hover/focus. */
@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
    .card-lift:hover {
        transform: none;
    }
}

/* Universal focus ring — primary tinted glow, no boxy default
   browser outline. Inputs and search fields override with their own
   tighter recipe (see .input:focus, .admin-topbar-search input:focus). */
*:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 30%, transparent);
    border-radius: inherit;
}

/* ---------- Page head ------------------------------------------- */

.page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-5);
    margin-bottom: var(--space-7);
    flex-wrap: wrap;
}

/* Right-hand action group on page heads (e.g. Plans list:
   secondary "Manage features" + primary "New plan"). */
.page-head-actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* Back link sits on its own line above the eyebrow + title. Was
   inline-flex which collided with the .label-eyebrow on the next
   line — flex + fit-content forces a clean break. */
.page-back {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    width: fit-content;
    color: var(--color-on-surface-variant);
    font-weight: 600;
    font-size: 0.8125rem;
    letter-spacing: 0.02em;
    text-decoration: none;
    padding: 0.25rem 0;
    margin-bottom: 0.75rem;
    transition: color 120ms ease;
}
.page-back:hover { color: var(--color-primary); }
.page-back-icon { font-size: 18px; }

/* Silk & Pastel "display" headline — 48px Montserrat 600 with
   -0.02em tracking per the design system spec. Bigger and tighter
   than before. We bake a primary-tinted gradient into the trailing
   edge so the eye reads "lavender = action color" subliminally. */
.page-title {
    font-family: var(--font-headline);
    font-weight: 700;
    font-size: clamp(2.25rem, 4vw, 3rem);
    line-height: 1.05;
    letter-spacing: -0.025em;
    margin: 0.5rem 0 0;
    color: var(--color-on-surface);
    background: linear-gradient(115deg,
        var(--color-on-surface) 0%,
        var(--color-on-surface) 65%,
        color-mix(in oklab, var(--color-primary) 80%, var(--color-on-surface)) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

/* Eyebrow above .page-title gets a primary tint when it sits inside
   .page-head — keeps the hierarchy "primary eyebrow → editorial
   title → secondary subhead." Other contexts still get the muted
   on-surface-variant default from app.css. */
.page-head .label-eyebrow {
    color: var(--color-primary);
    opacity: 1;
    letter-spacing: 0.18em;
}

.page-sub {
    color: var(--color-on-surface-variant);
    font-size: 0.9375rem;
    line-height: 1.6;
    margin: 0.75rem 0 0;
    max-width: 42rem;
}

.page-sub code {
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: 0.85em;
    background: var(--color-surface-container);
    padding: 0.125rem 0.375rem;
    border-radius: var(--radius-md);
}

/* ---------- Form card ------------------------------------------- */

/* Glass surface (color-mix translucent + backdrop blur) + larger
   editorial radius and interior padding. Existing .form-card markup
   on every Create/Edit page picks this up automatically. The base
   layer is the theme's lowest surface so dark themes stay correct
   (no rgba(255,255,255) leakage). */
.form-card {
    padding: var(--space-7) var(--space-8);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    background: rgba(255, 255, 255, 0.72);
    backdrop-filter: blur(24px) saturate(150%);
    -webkit-backdrop-filter: blur(24px) saturate(150%);
    border: 1px solid var(--silk-edge);
    border-radius: var(--radius-card-2xl);
    box-shadow: var(--shadow-silk-rest);
    transition: border-color var(--transition-silk),
                box-shadow var(--transition-silk);
}
.form-card:hover {
    border-color: var(--silk-edge-strong);
    box-shadow: var(--shadow-silk-lift);
}

:root[data-theme*="-dark"] .form-card {
    background: color-mix(in oklab, var(--color-surface-container-lowest) 72%, transparent);
    border-color: color-mix(in oklab, white 8%, transparent);
}

/* Blazor's <EditForm> renders as a plain <form>. Without this rule
   its children (grid, fields, actions row) flow as block-level boxes
   with no gap between them, while the card's own gap only separates
   form-card-head from the <form> block — which made the header feel
   walled off from the fields. Match the card's gap so the whole card
   reads as one vertical rhythm. */
.form-card > form {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.form-card-head {
    margin-bottom: 0;
}

/* Variant where the head needs a right-hand action (e.g. plan edit
   "Add or edit features" button). The default head stacks vertically;
   this row variant lays the title block + the action side by side. */
.form-card-head-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    flex-wrap: wrap;
}
.form-card-head-row > div {
    min-width: 0;
}

.form-card-title {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: 1.375rem;
    line-height: 1.2;
    letter-spacing: -0.02em;
    margin: 0.375rem 0 0;
    color: var(--color-on-surface);
}

.form-card-sub {
    color: var(--color-on-surface-variant);
    font-size: 0.875rem;
    line-height: 1.55;
    margin: 0.5rem 0 0;
    max-width: 34rem;
}

/* ---------- Fields ---------------------------------------------- */

.form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
}
@media (max-width: 640px) {
    .form-grid {
        grid-template-columns: 1fr;
    }
}

/* Single-column stack variant — full-width fields, one per row.
   Used on the plan edit page where the feature list reads better
   stacked than in a 2-col grid. */
.form-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* Number badge that prefixes the label of a numbered feature row.
   Small, monospaced, neutral — reads like "1." in a lecturer's notes
   rather than competing with the field label. */
.form-field-num {
    display: inline-block;
    min-width: 1.5rem;
    margin-right: 0.375rem;
    color: var(--color-on-surface-variant);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-weight: 700;
    font-size: 0.8125rem;
    opacity: 0.7;
}

.form-field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.form-field-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-on-surface-variant);
    line-height: 1;
}

.form-field-hint {
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
    line-height: 1.5;
    margin-top: 0.125rem;
}

/* Input sizing inside admin forms — modest bump so labels don't feel
   pasted against them. Uses .form-field > .input so we don't touch
   the .input primitive used elsewhere in the app. */
.form-field > .input {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
    font-size: 0.9375rem;
}

/* Per-feature visibility toggles on the plan edit page. Two checkboxes
   (small / big screen) sit right under the value input so admin sees
   them grouped with the feature they affect. Subtle background +
   left rule visually attaches the row to the field above without
   introducing a heavyweight separator. */
.form-field-visibility {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    margin-top: 0.5rem;
    padding: 0.5rem 0.75rem;
    /* --color-surface-variant is defined only on the silk-pastel
       theme, not the mint/slate/sage palettes shipped from the MAUI
       client. Use --color-surface-container-high (defined on EVERY
       theme) so the visibility row keeps a soft tint regardless of
       which palette the operator picked. */
    background: var(--color-surface-container-high);
    border-left: 2px solid var(--color-outline-variant);
    border-radius: 0.25rem;
}

/* When a checkbox label is ALSO a .form-field (vertical stack with
   eyebrow label above input), .form-field-checkbox must override
   flex-direction back to row — otherwise the InputCheckbox renders
   below the "Active" label, both centered, which looks broken on
   the plan-edit form. Order matters: row + flex-start + small gap
   keeps the checkbox snug next to the label text. */
.form-field-checkbox {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.625rem;
    font-size: 0.8125rem;
    color: var(--color-on-surface-variant);
    cursor: pointer;
    text-transform: none;
    letter-spacing: normal;
    font-weight: 500;
}

/* The label/eyebrow ("Active") shows BEFORE the checkbox; reset its
   width so it doesn't push the input off the row when the parent is
   in a .form-grid 2-col layout. */
.form-field-checkbox > .form-field-label {
    margin: 0;
    line-height: 1;
}

.form-field-checkbox input[type="checkbox"] {
    width: 1.125rem;
    height: 1.125rem;
    accent-color: var(--color-primary);
    cursor: pointer;
    margin: 0;
}

/* ---------- Actions row ----------------------------------------- */

.form-actions {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 0.625rem;
    margin-top: 0;        /* card-level gap already spaces this row */
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-outline-variant);
    flex-wrap: wrap;
}

.form-actions-icon {
    font-size: 18px;
}

/* ---------- Inline alerts --------------------------------------- */

.form-alert {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    width: fit-content;
    font-size: 0.875rem;
    font-weight: 600;
    margin-bottom: var(--space-3);
}

.form-alert-success {
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
}

.form-alert-icon {
    font-size: 18px;
}

/* ---------- Danger + protected cards ---------------------------- */

.danger-card {
    border: 1px solid color-mix(in oklab, var(--color-error) 35%, transparent);
    background: color-mix(in oklab, var(--color-error-container) 40%, var(--color-surface-container-lowest));
}
.danger-eyebrow  { color: var(--color-error); opacity: 1; }
.danger-btn      { color: var(--color-error); border-color: var(--color-error); }
.danger-btn:hover{ background: var(--color-error-container); }
.danger-cta      { background: var(--color-error); color: var(--color-on-error, white); }
.danger-confirm  {
    font-size: 0.875rem;
    color: var(--color-on-surface);
    font-weight: 600;
    flex: 1;
    min-width: 100%;
    margin: 0;
}

.protected-card  {
    border: 1px solid color-mix(in oklab, var(--color-primary) 40%, transparent);
    background: color-mix(in oklab, var(--color-primary-container) 40%, var(--color-surface-container-lowest));
}
.protected-icon  {
    font-size: 28px;
    color: var(--color-primary);
}

/* ============================================================
   Admins list + cards
   ============================================================ */

.admins-new-cta {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.admins-new-cta-icon { font-size: 20px; }

.admins-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-4);
}

.admins-card {
    padding: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: 0.875rem;
    min-height: 12rem;
}
.admins-card-skeleton {
    min-height: 12rem;
    background:
        linear-gradient(90deg,
            var(--color-surface-container) 0%,
            var(--color-surface-container-high) 50%,
            var(--color-surface-container) 100%);
    background-size: 200% 100%;
    animation: admins-skeleton-pulse 1.4s ease-in-out infinite;
    border: none;
}
@keyframes admins-skeleton-pulse {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.admins-card-head {
    display: flex;
    align-items: center;
    gap: 0.875rem;
}

.admins-avatar {
    flex-shrink: 0;
    width: 3rem;
    height: 3rem;
    border-radius: 9999px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-primary);
    color: var(--color-on-primary);
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: 1.25rem;
    letter-spacing: -0.02em;
}

.admins-card-names {
    min-width: 0;
}

.admins-card-name {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: 1.125rem;
    line-height: 1.15;
    letter-spacing: -0.01em;
    margin: 0;
    color: var(--color-on-surface);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admins-card-email {
    display: block;
    font-size: 0.8125rem;
    color: var(--color-on-surface-variant);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.admins-card-roles {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    margin-top: 0.25rem;
}

.admins-role-chip {
    background: var(--color-surface-container);
    color: var(--color-on-surface-variant);
    font-weight: 600;
}

.admins-role-chip-icon {
    font-size: 14px;
    margin-right: 0.125rem;
}

.admins-protected-chip {
    background: color-mix(in oklab, var(--color-primary-container) 60%, transparent);
    color: var(--color-on-primary-container);
    font-weight: 700;
    letter-spacing: 0.04em;
}

.admins-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-top: auto;
    padding-top: var(--space-3);
    border-top: 1px solid var(--color-outline-variant);
    font-size: 0.8125rem;
}

.admins-card-created {
    color: var(--color-on-surface-variant);
}

.admins-card-actions {
    display: flex;
    gap: 0.375rem;
}

.admins-card-action {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    font-weight: 700;
}

.admins-card-action-icon {
    font-size: 16px;
}

.admins-empty {
    padding: var(--space-8);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
}

.admins-empty-icon {
    font-size: 48px;
    color: var(--color-on-surface-variant);
    opacity: 0.5;
}

.admins-empty-title {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: 1.5rem;
    margin: 0;
    color: var(--color-on-surface);
}

.admins-empty-sub {
    color: var(--color-on-surface-variant);
    margin: 0;
}

/* ============================================================
   Roles list + role detail
   ============================================================ */

.roles-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--space-4);
}

.roles-card {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: var(--space-5);
    text-decoration: none;
    color: inherit;
    min-height: 10rem;
}
.roles-card-skeleton {
    min-height: 10rem;
    background:
        linear-gradient(90deg,
            var(--color-surface-container) 0%,
            var(--color-surface-container-high) 50%,
            var(--color-surface-container) 100%);
    background-size: 200% 100%;
    animation: admins-skeleton-pulse 1.4s ease-in-out infinite;
    border: none;
}

.roles-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.roles-card-icon {
    font-size: 32px;
    color: var(--color-on-surface-variant);
    width: 3rem;
    height: 3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 9999px;
    background: var(--color-surface-container);
}

.roles-card-icon-system {
    color: var(--color-on-primary-container);
    background: var(--color-primary-container);
}

.roles-system-chip {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.05em;
}

.roles-system-chip-icon {
    font-size: 14px;
    margin-right: 0.125rem;
}

.roles-card-name {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: 1.5rem;
    line-height: 1.1;
    letter-spacing: -0.02em;
    margin: 0.5rem 0 0;
    color: var(--color-on-surface);
    word-break: break-word;
}

.roles-card-count {
    color: var(--color-on-surface-variant);
    font-size: 0.875rem;
    margin: 0.25rem 0 0;
}

/* Members list inside /roles/{name} */

.role-empty {
    color: var(--color-on-surface-variant);
    margin: 0;
}

.role-member-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.role-member {
    display: flex;
    align-items: center;
    gap: 0.875rem;
    padding: 0.625rem 0.875rem;
    border-radius: var(--radius-xl);
    background: var(--color-surface-container-lowest);
    border: 1px solid var(--color-outline-variant);
}

.role-member-avatar {
    width: 2.25rem;
    height: 2.25rem;
    font-size: 0.9375rem;
}

.role-member-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    line-height: 1.2;
}

.role-member-name {
    font-weight: 700;
    color: var(--color-on-surface);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.role-member-email {
    font-size: 0.8125rem;
    color: var(--color-on-surface-variant);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.role-member-chip {
    flex-shrink: 0;
}

.role-member-remove {
    flex-shrink: 0;
    width: 2rem;
    height: 2rem;
    border-radius: 9999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    color: var(--color-on-surface-variant);
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}
.role-member-remove:hover:not(:disabled) {
    background: var(--color-error-container);
    color: var(--color-error);
}
.role-member-remove .material-symbols-outlined {
    font-size: 18px;
}

/* ============================================================
   Role permissions checklist
   ============================================================ */

.role-perm-group {
    margin-top: var(--space-4);
}
.role-perm-group:first-of-type { margin-top: 0; }

.role-perm-group-eyebrow {
    margin: 0 0 0.5rem;
}

.role-perm-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0.625rem;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color 120ms ease;
}
.role-perm-row:hover {
    background: color-mix(in oklab, var(--color-primary-container) 35%, transparent);
}

.role-perm-row input[type="checkbox"] {
    flex-shrink: 0;
    width: 1.125rem;
    height: 1.125rem;
    accent-color: var(--color-primary);
}

.role-perm-meta {
    display: flex;
    flex-direction: column;
    line-height: 1.2;
    min-width: 0;
}

.role-perm-name {
    font-weight: 600;
    font-size: 0.9375rem;
    color: var(--color-on-surface);
}

.role-perm-code {
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
}

/* ============================================================
   Plan-feature catalog list — drag-to-reorder
   ============================================================ */

/* Reuses .role-member as the row container; this layer adds the
   drag handle, drag-state visuals, and a drop-target indicator. */

.plan-feature-row[draggable="true"] {
    cursor: grab;
}

.plan-feature-row[draggable="true"]:active {
    cursor: grabbing;
}

.plan-feature-drag-handle {
    color: var(--color-on-surface-variant);
    opacity: 0.5;
    font-size: 20px;
    flex-shrink: 0;
    transition: opacity 120ms ease, color 120ms ease;
    /* Pointer-events on the handle would block the row's drag
       events on some browsers; let drag bubble up. */
    pointer-events: none;
}

.plan-feature-row:hover .plan-feature-drag-handle {
    opacity: 1;
    color: var(--color-primary);
}

/* The dragged source goes translucent so the user can see the slot
   it's about to leave; the drop target gets a primary-tinted border
   on top so it reads as "the new home." Keeping both effects light
   so the list stays readable mid-drag. */
.plan-feature-row.is-dragging {
    opacity: 0.4;
}

.plan-feature-row.is-drop-target {
    border-top: 2px solid var(--color-primary);
    background: color-mix(in oklab, var(--color-primary-container) 35%, var(--color-surface-container-lowest));
}

/* Number badge prefixed to each catalog row. Same visual language as
   .form-field-num so the plan edit and catalog list read as related. */
.plan-feature-num {
    flex-shrink: 0;
    width: 1.75rem;
    text-align: right;
    color: var(--color-on-surface-variant);
    font-family: var(--font-mono, ui-monospace, monospace);
    font-weight: 700;
    font-size: 0.875rem;
    opacity: 0.7;
}

/* ============================================================
   Profile hero badge
   ============================================================ */

.profile-hero-avatar {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 1.125rem;
}

/* ============================================================
   Theme picker (Profile → Appearance card)
   ============================================================ */

.theme-picker-group {
    display: flex;
    flex-direction: column;
    gap: 0.625rem;
}

.theme-picker-group-label {
    font-size: 0.6875rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--color-on-surface-variant);
    opacity: 0.75;
    margin: 0;
}

.theme-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
    gap: 0.625rem;
}

.theme-swatch {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.625rem 0.875rem;
    border-radius: var(--radius-xl);
    background: var(--color-surface-container-lowest);
    border: 1.5px solid var(--color-outline-variant);
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: inherit;
    transition:
        border-color 140ms ease,
        background-color 140ms ease,
        transform 140ms ease;
}

.theme-swatch:hover:not(:disabled) {
    border-color: var(--color-primary);
    transform: translateY(-1px);
}

.theme-swatch:disabled {
    cursor: progress;
    opacity: 0.7;
}

.theme-swatch-active {
    border-color: var(--color-primary);
    background: color-mix(in oklab, var(--color-primary-container) 50%, var(--color-surface-container-lowest));
    box-shadow: 0 0 0 3px color-mix(in oklab, var(--color-primary) 15%, transparent);
}

.theme-swatch-chip {
    flex-shrink: 0;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: 9999px;
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.25),
        0 2px 6px rgba(43, 52, 51, 0.2);
}

.theme-swatch-meta {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    justify-content: space-between;
}

.theme-swatch-name {
    font-size: 0.8125rem;
    font-weight: 700;
    color: var(--color-on-surface);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.theme-swatch-check {
    font-size: 18px;
    color: var(--color-primary);
    flex-shrink: 0;
}

/* "DEFAULT" eyebrow on the theme that ships as the console's
   default selection (silk-pastel). Tiny pill with primary tint,
   sits on the swatch's right side. Hidden once the user picks
   that theme so the active check-circle takes its place. */
.theme-swatch-default-badge {
    flex-shrink: 0;
    padding: 0.125rem 0.4375rem;
    border-radius: 9999px;
    background: color-mix(in oklab, var(--color-primary-container) 60%, transparent);
    color: var(--color-primary);
    font-family: var(--font-body);
    font-size: 0.5625rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    line-height: 1;
}

/* ============================================================
   Chromeless pages — login, access-denied, not-found, error

   Full-bleed editorial canvas with two large blurred orbs that echo
   the primary / tertiary theme tones. Lives in the shared stylesheet
   (not a scoped .razor.css) so NotFound + AccessDenied + Error can
   all reuse the same chassis without their own duplicated CSS.

   position: fixed + inset: 0 is deliberate — a min-height: 100dvh
   flex approach competed with body-level sizing in some layouts and
   let the card drift toward the top.
   ============================================================ */

/* Cinematic login canvas — three radial blooms layered over the
   off-white Silk surface. Primary lavender top-left, mint
   bottom-right, peach top-right kiss for warmth. Then two large
   orbs paint on top of the gradient for a sense of light hitting
   silk fabric. */
.login-canvas {
    position: fixed;
    inset: 0;
    display: grid;
    place-items: center;
    padding: clamp(1.5rem, 4vw, 3rem);
    overflow: hidden;
    background:
        radial-gradient(ellipse 80% 60% at 18% -5%,
            color-mix(in oklab, var(--color-primary-container) 75%, transparent),
            transparent 55%),
        radial-gradient(ellipse 70% 60% at 85% 105%,
            color-mix(in oklab, var(--color-secondary-container) 65%, transparent),
            transparent 55%),
        radial-gradient(ellipse 35% 30% at 92% 8%,
            color-mix(in oklab, var(--color-tertiary-container) 80%, transparent),
            transparent 60%),
        var(--color-surface);
    color-scheme: light;
    z-index: 0;
}

.login-orb {
    position: absolute;
    border-radius: 9999px;
    filter: blur(120px);
    pointer-events: none;
    z-index: 0;
}

.login-orb-primary {
    width: 44rem;
    height: 44rem;
    background: var(--color-primary);
    opacity: 0.32;
    top: -16rem;
    left: -12rem;
}

.login-orb-tertiary {
    width: 36rem;
    height: 36rem;
    background: var(--color-secondary);
    opacity: 0.28;
    bottom: -12rem;
    right: -10rem;
}

/* Login card — pure white glass at high opacity (88%), heavier
   blur (28px) and a richer triple-layered shadow so the card
   reads as floating in front of the orbs. The 32px radius matches
   the design system's "card-2xl" spec. */
.login-card {
    position: relative;
    z-index: 1;
    width: 100%;
    max-width: 34rem;
    padding: clamp(2.25rem, 4vw, 3.25rem) clamp(2rem, 3.5vw, 3rem);
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    backdrop-filter: blur(28px) saturate(160%);
    -webkit-backdrop-filter: blur(28px) saturate(160%);
    background: rgba(255, 255, 255, 0.78);
    border: 1px solid var(--silk-edge-strong);
    box-shadow: var(--shadow-silk-hero);
    border-radius: var(--radius-card-2xl);
}

.login-brand {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.login-brand-icon {
    font-size: 48px;
    color: var(--color-primary);
    flex-shrink: 0;
    filter: drop-shadow(0 4px 12px color-mix(in oklab, var(--color-primary) 25%, transparent));
}

.login-title {
    font-family: var(--font-headline);
    font-weight: 800;
    font-size: clamp(1.75rem, 3.5vw, 2.25rem);
    line-height: 1.05;
    letter-spacing: -0.025em;
    margin: 0.25rem 0 0;
    color: var(--color-on-surface);
    /* FocusOnNavigate puts focus on the h1 — suppress the browser's
       default focus ring so the editorial headline isn't boxed. */
    outline: none;
}

.login-sub {
    color: var(--color-on-surface-variant);
    font-size: 0.9375rem;
    line-height: 1.6;
    margin: 0;
}

.login-alert {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0.875rem;
    width: fit-content;
    font-size: 0.875rem;
    font-weight: 600;
}

.login-alert-icon {
    font-size: 18px;
}

/* ---------- Login form ------------------------------------------ */

.login-form {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    margin-top: 0.25rem;
}

.login-field {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.login-field-label {
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--color-on-surface-variant);
}

.login-field-input-wrap {
    position: relative;
    display: flex;
    align-items: center;
}

.login-field-icon {
    position: absolute;
    left: 1rem;
    font-size: 20px;
    color: var(--color-on-surface-variant);
    pointer-events: none;
    z-index: 1;
}

.login-field-input {
    width: 100%;
    padding-left: 2.875rem !important;
    padding-top: 0.875rem !important;
    padding-bottom: 0.875rem !important;
    font-size: 0.9375rem;
}

/* Remember-me row. Sits between the password field and the submit
   button. Native checkbox tinted to the brand primary so the affordance
   is visible without a custom-built checkbox component. */
.login-remember {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.875rem;
    color: var(--color-on-surface-variant);
    cursor: pointer;
    user-select: none;
    margin-top: -0.25rem;
}

.login-remember input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    accent-color: var(--color-primary);
    cursor: pointer;
}

.login-submit {
    margin-top: 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.875rem 1.25rem !important;
    font-size: 0.9375rem;
}

.login-submit-icon {
    font-size: 20px;
}

.login-footer {
    margin-top: 0.75rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--color-outline-variant);
    text-align: center;
}

.login-footer-hint {
    font-size: 0.6875rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-on-surface-variant);
    opacity: 0.8;
}

/* ---------- Authorizing spinner --------------------------------- */

.auth-loading {
    min-height: 40dvh;
    display: flex;
    align-items: center;
    justify-content: center;
}
.auth-loading-icon {
    font-size: 32px;
    color: var(--color-primary);
    animation: auth-spin 1s linear infinite;
}
@keyframes auth-spin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

/* ---------- Access-denied variant ------------------------------- */

.access-denied-card {
    text-align: left;
}
.access-denied-icon {
    color: var(--color-error);
}
.access-denied-actions {
    margin-top: 0.5rem;
}
.access-denied-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
}
.access-denied-btn-icon {
    font-size: 18px;
}

/* ---------- "Signing out…" transition --------------------------- */

.signing-out-spinner {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 3rem;
    height: 3rem;
    border-radius: 9999px;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    margin-bottom: 0.5rem;
}
.signing-out-spinner .material-symbols-outlined {
    font-size: 24px;
    animation: auth-spin 1s linear infinite;
}

/* ============================================================
   User profile — tabbed layout used at /users/{id} and /admins/{id}.
   Two-column shell: identity card on the left, tabs + panel on the
   right. Falls back to single-column under ~860px so the rail
   doesn't strangle the form widths on smaller laptops.
   ============================================================ */

.profile-page-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
}

.profile-shell {
    display: grid;
    grid-template-columns: 22rem minmax(0, 1fr);
    gap: 1.5rem;
    align-items: start;
}
@media (max-width: 980px) {
    .profile-shell {
        grid-template-columns: 1fr;
    }
}

.profile-rail {
    position: sticky;
    top: 1rem;
    align-self: start;
}
@media (max-width: 980px) {
    .profile-rail {
        position: static;
    }
}

.profile-card {
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.5rem;
}

.profile-avatar {
    width: 5rem;
    height: 5rem;
    border-radius: 9999px;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: var(--font-headline);
    font-size: 2rem;
    font-weight: 700;
    margin-bottom: 0.5rem;
}

.profile-name {
    font-family: var(--font-headline);
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--color-on-surface);
    margin: 0;
}

.profile-role-line {
    font-size: 0.875rem;
    color: var(--color-on-surface-variant);
    margin: 0;
}

.profile-divider {
    width: 100%;
    height: 1px;
    background: var(--color-outline-variant);
    margin: 1rem 0 0.5rem;
}

.profile-card .label-eyebrow {
    align-self: flex-start;
    margin: 0.5rem 0 0.25rem;
}

.profile-details {
    width: 100%;
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 0.375rem 1rem;
    font-size: 0.875rem;
    text-align: left;
}
.profile-details dt {
    color: var(--color-on-surface-variant);
    font-weight: 500;
}
.profile-details dd {
    margin: 0;
    color: var(--color-on-surface);
    word-break: break-word;
}
.profile-details a {
    color: var(--color-primary);
    text-decoration: none;
}
.profile-details a:hover {
    text-decoration: underline;
}

.profile-detail-sub {
    display: block;
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
    margin-top: 0.125rem;
}

.profile-chip {
    margin-left: 0.375rem;
    vertical-align: middle;
}

.profile-tags-eyebrow {
    align-self: flex-start;
    margin: 0.75rem 0 0.375rem;
}

.profile-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.375rem;
    width: 100%;
    justify-content: flex-start;
}
.profile-tag {
    background: var(--color-surface-container);
    color: var(--color-on-surface);
    padding: 0.25rem 0.625rem;
    border-radius: 9999px;
    font-size: 0.75rem;
    font-weight: 500;
}

/* ---------- TABS ---------- */

.profile-pane {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.profile-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
    border-bottom: 1px solid var(--color-outline-variant);
    margin-bottom: 1rem;
    background: var(--color-surface);
    padding: 0.25rem 0.25rem 0;
    border-radius: 0.625rem 0.625rem 0 0;
}
.profile-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.625rem 0.875rem;
    background: transparent;
    border: 0;
    border-radius: 0.5rem 0.5rem 0 0;
    color: var(--color-on-surface-variant);
    font-family: var(--font-headline);
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color var(--transition-fast), background var(--transition-fast);
}
.profile-tab:hover {
    color: var(--color-on-surface);
    background: var(--color-surface-container);
}
.profile-tab.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
    background: var(--color-surface);
}
.profile-tab-icon {
    font-size: 1.125rem;
}

.profile-panel {
    background: var(--color-surface);
    border: 1px solid var(--color-outline-variant);
    border-radius: 0.875rem;
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* ---------- TIMELINE ---------- */

.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
    /* Vertical rail behind the markers — runs the full height of the
       feed so each item appears strung along it. */
    position: relative;
}

.timeline-item {
    display: grid;
    grid-template-columns: 2.5rem minmax(0, 1fr);
    gap: 0.75rem;
    padding: 0.625rem 0;
    position: relative;
}
.timeline-item:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 1.25rem;
    top: 2.75rem;
    bottom: -0.625rem;
    width: 2px;
    background: var(--color-outline-variant);
    transform: translateX(-1px);
}

.timeline-marker {
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 9999px;
    background: var(--color-primary-container);
    color: var(--color-on-primary-container);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    z-index: 1;
}
.timeline-marker .material-symbols-outlined {
    font-size: 1.25rem;
    color: var(--color-primary);
}

.timeline-content {
    min-width: 0;
}
.timeline-summary {
    font-family: var(--font-headline);
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--color-on-surface);
    margin: 0 0 0.125rem;
}
.timeline-detail {
    font-size: 0.8125rem;
    color: var(--color-on-surface-variant);
    margin: 0 0 0.25rem;
    word-break: break-word;
}
.timeline-meta {
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
    margin: 0;
    display: flex;
    gap: 0.375rem;
    align-items: center;
}
.timeline-actor {
    color: var(--color-primary);
}

/* Severity accents — Error rows must jump out of the biography (a beta
   tester killing the Accessibility Service stops their diagnostics
   capture); Warning gets a chip only. Info stays the unmarked default. */
.timeline-item--error .timeline-marker {
    background: var(--color-error-container);
}
.timeline-item--error .timeline-marker .material-symbols-outlined {
    color: var(--color-error);
}
.timeline-item--error .timeline-summary {
    color: var(--color-error);
}
.timeline-severity {
    margin-left: 0.5rem;
    padding: 0.125rem 0.5rem;
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    vertical-align: 0.0625rem;
}

/* ---------- Profile head action buttons ---------- */

.profile-action-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
}

/* ---------- Connected-services widget tiles ---------- */

.profile-widgets {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.75rem;
    margin-top: 1rem;
}
@media (max-width: 980px) {
    .profile-widgets {
        grid-template-columns: 1fr 1fr 1fr;
    }
}
@media (max-width: 600px) {
    .profile-widgets {
        grid-template-columns: 1fr 1fr;
    }
}

.profile-widget {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.875rem;
    background: var(--color-surface);
    border: 1px solid var(--color-outline-variant);
    border-radius: 0.875rem;
    color: var(--color-on-surface);
    text-decoration: none;
    cursor: pointer;
    transition: background var(--transition-fast), border-color var(--transition-fast);
}
.profile-widget:hover {
    border-color: color-mix(in srgb, var(--color-primary) 50%, var(--color-outline-variant));
    background: var(--color-surface-container);
}
.profile-widget-icon {
    font-size: 1.5rem;
    color: var(--color-primary);
    flex-shrink: 0;
}
.profile-widget-meta {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
    min-width: 0;
}
.profile-widget-label {
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
}
.profile-widget-value {
    font-family: var(--font-headline);
    font-size: 1.125rem;
    font-weight: 700;
    color: var(--color-on-surface);
}

.profile-widget-add {
    border-style: dashed;
    color: var(--color-on-surface-variant);
}

/* ---------- Profile data tables (sessions / audit / logs) ---------- */

.profile-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}
.profile-table thead th {
    text-align: left;
    padding: 0.5rem 0.625rem;
    font-family: var(--font-headline);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--color-on-surface-variant);
    border-bottom: 1px solid var(--color-outline-variant);
}
.profile-table tbody td {
    padding: 0.625rem 0.625rem;
    border-bottom: 1px solid var(--color-outline-variant);
    vertical-align: top;
    color: var(--color-on-surface);
}
.profile-table tbody tr:last-child td {
    border-bottom: 0;
}
.profile-table-mono {
    font-family: var(--font-mono, ui-monospace, "JetBrains Mono", monospace);
    font-size: 0.8125rem;
    color: var(--color-on-surface);
    display: block;
}
.profile-table-sub {
    display: block;
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
    margin-top: 0.125rem;
}
/* Muted placeholder for cells with no value (e.g. sessions minted
   before the client reported an app version). */
.profile-table-dim {
    color: var(--color-on-surface-variant);
}

/* ---------- Calendar tab (read-only day inspector) ---------- */

.cal-readonly-chip {
    margin-left: 0.5rem;
    vertical-align: middle;
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.cal-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.25rem 0 1.25rem;
}
.cal-nav-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem;
    line-height: 1;
}
.cal-date-input { min-width: 11rem; }
.cal-today-btn { padding-inline: 0.9rem; }
.cal-weekday {
    margin-left: auto;
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--color-on-surface-variant);
}

.cal-stats {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0.875rem;
    margin-bottom: 1.25rem;
}
@media (max-width: 720px) {
    .cal-stats { grid-template-columns: 1fr; }
    .cal-weekday { margin-left: 0; width: 100%; }
}
.cal-stat {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    padding: 1rem 1.1rem;
    border: 1px solid var(--color-outline-variant);
    border-radius: var(--radius-tile, 0.875rem);
    background: color-mix(in oklab, var(--color-surface-container-lowest) 70%, transparent);
}
.cal-stat-accent {
    border-color: color-mix(in oklab, var(--color-primary) 35%, var(--color-outline-variant));
    background: color-mix(in oklab, var(--color-primary-container) 35%, var(--color-surface-container-lowest));
}
.cal-stat-label {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-on-surface-variant);
}
.cal-stat-value {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
    color: var(--color-on-surface);
    font-variant-numeric: tabular-nums;
}
.cal-stat-accent .cal-stat-value { color: var(--color-primary); }
.cal-stat-sub {
    font-size: 0.75rem;
    color: var(--color-on-surface-variant);
}

.cal-config-hint {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: -0.5rem 0 1.25rem;
    padding: 0.6rem 0.85rem;
    font-size: 0.8125rem;
    color: var(--color-on-surface-variant);
    border-radius: 0.75rem;
    background: var(--color-surface-container-high);
    border-left: 2px solid var(--color-outline-variant);
}
.cal-config-hint .material-symbols-outlined { font-size: 1.125rem; }

.cal-section-eyebrow { margin: 1.5rem 0 0.5rem; }
.cal-clinic-table { margin-bottom: 0.5rem; }
.cal-noconfig-chip { font-size: 0.6875rem; }

.cal-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    font-size: 0.8125rem;
    line-height: 1;
}
.cal-view-btn .material-symbols-outlined { font-size: 1.05rem; }
.cal-view-btn:disabled { opacity: 0.4; cursor: not-allowed; }

.cal-detail-row > td {
    padding: 0.5rem 0.75rem 1rem;
    background: color-mix(in oklab, var(--color-surface-container-high) 55%, transparent);
}
.cal-line-table { margin: 0; }
.cal-line-table th,
.cal-line-table td { font-size: 0.8125rem; }
.cal-rule-chip { font-size: 0.6875rem; }
/* Tooth tag — tertiary accent so it reads distinctly from rule chips. */
.cal-tooth-chip {
    font-size: 0.6875rem;
    font-weight: 700;
    background: color-mix(in oklab, var(--color-tertiary, var(--color-primary)) 18%, var(--color-surface-container-lowest));
    color: var(--color-tertiary, var(--color-primary));
    border: 1px solid color-mix(in oklab, var(--color-tertiary, var(--color-primary)) 35%, transparent);
}

/* ---------- Procedures tab — multi-named pricing ---------- */

.price-options {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    min-width: 11rem;
}
.price-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.3rem 0.5rem;
    border-radius: 0.5rem;
    border: 1px solid var(--color-outline-variant);
    background: color-mix(in oklab, var(--color-surface-container-lowest) 70%, transparent);
}
/* Default price reads in primary — same accent as the in-app picker radio. */
.price-option.is-default {
    border-color: color-mix(in oklab, var(--color-primary) 40%, var(--color-outline-variant));
    background: color-mix(in oklab, var(--color-primary-container) 30%, var(--color-surface-container-lowest));
}
.price-option-label {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--color-on-surface);
}
.price-option-star {
    font-size: 1rem;
    color: var(--color-primary);
    font-variation-settings: 'FILL' 1;
}
/* Inline variant used in the section blurb — sits on the text baseline. */
.price-option-star-inline {
    font-size: 1rem;
    vertical-align: text-bottom;
    color: var(--color-primary);
    font-variation-settings: 'FILL' 1;
}
.price-option-tag {
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    padding: 0.05rem 0.3rem;
    border-radius: 0.375rem;
    color: var(--color-primary);
    background: color-mix(in oklab, var(--color-primary) 14%, transparent);
}
.price-option-amount {
    font-family: var(--font-headline, inherit);
    font-weight: 700;
    font-size: 0.8125rem;
    color: var(--color-on-surface);
    font-variant-numeric: tabular-nums;
}
.price-option.is-default .price-option-amount { color: var(--color-primary); }

/* ---------- Empty states (Invoices, etc.) ---------- */

.profile-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 2rem 1rem;
    gap: 0.5rem;
    border: 1px dashed var(--color-outline-variant);
    border-radius: 0.875rem;
}
.profile-empty-icon {
    font-size: 2.5rem;
    color: var(--color-on-surface-variant);
    margin-bottom: 0.25rem;
}
.profile-empty-title {
    font-family: var(--font-headline);
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-on-surface);
    margin: 0;
}
.profile-empty-sub {
    font-size: 0.875rem;
    color: var(--color-on-surface-variant);
    margin: 0;
    max-width: 32rem;
}

/* ---------- Danger panel — multiple sections (roles + delete) ---------- */

.danger-section {
    padding-top: 1rem;
    margin-top: 1rem;
    border-top: 1px dashed var(--color-outline-variant);
}
.danger-section:first-of-type {
    padding-top: 0;
    margin-top: 0;
    border-top: 0;
}

/* ---------- Invoice editor line items ----------------------------
   The original layout was a <table> with fixed pixel widths, so when
   the editor sat inside a tabbed panel the inputs spilled out of their
   cells and overlapped. Switching to CSS grid lets columns resize
   responsively while keeping the right rail (Qty / Unit / Total /
   remove-button) compact. The Description cell stacks a "Choose plan"
   helper select on top of the text input so the form has a quick way
   to seed a line from a Plan without us re-adding a top-level Plan
   dropdown.

   Grid template (desktop): description gets all the slack; the
   numeric cells take only what they need; the remove button is a
   thumb-sized button column. On narrow viewports we drop down to two
   columns (description on top, the numerics in their own row) so the
   inputs never have to squeeze. */
.invoice-lines {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.invoice-lines-head,
.invoice-line-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 4.5rem 7rem 6rem 2.5rem;
    gap: 0.5rem 0.75rem;
    align-items: start;
}
.invoice-lines-head {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-on-surface-variant);
    padding: 0 0.25rem;
}
.invoice-line-desc {
    display: flex;
    flex-direction: column;
    gap: 0.375rem;
    min-width: 0;
}
.invoice-line-plan {
    font-size: 0.8125rem;
    padding-top: 0.5rem !important;
    padding-bottom: 0.5rem !important;
    color: var(--color-on-surface-variant);
}
.invoice-line-num {
    text-align: right;
    min-width: 0;
}
.invoice-line-total {
    align-self: center;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.invoice-line-remove {
    justify-self: center;
    align-self: center;
}
.invoice-lines-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 0.5rem;
    padding-top: 0.5rem;
    border-top: 1px dashed var(--color-outline-variant);
}
.invoice-lines-subtotal {
    font-variant-numeric: tabular-nums;
    color: var(--color-on-surface-variant);
}
.invoice-lines-subtotal strong {
    color: var(--color-on-surface);
    margin-left: 0.5rem;
    font-size: 1rem;
}
@media (max-width: 640px) {
    /* Narrow stack: hide the column-headers row and re-flow each line
       into a 3-up strip — description spans across with the remove
       button pinned right, numerics tile below. */
    .invoice-lines-head { display: none; }
    .invoice-line-row {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) 2.5rem;
    }
    .invoice-line-desc {
        grid-column: 1 / -1;
    }
    .invoice-line-remove {
        grid-column: 4;
        grid-row: 1;
        justify-self: end;
    }
    .invoice-line-desc + .invoice-line-num,
    .invoice-line-num + .invoice-line-num,
    .invoice-line-total {
        grid-row: 2;
    }
}
