/* /Components/Account/Pages/Invitations/MyInvitations.razor.rz.scp.css */
/*
 * /account/invitations - card-grid layout for pending invitations.
 * Each invitation renders as an article (own form, own button) so a
 * tampered hidden input only affects its own row.
 */

.my-invitations__grid[b-etpt32a3ts] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-4);
    margin-top: var(--space-4);
}

.my-invitations__error[b-etpt32a3ts] {
    margin: var(--space-2) 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid color-mix(in srgb, var(--color-danger) 30%, transparent);
    background: color-mix(in srgb, var(--color-danger) 8%, var(--color-surface));
    color: var(--color-danger);
}

.my-invitations__empty-link[b-etpt32a3ts] {
    color: var(--color-brand);
    text-decoration: none;
    font-weight: var(--font-weight-medium);
}

    .my-invitations__empty-link:hover[b-etpt32a3ts] {
        text-decoration: underline;
    }

    .my-invitations__empty-link:focus-visible[b-etpt32a3ts] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-radius: var(--radius-sm);
    }

.invitation-card[b-etpt32a3ts] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    transition:
        transform var(--motion-duration-fast) var(--motion-easing-standard),
        box-shadow var(--motion-duration-fast) var(--motion-easing-standard);
}

    .invitation-card:hover[b-etpt32a3ts] {
        transform: translateY(-1px);
        box-shadow: var(--shadow-md);
    }

.invitation-card__header[b-etpt32a3ts] {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-3);
}

.invitation-card__title[b-etpt32a3ts] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
    line-height: var(--line-height-tight);
    overflow-wrap: anywhere;
}

.invitation-card__meta[b-etpt32a3ts] {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
}

.invitation-card__meta-row[b-etpt32a3ts] {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

    .invitation-card__meta-row dt[b-etpt32a3ts] {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        text-transform: uppercase;
        letter-spacing: var(--letter-spacing-wide);
        color: var(--color-text-muted);
    }

    .invitation-card__meta-row dd[b-etpt32a3ts] {
        margin: 0;
        color: var(--color-text);
    }

.invitation-card__expiry[b-etpt32a3ts] {
    color: var(--color-text-muted);
}

.invitation-card__form[b-etpt32a3ts] {
    margin: 0;
    margin-top: var(--space-2);
}

/* The Accept button uses the app-shell submit-button styling already
   inherited from app.css - only override max-width so it sits naturally
   inside the card. */
.invitation-card__accept[b-etpt32a3ts] {
    width: 100%;
    max-width: none;
}

@media (forced-colors: active) {
    .invitation-card[b-etpt32a3ts] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }

    .my-invitations__error[b-etpt32a3ts] {
        border: 1px solid CanvasText;
        background: Canvas;
    }
}

@media (prefers-reduced-motion: reduce) {
    .invitation-card[b-etpt32a3ts] {
        transition: none;
    }

    .invitation-card:hover[b-etpt32a3ts] {
        transform: none;
    }
}
/* /Components/Account/Pages/Manage/DevicesTable.razor.rz.scp.css */
/* Revoke status banner - mirrors the platform-users table tones so the
   account surface and the admin surfaces read the same. */
.account-devices__status[b-6x2jvwf3xm] {
    margin: 0 0 var(--space-3, 0.75rem);
    padding: var(--space-2, 0.5rem) 0.75rem;
    border-radius: var(--radius-md, 0.25rem);
}

.account-devices__status--ok[b-6x2jvwf3xm] {
    background: color-mix(in srgb, var(--color-info) 14%, var(--color-surface));
    color: var(--color-info);
}

.account-devices__status--error[b-6x2jvwf3xm] {
    background: color-mix(in srgb, var(--color-danger) 14%, var(--color-surface));
    color: var(--color-danger);
}

/* Toolbar "Revoke all" - a quiet secondary control that escalates to the
   danger tone on hover/focus, signalling the destructive intent. */
.account-devices__revoke-all[b-6x2jvwf3xm] {
    min-height: var(--target-size-minimum, 1.5rem);
    padding: var(--space-2, 0.5rem) 0.75rem;
    border: 1px solid var(--color-border, #d6d6d6);
    border-radius: var(--radius-md, 0.25rem);
    background: var(--color-surface, #ffffff);
    color: var(--color-danger, #b3261e);
    font: inherit;
    cursor: pointer;
}

.account-devices__revoke-all:hover:not(:disabled)[b-6x2jvwf3xm] {
    background: var(--color-danger-surface, #b3261e);
    color: var(--color-danger-on-surface, #ffffff);
    border-color: var(--color-danger-surface, #b3261e);
}

.account-devices__revoke-all:focus-visible[b-6x2jvwf3xm] {
    outline: 2px solid var(--color-focus-ring, #3b82f6);
    outline-offset: 2px;
}

.account-devices__revoke-all:disabled[b-6x2jvwf3xm] {
    opacity: 0.5;
    cursor: not-allowed;
}
/* /Components/Account/Pages/Manage/EnableAuthenticator.razor.rz.scp.css */
/* /account/manage/enableauthenticator - two stacked surface cards.
   The shared .surface-card recipe ships the border/shadow/radius;
   this file lays out the header rhythm, the steps list, the
   shared-key read-out, and the QR figure. */

.account-enable-auth-card[b-imx0h8wi12] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-6);
    inline-size: 100%;
}

.account-enable-auth-card__header[b-imx0h8wi12] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-enable-auth-card__heading[b-imx0h8wi12] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-enable-auth-card__steps[b-imx0h8wi12] {
    margin: 0;
    padding-inline-start: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    color: var(--color-text);
    line-height: var(--line-height-snug);
}

/* Shared-key read-out - label/value pair with the mono-styled key. */
.account-enable-auth-card__data[b-imx0h8wi12] {
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-1) var(--space-3);
    align-items: center;
}

    .account-enable-auth-card__data dt[b-imx0h8wi12] {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        text-transform: uppercase;
        letter-spacing: var(--letter-spacing-wide);
        color: var(--color-text-muted);
    }

    .account-enable-auth-card__data dd[b-imx0h8wi12] {
        margin: 0;
        color: var(--color-text);
        font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
        overflow-wrap: anywhere;
    }

    .account-enable-auth-card__data code[b-imx0h8wi12] {
        font-family: inherit;
        font-size: var(--font-size-base);
    }

/* QR figure - the QRCoder SVG is fixed-size; constrain the figure and
   force the SVG to fill it so the code stays inside the card on narrow
   phones (without this, the fixed-width SVG can overflow and trigger
   page-level horizontal scroll). `::deep` reaches into the SVG that
   MarkupString emits below the figure's scope attribute. */
.account-enable-auth-card__qr[b-imx0h8wi12] {
    max-inline-size: 16rem;
    margin-inline: auto;
    margin-block: 0;
}

    .account-enable-auth-card__qr[b-imx0h8wi12]  svg {
        inline-size: 100%;
        block-size: auto;
        max-inline-size: 100%;
    }

.account-enable-auth-card__provisioning[b-imx0h8wi12] {
    margin: 0;
    text-align: center;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* Cancel sits alongside the Submit button in the .form-actions row as
   a plain text link - same treatment as the Confirm Identity page. */
.account-enable-auth-card__cancel[b-imx0h8wi12] {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--target-size-minimum, 2.75rem);
    padding-inline: var(--space-3);
    color: var(--color-text-muted);
    text-decoration: none;
    border-radius: var(--radius-md);
}

    .account-enable-auth-card__cancel:hover[b-imx0h8wi12],
    .account-enable-auth-card__cancel:focus-visible[b-imx0h8wi12] {
        color: var(--color-text);
        text-decoration: underline;
    }

    .account-enable-auth-card__cancel:focus-visible[b-imx0h8wi12] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }
/* /Components/Account/Pages/Manage/Index.razor.rz.scp.css */
/*
 * /account/manage - profile + security hub. PageHeader drives the
 * hero; this file styles the Profile section card + Security action
 * grid. Inputs and labels inherit from the shell-wide rules in
 * app.css so the form chrome stays consistent with auth + settings.
 */

.account-manage__section[b-21sfvfr1wq] {
    margin-top: var(--space-6);
}

.account-manage__section-header[b-21sfvfr1wq] {
    margin-bottom: var(--space-4);
}

.account-manage__section-heading[b-21sfvfr1wq] {
    margin: 0 0 var(--space-1);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-manage__section-description[b-21sfvfr1wq] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
    max-width: 60ch;
}

/* Profile card holds the read-only email row + the display-name form.
   Token-driven hairline + radius so it reads as a discrete surface.
   Full-width to match the other manage cards; the input inside still
   caps at the 32rem .settings-form rule. */
.account-manage__profile-card[b-21sfvfr1wq] {
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    box-shadow: var(--shadow-sm);
    inline-size: 100%;
}

/* Display-name input inside the profile card caps at a comfortable
   reading width on large viewports - the global shell rule sets
   `width: 100%`, which would otherwise span the entire card now that
   it goes full-width. Mirrors the .settings-form cap and the
   account-form-card pattern.
   `::deep` is required because the <input> is rendered by an
   <InputText> child component; Blazor's CSS isolation otherwise tags
   only this component's own elements with the scope attribute, so
   the rule wouldn't match. */
.account-manage__profile-card[b-21sfvfr1wq]  input[type="text"],
.account-manage__profile-card[b-21sfvfr1wq]  input[type="email"],
.account-manage__profile-card[b-21sfvfr1wq]  input:not([type]) {
    max-inline-size: 32rem;
}

.account-manage__email[b-21sfvfr1wq] {
    margin: 0 0 var(--space-4);
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-1) var(--space-3);
}

    .account-manage__email dt[b-21sfvfr1wq] {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        text-transform: uppercase;
        letter-spacing: var(--letter-spacing-wide);
        color: var(--color-text-muted);
        align-self: center;
    }

    .account-manage__email dd[b-21sfvfr1wq] {
        margin: 0;
        color: var(--color-text);
    }

.account-manage__tile-grid[b-21sfvfr1wq] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--space-3);
}

.account-manage__action-grid[b-21sfvfr1wq] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: var(--space-3);
}

@media (forced-colors: active) {
    .account-manage__profile-card[b-21sfvfr1wq] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }
}

@media (max-width: 599px) {
    .account-manage__profile-card[b-21sfvfr1wq] {
        padding: var(--space-4);
    }
}
/* /Components/Account/Pages/Manage/RecoveryEmail.razor.rz.scp.css */
/* /account/manage/recovery-email - surface cards under the hero
   tiles. The shared .surface-card recipe ships the border / shadow /
   radius; this file only adds the header rhythm and the side-by-side
   "Replace" + "Remove" grid for the verified state. */

.account-recovery-card[b-rb29ec7iha] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-6);
    /* Full-width on every state - verified, pending, and not-configured
       all want the card to anchor the page rather than float as a
       narrow strip. The destructive `--danger` variant inherits the
       same width without an override. */
    inline-size: 100%;
}

.account-recovery-card__header[b-rb29ec7iha] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-recovery-card__heading[b-rb29ec7iha] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-recovery-card__description[b-rb29ec7iha] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

/* Verified address read-out - small label/value pair inside the
   verified-state card, mirroring the email block on /account/manage. */
.account-recovery-card__data[b-rb29ec7iha] {
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-1) var(--space-3);
}

    .account-recovery-card__data dt[b-rb29ec7iha] {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        text-transform: uppercase;
        letter-spacing: var(--letter-spacing-wide);
        color: var(--color-text-muted);
        align-self: center;
    }

    .account-recovery-card__data dd[b-rb29ec7iha] {
        margin: 0;
        color: var(--color-text);
        font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    }

/* Two-card row shown when a recovery email is already verified -
   one Replace card, one Remove card, side-by-side on wide viewports
   and stacked on narrow. The grid lives BELOW the read-only summary
   card; .account-recovery-card's own margin-top stacks each card with
   the same rhythm as the standalone state cards. */
.account-recovery-cards[b-rb29ec7iha] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-4);
    margin-top: var(--space-4);
    max-width: 60rem;
}

    .account-recovery-cards .account-recovery-card[b-rb29ec7iha] {
        margin-top: 0;
        max-width: none;
    }

.account-recovery-card--danger[b-rb29ec7iha] {
    border-color: var(--color-danger, var(--color-border-subtle));
}
/* /Components/Account/Pages/Manage/RemoveRecoveryEmail.razor.rz.scp.css */
/* /account/manage/recovery-email/remove - scoped chrome.
   The shared .surface-card recipe ships the border/shadow/radius;
   this file overrides browser user-agent defaults the global
   stylesheet doesn't (the <dl> 40px margin) and pins the danger
   card to full container width so the destructive confirm + cancel
   row reads as the focal surface of the page. */

.account-recovery-card[b-fs7on45kpg] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-6);
    /* Stretch to the container width on this destructive page so the
       Confirm + Cancel row is visually anchored. The main settings
       page constrains its cards to 40rem; here the page IS the
       destructive action, so full width reads correctly. */
    inline-size: 100%;
    max-inline-size: 100%;
}

.account-recovery-card__data[b-fs7on45kpg] {
    /* Override the user-agent `<dl>` margin (40px inline-start) so the
       label / value pair reads flush with the card's padding. */
    margin: 0;
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-1) var(--space-3);
}

    .account-recovery-card__data dt[b-fs7on45kpg] {
        font-size: var(--font-size-xs);
        font-weight: var(--font-weight-semibold);
        text-transform: uppercase;
        letter-spacing: var(--letter-spacing-wide);
        color: var(--color-text-muted);
        align-self: center;
    }

    .account-recovery-card__data dd[b-fs7on45kpg] {
        margin: 0;
        color: var(--color-text);
        font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    }

.account-recovery-card--danger[b-fs7on45kpg] {
    border-color: var(--color-danger, var(--color-border-subtle));
}
/* /Components/Account/Pages/Manage/SetupLocalAccess.razor.rz.scp.css */
/* Setup-local-access checklist card. The step rows are flex so the
   status glyph, label, and hint/action read as separated columns -
   without this the inline spans run together ("Choose a passwordAlready
   set"). Tokens only; no page-specific colors. */

.setup-local-card[b-550vdpddtd] {
    max-width: 34rem;
}

.setup-local-card__header[b-550vdpddtd] {
    margin-bottom: var(--space-4);
}

.setup-local-card__heading[b-550vdpddtd] {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-lg);
}

.setup-local-card__description[b-550vdpddtd] {
    margin: 0;
    color: var(--color-text-muted);
}

.setup-local-card__steps[b-550vdpddtd] {
    list-style: none;
    margin: 0 0 var(--space-5);
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.setup-local-card__step[b-550vdpddtd] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
}

.setup-local-card__step-status[b-550vdpddtd] {
    flex: none;
    width: 1.25rem;
    text-align: center;
    font-weight: var(--font-weight-semibold);
}

.setup-local-card__step[data-state="done"] .setup-local-card__step-status[b-550vdpddtd] {
    color: var(--color-success, #15803d);
}

.setup-local-card__step-label[b-550vdpddtd] {
    font-weight: var(--font-weight-semibold);
}

.setup-local-card__step-hint[b-550vdpddtd] {
    color: var(--color-text-muted);
}

.setup-local-card__step-hint[b-550vdpddtd]::before,
.setup-local-card__step-action[b-550vdpddtd]::before {
    /* Typographic separator between the label and its status/action so
       the pair never reads as one word. */
    content: "-";
    margin-inline-end: var(--space-2);
    color: var(--color-text-muted);
}

.setup-local-card__continue[b-550vdpddtd] {
    margin: 0;
}

.setup-local-card__continue-hint[b-550vdpddtd] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}
/* /Components/Account/Pages/Manage/ShowRecoveryCodes.razor.rz.scp.css */
/* /account/manage/showrecoverycodes - one-shot recovery-code reveal
   wrapped in a surface card. The shared .surface-card recipe ships
   the border/shadow/radius; this file lays out the header rhythm,
   the codes grid, and the trailing "Done" button. */

.account-recovery-codes-card[b-ssejn355h2] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-top: var(--space-4);
    inline-size: 100%;
}

.account-recovery-codes-card__header[b-ssejn355h2] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-recovery-codes-card__heading[b-ssejn355h2] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-recovery-codes-card__description[b-ssejn355h2] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

/* Codes laid out as a responsive 2 / 3 / 5-column grid (instead of a
   tall bulleted list) so the user can scan / paste all of them at
   once. Each cell is a monospace block with a subtle border so the
   group reads as a printable receipt rather than body copy. */
.account-recovery-codes-card__list[b-ssejn355h2] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: var(--space-2);
}

.account-recovery-codes-card__item[b-ssejn355h2] {
    margin: 0;
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--color-surface-sunken, var(--color-surface));
    text-align: center;
}

    .account-recovery-codes-card__item code[b-ssejn355h2] {
        font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
        font-size: var(--font-size-base);
        color: var(--color-text);
        word-break: break-all;
        overflow-wrap: anywhere;
    }

.account-recovery-codes-card__store[b-ssejn355h2] {
    margin: 0;
    color: var(--color-text-muted);
}

.account-recovery-codes-card__done[b-ssejn355h2] {
    margin: 0;
}

.account-recovery-codes-card--banner p[b-ssejn355h2] {
    margin: 0;
    color: var(--color-text);
}
/* /Components/Account/Pages/Manage/TwoFactor.razor.rz.scp.css */
/* /account/manage/twofactor - one card per credential category
   (Authenticator app, Passkeys) under the hero tiles. The shared
   .surface-card recipe ships the border/shadow/radius; this file
   only adds the grid layout, header rhythm, and a tidied bulletless
   link list. */

.account-twofactor-cards[b-4lqhvg00gr] {
    margin-top: var(--space-6);
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-4);
    /* Full-width on the page - the two-card row should anchor the
       layout below the hero tiles rather than float as a narrow
       strip on wide viewports. The per-card minmax(20rem, 1fr) still
       collapses to a single column under ~640px. */
    inline-size: 100%;
}

.account-twofactor-card[b-4lqhvg00gr] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.account-twofactor-card__header[b-4lqhvg00gr] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-twofactor-card__heading[b-4lqhvg00gr] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-twofactor-card__description[b-4lqhvg00gr] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

.account-twofactor-card__list[b-4lqhvg00gr] {
    list-style: none;
    /* Push the action list to the bottom of the card so the buttons
       on Authenticator + Passkeys cards line up at the same vertical
       position regardless of the description's length. Grid items in
       the same row already stretch to match height (auto-stretch), so
       margin-block-start: auto on the list does the rest. */
    margin: auto 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    /* Buttons inside should size to content, not stretch - keep them
       anchored at the start of the list's inline axis (lower-left of
       the card) rather than centred or filling the row. */
    align-items: flex-start;
}

    .account-twofactor-card__list li[b-4lqhvg00gr] {
        margin: 0;
    }

    /* Each action is a tiny GET-form wrapping a submit button so the
       link appears as a proper action button (picking up the shell
       submit-button rules). The form itself shouldn't add chrome -
       display: contents lets the button participate directly in the
       list's flex column without an extra block container. */
    .account-twofactor-card__list form[b-4lqhvg00gr] {
        display: contents;
    }
/* /Components/Account/Pages/Passkeys/Passkeys.razor.rz.scp.css */
/* /account/manage/passkeys - surface cards under the hero tile.
   The shared .surface-card recipe ships the border/shadow/radius;
   this file lays out the two-card grid + the per-row passkey list. */

.account-passkeys-cards[b-tthxss1g1n] {
    margin-top: var(--space-6);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-4);
    inline-size: 100%;
}

.account-passkeys-card[b-tthxss1g1n] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.account-passkeys-card__header[b-tthxss1g1n] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-passkeys-card__heading[b-tthxss1g1n] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-passkeys-card__description[b-tthxss1g1n] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

/* Passkey list - one row per registered credential. Name on the left,
   Rename + Delete on the right. Wraps to two lines under ~480px. */
.account-passkeys-list[b-tthxss1g1n] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.account-passkeys-list__item[b-tthxss1g1n] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    padding-block: var(--space-2);
    border-block-start: 1px solid var(--color-border-subtle);
}

    .account-passkeys-list__item:first-child[b-tthxss1g1n] {
        border-block-start: 0;
        padding-block-start: 0;
    }

.account-passkeys-list__info[b-tthxss1g1n] {
    flex: 1 1 auto;
    min-inline-size: 12rem;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-passkeys-list__name[b-tthxss1g1n] {
    color: var(--color-text);
    overflow-wrap: anywhere;
}

/* Added / last-used line under the name. Muted, wraps under the credential. */
.account-passkeys-list__meta[b-tthxss1g1n] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.account-passkeys-list__actions[b-tthxss1g1n] {
    flex: 0 0 auto;
    margin: 0;
}
/* /Components/Account/Pages/SignIn/ConfirmIdentity.razor.rz.scp.css */
/* /account/confirm - step-up re-auth gate. The shared .surface-card
   recipe ships the border/shadow/radius; this file lays out the
   header rhythm + the trailing Cancel-button row. */

.account-confirm-card[b-awbz9xgysd] {
    margin-top: var(--space-6);
    inline-size: 100%;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.account-confirm-card__header[b-awbz9xgysd] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-confirm-card__heading[b-awbz9xgysd] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.account-confirm-card__description[b-awbz9xgysd] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

/* Cancel sits inside the same .form-actions row as the Submit
   button as a plain anchor - a click bypasses the EditForm's
   validation cycle and navigates to the return URL. Sized to the
   same minimum tap height as the shell submit-button rule so the
   two read as a balanced pair on the row. */
.account-confirm-card__cancel-link[b-awbz9xgysd] {
    display: inline-flex;
    align-items: center;
    min-block-size: var(--target-size-minimum, 2.75rem);
    padding-inline: var(--space-3);
    color: var(--color-text-muted);
    text-decoration: none;
    border-radius: var(--radius-md);
}

    .account-confirm-card__cancel-link:hover[b-awbz9xgysd],
    .account-confirm-card__cancel-link:focus-visible[b-awbz9xgysd] {
        color: var(--color-text);
        text-decoration: underline;
    }

    .account-confirm-card__cancel-link:focus-visible[b-awbz9xgysd] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Banner variant - used when the gate can't run (unknown purpose
   or stale cookie). No form chrome, just the explanatory paragraph
   inside the surface so the page still has structure. */
.account-confirm-card--banner p[b-awbz9xgysd] {
    margin: 0;
    color: var(--color-text);
}
/* /Components/Account/Pages/SignIn/LoginCredential.razor.rz.scp.css */
/* /account/login/credential - "signed in as" identity row that pairs
   the email pinned by step 1 with a back-arrow link to step 1
   (change-account). The arrow + email sit on one line, tightly
   coupled, instead of a separate footer paragraph. */

.login-credential__identity[b-5kcdoh4w4z] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-block: 0 var(--space-3);
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
}

/* Subtle borderless icon button. The :not(.login-credential__back)
   exclusion in app.css means the global submit-CTA chrome no longer
   applies, so we restate the reset here (transparent background,
   no border/shadow, muted icon colour) to give the back arrow a
   "secondary affordance" weight that doesn't compete with the
   primary Sign in button below. */
.login-credential__back[b-5kcdoh4w4z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* WCAG 2.5.5 touch target (44px); the form is mobile-responsive and the
       design system's touch token is used for the other nav affordances. */
    inline-size: var(--target-size-touch);
    block-size: var(--target-size-touch);
    flex: 0 0 auto;
    margin: 0;
    padding: 0;
    background: transparent;
    color: var(--color-text-muted);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    box-shadow: none;
    cursor: pointer;
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .login-credential__back:hover[b-5kcdoh4w4z],
    .login-credential__back:focus-visible[b-5kcdoh4w4z] {
        background: var(--color-surface-sunken, var(--color-border-subtle));
        color: var(--color-text);
    }

    .login-credential__back:focus-visible[b-5kcdoh4w4z] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.login-credential__email[b-5kcdoh4w4z] {
    color: var(--color-text);
    overflow-wrap: anywhere;
    min-inline-size: 0;
}

@media (forced-colors: active) {
    .login-credential__identity[b-5kcdoh4w4z] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Account/Pages/SignIn/MfaRequired.razor.rz.scp.css */
/* /account/mfa-required - two-card grid mirroring the
   /account/manage/twofactor layout: one card per credential method
   (passkey vs authenticator app), side-by-side on wide viewports and
   stacked under ~640px. */

.account-mfa-required-cards[b-98it0174zj] {
    margin-top: var(--space-6);
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-4);
    inline-size: 100%;
}

.account-mfa-required-card[b-98it0174zj] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.account-mfa-required-card__header[b-98it0174zj] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.account-mfa-required-card__heading[b-98it0174zj] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

.account-mfa-required-card__badge[b-98it0174zj] {
    display: inline-flex;
    align-items: center;
    padding: 0 var(--space-2);
    block-size: 1.5rem;
    border-radius: var(--radius-md);
    background: var(--color-success, var(--color-brand));
    color: var(--color-text-on-accent);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    letter-spacing: var(--letter-spacing-wide);
    text-transform: uppercase;
}

.account-mfa-required-card__description[b-98it0174zj] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

/* CTA row anchored to the bottom of each card so the buttons on the
   passkey + authenticator cards line up at the same vertical position
   regardless of description length (grid auto-stretch + margin-top:
   auto, same trick the twofactor cards use). */
.account-mfa-required-card__actions[b-98it0174zj] {
    margin: auto 0 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
}

/* Footer "not the right account? Sign out" sits under both cards. */
.account-mfa-required__sign-out[b-98it0174zj] {
    margin-top: var(--space-5);
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--color-text-muted);
}
/* /Components/Account/Registration/VerifyEmail.razor.rz.scp.css */
/* The action row holds only the primary Verify button; the resend
   affordance lives in its own .auth-secondary-action form BELOW the
   card (shared app.css styling), matching every other sign-in page's
   secondary links. */
.verify-email__actions[b-6cmti0l73k] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
    margin-top: var(--space-3);
    /* Cap children to the action row's width so a long resend
       label can wrap instead of forcing horizontal scroll on
       narrow viewports. */
    max-width: 100%;
}

    .verify-email__actions > *[b-6cmti0l73k] {
        max-width: 100%;
    }

/* Long resend label needs to wrap on narrow viewports. The shared
   .link-button rule does not set white-space, but combined with
   width: auto the button can still grow as wide as the text needs
   - unless we explicitly let it wrap. (The button also wears
   .link-button so the global navy-CTA submit styling doesn't
   apply below the card.) */
.verify-email__resend-link[b-6cmti0l73k] {
    white-space: normal;
    text-align: left;
}

.verify-email__resend-status[b-6cmti0l73k] {
    color: var(--color-text);
    background: var(--color-surface-emphasis, var(--color-surface));
    border-left: 3px solid var(--color-brand);
    padding: var(--space-2) var(--space-3);
    margin: var(--space-2) 0;
    border-radius: var(--border-radius-sm, 4px);
    /* Same overflow-guard as .verify-email__actions: long status
       messages wrap at the card's width. */
    max-width: 100%;
}
/* /Components/Layout/AccountMenu.razor.rz.scp.css */
/*
 * AccountMenu - header user-menu disclosure. Slots into
 * AppShell.UserMenu via MainLayout. Uses the same token language as
 * AppShell.razor.css so light / dark / Windows High Contrast all
 * stay legible.
 *
 * Open/close mechanics: native <details>/<summary>, same pattern as
 * AppShell's mobile drawer + desktop collapse. Esc + outside-click
 * closure are added by wwwroot/js/app-shell-drawer.js when the
 * disclosure carries `data-app-shell-user-menu`.
 *
 * Mobile (≤ 768 px) - full-height side sheet:
 *   - Trigger collapses to icon-only so it fits the header alongside
 *     brand / drawer toggle / tenant selector. The "Account" label
 *     stays in the DOM as visually-hidden text so screen readers +
 *     the aria-label still announce the trigger.
 *   - The panel becomes a fixed-position side sheet sliding in from
 *     the right edge - same geometry as AppShell's nav drawer
 *     (mirrored). A scrim covers the rest of the viewport so the
 *     modal nature is obvious to touch users.
 *   - An explicit ✕ close button is rendered at the top-right of
 *     the panel because Esc and outside-tap aren't always
 *     discoverable on touch (no Esc key on a phone). The button is
 *     hidden on desktop where the dropdown's caret + click-outside
 *     are obvious affordances.
 *   - All interactive elements clear WCAG SC 2.5.5 (AAA) 44 px
 *     minimum touch-target size.
 *   - Breakpoint aligned with the nav drawer (768 px) so tablets
 *     get a single consistent mobile treatment instead of
 *     "hamburger drawer + dropdown popover".
 */

.account-menu[b-72gg62wld3] {
    position: relative;
}

.account-menu__summary[b-72gg62wld3] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    /* min-height ≥ 44 px satisfies WCAG 2.5.5 touch-target on touch
       devices; padding adds horizontal breathing room without making
       the row taller than the rest of the header chrome. */
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    background: transparent;
    /* Trigger sits inside the navy header chrome - flip to the
       chrome on-surface tokens so "Account" + avatar stay legible.
       The dropdown panel below floats on the white surface and
       keeps its own --color-text / --color-surface-raised tokens. */
    color: var(--color-chrome-on-surface);
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    cursor: pointer;
    list-style: none; /* hide the default ▶ marker */
}

    /* Suppress the default <summary> marker across browsers. */
    .account-menu__summary[b-72gg62wld3]::-webkit-details-marker {
        display: none;
    }

    .account-menu__summary[b-72gg62wld3]::marker {
        content: none;
    }

    .account-menu__summary:hover[b-72gg62wld3] {
        background: var(--color-chrome-surface-hover);
    }

    .account-menu__summary:focus-visible[b-72gg62wld3] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

.account-menu__avatar[b-72gg62wld3] {
    flex-shrink: 0;
    /* Matches the trigger label brightness so the icon + word "Account"
       read as one unit, not "muted icon + bright label". */
    color: var(--color-chrome-on-surface);
}

.account-menu__label[b-72gg62wld3] {
    /* Trigger label is "Account" on desktop / tablet. Hidden via
       the @media block below on small screens, but stays in the DOM
       for assistive tech alongside the summary's aria-label. */
    white-space: nowrap;
}

.account-menu__caret[b-72gg62wld3] {
    flex-shrink: 0;
    transition: transform var(--motion-duration-quick, 120ms) ease;
}

/* Rotate the caret when the disclosure is open. */
.account-menu[open] .account-menu__caret[b-72gg62wld3] {
    transform: rotate(180deg);
}

/* ---------------- Panel ---------------- */

.account-menu__panel[b-72gg62wld3] {
    position: absolute;
    right: 0;
    top: calc(100% + var(--space-1));
    min-width: 16rem;
    /* Cap to the viewport so a long email + label can't push the
       panel past the right edge on narrow screens. The right:0
       anchor keeps it flush with the trigger; max-width clamps the
       overflow. */
    max-width: calc(100vw - var(--space-4));
    padding: var(--space-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-raised);
    box-shadow: var(--shadow-lg);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    /* --z-popover does not exist in tokens.css, so this resolved to the literal 50
       fallback - below --z-sticky (200) - and a sticky table <th> in the content
       column painted straight over the open menu. Nothing traps the panel: the
       header is deliberately `position: relative` with NO z-index (see
       AppShell.razor.css) precisely so it does not become a stacking context, which
       leaves this number competing directly with the table chrome at the root.
       --z-overlay (300) is the scale's "above every sticky surface, below modals"
       layer; the ≤1024px side-sheet below raises it further to --z-modal. */
    z-index: var(--z-overlay);
}

.account-menu__signed-in-as[b-72gg62wld3] {
    /* Non-interactive label. Smaller font + muted colour so the
       email reads as informational, not actionable. word-break
       lets long emails wrap inside the panel rather than overflow. */
    padding: var(--space-2) var(--space-3);
    color: var(--color-text-muted, var(--color-text));
    font-size: var(--font-size-xs, 0.8125rem);
    line-height: var(--line-height-tight, 1.3);
    word-break: break-word;
}

.account-menu__signed-in-as-email[b-72gg62wld3] {
    display: block;
    margin-top: var(--space-1);
    color: var(--color-text);
    font-weight: var(--font-weight-semibold, 600);
}

.account-menu__divider[b-72gg62wld3] {
    height: 1px;
    margin: var(--space-1) calc(var(--space-2) * -1);
    background: var(--color-border);
}

.account-menu__sessions[b-72gg62wld3] {
    /* Tenant-session list - one row per active sign-in. The heading
       is muted to match the "Signed in as" treatment above; rows
       carry the slug + a small ✕ button that POSTs to the per-tenant
       sign-out endpoint. */
    padding: 0 var(--space-1);
}

.account-menu__sessions-heading[b-72gg62wld3] {
    padding: var(--space-2) var(--space-3) var(--space-1);
    color: var(--color-text-muted, var(--color-text));
    font-size: var(--font-size-xs, 0.8125rem);
    text-transform: uppercase;
    letter-spacing: var(--letter-spacing-wide, 0.05em);
}

.account-menu__session-row[b-72gg62wld3] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    /* WCAG 2.5.5 minimum target height for the form's interactive
       child (the ✕ button). The row itself isn't interactive; the
       button is. */
    min-height: 44px;
    padding: var(--space-1) var(--space-3);
    margin: 0;
}

.account-menu__session-slug[b-72gg62wld3] {
    flex: 1 1 auto;
    color: var(--color-text);
    font-size: var(--font-size-sm);
    word-break: break-all;
}

/* Sign-in method tag (SSO / Local) - quiet pill so the tenant name
   stays the row's anchor; the tag answers "which credential is this
   session on" at a glance. */
.account-menu__session-method[b-72gg62wld3] {
    flex: 0 0 auto;
    padding: 0 var(--space-2);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-full, 999px);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs, 0.75rem);
    line-height: 1.6;
    white-space: nowrap;
}

@media (forced-colors: active) {
    .account-menu__session-method[b-72gg62wld3] {
        border-color: CanvasText;
    }
}

.account-menu__session-signout[b-72gg62wld3] {
    flex: 0 0 auto;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text-muted, var(--color-text));
    font-size: var(--font-size-lg);
    line-height: 1;
    cursor: pointer;
}

    .account-menu__session-signout:hover[b-72gg62wld3],
    .account-menu__session-signout:focus-visible[b-72gg62wld3] {
        color: var(--color-text);
        border-color: var(--color-border);
        background: var(--color-surface-subtle, transparent);
    }

    .account-menu__session-signout:focus-visible[b-72gg62wld3] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 1px;
    }

.account-menu__item[b-72gg62wld3] {
    display: flex;
    align-items: center;
    /* Match the WCAG 2.5.5 minimum on the panel items too - they're
       primary touch targets when the menu is open. */
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    text-decoration: none;
    font-size: var(--font-size-sm);
}

    .account-menu__item:hover[b-72gg62wld3] {
        background: var(--color-surface-raised-hover, var(--color-surface-hover));
    }

    .account-menu__item:focus-visible[b-72gg62wld3] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.account-menu__signout-form[b-72gg62wld3] {
    margin: 0;
}

/* ---------------- Close button (mobile only) ---------------- */

/* Hidden on desktop where the dropdown doesn't need an explicit
   dismiss control. Mobile rules below switch it to inline-flex. */
.account-menu__close[b-72gg62wld3] {
    display: none;
}

.account-menu__signout[b-72gg62wld3] {
    /* Visually identical to .account-menu__item so the menu reads as
       a uniform list of actions. The semantic difference (link vs
       form-submit button) is preserved for assistive tech. */
    display: flex;
    align-items: center;
    width: 100%;
    text-align: left;
    min-height: 44px;
    padding: var(--space-2) var(--space-3);
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-text);
    font-family: var(--font-sans);
    font-size: var(--font-size-sm);
    cursor: pointer;
}

    .account-menu__signout:hover[b-72gg62wld3] {
        background: var(--color-surface-raised-hover, var(--color-surface-hover));
    }

    .account-menu__signout:focus-visible[b-72gg62wld3] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* ---------------- Narrow viewport (≤ 1024 px) - side-sheet drawer ----------------
   Matches AppShell's mobile-drawer breakpoint so tablet + narrow
   desktop chrome stays consistent across both nav surfaces. */

@media (max-width: 1024px) {
    /* Icon-only trigger. Hide the "Account" label visually but keep
       it in the DOM for screen readers - same visually-hidden
       pattern AppShell uses for the skip link off-screen offsets. */
    .account-menu__label[b-72gg62wld3] {
        position: absolute;
        left: -10000px;
        width: 1px;
        height: 1px;
        overflow: hidden;
    }

    /* Compact the trigger so the icon hugs the edge on tight chrome. */
    .account-menu__summary[b-72gg62wld3] {
        gap: var(--space-1);
        padding: var(--space-2);
    }

    /* The caret is dropdown grammar, not drawer grammar - hide it. */
    .account-menu__caret[b-72gg62wld3] {
        display: none;
    }

    /* Scrim - fixed-position pseudo on the [open] disclosure. Only
       paints inside this @media block, so desktop never gets a scrim.
       Sits one layer below the panel so the panel paints over it. */
    .account-menu[open][b-72gg62wld3]::before {
        content: "";
        position: fixed;
        inset: 0;
        background: rgb(0 0 0 / 40%);
        z-index: calc(var(--z-modal) - 1);
    }

    /* Panel becomes a fixed full-height side sheet, sliding in from
       the right. Geometry mirrors AppShell's left nav drawer; surface
       tone matches the chrome (--color-surface-sunken) so the two
       drawers read as siblings, not as a dropdown bolted onto a sheet. */
    .account-menu__panel[b-72gg62wld3] {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        width: 16rem;
        max-width: 80vw;
        min-width: 0;
        padding: var(--space-4);
        border: none;
        border-left: 1px solid var(--color-border);
        border-radius: 0;
        background: var(--color-surface-sunken);
        box-shadow: none;
        z-index: var(--z-modal);
        overflow: auto;
        transform: translateX(100%);
        transition: transform var(--motion-duration-normal) var(--motion-easing-standard);
    }

    .account-menu[open] .account-menu__panel[b-72gg62wld3] {
        transform: translateX(0);
    }

    /* Close button - top-right of the panel, right-aligned in the
       column flex flow so the rest of the panel content stays in
       its natural reading order below. 44 px target for WCAG 2.5.5. */
    .account-menu__close[b-72gg62wld3] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        align-self: flex-end;
        width: 44px;
        height: 44px;
        min-width: 44px;
        min-height: 44px;
        margin-bottom: var(--space-1);
        padding: 0;
        border: none;
        border-radius: var(--radius-md);
        background: transparent;
        color: var(--color-text);
        cursor: pointer;
    }

        .account-menu__close:hover[b-72gg62wld3] {
            background: var(--color-surface-raised-hover, var(--color-surface-hover));
        }

        .account-menu__close:focus-visible[b-72gg62wld3] {
            outline: 2px solid var(--color-focus-ring);
            outline-offset: 2px;
        }

    /* Reduced-motion users get the open state instantly; no slide. */
    @media (prefers-reduced-motion: reduce) {
        .account-menu__panel[b-72gg62wld3] {
            transition: none;
        }
    }
}

/* Windows High Contrast: ensure the panel borders + caret + avatar
   remain visible even when token values flatten. */
@media (forced-colors: active) {
    .account-menu__panel[b-72gg62wld3],
    .account-menu__divider[b-72gg62wld3] {
        border-color: CanvasText;
        background-color: Canvas;
    }

    .account-menu__avatar[b-72gg62wld3],
    .account-menu__caret[b-72gg62wld3] {
        color: CanvasText;
    }

    .account-menu__summary[b-72gg62wld3],
    .account-menu__item[b-72gg62wld3],
    .account-menu__signout[b-72gg62wld3],
    .account-menu__signed-in-as[b-72gg62wld3],
    .account-menu__signed-in-as-email[b-72gg62wld3],
    .account-menu__close[b-72gg62wld3] {
        color: CanvasText;
    }
}
/* /Components/Layout/AppShell.razor.rz.scp.css */
/*
 * AppShell - chrome for authenticated surfaces. Token-driven so light /
 * dark / Windows High Contrast all stay legible.
 *
 * Drawer + collapse mechanics: both toggles are <details>/<summary>
 * elements. CSS reacts to the platform `[open]` attribute instead of
 * a hidden checkbox's :checked state. The desktop sidebar's <details>
 * renders with `open` by default; activating its summary collapses
 * it to a rail showing only the toggle. The mobile drawer's
 * <details> defaults closed; activating its summary slides the nav
 * in from the left edge.
 */

/* Skip-link - see PublicShell.razor.css for the rationale. */
.app-shell__skip-link[b-t4mtcicg3z] {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

    .app-shell__skip-link:focus[b-t4mtcicg3z] {
        position: fixed;
        top: var(--space-2);
        left: var(--space-2);
        width: auto;
        height: auto;
        padding: var(--space-2) var(--space-4);
        background: var(--color-surface);
        color: var(--color-text);
        border: 2px solid var(--color-focus-ring);
        border-radius: var(--radius-md);
        z-index: var(--z-toast);
    }

.app-shell[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: var(--font-sans);
    line-height: var(--line-height-normal);
}

.app-shell__header[b-t4mtcicg3z] {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-5);
    /* Brand blue via --color-chrome-surface so the header reads as a
       branded frame above the white content surface. White-on-brand
       clears WCAG 2.2 AA at body sizes (~5.8:1). The token is constant
       across light/dark so platform identity holds on every theme. No
       bottom border - header → sidebar is chrome → chrome, and any seam
       there reads as a hard hairline. Header scrolls away with the page
       so deep tenant content gets the full viewport. */
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    /* Floats the navy chrome above the white content surface; pairs
       with the matching shadow on .app-shell__collapse so the two
       chrome panels read as one elevated tray. Forced-colors mode
       strips shadows so HC stays system-faithful. */
    box-shadow: var(--shadow-md);
    /* position: relative without z-index keeps the box-shadow paint
       order intact relative to the next-in-flow row (the body) but
       does NOT promote the header to its own stacking context.
       Earlier this carried `z-index: 1` so the header's shadow
       overlapped the sidebar's top edge - but with the sidebar now
       at --z-overlay (300) to clear sticky table headers in the
       main column, that 1-unit context broke the layering: sticky
       elements in the main column ended up painting OVER the
       sidebar, masking the nav. Dropping the explicit z-index here
       restores the intended sidebar > sticky-content stacking; the
       only visible side-effect is the header's shadow now stops at
       the sidebar's top edge instead of crossing it. */
    position: relative;
}

@media (forced-colors: active) {
    .app-shell__header[b-t4mtcicg3z] {
        background: Canvas;
        color: CanvasText;
    }
}

/* ---------------- Mobile drawer - <details class="app-shell__drawer"> ---------------- */
/* Hidden on desktop. The drawer body slides in from the left edge when
   the <details> is in the [open] state. */
.app-shell__drawer[b-t4mtcicg3z] {
    display: none; /* breakpoint-driven - shown at <= 768px */
}

.app-shell__drawer-toggle[b-t4mtcicg3z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Disable the default disclosure marker so we render only our SVG. */
    list-style: none;
    cursor: pointer;
    user-select: none;
    width: var(--space-10);                          /* 40px */
    height: var(--space-10);
    min-width: var(--target-size-minimum);           /* WCAG 2.5.8 */
    min-height: var(--target-size-minimum);
    border-radius: var(--radius-md);
    color: var(--color-chrome-on-surface);
    background: transparent;
}

    .app-shell__drawer-toggle[b-t4mtcicg3z]::-webkit-details-marker {
        display: none;
    }

    .app-shell__drawer-toggle:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
    }

    .app-shell__drawer-toggle:focus-visible[b-t4mtcicg3z] {
        /* White ring, not --color-focus-ring: the toggle sits on the brand-blue
           header and --color-focus-ring IS the brand blue, so the ring would be
           invisible (1:1). White on the blue clears the 3:1 focus floor (5.79:1). */
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

.app-shell__drawer-icon[b-t4mtcicg3z] {
    display: block;
    color: currentColor;
}

/* Drawer body - only meaningful on mobile. Hidden by default; CSS
   reveals it when [open] in the mobile breakpoint block below. */
.app-shell__drawer-nav[b-t4mtcicg3z] {
    display: none;
}

/* Drawer close button - hidden by default; the mobile breakpoint
   block below switches it to inline-flex so it renders inside the
   open drawer panel only. Desktop never shows it because the drawer
   itself is display:none above the breakpoint. */
.app-shell__drawer-close[b-t4mtcicg3z] {
    display: none;
}

/* ---------------- Brand / header slots ---------------- */

.app-shell__brand[b-t4mtcicg3z] {
    color: var(--color-chrome-on-surface);
    text-decoration: none;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    /* WCAG 2.5.8 minimum target size - apply to the inline brand link
       so the click target meets 24x24 even before padding adds height. */
    min-height: var(--target-size-minimum);
    display: inline-flex;
    align-items: center;
    /* Even spacing between the mark, the wordmark, and the release-stage
       chip so the three read as one brand unit. */
    gap: var(--space-2);
}

    /* No hover affordance on the brand link by design - it's the home
       link, not a button. Keyboard focus still gets a visible ring. */
    .app-shell__brand:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

/* ::deep - the honeycomb <svg> is rendered by the child <BrandMark>
   component, so this AppShell-scoped rule needs ::deep to reach it (the
   svg carries BrandMark's scope, not AppShell's). aspect-ratio guarantees
   the auto width is computed from the portrait viewBox even as a flex item. */
.app-shell__brand[b-t4mtcicg3z]  .app-shell__brand-mark {
    display: block;
    height: 26px;
    width: auto;
    aspect-ratio: 76.42 / 94.8;
    /* The honeycomb cells use fill="currentColor"; this color flows in so
       the cells stay white on the navy chrome (the flagged cell is fixed
       Signal Amber). Slightly taller than the wordmark cap height per the
       brand lockup spec. */
    color: var(--color-chrome-on-surface);
    flex: none;
}

/* Wordmark - "Admin Companion" in the brand display face. "Admin" is bold,
   "Companion" is medium; both inherit the chrome text colour (white on the
   navy header). */
.app-shell__brand-word[b-t4mtcicg3z] {
    font-family: var(--font-display);
    font-size: 1.0625rem;
    font-weight: var(--font-weight-medium);
    letter-spacing: -0.01em;
    line-height: 1;
    white-space: nowrap;
    color: var(--color-chrome-on-surface);
}

    /* "Admin" - bold, full chrome text colour (inherits from .app-shell__brand-word). */
    .app-shell__brand-word b[b-t4mtcicg3z] {
        font-weight: var(--font-weight-bold);
    }

    /* "Companion" - medium weight in the muted chrome tone (72% white on the navy
       chrome), per the brand lockup spec. */
    .app-shell__brand-word span[b-t4mtcicg3z] {
        font-weight: var(--font-weight-medium);
        /* Muted chrome tone via the AA-safe muted token (0.92 white = 5.2:1 on
           the brand blue) rather than a bare 72% white mix (3.77:1). Keeps the
           "Companion" half visually subordinate to the bold "Admin" without
           leaning on the WCAG logotype exemption. */
        color: var(--color-chrome-on-surface-muted);
    }

/* Hide the wordmark text on the narrowest viewports - the mark alone still
   identifies the app, and the header stays tight on mobile. */
@media (max-width: 26rem) {
    .app-shell__brand-word[b-t4mtcicg3z] {
        display: none;
    }
}

/* "Private Preview" chip pinned next to the wordmark. Uses a translucent
   panel over the chrome so it reads as a release-stage tag without
   competing with the wordmark for attention. Compact line-height keeps
   the chip's vertical footprint to the wordmark's 24px without enlarging
   the header. Hidden under narrow viewports to keep the header tight. */
.app-shell__brand-tag[b-t4mtcicg3z] {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    /* Black-alpha (darken) fill, not white-alpha (lighten): on the brighter
       brand blue a white-alpha fill lifted the chip background enough to drop
       white text to 4.45:1 (under AA). Darkening keeps white text well clear
       (~7:1), matching the nav hover/active overlays' approach. */
    background: rgba(0, 0, 0, 0.16);
    color: var(--color-chrome-on-surface);
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: var(--radius-sm);
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
}

@media (max-width: 32rem) {
    .app-shell__brand-tag[b-t4mtcicg3z] {
        display: none;
    }
}

.app-shell__user-menu[b-t4mtcicg3z] {
    display: flex;
    align-items: center;
}

/* Tenant selector slot - rendered at the top of the desktop sidebar
   nav AND at the top of the mobile drawer nav. Surrounding padding +
   bottom hairline so the card reads as a section above the nav
   groups; the card itself owns its background + border via its
   scoped CSS. */
.app-shell__sidebar-tenant[b-t4mtcicg3z] {
    padding-bottom: var(--space-3);
    margin-bottom: var(--space-2);
    border-bottom: 1px solid var(--color-chrome-border-subtle);
}

@media (forced-colors: active) {
    .app-shell__sidebar-tenant[b-t4mtcicg3z] {
        border-bottom: 1px solid CanvasText;
    }
}

.app-shell__header-spacer[b-t4mtcicg3z] {
    flex: 1 1 auto;
}

/* ---------------- Body / sidebar / main ---------------- */

.app-shell__body[b-t4mtcicg3z] {
    display: flex;
    flex: 1 1 auto;
    min-height: 0;
    /* Paints behind any visible flex gap so the boundary reads as
       intentional whitespace rather than a leak through to the host
       document body. */
    background: var(--color-surface);
}

/* Desktop sidebar wrapper. The <aside> carries the sidebar's
   background, width, border, and full-height fill so the raised
   surface reaches from the bottom of the sticky header all the way
   to the bottom of the body. The inner <nav> is a transparent child
   that holds padding + nav-link layout. Hidden on mobile in favour
   of the <details data-app-shell-drawer> mobile drawer below. */
.app-shell__collapse[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    width: 16rem;
    /* Position + z-index so the sidebar paints above any sticky
       content inside the main column (table headers, bulk-action
       bars at `--z-sticky` = 200). Without this, sticky elements
       inside scrollable content would overlap the sidebar edge on
       narrow viewports where their column is wide relative to the
       sidebar. `--z-overlay` (300) sits below modals but above all
       sticky surfaces in the content area. */
    position: relative;
    z-index: var(--z-overlay);
    /* Brand blue via --color-chrome-surface so the sidebar reads as one
       continuous brand frame with the header. White text via
       --color-chrome-on-surface; hover/active variants are black-alpha
       overlays that DARKEN the brand blue so white text keeps AA on the
       interactive rows. Forced-colors maps to Canvas/CanvasText so HC
       users get the system palette unchanged. */
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    /* Faint white-alpha hairline against the white main content -
       presence, not weight. The chrome-border (dark navy) would read
       as a hard black line here against white. */
    border-right: 1px solid var(--color-chrome-border-subtle);
    /* Casts a soft right-edge shadow onto the white main column so
       the chrome reads as an elevated panel. The header's shadow
       caps the top edge; together they bracket the content surface. */
    box-shadow: var(--shadow-md);
    overflow: hidden;
    transition: width var(--motion-duration-normal) var(--motion-easing-standard);
}

@media (forced-colors: active) {
    .app-shell__collapse[b-t4mtcicg3z] {
        background: Canvas;
        color: CanvasText;
        border-right-color: CanvasText;
    }
}

/* Toggle's left edge + inner padding mirror the nav's outer padding +
   the nav-link's inner padding, so the hamburger icon ends up at the
   same `x` as the first character of every nav-link below it. The
   visual disclosure column reads as one straight line. */
.app-shell__collapse-toggle[b-t4mtcicg3z] {
    display: inline-flex;
    align-items: center;
    justify-content: flex-start;
    cursor: pointer;
    user-select: none;
    align-self: flex-start;
    width: auto;
    min-width: var(--target-size-minimum);
    min-height: var(--target-size-minimum);
    padding: var(--space-2) var(--space-3);
    margin: var(--space-2) var(--space-4) 0;
    border: 0;
    border-radius: var(--radius-md);
    color: var(--color-chrome-on-surface);
    background: transparent;
    flex: 0 0 auto;
    font: inherit;
}

    .app-shell__collapse-toggle:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
    }

    .app-shell__collapse-toggle:focus-visible[b-t4mtcicg3z] {
        /* White ring, not --color-focus-ring (which is the brand blue = the
           sidebar surface here) so the focus indicator is visible (5.79:1). */
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

.app-shell__nav[b-t4mtcicg3z] {
    flex: 1 1 auto;
    overflow: auto;
    padding: var(--space-2) var(--space-4) var(--space-4);
    background: transparent;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Rail mode - `data-collapsed="true"` shrinks the sidebar to a thin
   column. The whole nav is hidden so no empty / icon-less rows linger
   in the narrow column; only the toggle button stays, to expand back. */
.app-shell__collapse[data-collapsed="true"][b-t4mtcicg3z] {
    width: 3.5rem;
}

    /* Collapsed = chrome only: hide the entire nav (groups, items, tenant
       selector). Navigation resumes once the sidebar is expanded. */
    .app-shell__collapse[data-collapsed="true"] > .app-shell__nav[b-t4mtcicg3z] {
        display: none;
    }

    /* Centre the collapse toggle button in the narrow rail - it is the
       only thing shown when collapsed. The expanded-state margin aligns
       the hamburger glyph with the nav text; that calibration is wrong
       here, so reset to a centred column. */
    .app-shell__collapse[data-collapsed="true"] .app-shell__collapse-toggle[b-t4mtcicg3z] {
        align-self: stretch;
        justify-content: center;
        margin-inline: 0;
        padding-inline: 0;
    }

/* ---------------- Nav links ---------------- */

.app-shell__nav-link[b-t4mtcicg3z] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    color: var(--color-chrome-on-surface-muted);
    text-decoration: none;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    /* Regular weight reads as subordinate to the semibold group
       headers above - visual hierarchy: group (600) > active sub
       (500) > inactive sub (400). */
    font-weight: var(--font-weight-regular);
    /* WCAG 2.5.8 minimum target size - links need 24px tall hit areas. */
    min-height: var(--target-size-minimum);
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

/* Top-level (ungrouped) entries - Dashboard, Support - are peers of the
   Tenant / Platform group headers, not sub-items of anything, so they take
   the headers' weight and ink. The base class keeps its subordinate weight
   for the links inside groups, where the hierarchy comment above applies. */
.app-shell__nav-link--root[b-t4mtcicg3z] {
    font-weight: var(--font-weight-semibold);
    color: var(--color-chrome-on-surface);
}

/* Label inside the nav link - shrinks past content width so long
   localised strings ellipsise rather than push the layout. */
.app-shell__nav-link-label[b-t4mtcicg3z] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Pending-approvals count on the Approvals nav link - a filled brand pill that flags
   "items awaiting your decision", mirroring the attention badge on the control's
   Remediations tab. The label's flex-grow pushes it to the trailing edge. */
.app-shell__nav-link-badge[b-t4mtcicg3z] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    padding: 0 var(--space-2);
    /* Inverted pill - white fill + brand-blue digit - so it stands out on the
       brand-blue sidebar (a filled --color-brand pill would blend into the
       chrome at 1:1, and its white digit fails AA in dark mode at 3.29:1).
       Using the constant chrome tokens keeps both the pill boundary (5.79:1)
       and the digit contrast (5.79:1) AA in light AND dark. */
    background: var(--color-chrome-on-surface);
    color: var(--color-chrome-surface);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-full);
}

@media (forced-colors: active) {
    .app-shell__nav-link-badge[b-t4mtcicg3z] {
        forced-color-adjust: none;
        background: Highlight;
        color: HighlightText;
    }
}

    .app-shell__nav-link:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
        color: var(--color-chrome-on-surface);
    }

    .app-shell__nav-link:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

/* Active route - Blazor's <NavLink> sets `active` and
   `aria-current="page"` when the URL matches. White text + brighter
   alpha pill on the navy chrome so the active row reads at a glance
   without needing a coloured accent that fights the chrome. Weight
   steps one tier above the inactive sub-items (regular → medium) so
   the active row is distinct but still subordinate to the group
   header (semibold). */
.app-shell__nav-link.active[b-t4mtcicg3z],
.app-shell__nav-link[aria-current="page"][b-t4mtcicg3z] {
    background: var(--color-chrome-surface-active);
    color: var(--color-chrome-on-surface);
    font-weight: var(--font-weight-medium);
}

/* Stronger active treatment inside the secondary rail - a 3px inset
   accent bar on the leading edge plus semibold weight makes the "you
   are here" row read at a glance. The desktop rail is a light,
   brand-tinted panel so the active fill + accent + text are all
   brand-toned (dark); the mobile drawer's secondary panel stays on the
   blue drawer surface, so its active row darkens (chrome-surface-active)
   and keeps white text + a white accent bar to hold AA. */
.app-shell__secondary-rail .app-shell__nav-link[aria-current="page"][b-t4mtcicg3z] {
    background: var(--color-chrome-secondary-surface-active);
    color: var(--color-chrome-secondary-on-surface);
    font-weight: var(--font-weight-semibold);
    box-shadow: inset 3px 0 0 var(--color-chrome-secondary-on-surface);
}

.app-shell__drawer-panel--secondary .app-shell__nav-link[aria-current="page"][b-t4mtcicg3z] {
    background: var(--color-chrome-surface-active);
    color: var(--color-chrome-on-surface);
    font-weight: var(--font-weight-semibold);
    box-shadow: inset 3px 0 0 var(--color-chrome-on-surface);
}

@media (forced-colors: active) {
    .app-shell__secondary-rail .app-shell__nav-link[aria-current="page"][b-t4mtcicg3z],
    .app-shell__drawer-panel--secondary .app-shell__nav-link[aria-current="page"][b-t4mtcicg3z] {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
        box-shadow: none;
    }
}

@media (forced-colors: active) {
    .app-shell__nav-link.active[b-t4mtcicg3z],
    .app-shell__nav-link[aria-current="page"][b-t4mtcicg3z] {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }
}

/* External-link nav rows: icon sits AFTER the label and is pushed to
   the row's right edge so the label aligns with non-external
   siblings (which have no trailing icon). Keys off target="_blank"
   so any future external nav row picks up the treatment without
   per-row CSS. */
.app-shell__nav-link[target="_blank"] .nav-icon[b-t4mtcicg3z] {
    margin-left: auto;
}

.app-shell__main[b-t4mtcicg3z] {
    /* Column flex so the in-main footer can pin to the bottom via
       margin-top: auto on short pages. Padding lives on the inner
       .app-shell__content wrapper so the footer can paint
       edge-to-edge across the main column. White surface on the
       full column so the chrome → content boundary always reads
       cleanly regardless of which descendant carries the padding. */
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0; /* let flex children shrink past content min-width */
    background: var(--color-surface);
    outline: none;
}

.app-shell__content[b-t4mtcicg3z] {
    /* Page-level padding; the footer below this wrapper paints flush
       to the main column's left + right + bottom edges. */
    padding: var(--space-6);
}

/* Persistent read-only notice for a tenant under a commercial hold.
   Sits above the breadcrumb trail so it reads before the page, on every
   page, for as long as the hold lasts. Warning tone rather than danger:
   nothing is broken and nothing has been lost. */
.app-shell__suspension[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-bottom: var(--space-5);
    padding: var(--space-4);
    border: 1px solid var(--color-warning);
    border-radius: var(--radius-lg, 12px);
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
}

.app-shell__suspension-heading[b-t4mtcicg3z] {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
}

.app-shell__suspension-body[b-t4mtcicg3z] {
    line-height: var(--line-height-relaxed);
}

/* The operator's message is customer-visible free text supplied by a
   human, so it is set apart from our own copy rather than blended into
   it - the reader can tell which words are ours. */
.app-shell__suspension-message[b-t4mtcicg3z] {
    padding-left: var(--space-3);
    border-left: 3px solid var(--color-warning);
    line-height: var(--line-height-relaxed);
}

/* ---------------- Collapsible nav groups (Tenant section) ----------------
   <details class="app-shell__nav-group"> contains a <summary> that toggles
   the disclosure plus a nested <div> of sub-links. Native <details> handles
   the open/close primitive and announces expanded/collapsed state via the
   platform disclosure pattern, so no JS is required. The group is rendered
   inside both the desktop sidebar and the mobile drawer; the existing
   <= 768px breakpoint switches the surrounding chrome, the group itself
   needs no media query. */
.app-shell__nav-group[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Header row holds the navigation link + the disclosure toggle as
   siblings. The link absorbs the row width via `flex: 1` and the
   toggle button hugs the right edge. */
.app-shell__nav-group-header[b-t4mtcicg3z] {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

/* Section-header link - clicking navigates to the section dashboard
   (Tenant landing / Platform admin dashboard). Visual weight matches
   a top-level nav row; padding + min-height clear WCAG 2.5.5/2.5.8. */
.app-shell__nav-group-link[b-t4mtcicg3z] {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    min-height: var(--target-size-minimum);
    border-radius: var(--radius-md);
    color: var(--color-chrome-on-surface);
    text-decoration: none;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
}

    .app-shell__nav-group-link:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
    }

    .app-shell__nav-group-link:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

    .app-shell__nav-group-link[aria-current="page"][b-t4mtcicg3z] {
        background: var(--color-chrome-surface-active);
        color: var(--color-chrome-on-surface);
        border-left: 3px solid var(--color-chrome-on-surface);
        padding-left: calc(var(--space-3) - 3px);
    }

    /* When a sub-section rail under this group is open (e.g. "Settings"
       under "Tenant"), the rail's parent toggle already carries the
       "you are here" affordance. Suppress the group header's own
       active style so the focus reads as the open sub-section alone,
       not the group + the toggle simultaneously. */
    .app-shell__nav-group:has(.app-shell__nav-link--toggle[aria-expanded="true"])
        .app-shell__nav-group-link[aria-current="page"][b-t4mtcicg3z] {
        background: transparent;
        border-left-color: transparent;
        padding-left: var(--space-3);
    }

.app-shell__nav-group-label[b-t4mtcicg3z] {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Disclosure toggle - icon-only button that flips the group's
   `data-expanded` between true/false. Sits to the right of the
   header link. `align-self: stretch` makes the button grow to the
   row's full height (driven by the link sibling's padded box) so
   hover / focus backgrounds line up vertically with the link
   instead of sitting in a shorter centred pill. */
.app-shell__nav-group-toggle[b-t4mtcicg3z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    align-self: stretch;
    min-width: var(--target-size-minimum);
    min-height: var(--target-size-minimum);
    padding-block: 0;
    padding-inline: var(--space-2);
    border: 0;
    background: transparent;
    color: var(--color-chrome-on-surface);
    border-radius: var(--radius-md);
    cursor: pointer;
    user-select: none;
}

    .app-shell__nav-group-toggle:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
    }

    .app-shell__nav-group-toggle:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

.app-shell__nav-group-chevron[b-t4mtcicg3z] {
    flex: 0 0 auto;
    transition: transform var(--motion-duration-normal) var(--motion-easing-standard);
}

/* Collapsed state - chevron rotates to point right (`-90deg`) and
   the items container hides. Convention matches Linear / VS Code
   sidebars: down = expanded, right = collapsed. */
.app-shell__nav-group[data-expanded="false"] .app-shell__nav-group-chevron[b-t4mtcicg3z] {
    transform: rotate(-90deg);
}

.app-shell__nav-group[data-expanded="false"] .app-shell__nav-group-items[b-t4mtcicg3z] {
    display: none;
}

.app-shell__nav-group-items[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    /* No left indent - sub-items share the left edge with the group
       header's icon so the hierarchy reads via the group disclosure
       + chevron, not via horizontal offset. */
}

@media (prefers-reduced-motion: reduce) {
    .app-shell__nav-group-chevron[b-t4mtcicg3z] {
        transition: none;
    }
}

/* ---------------- Secondary rail (sub-section panel) ----------------
   One <aside class="app-shell__secondary-rail"> per registered
   NavSubSection descriptor, rendered immediately to the right of the
   main sidebar. A LIGHTER, brand-tinted panel with dark text so the
   visual hierarchy reads main-rail (brand blue) → secondary-rail
   (light blue wash) → content (white). Themes cleanly: a deep-navy
   wash in dark mode (see the --color-chrome-secondary-* tokens).

   States are driven by data attributes flipped client-side by
   wwwroot/js/app-shell-secondary-rail.js:
     data-open="true|false"        → visible vs hidden entirely
     data-collapsed="true|false"   → full width vs icon-only rail mode

   Hidden on mobile breakpoint - the mobile drawer flattens the
   sub-section entries inline below the toggle button instead. */
.app-shell__secondary-rail[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    flex: 0 0 auto;
    width: 14rem;
    min-width: 12rem;
    max-width: 20rem;
    /* Same z-index treatment as .app-shell__collapse so sticky
       headers inside the content column can't paint over the rail. */
    position: relative;
    z-index: var(--z-overlay);
    /* Lighter than the brand-blue primary sidebar so the visual
       hierarchy reads main-rail (brand blue) → secondary-rail (light
       brand-tinted wash) → content (white). Dark brand-toned text on
       the light panel clears WCAG AA comfortably (~10:1 light, ~7:1
       dark). */
    background: var(--color-chrome-secondary-surface);
    color: var(--color-chrome-secondary-on-surface);
    border-right: 1px solid var(--color-chrome-secondary-border);
    /* Casts onto the main content surface so the rail reads as an
       elevated panel when open. Pairs with the chrome shadows. */
    box-shadow: var(--shadow-md);
    transition: width var(--motion-duration-normal) var(--motion-easing-standard);
}

.app-shell__secondary-rail[data-open="false"][b-t4mtcicg3z] {
    display: none;
}

.app-shell__secondary-rail[data-collapsed="true"][b-t4mtcicg3z] {
    width: 3.5rem;
    min-width: 3.5rem;
    max-width: 3.5rem;
}

.app-shell__secondary-rail-header[b-t4mtcicg3z] {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-3) var(--space-3);
    border-bottom: 1px solid var(--color-chrome-secondary-border);
}

.app-shell__secondary-rail-title[b-t4mtcicg3z] {
    flex: 1 1 auto;
    min-width: 0;
    font-weight: var(--font-weight-semibold);
    color: var(--color-chrome-secondary-on-surface);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-shell__secondary-rail-collapse[b-t4mtcicg3z],
.app-shell__secondary-rail-close[b-t4mtcicg3z] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    min-width: var(--target-size-minimum);
    min-height: var(--target-size-minimum);
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--color-chrome-secondary-on-surface);
    border-radius: var(--radius-md);
    cursor: pointer;
    font-size: var(--font-size-lg);
    line-height: 1;
}

    .app-shell__secondary-rail-collapse:hover[b-t4mtcicg3z],
    .app-shell__secondary-rail-close:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-secondary-surface-hover);
    }

    .app-shell__secondary-rail-collapse:focus-visible[b-t4mtcicg3z],
    .app-shell__secondary-rail-close:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Collapsed state - flip the static '‹' to '›' so the chevron points
   in the direction the click will expand the rail. Open state keeps the
   default '‹' which reads as 'click to collapse back to the left'. */
.app-shell__secondary-rail[data-collapsed="true"] .app-shell__secondary-rail-collapse[b-t4mtcicg3z] {
    transform: rotate(180deg);
}

/* Collapsed rail hides the close button + the entire nav (sub-items
   render label-only, so an 'icon-only' collapsed mode would show
   empty squares - not informative). The title and the rail-mode
   toggle chevron stay visible so the user sees what section they're
   in and can expand back. Same shape as the primary AppShell
   collapse - both reduce to 'just the current scope' rather than a
   stripped icon strip. */
.app-shell__secondary-rail[data-collapsed="true"] .app-shell__secondary-rail-close[b-t4mtcicg3z],
.app-shell__secondary-rail[data-collapsed="true"] .app-shell__secondary-rail-nav[b-t4mtcicg3z] {
    display: none;
}

.app-shell__secondary-rail[data-collapsed="true"] .app-shell__secondary-rail-title[b-t4mtcicg3z] {
    /* Rotate the title 180deg so it reads vertically along the
       narrow rail. writing-mode keeps it on a single visual line; the
       transform-origin keeps the rotated baseline aligned with the
       rail's centre line. */
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    text-align: center;
    margin-top: var(--space-3);
}

.app-shell__secondary-rail-nav[b-t4mtcicg3z] {
    flex: 1 1 auto;
    overflow: auto;
    padding: var(--space-2) var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Sub-section TOGGLE button rendered inline in the sidebar - same
   visual treatment as a nav-link so the row reads as a sidebar entry,
   but it's a <button> because it toggles state (not a link). The
   icon comes from the descriptor; the rail items below render
   label-only by contrast (no per-item icons). */
.app-shell__nav-link--toggle[b-t4mtcicg3z] {
    background: transparent;
    border: 0;
    text-align: left;
    width: 100%;
    cursor: pointer;
    /* font-family / -weight / -style / line-height inherit from the
       chrome surface so the user-agent default button font (Tahoma /
       Arial) doesn't sneak in. font-size is set explicitly because
       the prior `font: inherit` shorthand also reset font-size - and
       inherited body 16 px - overriding the 14 px from
       .app-shell__nav-link this modifier sits alongside. */
    font-family: inherit;
    font-style: inherit;
    font-weight: inherit;
    line-height: inherit;
    font-size: var(--font-size-sm);
}

/* Flyout affordance - a trailing right-chevron marks the toggles that
   open a secondary rail (as opposed to leaf links that navigate). It is
   the conventional "reveals a side panel" cue, so a user clicking
   "Connections" / "Benchmarks" understands the second rail is what
   changed rather than expecting the page to swap. Decorative (CSS
   content is ignored by AT; aria-expanded already conveys state). */
.app-shell__nav-link--toggle[b-t4mtcicg3z]::after {
    content: "\203A"; /* › */
    margin-left: auto;
    padding-left: var(--space-2);
    color: var(--color-chrome-on-surface-muted);
    font-size: var(--font-size-md);
    line-height: 1;
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .app-shell__nav-link--toggle:hover[b-t4mtcicg3z]::after {
        color: var(--color-chrome-on-surface);
    }

/* Open state - flip the chevron to point back (‹) so the row now reads
   as "click to close the rail", and brighten it to match the active
   highlight. */
.app-shell__nav-link--toggle[aria-expanded="true"][b-t4mtcicg3z]::after {
    content: "\2039"; /* ‹ */
    color: var(--color-chrome-on-surface);
}

/* Open-state highlight: when the secondary rail is open the parent
   toggle carries the standard active pill (a darkened brand row on the
   blue sidebar) so it reads as "this section is open". The rail beside
   it is now a lighter, distinct panel, so the two no longer merge into
   one surface - the highlight just marks the open parent. The JS module
   flips aria-expanded on toggle so this keys off the same source of
   truth that AT users hear. */
.app-shell__nav-link--toggle[aria-expanded="true"][b-t4mtcicg3z] {
    background: var(--color-chrome-surface-active);
    color: var(--color-chrome-on-surface);
    font-weight: var(--font-weight-medium);
}

@media (forced-colors: active) {
    .app-shell__nav-link--toggle[aria-expanded="true"][b-t4mtcicg3z] {
        outline: 2px solid CanvasText;
        outline-offset: -2px;
    }
}

/* Rail sub-items: label-only rows. The BASE rule targets the mobile
   drawer's secondary panel (which stays on the blue drawer surface) -
   white text, white-alpha isn't used here so the row inherits full
   white and the hover/active darken via the chrome-surface overlays.
   The DESKTOP light rail overrides these below to dark brand-toned
   text. Font size inherits the base .app-shell__nav-link rule's 14 px
   so the rail items stay in lockstep with the primary sidebar rows. */
.app-shell__nav-link--rail-item[b-t4mtcicg3z] {
    color: var(--color-chrome-on-surface);
}

    .app-shell__nav-link--rail-item:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-surface-hover);
        color: var(--color-chrome-on-surface);
    }

    .app-shell__nav-link--rail-item:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

    .app-shell__nav-link--rail-item.active[b-t4mtcicg3z],
    .app-shell__nav-link--rail-item[aria-current="page"][b-t4mtcicg3z] {
        background: var(--color-chrome-surface-active);
        color: var(--color-chrome-on-surface);
        font-weight: var(--font-weight-medium);
    }

/* Desktop light rail - the rail rows use dark brand-toned text on the
   light brand-tinted panel (the aria-current active row is handled by
   the stronger accent-bar rule above). Scoped to .app-shell__secondary-rail
   so the mobile drawer's secondary panel (base rules above) keeps its
   white text on the blue drawer surface. The base rules' white outline /
   white-alpha overlays would be invisible / illegible on the light rail,
   so each interactive state is re-pointed at the secondary tokens + the
   dark focus ring. */
.app-shell__secondary-rail .app-shell__nav-link--rail-item[b-t4mtcicg3z] {
    color: var(--color-chrome-secondary-on-surface-muted);
}

    .app-shell__secondary-rail .app-shell__nav-link--rail-item:hover[b-t4mtcicg3z] {
        background: var(--color-chrome-secondary-surface-hover);
        color: var(--color-chrome-secondary-on-surface);
    }

    .app-shell__secondary-rail .app-shell__nav-link--rail-item:focus-visible[b-t4mtcicg3z] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Rail group disclosure - <details>/<summary> cluster used inside
   the secondary rail (e.g. Benchmarks > CIS > Microsoft 365 Foundation).
   Strip the UA marker so our own chevron is the only affordance, and
   indent nested children so the grouping reads visually. The chevron
   rotates when the disclosure is open. */
.app-shell__nav-rail-group[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
}

    .app-shell__nav-rail-group > summary[b-t4mtcicg3z] {
        list-style: none;
        cursor: pointer;
    }

        .app-shell__nav-rail-group > summary[b-t4mtcicg3z]::-webkit-details-marker {
            display: none;
        }

.app-shell__nav-rail-group-summary[b-t4mtcicg3z] {
    justify-content: space-between;
}

.app-shell__nav-rail-group-chevron[b-t4mtcicg3z] {
    transition: transform 120ms ease;
    margin-inline-start: auto;
    font-size: 0.85em;
}

.app-shell__nav-rail-group[open] > summary .app-shell__nav-rail-group-chevron[b-t4mtcicg3z] {
    transform: rotate(180deg);
}

.app-shell__nav-rail-group-items[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Nested leaf rows (e.g. Benchmarks > CIS > Microsoft 365 Foundation)
   are label-only - they carry no NavIcon, so their text must start at
   the same inline offset as the parent group row's content (its icon),
   i.e. the base nav-link padding. The earlier extra +space-2 pushed the
   label a few pixels right of the parent, reading as misaligned. */
.app-shell__nav-link--rail-nested[b-t4mtcicg3z] {
    padding-inline-start: var(--space-3);
    /* Sub-items sit one level under the rail's group heading; drop them
       back to 14px so the visual hierarchy mirrors the primary
       sidebar's heading (16px) → sub-item (14px) pattern. The earlier
       rail-item rule bumps the non-nested heading rows back to 16px. */
    font-size: var(--font-size-sm);
}

@media (prefers-reduced-motion: reduce) {
    .app-shell__nav-rail-group-chevron[b-t4mtcicg3z] {
        transition: none;
    }
}

/* Mobile drawer panels container - only meaningful inside the
   mobile drawer (the desktop sidebar has no panels). The mobile
   breakpoint block below switches it to positioned-panel layout;
   on desktop the container is irrelevant because the drawer
   itself is display:none. */
.app-shell__drawer-panels[b-t4mtcicg3z] {
    flex: 1 1 auto;
    min-height: 0;
}

.app-shell__drawer-panel[b-t4mtcicg3z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Secondary panels stay hidden by default - the active panel
   class (data-active-panel="…") below reveals the matching one. */
.app-shell__drawer-panel--secondary[b-t4mtcicg3z] {
    display: none;
}

/* Forced-colors fallback: rail surfaces map to system Canvas so HC
   users get the system palette + visible hairline borders. The
   shadow drops automatically in forced-colors mode (UA behaviour). */
@media (forced-colors: active) {
    .app-shell__secondary-rail[b-t4mtcicg3z] {
        background: Canvas;
        color: CanvasText;
        border-right-color: CanvasText;
    }

    .app-shell__secondary-rail-header[b-t4mtcicg3z] {
        border-bottom-color: CanvasText;
    }

    .app-shell__secondary-rail-title[b-t4mtcicg3z],
    .app-shell__secondary-rail-collapse[b-t4mtcicg3z],
    .app-shell__secondary-rail-close[b-t4mtcicg3z],
    .app-shell__nav-link--rail-item[b-t4mtcicg3z] {
        color: CanvasText;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-shell__secondary-rail[b-t4mtcicg3z] {
        transition: none;
    }

    /* NOTE: the collapsed-state 'transform: rotate(180deg)' on
       .app-shell__secondary-rail-collapse is NOT animated - it's a
       static state indicator that flips '‹' to '›' depending on
       data-collapsed. A prior version of this rule reset it to
       transform: none under reduce-motion, which silently kept the
       chevron pointing left in the collapsed state and broke the
       affordance for every user on macOS Reduce Motion / Windows
       'Show animations' off / DevTools 'prefers-reduced-motion'.
       Leaving the rotation in place; only the rail's width
       transition is suppressed. */
}

/* ---------------- Mobile / narrow-viewport breakpoint ----------------
   Activates the slide-in drawer for tablets + narrow desktop windows
   too - below 1024px the dual chrome (sidebar + secondary rail) eats
   more than half the viewport on a 900-1000px screen, so we switch
   to the same single-column drawer pattern used on phones. */
@media (max-width: 1024px) {
    /* Mobile drawer becomes the only nav surface. */
    .app-shell__drawer[b-t4mtcicg3z] {
        display: inline-block;
    }

    /* Desktop collapse sidebar hidden on mobile (the drawer takes over). */
    .app-shell__collapse[b-t4mtcicg3z] {
        display: none;
    }

    /* Secondary rail hidden on mobile - the mobile drawer uses the
       slide-in panels pattern instead. The toggle button inside the
       drawer carries `data-mobile-target-panel`; tapping it switches
       the drawer panel rather than opening the (hidden) rail, so the
       button stays visible. */
    .app-shell__secondary-rail[b-t4mtcicg3z] {
        display: none;
    }

    /* Drawer body - fixed-position slide-in. The browser shows the
       <details> body when [open]; CSS positions it. Surface matches
       the desktop sidebar's --color-chrome-surface so the chrome
       reads identically across the breakpoint. */
    .app-shell__drawer[open] .app-shell__drawer-nav[b-t4mtcicg3z] {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        width: 16rem;
        max-width: 80vw;
        padding: var(--space-4);
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
        border-right: 1px solid var(--color-chrome-border);
        z-index: var(--z-modal);
        overflow: auto;
    }

    /* Close button - top-right of the drawer panel, right-aligned
       in the column flex flow so the nav links flow below it in
       reading order. 44 px target for WCAG 2.5.5; click handler is
       wired by app-shell-drawer.js via the data-app-shell-close
       attribute. */
    .app-shell__drawer[open] .app-shell__drawer-close[b-t4mtcicg3z] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        align-self: flex-end;
        width: var(--target-size-touch);
        height: var(--target-size-touch);
        min-width: var(--target-size-touch);
        min-height: var(--target-size-touch);
        padding: 0;
        margin-bottom: var(--space-2);
        border: none;
        border-radius: var(--radius-md);
        background: transparent;
        color: var(--color-chrome-on-surface);
        cursor: pointer;
    }

        .app-shell__drawer[open] .app-shell__drawer-close:hover[b-t4mtcicg3z] {
            background: var(--color-chrome-surface-hover);
        }

        .app-shell__drawer[open] .app-shell__drawer-close:focus-visible[b-t4mtcicg3z] {
            outline: 2px solid var(--color-chrome-on-surface);
            outline-offset: 2px;
        }

    /* Mobile drawer panels - main vs secondary slide-in.
       Container clips to itself; panels position absolutely so the
       active panel fills the available area and inactive panels
       translate offscreen. The drawer-nav above is the
       fixed-position viewport; the panels container fills the area
       left after the close button at the top. */
    .app-shell__drawer[open] .app-shell__drawer-nav[b-t4mtcicg3z] {
        overflow: hidden;
    }

    .app-shell__drawer[open] .app-shell__drawer-panels[b-t4mtcicg3z] {
        position: relative;
        overflow: hidden;
        flex: 1 1 auto;
        min-height: 0;
    }

    .app-shell__drawer[open] .app-shell__drawer-panel[b-t4mtcicg3z] {
        position: absolute;
        inset: 0;
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        overflow: auto;
        transition: transform var(--motion-duration-normal) var(--motion-easing-standard);
    }

    /* Secondary panels are display:none outside the mobile block;
       the rule above bumps them up to display:flex so the slide-in
       transforms have something to animate. */

    /* Main panel: in view when the container is in "main" state,
       slid off to the left otherwise. The two rules tie on
       specificity so only one matches at a time (the :not()
       negates the other side of the swap). */
    .app-shell__drawer[open] .app-shell__drawer-panels[data-active-panel="main"] .app-shell__drawer-panel[data-panel="main"][b-t4mtcicg3z] {
        transform: translateX(0);
    }
    .app-shell__drawer[open] .app-shell__drawer-panels:not([data-active-panel="main"]) .app-shell__drawer-panel[data-panel="main"][b-t4mtcicg3z] {
        transform: translateX(-100%);
    }

    /* Secondary panels: parked one screen-width to the right by
       default. The JS sets data-active="true" on the matching panel
       when its toggle fires; that selector is more specific than
       the base parked-off-screen rule and wins. */
    .app-shell__drawer[open] .app-shell__drawer-panel--secondary[data-active="true"][b-t4mtcicg3z] {
        transform: translateX(0);
    }
    .app-shell__drawer[open] .app-shell__drawer-panel--secondary:not([data-active="true"])[b-t4mtcicg3z] {
        transform: translateX(100%);
    }

    /* The "← parent" back button at the top of every secondary
       panel. Inline-flex with a leading chevron pseudo-element so
       the row reads "← Tenant" / "← Platform" without extra
       markup. Padding mirrors the drawer-close button so the two
       controls sit at matching positions across panels. */
    .app-shell__drawer-panel-back[b-t4mtcicg3z] {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        align-self: flex-start;
        min-height: var(--target-size-minimum);
        padding: var(--space-2) var(--space-3);
        margin-bottom: var(--space-2);
        background: transparent;
        border: 0;
        color: var(--color-chrome-on-surface);
        border-radius: var(--radius-md);
        cursor: pointer;
        font: inherit;
        font-weight: var(--font-weight-medium);
    }

        .app-shell__drawer-panel-back[b-t4mtcicg3z]::before {
            content: "\2190"; /* leftwards arrow */
            font-size: var(--font-size-md);
            line-height: 1;
        }

        .app-shell__drawer-panel-back:hover[b-t4mtcicg3z] {
            background: var(--color-chrome-surface-hover);
        }

        .app-shell__drawer-panel-back:focus-visible[b-t4mtcicg3z] {
            outline: 2px solid var(--color-chrome-on-surface);
            outline-offset: 2px;
        }

    /* Section heading rendered between the "← Tenant" back button and
       the rail entries. Anchors the user on which sub-section they
       navigated into (e.g. "Settings"). */
    .app-shell__drawer-panel-heading[b-t4mtcicg3z] {
        margin: 0 0 var(--space-3);
        padding: 0 var(--space-3);
        font-size: var(--font-size-lg);
        font-weight: var(--font-weight-semibold);
        color: var(--color-chrome-on-surface);
        letter-spacing: var(--letter-spacing-tight, -0.01em);
    }

    .app-shell__drawer-panel-nav[b-t4mtcicg3z] {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
    }

    @media (prefers-reduced-motion: reduce) {
        .app-shell__drawer[open] .app-shell__drawer-panel[b-t4mtcicg3z] {
            transition: none;
        }
    }
}
/* /Components/Layout/AppShellFooter.razor.rz.scp.css */
/*
    AppShellFooter - slim utility band at the bottom of the main
    column on every signed-in page. White surface so it reads as a
    quiet section break below the page content; a hairline top
    border carries the visual boundary. Renders to the right of the
    navy sidebar (which extends to the viewport bottom edge), so the
    footer never paints under the chrome.
*/

.app-shell-footer[b-bdhqx265tq] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    /* Single dot-separated band - feedback · ☀ · version · ©.
       Right-aligned on wide viewports; wraps below the narrow
       breakpoint where the chrome surrounds the content edge-to-edge. */
    justify-content: flex-end;
    gap: var(--space-3);
    padding: var(--space-4) var(--space-5);
    margin-top: auto;
    /* White surface + hairline top border so the footer reads as a
       section break under the page content. The sidebar's navy
       chrome continues to the viewport bottom alongside this band. */
    background: var(--color-surface);
    border-top: 1px solid var(--color-border-subtle);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

@media (forced-colors: active) {
    .app-shell-footer[b-bdhqx265tq] {
        background: Canvas;
        color: CanvasText;
        border-top-color: CanvasText;
    }
}

.app-shell-footer__links[b-bdhqx265tq] {
    display: inline-flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.app-shell-footer__link[b-bdhqx265tq] {
    color: var(--color-text-muted);
    text-decoration: none;
    border-radius: var(--radius-sm);
    /* 44×44 minimum touch target - pointer-coarse media query keeps
       desktop visuals tight while phones / tablets get a thumb-friendly
       hit area. Without this the inline footer band (~22px) is too small
       to tap reliably on iOS / Android. */
    padding: 2px var(--space-1);
    transition: color var(--motion-duration-fast) var(--motion-easing-standard);
}

@media (pointer: coarse) {
    .app-shell-footer__link[b-bdhqx265tq] {
        min-block-size: 2.75rem;
        min-inline-size: 2.75rem;
        padding-inline: var(--space-2);
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
}

    .app-shell-footer__link:hover[b-bdhqx265tq] {
        color: var(--color-brand);
        text-decoration: underline;
    }

    .app-shell-footer__link:focus-visible[b-bdhqx265tq] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        color: var(--color-brand);
    }

.app-shell-footer__sep[b-bdhqx265tq] {
    color: var(--color-border);
}

.app-shell-footer__version[b-bdhqx265tq] {
    font-variant-numeric: tabular-nums;
    cursor: help;
}

.app-shell-footer__copyright[b-bdhqx265tq] {
    font-variant-numeric: tabular-nums;
}

@media (max-width: 599px) {
    .app-shell-footer[b-bdhqx265tq] {
        padding: var(--space-3) var(--space-4);
        justify-content: center;
        gap: var(--space-2);
    }

    .app-shell-footer__links[b-bdhqx265tq] {
        gap: var(--space-1);
    }

    /* The build-version chip is developer-facing detail (its full
       version lives in a hover tooltip that touch devices cannot reach
       anyway); dropping it - and the dot in front of it - keeps the
       band on one line on phones. :has() selects the separator that
       immediately precedes the version span. */
    .app-shell-footer__version[b-bdhqx265tq],
    .app-shell-footer__sep:has(+ .app-shell-footer__version)[b-bdhqx265tq] {
        display: none;
    }
}

@media print {
    .app-shell-footer[b-bdhqx265tq] {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .app-shell-footer__link[b-bdhqx265tq] {
        transition: none;
    }
}
/* /Components/Layout/MainLayout.razor.rz.scp.css */
/*
 * Framework error toast surfaced when the SignalR connection raises an
 * uncaught exception. Token-driven so light / dark / High-Contrast all
 * stay legible (the original Bootstrap-template `lightyellow` literal
 * disappeared into the void under prefers-color-scheme: dark).
 */

#blazor-error-ui[b-4lzmovs7lx] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
    bottom: 0;
    box-shadow: var(--shadow-md);
    box-sizing: border-box;
    display: none;
    left: 0;
    padding: var(--space-2) var(--space-5) var(--space-3) var(--space-5);
    position: fixed;
    width: 100%;
    z-index: var(--z-toast);
}

    #blazor-error-ui .dismiss[b-4lzmovs7lx] {
        cursor: pointer;
        position: absolute;
        right: var(--space-3);
        top: var(--space-2);
    }
/* /Components/Layout/PublicShell.razor.rz.scp.css */
/*
 * PublicShell - styles for the marketing / anonymous chrome. Every value
 * resolves through a token in wwwroot/css/tokens.css so the shell honours
 * light, dark, Windows High Contrast, and prefers-reduced-motion without
 * per-rule conditionals.
 *
 * No JS module is loaded by the shell itself; the visual layer is
 * pure CSS so first paint stays inside the ≤ 50 KB JS budget for
 * marketing pages.
 */

/* Skip-link - keyboard-only affordance to jump past the header straight
   to <main>. Hidden off-canvas until focused so it doesn't intrude on
   sighted-mouse users. */
.public-shell__skip-link[b-3x94fb1yvg] {
    position: absolute;
    left: -10000px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

    .public-shell__skip-link:focus[b-3x94fb1yvg] {
        position: fixed;
        top: var(--space-2);
        left: var(--space-2);
        width: auto;
        height: auto;
        padding: var(--space-2) var(--space-4);
        background: var(--color-surface);
        color: var(--color-text);
        border: 2px solid var(--color-focus-ring);
        border-radius: var(--radius-md);
        z-index: var(--z-toast);
    }

.public-shell[b-3x94fb1yvg] {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--color-surface);
    color: var(--color-text);
    /* Auth pages render plain forms inside an implicit card. Nothing
       in this layout should ever scroll horizontally - fixed loading
       overlays, long validation strings, or a stray descendant width
       beyond the viewport must clip, not produce a body-level scroll
       bar. `overflow-x: clip` (vs `hidden`) doesn't create a scroll
       container, so it has zero effect on the page's vertical
       scroll position when the loading overlay fades in / out. */
    overflow-x: clip;
    font-family: var(--font-sans);
    line-height: var(--line-height-normal);
}

.public-shell__header[b-3x94fb1yvg] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    /* 72px tall to match the marketing site's header (--header-height there),
       so the chrome is the same height across www and the sign-in portal. */
    min-height: 4.5rem;
    /* Cap the header CONTENT at the marketing site's content width (75rem /
       1200px - its --content-max) and centre it, so the brand + nav align with
       www instead of spanning wider. The background/border/backdrop still span
       full width; only the flex content is inset. The side padding never drops
       below --space-6, matching the site's .container. */
    padding: var(--space-3) max(var(--space-6), calc((100% - 75rem) / 2));
    /* Hairline border + translucent fill - the crisp-tech header
       sits over the hero's mesh gradient without an opaque slab. */
    border-bottom: 1px solid var(--color-border-subtle);
    background: color-mix(in srgb, var(--color-surface) 88%, transparent);
    backdrop-filter: saturate(180%) blur(8px);
    -webkit-backdrop-filter: saturate(180%) blur(8px);
    position: sticky;
    top: 0;
    z-index: var(--z-sticky);
}

@media (forced-colors: active) {
    .public-shell__header[b-3x94fb1yvg] {
        background: Canvas;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    /* Decorative hero blooms collapse to a flat Canvas - same as the site. */
    .public-shell__main[b-3x94fb1yvg] {
        background-image: none;
    }
}

.public-shell__brand-link[b-3x94fb1yvg] {
    display: inline-flex;
    align-items: center;
    /* Even spacing between the mark, wordmark, and release-stage chip so
       the three read as one brand unit (matches the marketing site's brand
       gap). */
    gap: var(--space-3);
    padding: var(--space-1) var(--space-2);
    margin-inline-start: calc(var(--space-2) * -1);
    border-radius: var(--radius-md);
    color: var(--color-text);
    text-decoration: none;
}

    /* Explicit no-affordance hover - the wordmark is the brand
       identity, not an interactive surface. Suppressing any
       background tint / text-decoration that a future global rule
       (or a user-agent default) might introduce keeps the public
       header chrome calm. Focus-visible stays in place for keyboard
       users; pointer hover is intentionally silent. */
    .public-shell__brand-link:hover[b-3x94fb1yvg] {
        background: transparent;
        color: var(--color-text);
        text-decoration: none;
    }

    .public-shell__brand-link:focus-visible[b-3x94fb1yvg] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* ::deep - the honeycomb <svg> is rendered by the child <BrandMark>
   component, so this rule needs ::deep to reach across the scope boundary. */
.public-shell__brand-link[b-3x94fb1yvg]  .public-shell__brand-mark {
    display: block;
    /* 28px (1.75rem) to match the marketing site's brand mark. */
    height: 28px;
    width: auto;
    aspect-ratio: 76.42 / 94.8;
    /* Blue cells on the light public header (the "primary" mark variant);
       the flagged cell is fixed Signal Amber. */
    color: var(--color-brand);
    flex: none;
    /* Playful tilt on hover, matching the marketing site's brand mark. */
    transition: transform var(--motion-duration-slow) var(--motion-easing-spring);
}

/* Hover animates the honeycomb mark (not the wordmark, which stays a calm
   brand lockup) - same gesture as www's header logo. */
.public-shell__brand-link:hover[b-3x94fb1yvg]  .public-shell__brand-mark {
    transform: rotate(-8deg) scale(1.06);
}

@media (prefers-reduced-motion: reduce) {
    .public-shell__brand-link:hover[b-3x94fb1yvg]  .public-shell__brand-mark {
        transform: none;
    }
}

/* Wordmark - "Admin Companion" in the brand display face, dark ink on the
   light public header. "Admin" is bold, "Companion" is medium. */
.public-shell__brand-word[b-3x94fb1yvg] {
    font-family: var(--font-display);
    /* 20px (--font-size-xl) to match the marketing site's wordmark. */
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-medium);
    letter-spacing: var(--letter-spacing-tight);
    line-height: 1;
    white-space: nowrap;
    color: var(--color-text);
}

    /* "Admin" - bold, full ink (inherits from .public-shell__brand-word). */
    .public-shell__brand-word b[b-3x94fb1yvg] {
        font-weight: var(--font-weight-bold);
    }

    /* "Companion" - medium weight in muted ink, per the brand lockup spec. */
    .public-shell__brand-word span[b-3x94fb1yvg] {
        font-weight: var(--font-weight-medium);
        color: var(--color-text-muted);
    }

@media (max-width: 26rem) {
    .public-shell__brand-word[b-3x94fb1yvg] {
        display: none;
    }
}

/* "Private Preview" chip pinned next to the public-shell wordmark.
   Light-surface variant: a tinted brand-color pill rather than the
   chrome-surface translucency the app shell uses. Hidden under narrow
   viewports to keep the public header tight. */
.public-shell__brand-tag[b-3x94fb1yvg] {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    background: var(--color-brand-subtle);
    color: var(--color-brand);
    border: 1px solid var(--color-brand-200);
    border-radius: var(--radius-sm);
    font-size: 0.72rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
}

@media (max-width: 32rem) {
    .public-shell__brand-tag[b-3x94fb1yvg] {
        display: none;
    }
}

.public-shell__nav[b-3x94fb1yvg] {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.public-shell__nav-link[b-3x94fb1yvg] {
    display: inline-flex;
    align-items: center;
    /* 44px pill links with muted ink - the same header link treatment as
       the marketing site, so the two chromes read as one. */
    min-height: var(--target-size-touch);
    padding: var(--space-2) var(--space-4);
    color: var(--color-text-muted);
    text-decoration: none;
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
    border: 1px solid transparent;
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .public-shell__nav-link:hover[b-3x94fb1yvg] {
        color: var(--color-text);
        background: var(--color-surface-sunken);
    }

    .public-shell__nav-link:focus-visible[b-3x94fb1yvg] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

    /* Active header item - aria-current is the source of truth, matching
       the marketing site's active-link treatment. */
    .public-shell__nav-link[aria-current="page"][b-3x94fb1yvg] {
        color: var(--color-link, var(--color-brand));
        background: var(--color-brand-50);
        font-weight: var(--font-weight-semibold);
    }

.public-shell__nav-link--cta[b-3x94fb1yvg] {
    /* Sign-up accent (brand decision 2026-07): amber #FFB020 pops
       against the navy chrome and stays CONSTANT across themes, so
       the text is a fixed dark ink rather than a theme token - it
       holds WCAG AA (~9:1) on the amber in both light and dark. */
    background: #ffb020;
    color: #0f172a;
    border-radius: var(--radius-lg);
    padding-inline: var(--space-4);
    box-shadow: var(--shadow-sm);
}

    .public-shell__nav-link--cta:hover[b-3x94fb1yvg] {
        background: #ffc04d;
        color: #0f172a;
    }

    .public-shell__nav-link--cta:active[b-3x94fb1yvg] {
        background: #f0a416;
        color: #0f172a;
    }

.public-shell__main[b-3x94fb1yvg] {
    flex: 1 1 auto;
    /* No top-level padding here - sections own their own padding so
       the hero can bleed edge-to-edge with its mesh background and
       the feature grid / final-CTA blocks pick their own rhythm. */
    padding: 0;
    outline: none;
    /* Same hero backdrop as the marketing site: a soft blue wash at the top
       with blue + amber corner blooms, so the sign-in page sits on the same
       surface as www. Mirrors the site's --gradient-mesh over --gradient-hero
       (the app's global mesh tokens are blue-only and never rendered, and it
       has no amber token, so the amber-100 #fff0cf is inlined here). */
    background-image:
        radial-gradient(circle at 85% 12%,
            color-mix(in srgb, #fff0cf 38%, transparent) 0%, transparent 40%),
        radial-gradient(circle at 92% 82%,
            color-mix(in srgb, var(--color-brand-100) 40%, transparent) 0%, transparent 44%),
        radial-gradient(ellipse 80% 60% at 50% 0%,
            var(--color-brand-50) 0%, transparent 70%);
    background-repeat: no-repeat;
    /* The default min-width on a flex item is auto = content size.
       If any descendant inside the auth-card grows past the viewport
       (long error string, wide button content, etc.) this flex item
       refuses to shrink and the body picks up a horizontal scroll
       bar. Setting min-width: 0 lets the item shrink past its
       intrinsic content width - children that need to wrap get a
       chance to, instead of forcing the page wider. */
    min-width: 0;
}

.public-shell__footer[b-3x94fb1yvg] {
    /* Flex row so the theme toggle sits inline with the copyright -
       same bottom-utility-band placement the signed-in AppShellFooter
       uses, keeping the affordance in one spot across sign-in. */
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-8) clamp(var(--space-4), 4vw, var(--space-8));
    border-top: 1px solid var(--color-border-subtle);
    background: var(--color-surface);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    text-align: center;
}

/* Canonical sm floor (599px): tighter band on phones so the toggle +
   copyright stay on one line. */
@media (max-width: 599px) {
    .public-shell__footer[b-3x94fb1yvg] {
        gap: var(--space-2);
        padding: var(--space-4);
    }
}

    .public-shell__footer p[b-3x94fb1yvg] {
        margin: 0;
    }

/* Canonical sm floor (599px) - see tokens.css "Responsive breakpoints".
   Below this the public-shell header drops every nav link that isn't
   the primary CTA so the small-viewport header stays uncluttered. */
@media (max-width: 599px) {
    .public-shell__nav-link:not(.public-shell__nav-link--cta)[b-3x94fb1yvg] {
        display: none;
    }
}
/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
/*
 * Blazor SignalR reconnect modal. The animation timings are framework-
 * tuned (1.5s slide-up + 0.3s delay) and deliberately attention-grabbing
 * - a connection drop is rare and the user needs to see it. Colours,
 * radii, shadows, and spacing all consume design tokens so the modal
 * inherits theme + High-Contrast support automatically.
 *
 * Motion preference: a `@media (prefers-reduced-motion: reduce)`
 * block at the bottom of this file disables the slide-up + fade
 * animations so users who have expressed a preference see an instant
 * fade-in instead of the dramatic transform. The failure-mode
 * messaging is the important part either way.
 *
 * The rejoining indicator is the shared BrandLoader - the same mark
 * page navigation shows - so a dropped circuit reads as the app still
 * working rather than as a different, unfamiliar failure surface. Its
 * animation lives in the global app.css on purpose: this modal has to
 * keep animating with no circuit and no component rendering.
 */

.components-reconnect-first-attempt-visible[b-n33rwhtzv4],
.components-reconnect-repeated-attempt-visible[b-n33rwhtzv4],
.components-reconnect-failed-visible[b-n33rwhtzv4],
.components-pause-visible[b-n33rwhtzv4],
.components-resume-failed-visible[b-n33rwhtzv4],
.components-rejoining-animation[b-n33rwhtzv4] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-retrying[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-failed[b-n33rwhtzv4],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-n33rwhtzv4] {
    display: block;
}


#components-reconnect-modal[b-n33rwhtzv4] {
    background-color: var(--color-surface-raised);
    color: var(--color-text);
    width: 20rem;
    margin: 20vh auto;
    padding: var(--space-8);
    border: 0;
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-n33rwhtzv4 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-n33rwhtzv4 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-n33rwhtzv4 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-n33rwhtzv4]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-n33rwhtzv4 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-n33rwhtzv4 {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-n33rwhtzv4 {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-n33rwhtzv4 {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-n33rwhtzv4] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}

#components-reconnect-modal p[b-n33rwhtzv4] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-n33rwhtzv4] {
    border: 0;
    background-color: var(--color-brand);
    color: var(--color-text-on-accent);
    padding: var(--space-1) var(--space-6);
    /* WCAG 2.5.8: enforce the 24px floor explicitly rather than relying on
       computed font/padding metrics. */
    min-block-size: var(--target-size-minimum);
    border-radius: var(--radius-md);
}

    #components-reconnect-modal button:hover[b-n33rwhtzv4] {
        background-color: var(--color-brand-hover);
    }

    #components-reconnect-modal button:active[b-n33rwhtzv4] {
        background-color: var(--color-brand-active);
    }

    /* WCAG 2.4.7 Focus Visible: the recovery dialog's buttons are plain
       <button> elements that the global submit-button focus rules don't
       match, so keyboard/switch users had no focus indicator here. */
    #components-reconnect-modal button:focus-visible[b-n33rwhtzv4] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* ::deep because BrandLoader is a child component: its <svg> never carries this
   component's scoped attribute, so a plain selector here would match nothing and
   the mark would render at the default block size app.css gives it. */
.components-rejoining-animation[b-n33rwhtzv4]  .components-rejoining-animation__loader {
    block-size: 5rem;
}

/* Reduced-motion override: an instant fade-in instead of the slide-up + scale.
   The mark's own sweep is NOT stopped here - app.css already slows it for this
   preference, and it keeps moving on purpose. A frozen indicator on a reconnect
   screen reads as "the app is hung", which is the one thing it must not say
   while it is in fact still trying. */
@media (prefers-reduced-motion: reduce) {
    #components-reconnect-modal[b-n33rwhtzv4],
    #components-reconnect-modal[open][b-n33rwhtzv4],
    #components-reconnect-modal[b-n33rwhtzv4]::backdrop {
        animation: none;
    }
}
/* /Components/Pages/Benchmarks/BenchmarkList.razor.rz.scp.css */
/*
 * BenchmarkList - card-grid layout for the controls library.
 * Each control is rendered as a single <a class="benchmark-card">
 * so the whole tile is a navigation target (no nested links). The
 * grid collapses to one column on narrow viewports.
 */

.benchmark-list[b-elbpwygjz1] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-5);
}

/* Base chrome + hover lift + transitions come from
   `.surface-card.surface-card--interactive` in app.css. BenchmarkCard
   adds its own three-column grid, anchor-link styling, brand hover
   border, and focus ring. */
.benchmark-card[b-elbpwygjz1] {
    display: grid;
    grid-template-columns: max-content 1fr auto;
    align-items: center;
    gap: var(--space-3);
    color: var(--color-text);
    text-decoration: none;
}

    .benchmark-card:hover[b-elbpwygjz1] {
        border-color: var(--color-brand);
    }

    .benchmark-card:focus-visible[b-elbpwygjz1] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.benchmark-card__id[b-elbpwygjz1] {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    color: var(--color-brand-hover);
    background: var(--color-brand-subtle);
    border-radius: var(--radius-sm);
    border: 1px solid color-mix(in srgb, var(--color-brand) 25%, transparent);
    flex: 0 0 auto;
    white-space: nowrap;
}

.benchmark-card__title[b-elbpwygjz1] {
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-snug);
    overflow-wrap: anywhere;
}

.benchmark-card__chevron[b-elbpwygjz1] {
    color: var(--color-text-muted);
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard);
    flex: 0 0 auto;
}

.benchmark-card:hover .benchmark-card__chevron[b-elbpwygjz1],
.benchmark-card:focus-visible .benchmark-card__chevron[b-elbpwygjz1] {
    color: var(--color-brand);
    transform: translateX(2px);
}

.benchmark-list__pager[b-elbpwygjz1] {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
}

.benchmark-list__pager-status[b-elbpwygjz1] {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    margin: 0;
    margin-right: auto;
}

.benchmark-list__pager a[b-elbpwygjz1] {
    color: var(--color-brand);
    text-decoration: none;
    font-weight: var(--font-weight-medium);
}

    .benchmark-list__pager a:hover[b-elbpwygjz1] {
        color: var(--color-brand-hover);
        text-decoration: underline;
    }

    .benchmark-list__pager a:focus-visible[b-elbpwygjz1] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-radius: var(--radius-sm);
    }

.benchmark-list__pager span[aria-disabled="true"][b-elbpwygjz1] {
    color: var(--color-text-muted);
}

@media (forced-colors: active) {
    /* .surface-card maps the benchmark card; the pager is a sibling
       surface that still needs its own override. */
    .benchmark-list__pager[b-elbpwygjz1] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }

    .benchmark-card__id[b-elbpwygjz1] {
        background: Canvas;
        border: 1px solid CanvasText;
        forced-color-adjust: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    /* .surface-card--interactive already flat-stops the hover lift +
       its own transitions; only the chevron remains page-specific. */
    .benchmark-card__chevron[b-elbpwygjz1] {
        transition: none;
    }
}
/* /Components/Pages/Benchmarks/ControlDetail.razor.rz.scp.css */
/*
 * ControlDetail - token-driven layout for the benchmark control
 * detail page. The body content (`.control-body`) holds upstream-
 * sanitised HTML produced by the Worker's content-sync renderer;
 * styles here are a defensive baseline so unstyled headings / code
 * blocks / lists still render reasonably even when the future shared
 * benchmark stylesheet hasn't loaded.
 */

.control-meta[b-p98mdwf2rt] {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    margin: var(--space-2) 0 var(--space-6);
}

.control-body[b-p98mdwf2rt] {
    line-height: var(--line-height-relaxed);
    color: var(--color-text);
}

    .control-body h2[b-p98mdwf2rt] {
        margin-top: var(--space-6);
        font-size: var(--font-size-xl);
    }

    .control-body h3[b-p98mdwf2rt] {
        margin-top: var(--space-5);
        font-size: var(--font-size-lg);
    }

    .control-body p[b-p98mdwf2rt] {
        margin: var(--space-3) 0;
    }

    .control-body pre[b-p98mdwf2rt] {
        background: var(--color-surface-sunken);
        border-radius: var(--radius-md);
        padding: var(--space-3) var(--space-4);
        overflow-x: auto;
        font-family: var(--font-mono);
        font-size: var(--font-size-sm);
    }

    .control-body code[b-p98mdwf2rt] {
        font-family: var(--font-mono);
        font-size: var(--font-size-sm);
    }

    .control-body :not(pre) > code[b-p98mdwf2rt] {
        background: var(--color-surface-sunken);
        padding: 0 var(--space-1);
        border-radius: var(--radius-sm);
    }

    .control-body ul[b-p98mdwf2rt],
    .control-body ol[b-p98mdwf2rt] {
        padding-left: var(--space-6);
    }

    .control-body a[b-p98mdwf2rt] {
        color: var(--color-brand);
        text-decoration: underline;
    }

        .control-body a:hover[b-p98mdwf2rt] {
            color: var(--color-brand-hover);
        }

        .control-body a:focus-visible[b-p98mdwf2rt] {
            outline: 2px solid var(--color-focus-ring);
            outline-offset: 2px;
        }
/* /Components/Pages/Dashboard/Dashboard.razor.rz.scp.css */
/*
 * Dashboard - top-level signed-in landing surface. The hero +
 * tile-grid styling is inherited from PageHeader (Components/Ui/Layout/
 * PageHeader.razor.css); this sheet carries the page-specific surfaces
 * that sit BELOW the hero: the Quick-actions row, two activity-feed
 * panels (side-by-side on desktop), and the empty state. Every value
 * resolves through a design token so dark mode + high-contrast track
 * automatically.
 */

/* ----- Section scaffolding ------------------------------------------ */
/* Two flavours of section: an open-air "eyebrow" section used for the
   Quick-actions row, and a tinted "--card" surface used for each of
   the two activity feed panels. The card variant gets its own heading
   treatment further down. */

.dashboard-section[b-3q6a13ql6x] {
    margin-block-start: var(--space-8);
}

/* "Quick actions" heading - subordinate eyebrow over a row of cards.
   Visually lighter than the feed-panel headings below so the eye
   reads it as navigation, not data. */
.dashboard-section__heading[b-3q6a13ql6x] {
    margin: 0 0 var(--space-3);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: var(--letter-spacing-wide);
}

/* Card surface - base chrome from .surface-card in app.css. Override the
   bottom padding so the inline-padded card body lands flush with the
   feed-row gap. */
.dashboard-section--card[b-3q6a13ql6x] {
    padding-block-end: var(--space-4);
    margin-block-start: 0; /* parent .dashboard-feeds carries the gap */
}

/* Inside-the-card heading - owns the panel, sized as the section's
   primary label (semibold + larger) instead of the eyebrow used in
   open-air sections. */
.dashboard-section--card .dashboard-section__heading[b-3q6a13ql6x] {
    margin: 0 0 var(--space-3);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
    text-transform: none;
    letter-spacing: var(--letter-spacing-tight, -0.01em);
}

/* Quick-action card grid - auto-fit minmax 16rem so two- vs. four-up
   layouts both work without per-page tweaks. Collapses to a single
   column under the mobile breakpoint. */
.dashboard-section__action-grid[b-3q6a13ql6x] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--space-4);
}

/* ----- Feeds wrapper: side-by-side at ≥ 960 px ---------------------- */
/* Holds the two .dashboard-section--card siblings. Single column
   under 960 px so cards stack on tablet / narrow desktop; two
   columns at wider viewports so the page doesn't sprawl vertically. */

.dashboard-feeds[b-3q6a13ql6x] {
    margin-block-start: var(--space-8);
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
}

@media (min-width: 960px) {
    .dashboard-feeds[b-3q6a13ql6x] {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ----- Activity feed rows ------------------------------------------- */
/* Single-line rows by design - the previous two-line treatment
   (title + muted meta) was the biggest source of vertical clutter.
   The meta string still rides along on the <li> as a title= tooltip
   and aria-label for keep-context-on-hover. */

.dashboard-feed[b-3q6a13ql6x] {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.dashboard-feed__row[b-3q6a13ql6x] {
    display: grid;
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
    min-height: 2.5rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
}

.dashboard-feed__leader[b-3q6a13ql6x] {
    display: inline-flex;
    align-items: center;
    color: var(--color-text-muted);
}

.dashboard-feed__body[b-3q6a13ql6x] {
    display: flex;
    align-items: center;
    min-width: 0;
}

.dashboard-feed__title[b-3q6a13ql6x] {
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dashboard-feed__time[b-3q6a13ql6x] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* Empty state for the recent-activity feed (no audit events yet). */
.dashboard-feed__empty[b-3q6a13ql6x] {
    margin: 0;
    padding: var(--space-2) 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.dashboard-feed__action[b-3q6a13ql6x] {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-brand);
    text-decoration: none;
    border-radius: var(--radius-sm);
    padding: var(--space-1) var(--space-2);
}

    .dashboard-feed__action:hover[b-3q6a13ql6x] {
        text-decoration: underline;
    }

    .dashboard-feed__action:focus-visible[b-3q6a13ql6x] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

@media (forced-colors: active) {
    .dashboard-feed__row[b-3q6a13ql6x] {
        border: 1px solid CanvasText;
    }
}

/* ----- Empty state (no memberships) --------------------------------- */

.dashboard__empty[b-3q6a13ql6x] {
    margin-block-start: var(--space-6);
}

/* ----- Mobile breakpoint ------------------------------------------- */
/* Mirrors the 599 px breakpoint that .list-page-hero__tiles already
   uses (lists.css) so the dashboard's tile grid + action grid + feed
   rows collapse at the same width. Feed row flattens to a two-row
   stack: title on top, leader + time + action below - the row
   template uses grid-template-areas so the optional action column
   doesn't push the time off the row. */

@media (max-width: 599px) {
    .dashboard-section--card[b-3q6a13ql6x] {
        padding-inline: var(--space-4);
        padding-block: var(--space-4);
    }

    .dashboard-section__action-grid[b-3q6a13ql6x] {
        grid-template-columns: 1fr;
    }

    .dashboard-feed__row[b-3q6a13ql6x] {
        grid-template-columns: auto 1fr auto;
        grid-template-areas:
            "leader body body"
            "spacer time action";
        row-gap: var(--space-1);
    }

    .dashboard-feed__leader[b-3q6a13ql6x] {
        grid-area: leader;
    }

    .dashboard-feed__body[b-3q6a13ql6x] {
        grid-area: body;
    }

    .dashboard-feed__time[b-3q6a13ql6x] {
        grid-area: time;
    }

    .dashboard-feed__action[b-3q6a13ql6x] {
        grid-area: action;
    }
}
/* /Components/Pages/Estate/EstateControls.razor.rz.scp.css */
.estate-controls__warning[b-j1awfpqiwj] {
    margin: var(--space-4) 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid var(--color-warning-border, #d97706);
    border-radius: var(--radius-md, 8px);
    background: var(--color-warning-surface, #fef3c7);
}

/* Cell fragments render inside the shared ListView's table, outside this
   component's scope - ::deep reaches them. */
[b-j1awfpqiwj] .estate-controls__control-link {
    display: block;
    font-weight: 600;
    white-space: nowrap;
}

[b-j1awfpqiwj] .estate-controls__benchmark {
    display: block;
}

[b-j1awfpqiwj] .estate-controls__control-title,
[b-j1awfpqiwj] .estate-controls__version {
    display: block;
    font-size: var(--text-sm, 0.875rem);
    color: var(--color-text-muted, #64748b);
}

[b-j1awfpqiwj] .estate-controls__time {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
/* /Components/Pages/Platform/AuditLog/PlatformAuditLog.razor.rz.scp.css */
/* Platform-admin audit-log page chrome - scoped CSS. Heading + intro
   now live in <ListPageHero>; the toolbar-row aligns the density
   toggle to the right of the page, above the InteractiveServer
   island. Table styling lives in PlatformAuditLogTable.razor.css;
   shared list-primitive styling lives in wwwroot/css/lists.css. */

.platform-audit-log__toolbar-row[b-vu28esk5pl] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}
/* /Components/Pages/Platform/Certificates/PlatformConnectionCertificates.razor.rz.scp.css */
/* Cell-content styles only - table chrome (header, rows, empty/loading
   states) is owned by the shared ListView component. */

.platform-certificates__tenant-name[b-mjbdaymo6m] {
    display: block;
    font-weight: var(--font-weight-medium);
}

.platform-certificates__tenant-slug[b-mjbdaymo6m] {
    display: block;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.platform-certificates__thumbprint[b-mjbdaymo6m] {
    display: inline-block;
    max-width: 22ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

.platform-certificates__thumbprint--pending[b-mjbdaymo6m] {
    color: var(--color-text-muted);
}

.platform-certificates__muted[b-mjbdaymo6m] {
    display: block;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.platform-certificates__badge[b-mjbdaymo6m] {
    display: inline-block;
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill, 999px);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.platform-certificates__badge--valid[b-mjbdaymo6m] {
    background: var(--color-success-surface);
    color: var(--color-success-on-surface);
}

.platform-certificates__badge--expiring[b-mjbdaymo6m] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
}

.platform-certificates__badge--expired[b-mjbdaymo6m] {
    background: var(--color-danger-surface);
    color: var(--color-danger-on-surface);
}

.platform-certificates__badge--pending[b-mjbdaymo6m],
.platform-certificates__badge--none[b-mjbdaymo6m] {
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
}
/* /Components/Pages/Platform/ContentSync/ContentSync.razor.rz.scp.css */
/*
 * /_admin/content-sync - operator-facing read-only view of the
 * Worker host's ContentSyncJob. Token-driven so light / dark /
 * Windows High Contrast remain legible. No interactive state on the
 * page today - the "sync now" button is disabled and rendered as a
 * standard disabled control rather than a confusing absent-but-
 * intended affordance.
 */

.content-sync__state[b-g7chagwzbw] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    margin-bottom: var(--space-6);
}

.content-sync__state-grid[b-g7chagwzbw] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: var(--space-3);
    margin: 0 0 var(--space-4);
}

.content-sync__sha[b-g7chagwzbw] {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    background: var(--color-surface-sunken);
    padding: 0 var(--space-1);
    border-radius: var(--radius-sm);
}

.content-sync__sync-now[b-g7chagwzbw] {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin: 0;
}

.content-sync__sync-now-hint[b-g7chagwzbw] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* Status / alert banner that surfaces after a trigger POST or on a
   pending-trigger detected at page load. Same spacing + treatment for
   the success and error variants - role="status" vs "alert" carries
   the semantic difference for assistive tech. */
.content-sync__sync-now-banner[b-g7chagwzbw] {
    margin: var(--space-3) 0 0 0;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    background: var(--color-surface-sunken);
    font-size: var(--font-size-sm);
}

.content-sync__audits[b-g7chagwzbw] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

/* Source-kind-driven row visibility on the Settings tab. The wrapping
   .content-sync-source-picker uses :has() to inspect the kind select's
   selected <option> and hide the rows that don't apply. Operator
   changes the dropdown → CSS does the toggling; no re-render needed.
   Same pattern as CadencePicker.razor.css. The option value attributes
   ("Git", "LocalDirectory") match ContentSyncSourceKindDto.ToString(). */

.content-sync-source-picker:has(.content-sync-source-picker__kind option[value="Git"]:checked) .content-sync-source-picker__local[b-g7chagwzbw] {
    display: none;
}

.content-sync-source-picker:has(.content-sync-source-picker__kind option[value="LocalDirectory"]:checked) .content-sync-source-picker__git[b-g7chagwzbw] {
    display: none;
}
/* /Components/Pages/Platform/ContentSync/ContentSyncAuditTable.razor.rz.scp.css */
/* Per-row chrome for the content-sync audits ListView island. The
   surrounding ListView already styles the table / header / row
   spacing; everything here is cell-content (badge, sha-mono, error
   message) that the row cells render via their RenderCell fragments. */

.content-sync-audits__sha[b-oqzpeq26b3] {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    background: var(--color-surface-sunken);
    padding: 0 var(--space-1);
    border-radius: var(--radius-sm);
}

/* Outcome badges - colour cues lifted from the design tokens so
   high-contrast mode keeps them legible. The base class carries
   shape + spacing; the modifier classes carry the colour. */
.content-sync-audits__badge[b-oqzpeq26b3] {
    display: inline-block;
    padding: 0 var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
    border: 1px solid currentColor;
}

.content-sync-audits__badge--success[b-oqzpeq26b3] {
    color: var(--color-success);
    background: transparent;
}

.content-sync-audits__badge--failed[b-oqzpeq26b3] {
    color: var(--color-danger);
    background: transparent;
}

.content-sync-audits__badge--skipped[b-oqzpeq26b3] {
    color: var(--color-warning);
    background: transparent;
}

.content-sync-audits__error[b-oqzpeq26b3] {
    font-family: var(--font-mono);
    font-size: var(--font-size-sm);
    color: var(--color-danger);
    word-break: break-word;
}
/* /Components/Pages/Platform/Email/Email.razor.rz.scp.css */
/* Provider- and auth-mode-driven section visibility on the platform
   Email settings page. The form wrapper (.platform-email-picker)
   uses :has() to inspect the currently-selected <option> on the
   mode / acs-auth selects and hide the rows / sections that don't
   apply. Operator changes the dropdown → CSS does the toggling;
   no re-render, no @rendermode InteractiveServer needed. Same
   pattern as ContentSync.razor.css and the cadence picker
   referenced there. The option value attributes match the
   EmailProvider / AcsAuthMode enum names verbatim. */

/* Example connection-string subtext under the ACS secret field -
   styled as a muted, monospaced hint so it reads as a copy-from
   reference rather than instructional prose. */
.platform-email-picker__example[b-xdjlfxfajj] {
    display: block;
    margin-top: var(--space-1);
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    word-break: break-all;
}

/* Mode = ACS → hide the SMTP <details> section. */
.platform-email-picker:has(.platform-email-picker__mode option[value="AzureCommunicationServices"]:checked) .platform-email-picker__smtp[b-xdjlfxfajj] {
    display: none;
}

/* Mode = SMTP → hide the ACS <details> section. */
.platform-email-picker:has(.platform-email-picker__mode option[value="Smtp"]:checked) .platform-email-picker__acs[b-xdjlfxfajj] {
    display: none;
}

/* Managed identity → hide the ACS connection-string row (the
   secret is meaningless when the host's MI handles auth). */
.platform-email-picker:has(.platform-email-picker__acs-auth option[value="ManagedIdentity"]:checked) .platform-email-picker__acs-conn[b-xdjlfxfajj] {
    display: none;
}
/* /Components/Pages/Platform/PlatformDashboard.razor.rz.scp.css */
/*
 * /_admin - platform-admin landing page. Hero with stat tiles, then
 * a "Quick actions" grid of clickable cards. The hero itself is
 * provided by <PageHeader>; this file styles only the page-scoped
 * section heading + action grid. Mirrors TenantLanding so both
 * landing pages read as siblings in the same UI family.
 */

.platform-dashboard__quick-actions[b-gftgmh0wgv] {
    margin-top: var(--space-6);
}

.platform-dashboard__section-heading[b-gftgmh0wgv] {
    margin: 0 0 var(--space-4);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.platform-dashboard__action-grid[b-gftgmh0wgv] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: var(--space-3);
}
/* /Components/Pages/Platform/Reference/M365Licenses.razor.rz.scp.css */
/* Cell-content + import-panel styles only - table chrome (header, rows,
   empty/loading states) is owned by the shared ListView component. */

.license-catalog__part[b-5bi5zcievn],
.license-catalog__sku-id[b-5bi5zcievn] {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    white-space: nowrap;
}

.license-catalog__badge[b-5bi5zcievn] {
    display: inline-block;
    padding: 2px var(--space-2);
    border-radius: var(--radius-pill, 999px);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

/* Paid = counted by the licensed-user reports; free / trial are the excluded states. */
.license-catalog__badge--paid[b-5bi5zcievn] {
    background: var(--color-success-surface);
    color: var(--color-success-on-surface);
}

.license-catalog__badge--trial[b-5bi5zcievn] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
}

.license-catalog__badge--free[b-5bi5zcievn] {
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
}

/* ── Refresh-from-CSV panel ─────────────────────────────────── */

.license-import[b-5bi5zcievn] {
    margin-block-end: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 8px);
    background: var(--color-surface-sunken);
}

.license-import > summary[b-5bi5zcievn] {
    padding: var(--space-3) var(--space-4);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.license-import__body[b-5bi5zcievn] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: 0 var(--space-4) var(--space-4);
}

.license-import__help[b-5bi5zcievn] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.license-import__file[b-5bi5zcievn] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.license-import__paste-label[b-5bi5zcievn] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.license-import__textarea[b-5bi5zcievn] {
    width: 100%;
    box-sizing: border-box;
    font-family: var(--font-mono, ui-monospace, "Cascadia Code", Consolas, monospace);
    font-size: var(--font-size-xs);
    resize: vertical;
}

.license-import__actions[b-5bi5zcievn] {
    display: flex;
    /* Wrap on a narrow viewport instead of pushing the button off the card. */
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
}

/* The *-on-surface tokens are text FOR a danger/success-colored surface (white in light theme) -
   using them on the plain card painted these lines white-on-white and the import error was
   invisible. --color-success / --color-danger are the theme-aware ink tokens. */
.license-import__status[b-5bi5zcievn] {
    margin: 0;
    color: var(--color-success);
    font-size: var(--font-size-sm);
}

.license-import__error[b-5bi5zcievn] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}

/* The import button is type="button" (it posts via @onclick, not a form submit) and sits outside
   .form-actions, so it matched NONE of the app-shell submit-button rules and rendered as a bare
   user-agent button next to fully styled chrome. Mirror the primary treatment here rather than
   widening the global selector, which would catch every icon button in the shell. */
.license-import__submit[b-5bi5zcievn] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: filter var(--motion-duration-fast) var(--motion-easing-standard);
}

    .license-import__submit:hover[b-5bi5zcievn] {
        filter: brightness(1.08);
    }

    .license-import__submit:disabled[b-5bi5zcievn] {
        opacity: 0.55;
        cursor: not-allowed;
        filter: grayscale(0.4);
    }

/* The file input's own button is a shadow part with its own user-agent chrome; without this it
   reads as a third, different button style beside the two real ones. Kept secondary - choosing a
   file is not the commit action. */
/* ::deep is load-bearing. InputFile is a child component, so its rendered <input> never receives this
   page's scoped-CSS attribute - without ::deep these rules compile to a selector that matches nothing
   and the browser draws its default, unstyled file button. */
.license-import__file[b-5bi5zcievn]  input[type="file"] {
    font: inherit;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.license-import__file[b-5bi5zcievn]  input[type="file"]::file-selector-button {
    min-height: 2.25rem;
    margin-inline-end: var(--space-3);
    padding: 0 var(--space-4);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

    .license-import__file[b-5bi5zcievn]  input[type="file"]::file-selector-button:hover {
        background: var(--color-surface-sunken);
    }

    .license-import__file[b-5bi5zcievn]  input[type="file"]::file-selector-button:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }
/* /Components/Pages/Platform/Reference/OsVersions.razor.rz.scp.css */
/* Editable reference table - inputs fill their cells so the grid reads as a
   spreadsheet-style editor; the add strip mirrors the row layout below it. */
.reference-table[b-ao3qf3a5d3] {
    width: 100%;
    border-collapse: collapse;
    margin-block-start: 1rem;
}

.reference-table th[b-ao3qf3a5d3],
.reference-table td[b-ao3qf3a5d3] {
    padding: 0.4rem 0.6rem;
    text-align: left;
    border-block-end: 1px solid var(--color-border, #d0d4da);
}

.reference-add[b-ao3qf3a5d3] {
    margin-block-start: 1.5rem;
    padding: 1rem;
    border: 1px solid var(--color-border, #d0d4da);
    border-radius: 0.5rem;
}

.reference-add__fields[b-ao3qf3a5d3] {
    margin-block-end: 0.75rem;
}

/* Fields stack vertically; space each from the one above it. */
.reference-add__fields > div + div[b-ao3qf3a5d3] {
    margin-block-start: 0.75rem;
}

.reference-add__fields label[b-ao3qf3a5d3] {
    display: block;
    margin-block-end: 0.25rem;
}

.reference-note[b-ao3qf3a5d3] {
    margin-block-start: 1rem;
    color: var(--color-text-muted, #5b6470);
}
/* /Components/Pages/Platform/Reference/ReferenceIndex.razor.rz.scp.css */
/* Card grid for the reference-data hub - mirrors the platform dashboard's
   quick-actions grid so the two admin landing surfaces read as one family. */
.reference-index__grid[b-k107be9st3] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 1rem;
    margin-block-start: 1.5rem;
}
/* /Components/Pages/Platform/Tenants/PlatformTenants.razor.rz.scp.css */
/* Platform-admin Tenants page chrome - scoped CSS.
   Table styling lives in PlatformTenantsTable.razor.css; shared
   list-primitive styling lives in wwwroot/css/lists.css. The page
   itself only owns the toolbar row + the hero "Create tenant" link. */

.platform-tenants__toolbar-row[b-pz7dhqgxli] {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-3);
    flex-wrap: wrap;
}

/* The actions row stays a plain block container - the two CTAs are
   inline-flex pills that align to each other on the baseline without
   a flex parent (a flex parent stretches the form-wrapped button to
   the row height and pushes its baseline off the anchor's). Spacing
   between the two CTAs comes from the anchor's right margin, since
   without flex the row can't use `gap`. */
.platform-tenants__actions[b-pz7dhqgxli] {
    margin: 0;
}

    .platform-tenants__actions > .platform-tenants__create-link[b-pz7dhqgxli] {
        margin-right: var(--space-3);
    }

/* The "Update tenants schema" button lives in an antiforgery-bound
   POST form; rendering the form inline lets the button sit on the
   shared baseline with the create-tenant anchor instead of dropping
   to its own line as a block-level form would. */
.platform-tenants__create-link-form[b-pz7dhqgxli] {
    display: inline;
    margin: 0;
}

/* Sized + tinted to match the global `.app-shell__main button[type="submit"]`
   rule in app.css - same chrome-navy surface, white text, shadow,
   radius. Keeps every primary CTA across the signed-in surface in
   one visual family. */
.platform-tenants__create-link[b-pz7dhqgxli] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    box-sizing: border-box;
    transition: filter var(--motion-duration-fast) var(--motion-easing-standard);
}

    .platform-tenants__create-link:hover[b-pz7dhqgxli] {
        filter: brightness(1.08);
        color: var(--color-chrome-on-surface);
        text-decoration: none;
    }

    .platform-tenants__create-link:active[b-pz7dhqgxli] {
        filter: brightness(0.92);
    }

    .platform-tenants__create-link:focus-visible[b-pz7dhqgxli] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

/* "Update tenants schema" is a heavier, less-frequent maintenance action
   than "Create tenant", so render it as an outline/secondary button - same
   size + family, subordinate weight - so the primary CTA stays dominant. */
.platform-tenants__create-link--secondary[b-pz7dhqgxli] {
    background: transparent;
    color: var(--color-text);
    border-color: var(--color-border);
    box-shadow: none;
}

    .platform-tenants__create-link--secondary:hover[b-pz7dhqgxli] {
        filter: none;
        background: var(--color-surface-sunken, var(--color-surface));
        color: var(--color-text);
    }

@media (forced-colors: active) {
    .platform-tenants__create-link[b-pz7dhqgxli] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Pages/Platform/Tenants/PlatformTenantSettings.razor.rz.scp.css */
/* Usage tiles sit above the quota override form on the Quotas tab; give them
   breathing room before the accordion. The element is authored in markup, so a
   scoped rule applies cleanly. */
.platform-tenant-settings__usage-tiles[b-6fc2pk0vic] {
    margin-bottom: var(--space-5);
}

/* Unlimited tick under the credits number input. The global label rule makes
   labels stacked blocks with a bottom margin; this one is a trailing inline
   row (box + caption on one line, a small gap above, none below). */
.platform-tenant-settings__unlimited[b-6fc2pk0vic] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    margin: var(--space-2) 0 0;
}

/* Lifecycle tab. Sub-headings separate the Suspend and Delete sections inside
   the one accordion body, which is otherwise a dense settings stack. */
.platform-tenant-settings__subheading[b-6fc2pk0vic] {
    margin: var(--space-5) 0 var(--space-2);
}

/* The member-facing message, quoted verbatim so it is obvious this is the
   customer's exact wording rather than our own copy. */
.platform-tenant-settings__suspension-message[b-6fc2pk0vic] {
    margin: 0 0 var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-left: 3px solid var(--color-border);
    background: var(--color-surface-sunken);
    white-space: pre-wrap;
}

/* Radio stack for the two suspension modes: not a select, because each option
   carries its own consequence text that must stay visible. */
.platform-tenant-settings__modes[b-6fc2pk0vic] {
    border: 0;
    margin: 0;
    padding: 0;
}

/* The visible label sits in the settings row's text column, so the legend is
   kept for assistive technology only. */
.platform-tenant-settings__modes legend[b-6fc2pk0vic] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.platform-tenant-settings__mode[b-6fc2pk0vic] {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    column-gap: var(--space-2);
    margin: 0 0 var(--space-3);
}

.platform-tenant-settings__mode-title[b-6fc2pk0vic] {
    font-weight: 600;
}

.platform-tenant-settings__mode-help[b-6fc2pk0vic] {
    grid-column: 2;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}
/* /Components/Pages/Platform/Users/PlatformUsers.razor.rz.scp.css */
/* Platform-admin Users page chrome - scoped CSS.
   Table styling lives in PlatformUsersTable.razor.css;
   shared list-primitive styling lives in wwwroot/css/lists.css.
   The page heading is now owned by <ListPageHero> so the
   .platform-users__heading rule is gone; the toolbar-row aligns
   the density toggle to the right of the page, above the
   interactive table island. */

.platform-users__toolbar-row[b-zp7xjs33gz] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}
/* /Components/Pages/Platform/Users/PlatformUserSettings.razor.rz.scp.css */
/* /_admin/users/{guid} - single-user platform-admin detail. Mirrors
   the PlatformTenantSettings card stack: hero, badge row, two
   read-only tables (SSO / memberships), action toolbar. */

.platform-user-settings__deleted-banner[b-5rdmog5sey] {
    margin-block: var(--space-3) var(--space-4);
}

.platform-user-settings__badges[b-5rdmog5sey] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin-block: var(--space-3) var(--space-4);
}

.platform-user-settings__card[b-5rdmog5sey] {
    margin-block-end: var(--space-5);
}

.platform-user-settings__card-header[b-5rdmog5sey] {
    margin-block-end: var(--space-3);
}

.platform-user-settings__card-heading[b-5rdmog5sey] {
    margin-block: 0 var(--space-1);
    font-size: var(--font-size-h3);
}

.platform-user-settings__card-description[b-5rdmog5sey] {
    margin-block: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.platform-user-settings__empty[b-5rdmog5sey] {
    margin-block: var(--space-2) 0;
    color: var(--color-text-muted);
    font-style: italic;
}

.platform-user-settings__table[b-5rdmog5sey] {
    inline-size: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

    .platform-user-settings__table th[b-5rdmog5sey],
    .platform-user-settings__table td[b-5rdmog5sey] {
        padding: var(--space-2) var(--space-3);
        text-align: start;
        vertical-align: top;
        border-block-end: 1px solid var(--color-border-subtle);
    }

    .platform-user-settings__table th[b-5rdmog5sey] {
        font-weight: var(--font-weight-semibold);
        color: var(--color-text-muted);
    }

.platform-user-settings__issuer[b-5rdmog5sey] {
    display: block;
    overflow-wrap: anywhere;
    max-inline-size: 28rem;
}

.platform-user-settings__directory[b-5rdmog5sey] {
    display: block;
    margin-block-start: var(--space-1);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.platform-user-settings__subject[b-5rdmog5sey] {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    overflow-wrap: anywhere;
}

.platform-user-settings__chips[b-5rdmog5sey] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.platform-user-settings__chip[b-5rdmog5sey] {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding: 2px var(--space-2);
    background: var(--color-surface-sunken, var(--color-border-subtle));
    color: var(--color-text);
    border-radius: var(--radius-pill, 9999px);
    text-decoration: none;
    font-size: var(--font-size-xs);
}

    .platform-user-settings__chip:hover[b-5rdmog5sey],
    .platform-user-settings__chip:focus-visible[b-5rdmog5sey] {
        background: var(--color-border-strong, var(--color-border-subtle));
        text-decoration: underline;
    }

.platform-user-settings__chip-provider[b-5rdmog5sey] {
    font-size: 0.75em;
    color: var(--color-text-muted);
}

.platform-user-settings__tenant-link[b-5rdmog5sey] {
    color: var(--color-link);
    text-decoration: none;
}

    .platform-user-settings__tenant-link:hover[b-5rdmog5sey],
    .platform-user-settings__tenant-link:focus-visible[b-5rdmog5sey] {
        text-decoration: underline;
    }

.platform-user-settings__tenant-status[b-5rdmog5sey] {
    margin-inline-start: var(--space-2);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* Action group heading - small, all-caps section divider so the
   operator scans "Flags / Sessions / Danger zone" before the rows
   inside each group. The --danger variant tints the heading so the
   destructive section is visually distinct without dominating. */
.platform-user-settings__action-group-heading[b-5rdmog5sey] {
    margin-block: var(--space-4) var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

    .platform-user-settings__action-group-heading--danger[b-5rdmog5sey] {
        color: var(--color-danger);
    }

    .platform-user-settings__action-group-heading:first-of-type[b-5rdmog5sey] {
        margin-block-start: 0;
    }

.platform-user-settings__action-rows[b-5rdmog5sey] {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.platform-user-settings__action-row[b-5rdmog5sey] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-3);
    background: var(--color-surface);
    border-block-end: 1px solid var(--color-border-subtle);
}

    .platform-user-settings__action-row:last-child[b-5rdmog5sey] {
        border-block-end: none;
    }

    .platform-user-settings__action-row--danger[b-5rdmog5sey] {
        background: color-mix(in srgb, var(--color-danger) 6%, var(--color-surface));
    }

.platform-user-settings__action-info[b-5rdmog5sey] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-inline-size: 0;
}

.platform-user-settings__action-label[b-5rdmog5sey] {
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.platform-user-settings__action-state[b-5rdmog5sey] {
    font-size: var(--font-size-sm);
}

    .platform-user-settings__action-state--active[b-5rdmog5sey] {
        color: var(--color-text);
        font-weight: var(--font-weight-semibold);
    }

    .platform-user-settings__action-state--inactive[b-5rdmog5sey] {
        color: var(--color-text-muted);
    }

.platform-user-settings__action-help[b-5rdmog5sey] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    max-inline-size: 36rem;
}

.platform-user-settings__action-form[b-5rdmog5sey] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin: 0;
    flex: 0 0 auto;
}

    /* The soft-delete row needs to host the typed-email confirmation
       input alongside the destructive button on the same line. On
       narrow viewports we stack so the input stays readable. */
    .platform-user-settings__action-form--with-input[b-5rdmog5sey] {
        flex-wrap: wrap;
        justify-content: flex-end;
    }

.platform-user-settings__confirm-input[b-5rdmog5sey] {
    min-inline-size: 14rem;
}

@media (max-width: 32rem) {
    .platform-user-settings__action-row[b-5rdmog5sey] {
        flex-direction: column;
        align-items: stretch;
    }
}

@media (forced-colors: active) {
    .platform-user-settings__chip[b-5rdmog5sey] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Pages/Platform/Users/PlatformUsersTable.razor.rz.scp.css */
/* Platform-users InteractiveServer island - scoped CSS.

   ::deep is used for any rule whose target is rendered by
   RenderTreeBuilder (the <th> / <td> cells emitted from
   RenderHeaderCell / RenderCell) - those elements don't pick up
   Blazor's per-component scope attribute, so a plain scoped selector
   wouldn't match them. The shared list-primitive styling lives in
   wwwroot/css/lists.css; everything here is platform-users specific. */

.platform-users-table[b-6okyh2coil] {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    min-inline-size: 0;
}

.platform-users-table__forbidden[b-6okyh2coil] {
    padding: 1rem;
    border: 1px solid var(--color-danger);
    border-radius: 0.5rem;
    color: var(--color-danger);
}

.platform-users-table__loading[b-6okyh2coil] {
    color: var(--color-text-muted);
}

.platform-users-table__status[b-6okyh2coil] {
    margin: 0;
    padding: 0.5rem 0.75rem;
    border-radius: 0.375rem;
}

.platform-users-table__status--ok[b-6okyh2coil] {
    background: color-mix(in srgb, var(--color-info) 14%, var(--color-surface));
    color: var(--color-info);
}

.platform-users-table__status--error[b-6okyh2coil] {
    background: color-mix(in srgb, var(--color-danger) 14%, var(--color-surface));
    color: var(--color-danger);
}

.platform-users-table__scroll[b-6okyh2coil] {
    overflow-x: auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    max-inline-size: 100%;
    flex: 1 1 auto;
    min-block-size: 0;
}

/* Desktop / tablet only: clamp the wrapper so filter expansions and tall
   tables never push the page past the viewport. On phones (≤ 599px) the
   table folds to mobile cards via .list-table--mobile-cards, and a fixed
   inner-scroll height there would fight iOS Safari's URL bar AND the
   sticky bulk-action strip - both reduce the effective viewport mid-
   scroll, leaving the user unable to reach the bottom rows. */
@media (min-width: 600px) {
    .platform-users-table__scroll[b-6okyh2coil] {
        max-block-size: calc(100vh - 14rem);
    }
}

.platform-users-table__table[b-6okyh2coil] {
    inline-size: max-content;
    min-inline-size: 100%;
    border-collapse: collapse;
}

/* Rules below target descendant <th> / <td> cells that come out of
   RenderTreeBuilder. ::deep removes the scope attribute requirement so
   they match regardless of which component rendered the element. */

.platform-users-table__table[b-6okyh2coil]  th,
.platform-users-table__table[b-6okyh2coil]  td {
    text-align: start;
    overflow-wrap: anywhere;
}

.platform-users-table__table[b-6okyh2coil]  thead th {
    padding: 0.5rem 0.75rem;
    background: var(--color-surface-sunken);
    border-bottom: 1px solid var(--color-border);
}

.platform-users-table__table[b-6okyh2coil]  tbody td,
.platform-users-table__table[b-6okyh2coil]  tbody th[scope="row"] {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--color-border-subtle);
    vertical-align: middle;
}

.platform-users-table__table[b-6okyh2coil]  tbody tr {
    background: var(--color-surface);
}

.platform-users-table__table[b-6okyh2coil]  tbody tr:nth-child(even) {
    background: var(--color-surface-sunken);
}

.platform-users-table__table[b-6okyh2coil]  tbody tr.platform-users-table__row--deleted,
.platform-users-table__table[b-6okyh2coil]  tbody tr.platform-users-table__row--deleted:nth-child(even) {
    background: color-mix(in srgb, var(--color-danger) 14%, var(--color-surface));
    color: var(--color-text-muted);
    font-style: italic;
}

.platform-users-table__table[b-6okyh2coil]  .platform-users-table__select-header,
.platform-users-table__table[b-6okyh2coil]  .platform-users-table__select-cell {
    inline-size: 2.5rem;
}

.platform-users-table__table[b-6okyh2coil]  .platform-users-table__email-cell {
    white-space: nowrap;
}

.platform-users-table__detail-link[b-6okyh2coil] {
    color: var(--color-link);
    text-decoration: none;
}

    .platform-users-table__detail-link:hover[b-6okyh2coil],
    .platform-users-table__detail-link:focus-visible[b-6okyh2coil] {
        text-decoration: underline;
    }

/* Sticky thead is intentionally not set. position: sticky on thead would
   anchor it inside the .platform-users-table__scroll container (because
   that wrapper is the nearest scrolling ancestor due to overflow-x: auto),
   which silently forces the wrapper to behave as a vertical scroll
   container too. We want the page to scroll vertically and the wrapper
   to scroll only horizontally - keeping the thead non-sticky preserves
   that behaviour. */
/* /Components/Pages/Support/Support.razor.rz.scp.css */
/* Subject links in the ticket table render brand-ink with no underline -
   the whole cell is the affordance, and the default underline made every
   row read as body copy with a correction in it.

   ::deep is REQUIRED: the anchor is emitted through a RenderFragment cell
   that ListView renders, so it never carries this page's scope attribute -
   only the .support-list wrapper in Support.razor does.

   `--color-brand` is theme-aware (light #0f5fd6 on white ≈ 5.8:1, dark
   #4d8df0 on #161616 ≈ 5.5:1 - both clear WCAG 2.2 AA) and is the same
   token the primary CTAs and hero tiles use. No outline rules here: the
   app-wide :focus-visible treatment must keep winning. */
.support-list[b-j4vp2v7zop]  .support-list__subject-link {
    color: var(--color-brand);
    text-decoration: none;
}

.support-list[b-j4vp2v7zop]  .support-list__subject-link:hover {
    /* Hover darkens (light) / lightens (dark) via the paired hover token and
       restores the underline so the state change survives forced-colors and
       colour-blind viewing. */
    color: var(--color-brand-hover);
    text-decoration: underline;
}

/* New-ticket CTA and the on-demand list refresh sit on one centered flex
   row inside the hero's Actions slot; the refresh wears the same secondary
   outline chrome as the detail page's action row
   (.support-detail__secondary-action in SupportTicketDetail.razor.css) so
   "refresh" reads identically wherever it appears. Restated because a
   type="button" control never receives the global submit skin.

   ::deep is REQUIRED here for the same reason as the subject link:
   ListPageHero renders the Actions fragment, so only the .support-hero
   wrapper in Support.razor is guaranteed to carry this page's scope
   attribute. */
.support-hero[b-j4vp2v7zop]  .support-hero__actions {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    /* The hero's column gap owns the vertical rhythm; the paragraph's UA
       margin would double it. */
    margin: 0;
}

.support-hero[b-j4vp2v7zop]  .support-hero__refresh {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Mirror a.button-link's metrics (reports.css) exactly - min-height,
       margin-top, padding, 1px border, and box-sizing - so both controls
       land at the same height on the centered row; the missing margin-top
       previously left the CTA sitting lower than the refresh. */
    min-height: 2.75rem;
    margin-top: var(--space-2);
    padding: 0 var(--space-5);
    background: transparent;
    color: var(--color-chrome-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-chrome-surface);
    border-radius: var(--radius-md);
    box-sizing: border-box;
    cursor: pointer;
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .support-hero[b-j4vp2v7zop]  .support-hero__refresh:hover:not(:disabled) {
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
    }

    .support-hero[b-j4vp2v7zop]  .support-hero__refresh:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

    .support-hero[b-j4vp2v7zop]  .support-hero__refresh:disabled {
        opacity: 0.55;
        cursor: not-allowed;
    }

@media (forced-colors: active) {
    .support-hero[b-j4vp2v7zop]  .support-hero__refresh {
        border: 1px solid ButtonText;
    }
}
/* /Components/Pages/Support/SupportTicketCreate.razor.rz.scp.css */
/* Arrangement only - field chrome, labels, validation colours, the primary
   submit button, and the submit-busy spinner all come from the shared
   app.css primitives (.settings-form, .form-actions, the app-shell submit
   rule, [data-busy-on-submit][data-submitting]). */

/* Full-width settings sheet: same surface + rhythm as .account-form-card
   (surface + hairline + radius + soft shadow + top margin under the hero),
   restated under this page's own name so support styling doesn't ride on
   the account area's class. The card fills the content area like the
   app's other settings forms; inputs inside still cap at the shared
   .settings-form max-inline-size rule, so fields keep a comfortable
   reading width on wide viewports. */
.support-create__card[b-4p4hna0cth] {
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    box-shadow: var(--shadow-sm);
    margin-top: var(--space-6);
}

/* Attachment drop target: dashed outline + sunken fill reads as "drop
   files here" without any new JS - the native file input inside accepts
   drag-and-drop on its own. */
.support-create__drop[b-4p4hna0cth] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-sunken);
}

    .support-create__drop:focus-within[b-4p4hna0cth] {
        border-color: var(--color-brand);
    }

.support-create__drop-hint[b-4p4hna0cth] {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* ::deep is load-bearing. InputFile is a child component, so its rendered
   <input> never receives this page's scoped-CSS attribute - without ::deep
   these rules compile to a selector that matches nothing and the browser
   draws its default, unstyled file button. Same fix as
   M365Licenses.razor.css. Kept secondary - choosing a file is not the
   commit action.

   color: transparent suppresses the native "no files selected" / filename
   text beside the button - the chip list under the drop zone already names
   every chosen file, so the native text would say it twice. Only the
   input's own text goes transparent: ::file-selector-button below restates
   color: var(--color-text), so the button label stays visible, and the
   input's :focus-visible rule keeps keyboard focus drawn. Same approach as
   SupportTicketDetail.razor.css. */
.support-create__drop[b-4p4hna0cth]  input[type="file"] {
    font: inherit;
    font-size: var(--font-size-sm);
    color: transparent;
}

    .support-create__drop[b-4p4hna0cth]  input[type="file"]:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* 2.75rem matches the shared app-shell submit-button min-height (app.css), so
   the browse affordance lines up with the form's primary action.
   SupportTicketDetail.razor.css carries the reply form's sibling of this
   block. */
.support-create__drop[b-4p4hna0cth]  input[type="file"]::file-selector-button {
    min-height: 2.75rem;
    margin-inline-end: var(--space-3);
    padding: 0 var(--space-4);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

    .support-create__drop[b-4p4hna0cth]  input[type="file"]::file-selector-button:hover {
        background: var(--color-surface-sunken);
    }

    .support-create__drop[b-4p4hna0cth]  input[type="file"]::file-selector-button:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Chip list mirrors the thread view's attachment chips
   (SupportTicketThread.razor.css) so a file reads the same before and
   after the ticket exists; these are static labels, not links, so they
   keep the text colour instead of the link brand. */
.support-create__chips[b-4p4hna0cth] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
}

.support-create__chip[b-4p4hna0cth] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: var(--font-size-xs);
}

.support-create__chip-name[b-4p4hna0cth] {
    /* Long unbroken filenames must wrap inside the chip, not push the
       card into a horizontal scroll. */
    overflow-wrap: anywhere;
}

.support-create__chip-size[b-4p4hna0cth] {
    color: var(--color-text-muted);
    white-space: nowrap;
}

/* Per-file remove control - the same chrome as the reply composer's chip
   remove (SupportTicketDetail.razor.css) so the widget behaves and reads
   identically on both ticket forms. Extra weight here: the file input's
   native text is transparent, so the chips are the only visible record of
   what will upload, and removal must not require redoing the selection. */
.support-create__chip-remove[b-4p4hna0cth] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    padding: 0;
    border: none;
    border-radius: var(--radius-full);
    background: transparent;
    color: var(--color-text-muted);
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.support-create__chip-remove:hover[b-4p4hna0cth] {
    background: var(--color-surface-sunken);
    color: var(--color-text);
}

/* Availability load-failed retry - outline treatment mirroring the detail
   page's secondary actions; restated because a type="button" control never
   receives the global submit skin. */
.support-create__retry[b-4p4hna0cth] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: transparent;
    color: var(--color-chrome-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-chrome-surface);
    border-radius: var(--radius-md);
    cursor: pointer;
}

.support-create__retry:hover[b-4p4hna0cth] {
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
}

@media (max-width: 599px) {
    .support-create__card[b-4p4hna0cth] {
        padding: var(--space-4);
    }
}

/* Forced colors: tints and shadows vanish, so the borders are the only
   affordance separating the card / drop zone / chips from the page. (The
   transparent file-input text also comes back - forced colors override
   `color` - which is the safe direction.) */
@media (forced-colors: active) {
    .support-create__card[b-4p4hna0cth],
    .support-create__chip[b-4p4hna0cth],
    .support-create__retry[b-4p4hna0cth] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }

    .support-create__drop[b-4p4hna0cth] {
        border: 1px dashed CanvasText;
    }
}
/* /Components/Pages/Support/SupportTicketDetail.razor.rz.scp.css */
/* Reply-composer + card chrome for the ticket detail page. Token-driven so
   the light / dark themes cascade in from tokens.css. */

/* Card surface for the history, reply composer, and conversation - mirrors
   .support-create__card (SupportTicketCreate.razor.css): same surface,
   hairline, radius, soft shadow, restated under this page's own name so
   detail styling doesn't ride on the create page's class. No own top
   margin: every card sits inside .support-detail__columns, whose margin
   and gaps own the page rhythm. */
.support-detail__card[b-lxwtljczo7] {
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    box-shadow: var(--shadow-sm);
}

/* Ticket-wide action row between the page header and the columns:
   Resolve / Reopen beside Refresh, all in the same secondary chrome so
   the row reads as one set. */
.support-detail__actions[b-lxwtljczo7] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
}

/* 30/70 split under the actions row. Mobile-first: one column ordered
   details, conversation, history - the conversation is the main content
   on a phone, but the compact details card stays on top as orientation.
   From 960px explicit placement stacks details over history in the 3fr
   left column while the reply + conversation column spans every row; the
   trailing 1fr row absorbs the tall conversation's extra height so the
   two left cards stay snug at the top. */
.support-detail__columns[b-lxwtljczo7] {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-6);
    align-items: start;
    margin-top: var(--space-6);
}

.support-detail__facts[b-lxwtljczo7] {
    min-inline-size: 0;
}

.support-detail__history[b-lxwtljczo7] {
    order: 2;
    min-inline-size: 0;
}

/* The reply and conversation cards stack inside the right column; the
   column flex gap matches the grid gap so vertical rhythm is uniform. */
.support-detail__main[b-lxwtljczo7] {
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
    min-inline-size: 0;
    order: 1;
}

@media (min-width: 960px) {
    .support-detail__columns[b-lxwtljczo7] {
        grid-template-columns: 3fr 7fr;
        grid-template-rows: auto auto 1fr;
    }

    .support-detail__facts[b-lxwtljczo7] {
        grid-column: 1;
        grid-row: 1;
    }

    .support-detail__history[b-lxwtljczo7] {
        grid-column: 1;
        grid-row: 2;
        order: 0;
    }

    .support-detail__main[b-lxwtljczo7] {
        grid-column: 2;
        grid-row: 1 / span 3;
        order: 0;
    }
}

.support-detail__facts h2[b-lxwtljczo7],
.support-detail__history h2[b-lxwtljczo7] {
    margin: 0 0 var(--space-4);
}

/* Definition list of ticket facts, one "Label: value" line per row - the
   bold inline dt plus the CSS-supplied ": " keep label and value in one
   accessible dl structure without a two-column layout. */
.support-detail__facts-list[b-lxwtljczo7] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    margin: 0;
}

.support-detail__fact dt[b-lxwtljczo7] {
    display: inline;
    font-weight: var(--font-weight-semibold);
}

    .support-detail__fact dt[b-lxwtljczo7]::after {
        content: ": ";
    }

.support-detail__fact dd[b-lxwtljczo7] {
    display: inline;
    margin: 0;
    overflow-wrap: anywhere;
}

.support-detail__history-empty[b-lxwtljczo7] {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* Compact status timeline, newest first: each entry hangs off a rail of
   dot markers, the dots joined by a hairline that stops at the last
   (oldest, creation) entry. */
.support-detail__history-list[b-lxwtljczo7] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    margin: 0;
    padding: 0;
    list-style: none;
}

.support-detail__history-item[b-lxwtljczo7] {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding-inline-start: var(--space-5);
}

.support-detail__history-item[b-lxwtljczo7]::before {
    content: "";
    position: absolute;
    inset-inline-start: 0;
    inset-block-start: 0.3rem;
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: var(--radius-full);
    background: var(--color-brand);
}

.support-detail__history-item[b-lxwtljczo7]::after {
    content: "";
    position: absolute;
    inset-inline-start: calc(0.25rem - 0.5px);
    inset-block-start: 1rem;
    inset-block-end: calc(-1 * var(--space-3));
    inline-size: 1px;
    background: var(--color-border);
}

.support-detail__history-item:last-child[b-lxwtljczo7]::after {
    content: none;
}

.support-detail__history-status[b-lxwtljczo7] {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.support-detail__history-time[b-lxwtljczo7] {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* Actions row under the composer - Send reply alone (the ticket-wide
   actions live in .support-detail__actions above the columns), kept as a
   flex row so validation hints wrap around it predictably. */
.support-reply__actions[b-lxwtljczo7] {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: var(--space-3);
    justify-content: flex-start;
}

/* Secondary action chrome - outline treatment mirroring the app-shell
   `button[type="submit"].secondary` skin (app.css); restated here because
   a type="button" control never receives that global skin. Metrics match
   the app-shell submit (min-height / padding) so the whole action row
   reads as one size. */
.support-detail__secondary-action[b-lxwtljczo7] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: transparent;
    color: var(--color-chrome-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-chrome-surface);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .support-detail__secondary-action:hover:not(:disabled)[b-lxwtljczo7] {
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
    }

    .support-detail__secondary-action:focus-visible[b-lxwtljczo7] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

    .support-detail__secondary-action:disabled[b-lxwtljczo7] {
        opacity: 0.55;
        cursor: not-allowed;
    }

    /* The Export PDF control is an <a> (a new-tab download link), not a <button> - the shared
       chrome above was written for buttons, so restate the anchor-only resets: no underline in
       any state, and the class colour wins over any global :visited anchor rule. */
    a.support-detail__secondary-action[b-lxwtljczo7] {
        text-decoration: none;
    }

        a.support-detail__secondary-action:visited[b-lxwtljczo7] {
            color: var(--color-chrome-surface);
        }

        a.support-detail__secondary-action:hover[b-lxwtljczo7] {
            text-decoration: none;
        }

/* Attachment drop target - same presentation as the create page's
   .support-create__drop (dashed outline + sunken fill reads as "drop
   files here" without any new JS; the native file input inside accepts
   drag-and-drop on its own), restated under this page's own name. */
.support-reply__drop[b-lxwtljczo7] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-4);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-sunken);
}

    .support-reply__drop:focus-within[b-lxwtljczo7] {
        border-color: var(--color-brand);
    }

.support-reply__drop-hint[b-lxwtljczo7] {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* ::deep is load-bearing. InputFile is a child component, so its rendered
   <input> never receives this page's scoped-CSS attribute - without ::deep
   these rules compile to a selector that matches nothing and the browser
   draws its default, unstyled file button. Same fix as
   SupportTicketCreate.razor.css.

   color: transparent suppresses the native "no files selected" / filename
   text beside the button - the chip list under the drop zone already names
   every chosen file, so the native text would say it twice. Only the
   input's own text goes transparent: ::file-selector-button below restates
   color: var(--color-text), so the button label stays visible, and the
   input's :focus-visible rule keeps keyboard focus drawn. */
.support-reply__drop[b-lxwtljczo7]  input[type="file"] {
    font: inherit;
    font-size: var(--font-size-sm);
    color: transparent;
}

    .support-reply__drop[b-lxwtljczo7]  input[type="file"]:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* The picker button matches the Send reply submit's metrics (min-height
   2.75rem, 0 var(--space-5) padding - the app-shell submit rule in
   app.css) so the two controls share one visual weight across the form. */
.support-reply__drop[b-lxwtljczo7]  input[type="file"]::file-selector-button {
    min-height: 2.75rem;
    margin-inline-end: var(--space-3);
    padding: 0 var(--space-5);
    background: var(--color-surface);
    color: var(--color-text);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

    .support-reply__drop[b-lxwtljczo7]  input[type="file"]::file-selector-button:hover {
        background: var(--color-surface-sunken);
    }

    .support-reply__drop[b-lxwtljczo7]  input[type="file"]::file-selector-button:focus-visible {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.support-reply__chips[b-lxwtljczo7] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: var(--space-2) 0 0;
    padding: 0;
    list-style: none;
}

.support-reply__chip[b-lxwtljczo7] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface-raised);
    color: var(--color-text);
    font-size: var(--font-size-xs);
}

.support-reply__chip-name[b-lxwtljczo7] {
    overflow-wrap: anywhere;
}

.support-reply__chip-size[b-lxwtljczo7] {
    color: var(--color-text-muted);
    white-space: nowrap;
}

.support-reply__chip-remove[b-lxwtljczo7] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 1.25rem;
    block-size: 1.25rem;
    padding: 0;
    border: none;
    border-radius: var(--radius-full);
    background: transparent;
    color: var(--color-text-muted);
    font: inherit;
    line-height: 1;
    cursor: pointer;
}

.support-reply__chip-remove:hover[b-lxwtljczo7] {
    background: var(--color-surface-sunken);
    color: var(--color-text);
}

@media (max-width: 599px) {
    .support-detail__card[b-lxwtljczo7] {
        padding: var(--space-4);
    }
}

/* Forced colors: tints and shadows vanish, so the borders are the only
   affordance separating card / drop zone / chips / buttons from the page.
   The timeline's dot and rail restate CanvasText because their brand /
   border tints are stripped. (The transparent file-input text also comes
   back - forced colors override `color` - which is the safe direction.) */
@media (forced-colors: active) {
    .support-detail__card[b-lxwtljczo7],
    .support-reply__chip[b-lxwtljczo7],
    .support-detail__secondary-action[b-lxwtljczo7] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }

    .support-reply__drop[b-lxwtljczo7] {
        border: 1px dashed CanvasText;
    }

    .support-detail__history-item[b-lxwtljczo7]::before,
    .support-detail__history-item[b-lxwtljczo7]::after {
        background: CanvasText;
    }
}

/* Solved-state hint above the actions row - muted, not an alert: the state
   is expected, the operator just needs to know why Send is greyed out. */
.support-reply__state-hint[b-lxwtljczo7] {
    margin: 0 0 var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}
/* /Components/Pages/Support/SupportTicketThread.razor.rz.scp.css */
/* Chat layout for the ticket conversation. Token-driven throughout so the
   light / dark themes and per-tenant branding cascade in from tokens.css.
   No entrance animations on purpose - messages appear instantly, so there
   is nothing prefers-reduced-motion would need to disable. */

/* The heading drops its document margins; the fixed bottom gap owns the
   rhythm between it and the first message. */
.support-thread__heading[b-ycczazokyv] {
    margin: 0 0 var(--space-4);
}

.support-thread[b-ycczazokyv] {
    list-style: none;
    margin: 0 0 var(--space-6);
    padding: 0;
}

.support-thread__message[b-ycczazokyv] {
    display: flex;
    outline: none;
}

.support-thread__message + .support-thread__message[b-ycczazokyv] {
    margin-top: var(--space-4);
}

/* A continuation of the same author's run sits tight under its predecessor -
   the avatar spacer keeps the bubble column aligned with the group head. */
.support-thread__message + .support-thread__message--grouped[b-ycczazokyv] {
    margin-top: var(--space-1);
}

.support-thread__message--own[b-ycczazokyv] {
    justify-content: flex-end;
}

.support-thread__row[b-ycczazokyv] {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2);
    max-inline-size: min(85%, 44rem);
}

.support-thread__message--own .support-thread__row[b-ycczazokyv] {
    flex-direction: row-reverse;
}

.support-thread__content[b-ycczazokyv] {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    min-inline-size: 0;
}

.support-thread__message--own .support-thread__content[b-ycczazokyv] {
    align-items: flex-end;
}

.support-thread__meta[b-ycczazokyv] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    margin-bottom: var(--space-1);
}

.support-thread__author[b-ycczazokyv] {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

/* Automations are labelled, not impersonated: muted italic instead of a
   person's name, and no avatar column at all. */
.support-thread__message--automation .support-thread__author[b-ycczazokyv] {
    color: var(--color-text-muted);
    font-weight: var(--font-weight-medium);
    font-style: italic;
}

.support-thread__badge[b-ycczazokyv] {
    padding: 0 var(--space-2);
    border: 1px solid var(--color-brand);
    border-radius: var(--radius-full);
    background: var(--color-brand-subtle);
    color: var(--color-brand);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
}

.support-thread__avatar[b-ycczazokyv] {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    overflow: hidden;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-full);
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
}

/* Grouped rows render an empty, invisible avatar cell purely to keep the
   bubble column aligned under the group head's bubble. */
.support-thread__avatar--spacer[b-ycczazokyv] {
    visibility: hidden;
}

.support-thread__avatar-img[b-ycczazokyv] {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
}

/* ::deep - the honeycomb <svg> is rendered by the child <BrandMark>
   component, so this scoped rule needs ::deep to reach across the scope
   boundary. currentColor flows the brand blue into the mark's cells. */
.support-thread__avatar[b-ycczazokyv]  .support-thread__avatar-brand {
    inline-size: 1.25rem;
    block-size: auto;
    color: var(--color-brand);
}

.support-thread__bubble[b-ycczazokyv] {
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    background: var(--color-surface-raised);
    color: var(--color-text);
    /* Provider text is untrusted plain text: keep the requester's line breaks
       and break unbroken tokens (URLs, ids) instead of overflowing the page. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.support-thread__message--own .support-thread__bubble[b-ycczazokyv] {
    border-color: transparent;
    background: var(--color-brand-subtle);
}

/* Server-sanitized BodyHtml renders as real markup: pre-wrap would double up
   the markup's own line structure, so the rich variant returns to normal
   flow and styles the nine allowed tags. ::deep is load-bearing - the
   injected elements come from a MarkupString, so they never receive this
   component's scoped-CSS attribute; ::deep anchors the rule on the scoped
   bubble and reaches the unscoped descendants. */
.support-thread__bubble--rich[b-ycczazokyv] {
    white-space: normal;
}

.support-thread__bubble--rich[b-ycczazokyv]  p {
    margin: 0 0 var(--space-2);
}

    .support-thread__bubble--rich[b-ycczazokyv]  p:last-child {
        margin-bottom: 0;
    }

.support-thread__bubble--rich[b-ycczazokyv]  ul,
.support-thread__bubble--rich[b-ycczazokyv]  ol {
    margin: var(--space-1) 0 var(--space-2);
    padding-inline-start: var(--space-5);
}

    .support-thread__bubble--rich[b-ycczazokyv]  ul:last-child,
    .support-thread__bubble--rich[b-ycczazokyv]  ol:last-child {
        margin-bottom: 0;
    }

.support-thread__bubble--rich[b-ycczazokyv]  li {
    margin-block: var(--space-1);
}

.support-thread__attachments[b-ycczazokyv] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    margin: var(--space-1) 0 0;
    padding: 0;
    list-style: none;
}

.support-thread__attachment-chip[b-ycczazokyv] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-2);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    background: var(--color-surface);
    color: var(--color-brand);
    font-size: var(--font-size-xs);
    text-decoration: none;
}

.support-thread__attachment-chip:hover[b-ycczazokyv] {
    border-color: var(--color-brand);
}

.support-thread__attachment-size[b-ycczazokyv] {
    color: var(--color-text-muted);
}

.support-thread__time[b-ycczazokyv] {
    margin-top: var(--space-1);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

/* Forced colors: the bubble tint disappears, so the border is the only
   affordance separating a message from the page - make it system-visible. */
@media (forced-colors: active) {
    .support-thread__bubble[b-ycczazokyv],
    .support-thread__avatar[b-ycczazokyv],
    .support-thread__attachment-chip[b-ycczazokyv],
    .support-thread__badge[b-ycczazokyv] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Pages/Tenant/Actions/ActionRunDecisionPanel.razor.rz.scp.css */
/* Action row beneath the candidates ListView. Approve / Reject sit on
   the right; on mobile they stack and stretch full-width. The buttons
   are `type="button"` (no form submit - they open the modal), so the
   global `button[type="submit"]` rule doesn't reach them; the rules
   below copy the canonical chrome so they match the rest of the
   solution (primary = chrome navy, .secondary = bordered, .danger =
   solid red). */
.action-run-decision__actions[b-nt6tdrqy0z] {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-block-start: var(--space-4);
}

    .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"],
    .modal__actions[b-nt6tdrqy0z]  button[type="button"] {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 2.75rem;
        padding: 0 var(--space-5);
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
        font: inherit;
        font-weight: var(--font-weight-semibold);
        text-align: center;
        text-decoration: none;
        border: 1px solid transparent;
        border-radius: var(--radius-md);
        box-sizing: border-box;
        cursor: pointer;
        box-shadow: var(--shadow-sm);
        transition: filter var(--motion-duration-fast) var(--motion-easing-standard);
    }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"]:hover:not(:disabled),
        .modal__actions[b-nt6tdrqy0z]  button[type="button"]:hover:not(:disabled) {
            filter: brightness(1.08);
        }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"]:active:not(:disabled),
        .modal__actions[b-nt6tdrqy0z]  button[type="button"]:active:not(:disabled) {
            filter: brightness(0.92);
        }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"]:focus-visible,
        .modal__actions[b-nt6tdrqy0z]  button[type="button"]:focus-visible {
            outline: 2px solid var(--color-focus-ring);
            outline-offset: 3px;
        }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"]:disabled,
        .modal__actions[b-nt6tdrqy0z]  button[type="button"]:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            filter: none;
        }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"].secondary,
        .modal__actions[b-nt6tdrqy0z]  button[type="button"].secondary {
            background: transparent;
            color: var(--color-chrome-surface);
            border-color: var(--color-chrome-surface);
            box-shadow: none;
        }

            .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"].secondary:hover:not(:disabled),
            .modal__actions[b-nt6tdrqy0z]  button[type="button"].secondary:hover:not(:disabled) {
                background: var(--color-chrome-surface);
                color: var(--color-chrome-on-surface);
                filter: none;
            }

        .action-run-decision__actions[b-nt6tdrqy0z]  button[type="button"].danger,
        .modal__actions[b-nt6tdrqy0z]  button[type="button"].danger {
            background: var(--color-danger);
            color: var(--color-text-on-accent);
        }

/* Modal - native <dialog> centred on desktop, full-sheet on small
   viewports so typing the decision comment on a phone is comfortable. */
.modal[b-nt6tdrqy0z] {
    width: min(36rem, calc(100vw - var(--space-6)));
    max-height: calc(100vh - var(--space-6));
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-lg);
    overflow: hidden;
}

    .modal[b-nt6tdrqy0z]::backdrop {
        background: rgba(0, 0, 0, 0.4);
        backdrop-filter: blur(2px);
    }

.modal__contents[b-nt6tdrqy0z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--space-5);
    max-height: inherit;
    overflow: auto;
}

.modal__title[b-nt6tdrqy0z] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}

.modal__intro[b-nt6tdrqy0z] {
    margin: 0;
    color: var(--color-text-muted);
}

.modal__actions[b-nt6tdrqy0z] {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-3);
    margin-block-start: var(--space-3);
}

    .modal__actions[b-nt6tdrqy0z]  button {
        min-width: 8rem;
    }

.action-run-confirm__label[b-nt6tdrqy0z] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
}

.action-run-confirm__textarea[b-nt6tdrqy0z] {
    width: 100%;
    min-height: 7rem;
    font: inherit;
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    resize: vertical;
}

.action-run-confirm__hint[b-nt6tdrqy0z] {
    font-weight: var(--font-weight-regular);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.action-run-confirm__exclusion[b-nt6tdrqy0z] {
    margin: 0;
    padding: var(--space-2) var(--space-3);
    background: color-mix(in srgb, var(--color-warning) 12%, transparent);
    color: var(--color-text);
    border-left: 3px solid var(--color-warning);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

.action-run-confirm__error[b-nt6tdrqy0z] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}

/* Summary metric chips - the dataset's headline numbers rendered as
   compact "label + value" chips above the candidate table, so the
   approver sees the aggregate impact before scanning rows. */
.action-run-decision__metrics[b-nt6tdrqy0z] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    list-style: none;
    margin: 0 0 var(--space-3);
    padding: 0;
}

.action-run-decision__metric[b-nt6tdrqy0z] {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding: var(--space-1) var(--space-3);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
}

.action-run-decision__metric-label[b-nt6tdrqy0z] {
    color: var(--color-text-muted);
}

.action-run-decision__metric-value[b-nt6tdrqy0z] {
    font-weight: var(--font-weight-semibold);
}

/* Inline per-item failure cell - code-styled because executor failure
   reasons are usually exception class names + a short message, which
   read better as terminal-style text than prose. The title attribute
   carries the full string for hover-to-read when the cell is narrow. */
.action-run-decision__failure[b-nt6tdrqy0z] {
    display: inline-block;
    max-width: 24rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-danger);
}

/* Benign twin of the failure cell for non-Failed detail text (skip
   reasons like "already a member") - same truncating mono treatment,
   muted instead of danger so it never reads as an error. */
.action-run-decision__detail[b-nt6tdrqy0z] {
    display: inline-block;
    max-width: 24rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* Truncated-preview notice beside the approve controls - the approval
   still covers every candidate, so the operator is pointed at the CSV
   for the full set before deciding. */
.action-run-decision__truncation[b-nt6tdrqy0z] {
    margin: var(--space-3) 0 0;
    padding: var(--space-2) var(--space-3);
    background: color-mix(in srgb, var(--color-warning) 12%, transparent);
    color: var(--color-text);
    border-left: 3px solid var(--color-warning);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-sm);
}

@media (max-width: 40rem) {
    .modal[b-nt6tdrqy0z] {
        width: 100vw;
        max-height: 100vh;
        max-width: 100vw;
        margin: 0;
        border-radius: 0;
        border: 0;
    }

    .modal__contents[b-nt6tdrqy0z] {
        padding: var(--space-4);
        gap: var(--space-4);
    }

    .modal__actions[b-nt6tdrqy0z] {
        flex-direction: column-reverse;
        align-items: stretch;
    }

        .modal__actions[b-nt6tdrqy0z]  button {
            min-width: 0;
            width: 100%;
        }

    .action-run-decision__actions[b-nt6tdrqy0z] {
        flex-direction: column;
        align-items: stretch;
    }

        .action-run-decision__actions[b-nt6tdrqy0z]  button {
            width: 100%;
        }
}
/* /Components/Pages/Tenant/Actions/ActionRunDetail.razor.rz.scp.css */
/* Error banner - same tile chrome but with a danger accent so it reads
   as "something to look at" without panicking a healthy run. */
.action-run-error[b-ddh2ezis2s] {
    border-left: 4px solid var(--color-danger);
}

.action-run-error__list[b-ddh2ezis2s] {
    display: grid;
    grid-template-columns: minmax(8rem, max-content) 1fr;
    gap: var(--space-2) var(--space-4);
    margin: 0;
}

    .action-run-error__list[b-ddh2ezis2s]  dt {
        font-weight: var(--font-weight-semibold);
        color: var(--color-text-muted);
    }

    .action-run-error__list[b-ddh2ezis2s]  dd {
        margin: 0;
        word-break: break-word;
    }

/* Header-adjacent export row - right-aligned so the CSV link reads as a
   page action, matching where the report toolbar places its exports. */
.action-run-detail__export[b-ddh2ezis2s] {
    display: flex;
    justify-content: flex-end;
    margin: 0;
}
/* /Components/Pages/Tenant/Actions/ActionRunHistoryTable.razor.rz.scp.css */
/* Outcome cell - executed / total in the row's normal text colour, with
   a small ⚠ glyph appended only when a run had failures or skips. The
   glyph's title attribute carries the breakdown for hover; the cell
   stays a scannable number rather than a coloured swarm. */
.action-run-history__outcome[b-6nq6tg9zdk] {
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: baseline;
    gap: 0;
    font-variant-numeric: tabular-nums;
}

.action-run-history__outcome-flag[b-6nq6tg9zdk] {
    margin-inline-start: var(--space-1, 0.25rem);
    cursor: help;
    opacity: 0.75;
}
/* /Components/Pages/Tenant/Actions/GroupCopyMappingsEditor.razor.rz.scp.css */
/* Editor-specific chrome only - the toolbar, table, zebra/hover, sticky
   header, and the ≤599px table-becomes-cards transform all come from the
   shared list classes in wwwroot/css/lists.css so this editable table reads
   like every read-only ListView in the app. Rules that fight the global
   element skin for inputs/selects (specificity (0,2,1) via
   `:is(.app-shell__main) select`) are written table-prefixed so they win. */

.copy-mappings[b-nelmvcteoz] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    inline-size: 100%;

    /* A single-row table left the card stranded in the top third of a tall
       viewport. The editor claims the height instead, and the table region
       below absorbs the slack.
       The subtrahend approximates the chrome above this editor (app header,
       page hero, tab strip, card padding). It is an APPROXIMATION on purpose:
       nothing in CSS can measure an ancestor's height, and the alternative -
       making .app-shell__content a flex column - changes layout on every page
       in the app to fix one tab. Being a few rem out costs a little slack at
       the bottom; the Full screen toggle in the toolbar is the exact answer
       when an operator wants every pixel. */
    min-block-size: calc(100dvh - 22rem);
}

/* Full screen already fills the viewport; the approximation would fight it. */
.copy-mappings.list-view--fullscreen[b-nelmvcteoz] {
    min-block-size: 0;
}

/* The scroll region must HUG its content, never stretch.
   Stretching it (flex: 1 1 auto) seemed like the way to put the extra height
   on the table, but a horizontal scrollbar renders at the BOTTOM EDGE of its
   scroll container - so a stretched container pushes the scrollbar below the
   fold and the operator cannot reach the columns it exists to reveal. The
   leftover height falls to the end of this flex column instead, which fills
   the card just the same. */
.copy-mappings .list-view__scroll[b-nelmvcteoz] {
    flex: 0 0 auto;
}

/* One-line orientation above the toolbar. Muted and small: it is a reminder,
   not a section of documentation. */
.copy-mappings__intro[b-nelmvcteoz] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* The toolbar's controls come from three different places - a submit button,
   a plain button, and the shared column-picker trigger - and only line up if
   the row aligns them explicitly. Without this the submit sat a few pixels
   low, because the global submit-button rule contributes a margin the
   toolbar pills do not have. */
.copy-mappings .list-toolbar__start[b-nelmvcteoz] {
    align-items: center;
}

    .copy-mappings .list-toolbar__start button[type="submit"][b-nelmvcteoz] {
        margin: 0;
    }

/* The flex gap above already separates the blocks; drop the shared toolbar's
   and callout's own margins so spacing doesn't compound to an odd rhythm. */
.copy-mappings .list-toolbar[b-nelmvcteoz] {
    margin-block-end: 0;
}

.copy-mappings .callout[b-nelmvcteoz] {
    margin: 0;
}

/* Save is the toolbar's primary action, so it inverts the shared outline
   pill rather than sitting flush with the secondary controls beside it.
   Everything else (44px target, radius, focus ring, motion) still comes
   from .list-toolbar__action in lists.css - only the fill changes. */
.copy-mappings .list-toolbar__action--primary[b-nelmvcteoz] {
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
}

    .copy-mappings .list-toolbar__action--primary:hover[b-nelmvcteoz] {
        background: var(--color-chrome-surface-strong, var(--color-chrome-surface));
        color: var(--color-chrome-on-surface);
    }

/* Toolbar/empty-state button glyphs - matched to the 14px inline SVGs the
   shared list triggers use. */
.copy-mappings__icon[b-nelmvcteoz] {
    display: inline-flex;
    align-items: center;
}

    .copy-mappings__icon svg[b-nelmvcteoz] {
        display: block;
        fill: currentColor;
    }

/* ── Column widths ───────────────────────────────────────────────
   The four identity columns (source/destination id + type) are hidden by
   default, so the visible table is the seven columns that carry the row's
   meaning and they can breathe. When the operator switches an identity
   column on it is sized to show its value WHOLE - a truncated guid or a
   clipped "Mail-enabled security group" is worth nothing, which is the
   entire reason for revealing the column. The table still scrolls
   horizontally inside .list-view__scroll, like the app's other wide
   tables. */
/* Header aligns with its value - a right-aligned "#" over left-aligned
   ordinals reads as two different columns. */
.copy-mappings__col--row[b-nelmvcteoz] {
    inline-size: 3rem;
    text-align: start;
}

.copy-mappings__col--picker[b-nelmvcteoz] {
    min-inline-size: 16rem;
}

/* 36 monospace characters plus cell padding - a full guid, never elided. */
.copy-mappings__col--id[b-nelmvcteoz] {
    inline-size: 20rem;
}

.copy-mappings__col--kind[b-nelmvcteoz] {
    inline-size: 13rem;
}

/* Three checkboxes stacked; wide enough that no label wraps. */
.copy-mappings__col--types[b-nelmvcteoz] {
    inline-size: 9rem;
}

.copy-mappings__types[b-nelmvcteoz] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.copy-mappings__type[b-nelmvcteoz] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    white-space: nowrap;
    font-size: var(--font-size-xs);
}

    /* The global input skin stretches checkboxes to full width; keep them the
       size of a checkbox. */
    .copy-mappings__table .copy-mappings__type input[type="checkbox"][b-nelmvcteoz] {
        inline-size: auto;
        min-inline-size: 0;
        margin: 0;
    }

.copy-mappings__col--control[b-nelmvcteoz] {
    min-inline-size: 8.5rem;
}

.copy-mappings__col--narrow[b-nelmvcteoz] {
    inline-size: 6rem;
}

.copy-mappings__col--switch[b-nelmvcteoz] {
    inline-size: 5.5rem;
}

.copy-mappings__col--actions[b-nelmvcteoz] {
    inline-size: 3.5rem;
}

/* ── Cell content ────────────────────────────────────────────────── */

/* Directory ids read as identifiers, not prose: monospace, muted, one line
   (the Usage ledger's job-id convention). No truncation - the column is
   opt-in and sized for the whole guid, so eliding it here would defeat the
   point of turning it on. */
.copy-mappings__id[b-nelmvcteoz] {
    display: inline-block;
    white-space: nowrap;
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    vertical-align: middle;
}

/* The row-number cell is a <th scope="row"> (it labels its row), which means
   it matches NEITHER `.list-view__table td` NOR `.list-view__th` - so it
   inherited zero padding while the column header carried 0.75rem, and the
   ordinal sat flush against the cell edge under an apparently-indented "#".
   Give every body header cell the shared cell padding. */
.copy-mappings__table tbody th[b-nelmvcteoz] {
    padding: 0.5rem 0.75rem;
}

/* Row number: a quiet ordinal, tabular so the digits line up as rows are
   added and removed. Leading- and TOP-aligned: a row is as tall as its
   tallest control, and a vertically-centred ordinal drifts away from the
   row it labels as soon as one cell grows. */
.copy-mappings__cell--row[b-nelmvcteoz] {
    color: var(--color-text-muted);
    font-weight: var(--font-weight-normal);
    font-variant-numeric: tabular-nums;
    text-align: start;
    vertical-align: top;
}

/* Every cell tops out for the same reason - the pickers and the schedule
   stack are much taller than a select, and centring the short cells against
   them scatters the row. */
.copy-mappings__table tbody td[b-nelmvcteoz],
.copy-mappings__table tbody th[b-nelmvcteoz] {
    vertical-align: top;
}

/* A paused row still has to be readable (it is being edited), so it is
   dimmed rather than greyed out, and the toggle itself keeps full contrast
   so the way back on is never ambiguous. */
.copy-mappings__row--disabled[b-nelmvcteoz] {
    opacity: 0.55;
}

    .copy-mappings__row--disabled .copy-mappings__cell--switch:first-of-type[b-nelmvcteoz] {
        opacity: 1;
    }

/* A row can source several groups, so the id and type cells hold a LIST.
   The stack lives in a wrapper rather than on the cell itself: a `td` with
   `display: flex` stops being a table-cell, and the browser then wraps it in
   an anonymous cell that no longer participates in column sizing. */
.copy-mappings__stack[b-nelmvcteoz] {
    display: flex;
    flex-direction: column;
    align-items: start;
    gap: var(--space-1);
}

/* Group-type chip - same shape as the group picker's kind badge, so the
   type column and the chip inside the picker read as one vocabulary. */
.copy-mappings__badge[b-nelmvcteoz] {
    display: inline-flex;
    align-items: center;
    padding-block: 0.0625rem;
    padding-inline: 0.375rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    /* Type names are phrases ("Mail-enabled security group"), and the column
       is opt-in and sized for them - let a long one wrap inside the chip
       rather than forcing the column wider than its content needs. */
    text-align: start;
}

.copy-mappings__blank[b-nelmvcteoz] {
    color: var(--color-text-muted);
}

.copy-mappings__cell--switch[b-nelmvcteoz] {
    text-align: center;
}

.copy-mappings__cell--actions[b-nelmvcteoz] {
    text-align: end;
    white-space: nowrap;
}

/* Schedule cell stacks the cadence select and its day control. */
.copy-mappings__stack[b-nelmvcteoz] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* Table-prefixed so these beat the global full-width input/select skin.
   min-inline-size is a real FLOOR, not 0: a table cell will happily compress
   its contents to fit, and `min-inline-size: 0` actively grants permission to
   do so - which is what left the selects and number boxes rendering half
   visible. With a floor, the cell can no longer shrink past its control, so
   the table overflows into the scroll container instead. */
.copy-mappings__table select.copy-mappings__select[b-nelmvcteoz] {
    inline-size: 100%;
    min-inline-size: 7.5rem;
}

.copy-mappings__table input.copy-mappings__number[b-nelmvcteoz] {
    inline-size: 100%;
    max-inline-size: 6rem;
    min-inline-size: 4rem;
}

.copy-mappings__table[b-nelmvcteoz]  .group-picker__search {
    min-inline-size: 12rem;
}

/* Icon-only row remove - the app's square icon-button recipe (rich-text
   editor toolbar) tinted with destructive intent on hover. */
.copy-mappings__remove[b-nelmvcteoz] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2.25rem;
    block-size: 2.25rem;
    padding: 0;
    background: var(--color-surface);
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard),
                border-color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .copy-mappings__remove:hover[b-nelmvcteoz] {
        background: var(--color-danger-surface);
        color: var(--color-danger-on-surface);
        border-color: var(--color-danger);
    }

    .copy-mappings__remove:focus-visible[b-nelmvcteoz] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Every column descriptor here is position-locked (the table's cells are
   bespoke per column, so a reorder could not be honoured). The shared
   surface still renders its decorative drag grip, which would advertise a
   drag that does nothing - hide it so the panel reads as the pure
   visibility list this consumer actually implements. */
.copy-mappings[b-nelmvcteoz]  .list-column-picker__grip {
    display: none;
}

/* The picker's results list renders inline (not as an overlay), so cap it
   inside a table row - an open picker must not push the row to full height. */
.copy-mappings__cell--picker[b-nelmvcteoz]  .group-picker__results {
    max-block-size: 9rem;
}

/* ── Narrow desktops and tablets ─────────────────────────────────
   Between the card breakpoint and a wide desktop, ten editable columns do
   not fit. Left alone the browser resolves that by SQUASHING cells until
   labels wrap to three lines and controls clip - unreadable, and the reason
   this table looked broken on a laptop. Give the table a floor instead, so
   it overflows into the shared scroll container and the operator pans a
   legible table rather than reading a compressed one. */
/* Size to CONTENT, never to the container. A magic min-width was the wrong
   tool - it has to be re-guessed every time a column is added or the picker
   toggles the identity columns on, and if it is even slightly low the browser
   resolves the shortfall by squashing cells. max-content lets the columns
   claim what they actually need; min-inline-size keeps the table filling the
   card when there is room to spare. */
.copy-mappings__table[b-nelmvcteoz] {
    inline-size: max-content;
    min-inline-size: 100%;
}

/* Headers must not wrap either - a two-line "Destination group" is what makes
   a column look broken before its cells even render. */
.copy-mappings__table th[b-nelmvcteoz] {
    white-space: nowrap;
}

/* An overlay scrollbar is invisible until it is scrolled, so the fact that
   there IS more table to the right has to be advertised. Same treatment the
   app's other wide tables use. */
.copy-mappings .list-view__scroll[b-nelmvcteoz] {
    overflow-x: auto;
    scrollbar-width: thin;
}

    .copy-mappings .list-view__scroll[b-nelmvcteoz]::-webkit-scrollbar {
        block-size: 0.5rem;
    }

    .copy-mappings .list-view__scroll[b-nelmvcteoz]::-webkit-scrollbar-thumb {
        background: var(--color-border);
        border-radius: var(--radius-full);
    }

/* ── Advisory hints + caveats ───────────────────────────────────── */

/* .callout supplies the warning skin + leading glyph; only the inner
   rhythm belongs here. */
.copy-mappings__hints-intro[b-nelmvcteoz] {
    margin: 0 0 var(--space-1);
    font-weight: var(--font-weight-semibold);
}

.copy-mappings__hints-list[b-nelmvcteoz] {
    margin: 0;
    padding-inline-start: 1.25rem;
    line-height: var(--line-height-snug);
}

/* ── Narrow viewports ───────────────────────────────────────────
   The shared card transform turns each row into a bordered card with the
   column label as a leading pseudo-element. Editable cells need the label
   ABOVE a full-width control rather than the read-only label/value pair. */
@media (max-width: 599px) {
    /* The card transform makes each row a full-width block, so the desktop
       content sizing must be released - max-content on a card layout would
       still force a horizontal scroll, and the control floors would push the
       cards wider than the screen. Cards give every control the full width
       instead, so nothing can be clipped here. */
    .copy-mappings__table[b-nelmvcteoz] {
        inline-size: 100%;
        min-inline-size: 0;
    }

    .copy-mappings__table select.copy-mappings__select[b-nelmvcteoz],
    .copy-mappings__table[b-nelmvcteoz]  .group-picker__search {
        min-inline-size: 0;
    }

    .copy-mappings__table td[b-nelmvcteoz] {
        flex-direction: column;
        align-items: stretch;
        gap: var(--space-1);
        padding-block: var(--space-2);
        text-align: start;
    }

    /* The __col--* widths live on <th>, and the shared card transform hides
       <thead> entirely, so only the cell-level rules need resetting here. */
    .copy-mappings__cell--switch[b-nelmvcteoz],
    .copy-mappings__cell--actions[b-nelmvcteoz] {
        text-align: start;
    }

    .copy-mappings__id[b-nelmvcteoz] {
        max-inline-size: none;
    }

    .copy-mappings__table input.copy-mappings__number[b-nelmvcteoz] {
        max-inline-size: 8rem;
    }
}
/* /Components/Pages/Tenant/Actions/SiteSharingCapabilityEditor.razor.rz.scp.css */
/* Editor-specific chrome only - the table, toolbar, and scroll region reuse the
   shared list contract from wwwroot/css/lists.css verbatim (see the component's
   header comment); nothing here may restyle those classes. */

.site-sharing-hints[b-vi3rvtere5] {
    margin: 0 0 0.75rem;
    padding: 0.5rem 1rem 0.5rem 2rem;
    border-left: 3px solid var(--warning, #b7791f);
    background: var(--warning-subtle, #fdf6ec);
}

/* The shared bulk bar is bottom-sticky, which suits a list page whose
   toolbar sits well clear of the fold. This editor's toolbar carries six
   controls that wrap to several rows on a phone, and the bar's own place in
   the document is then BELOW the fold - so sticky pulls it back up to the
   viewport edge, where its z-index paints it over Save / Filters / Columns
   (measured: an 18px bite out of the toolbar's last row at 390x844). Keeping
   it in flow costs the pinned-while-scrolling affordance and removes the
   collision outright. ::deep because the bar is a child component's element. */
.site-sharing-bulk-bar[b-vi3rvtere5]  .list-bulk-action-bar {
    position: static;
}

/* The bar casts a shadow and the table starts immediately beneath it; without
   clearance the table's own top edge crops that shadow and the two read as one
   welded block. */
.site-sharing-bulk-bar[b-vi3rvtere5] {
    margin-block-end: 0.75rem;
}

.site-sharing-bulk-panel[b-vi3rvtere5] {
    border: 1px solid var(--border-subtle, #d0d4da);
    border-radius: 0.5rem;
    padding: 1rem;
    margin-bottom: 0.75rem;
}

.site-sharing-bulk-panel__actions[b-vi3rvtere5] {
    margin-top: 0.75rem;
}

.site-sharing-row--readonly[b-vi3rvtere5] {
    color: var(--text-subtle, #5b6472);
}

/* The site cell doubles as the expand trigger on editable rows - a text-styled
   button so clicking the name opens that site's sharing settings. */
.site-sharing-row__site[b-vi3rvtere5] {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    text-align: inherit;
    font: inherit;
    color: inherit;
    cursor: pointer;
}

.site-sharing-row__site:hover .site-sharing-row__title[b-vi3rvtere5],
.site-sharing-row__site:focus-visible .site-sharing-row__title[b-vi3rvtere5] {
    text-decoration: underline;
}

/* The trigger's label flips between "Edit sharing" and "Close"; a fixed
   width sized to the longer label keeps the button from resizing under the
   pointer, and the centered text keeps the shorter label from hugging the
   leading edge. */
.site-sharing-row__edit[b-vi3rvtere5] {
    inline-size: 6.75rem;
    justify-content: center;
    text-align: center;
    white-space: nowrap;
    padding-inline: 0.5rem;
}

.site-sharing-export-error[b-vi3rvtere5] {
    margin: 0 0 0.5rem;
    color: var(--danger, #b42318);
}

/* The on-demand gate shown in place of the grid until the operator asks. */
.site-sharing-load[b-vi3rvtere5] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 2.5rem 1rem;
    border: 1px dashed var(--border-subtle, #d0d4da);
    border-radius: 0.5rem;
    text-align: center;
}

.site-sharing-load p[b-vi3rvtere5] {
    margin: 0;
    max-width: 44rem;
    color: var(--text-subtle, #5b6472);
}

/* The snapshot-capture tile row directly under the card heading. */
/* One tile, not a row of them: the shared grid's auto-fit tracks are `1fr`,
   so a lone tile stretches the full width and reads as a banner rather than
   a stat. Size the track to its content instead, and keep the phone rule's
   full-width behaviour where a content-width tile would look stranded. */
.site-sharing-editor__tiles[b-vi3rvtere5] {
    margin: 0 0 0.75rem;
    grid-template-columns: max-content;
}

@media (max-width: 599px) {
    .site-sharing-editor__tiles[b-vi3rvtere5] {
        grid-template-columns: 1fr;
    }
}

.site-sharing-row__title[b-vi3rvtere5] {
    display: block;
    font-weight: 600;
}

.site-sharing-row__url[b-vi3rvtere5] {
    display: block;
    font-size: 0.75rem;
    color: var(--text-subtle, #5b6472);
    word-break: break-all;
}

.site-sharing-chip[b-vi3rvtere5] {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    margin-right: 0.25rem;
    border-radius: 1rem;
    font-size: 0.75rem;
    background: var(--surface-subtle, #eef0f3);
}

.site-sharing-chip--modified[b-vi3rvtere5] {
    background: var(--accent-subtle, #e3edfb);
    font-weight: 600;
}

.site-sharing-chip--readonly[b-vi3rvtere5] {
    background: var(--warning-subtle, #fdf6ec);
}

.site-sharing-fields[b-vi3rvtere5] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
    gap: 0.75rem;
    padding: 0.75rem 0;
}

.site-sharing-fields label[b-vi3rvtere5] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.85rem;
    /* These labels ARE the field cells, not captions above a form control, so
       the global app-shell label margin does not belong on them. Left in, it
       shortened every label-wrapped field by 8px against the domain fields,
       whose wrapper is a <div> and carries no such margin - and since each
       control is pinned to the BOTTOM of its cell, that 8px landed as a
       visible step between the domain boxes and the dropdowns beside them. */
    margin-bottom: 0;
}

/* Controls align at the BOTTOM of each grid cell, so a field whose label
   wraps to two lines does not push its control below the row's other
   controls - every input/select/toggle sits on one baseline. */
.site-sharing-fields label > :last-child[b-vi3rvtere5] {
    margin-block-start: auto;
}

/* The toggle switch is much shorter than the 2.75rem inputs; the slot
   reserves the same control height and centers the switch in it, so the
   toggles line up with the textboxes beside them. */
.site-sharing-fields__toggle-slot[b-vi3rvtere5] {
    display: flex;
    align-items: center;
    min-block-size: 2.75rem;
}

/* The toggle is a fixed-width control inside a stretch-aligned column flex
   field - without this it stretches/centers instead of hugging the leading
   edge under its label like every other control. */
.site-sharing-fields .toggle-switch[b-vi3rvtere5] {
    align-self: flex-start;
}

.site-sharing-fields__note[b-vi3rvtere5] {
    grid-column: 1 / -1;
    margin: 0;
}

.site-sharing-load-more[b-vi3rvtere5] {
    display: flex;
    justify-content: center;
    padding: 0.75rem;
}
/* /Components/Pages/Tenant/Actions/SiteSharingDomainTagInput.razor.rz.scp.css */
/* Chip-style domain list input. The root sits as one field cell inside the
   editor's .site-sharing-fields grid; the parent's scoped label rules cannot
   reach into this component, so the label + column layout is restated here to
   match the sibling fields. */

.site-sharing-domains[b-0y2h72sd0f] {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.85rem;
}

.site-sharing-domains__label[b-0y2h72sd0f] {
    display: block;
    /* The global app-shell label rule adds a bottom margin meant for form
       layouts; the sibling fields' labels are spans, so that margin pushed
       this field's box a few pixels below its row - the flex gap alone is
       the spacing here, exactly like the siblings. */
    margin-bottom: 0;
    font-size: inherit;
}

/* The box impersonates a text input: chips and the real (borderless) input
   share one bordered surface that grows and wraps as chips accumulate. Empty,
   it sits at exactly the shared 2.75rem control height so the field lines up
   with the dropdowns beside it; the bottom-alignment rule in the editor's
   grid needs the box (not the error line) pinned to the control baseline. */
.site-sharing-domains__box[b-0y2h72sd0f] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.25rem;
    min-block-size: 2.75rem;
    box-sizing: border-box;
    margin-block-start: auto;
    padding: 0.25rem var(--space-3, 0.75rem);
    border: 1px solid var(--border-subtle, #d0d4da);
    border-radius: 0.375rem;
    background: var(--surface, #ffffff);
}

/* The inner input must NOT look or size like a standalone control - the
   global app-shell input rule gives every text input the full 2.75rem
   bordered treatment, which stacked a control inside a control and made
   this field taller than its siblings. Specificity-bumped (two classes)
   to beat the global :is() + attribute selector. */
.site-sharing-domains .site-sharing-domains__input[b-0y2h72sd0f] {
    width: auto;
    min-height: 0;
    padding: 0.15rem 0.25rem;
    border: 0;
    background: none;
    box-shadow: none;
}

.site-sharing-domains__box:focus-within[b-0y2h72sd0f] {
    border-color: var(--accent, #0f5fd6);
}

.site-sharing-domains__chip[b-0y2h72sd0f] {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    padding: 0.1rem 0.3rem 0.1rem 0.5rem;
    border-radius: 1rem;
    font-size: 0.8rem;
    background: var(--surface-subtle, #eef0f3);
    /* Domains are unbroken tokens; a very long one must wrap inside its
       chip rather than force the box (and the input) sideways. */
    max-inline-size: 100%;
    min-width: 0;
}

.site-sharing-domains__chip-text[b-0y2h72sd0f] {
    overflow-wrap: anywhere;
    min-width: 0;
}

.site-sharing-domains__remove[b-0y2h72sd0f] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 0.15rem;
    border: 0;
    background: none;
    font: inherit;
    line-height: 1;
    color: var(--text-subtle, #5b6472);
    cursor: pointer;
}

.site-sharing-domains__remove:hover[b-0y2h72sd0f],
.site-sharing-domains__remove:focus-visible[b-0y2h72sd0f] {
    color: var(--danger, #b42318);
}

.site-sharing-domains__input[b-0y2h72sd0f] {
    /* Never shrinks below its basis: as chips accumulate the input WRAPS to
       its own full line instead of collapsing to an untypeable sliver. */
    flex: 1 0 8rem;
    min-inline-size: 8rem;
    padding: 0.15rem 0.25rem;
    border: 0;
    background: none;
    font: inherit;
}

.site-sharing-domains__input:focus[b-0y2h72sd0f] {
    /* The box's focus-within border carries the focus indication. */
    outline: none;
}

.site-sharing-domains__error[b-0y2h72sd0f] {
    margin: 0;
    font-size: 0.8rem;
    color: var(--danger, #b42318);
}
/* /Components/Pages/Tenant/Approvals/PendingApprovalsTable.razor.rz.scp.css */
/* Type cell: the Benchmark/Action label on top, the muted benchmark/category source beneath. */
.pending-approvals-table__primary[b-pxbgioy7x8] {
    display: block;
    font-weight: 500;
}

.pending-approvals-table__detail[b-pxbgioy7x8] {
    display: block;
    color: var(--color-text-muted);
    font-size: 0.8125rem;
}
/* /Components/Pages/Tenant/Benchmarks/Shared/ManualAttestActions.razor.rz.scp.css */
/* ManualAttestActions - InteractiveServer island living inside
   ControlTrend.razor. Scoped CSS so the action row + dialogs paint
   on-brand without depending on the global `button[type="submit"]`
   skin (these are `type="button"` because they open dialogs rather
   than submitting forms). */

.manual-attest-actions[b-s0kefz2mih] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-3);
    margin-block-end: var(--space-3);
}

.manual-attest-actions__primary[b-s0kefz2mih],
.manual-attest-actions__destructive[b-s0kefz2mih] {
    /* Match the global action-button skin: navy primary, white text,
       semibold, ≥ 2.75rem tap height. Mirrors the `.app-shell__main
       button[type="submit"]` rule in app.css. */
    appearance: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    padding: 0.625rem 1.25rem;
    min-height: 2.75rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-md);
    line-height: 1;
    cursor: pointer;
    transition:
        background var(--motion-duration-fast) var(--motion-easing-standard),
        color var(--motion-duration-fast) var(--motion-easing-standard),
        border-color var(--motion-duration-fast) var(--motion-easing-standard);
}

.manual-attest-actions__primary[b-s0kefz2mih] {
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
}

    .manual-attest-actions__primary:hover:not(:disabled)[b-s0kefz2mih] {
        /* --color-chrome-surface-hover is a 10% white OVERLAY token
           (designed to sit on top of the navy nav), not a button
           background - using it here turned the navy near-white on
           hover. Brighten the navy itself instead. */
        filter: brightness(1.08);
    }

    .manual-attest-actions__primary:focus-visible[b-s0kefz2mih] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.manual-attest-actions__destructive[b-s0kefz2mih] {
    background: var(--color-surface);
    color: var(--color-danger);
    border-color: var(--color-danger);
}

    .manual-attest-actions__destructive:hover:not(:disabled)[b-s0kefz2mih] {
        /* Filled state uses the danger surface/on-surface PAIR (not
           --color-danger + white): in dark mode --color-danger is a
           light red, so white text on it drops below AA - the paired
           tokens keep the fill/text contrast AA in both themes. */
        background: var(--color-danger-surface);
        color: var(--color-danger-on-surface);
    }

    .manual-attest-actions__destructive:focus-visible[b-s0kefz2mih] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.manual-attest-actions__primary:disabled[b-s0kefz2mih],
.manual-attest-actions__destructive:disabled[b-s0kefz2mih] {
    opacity: 0.5;
    cursor: not-allowed;
    filter: grayscale(0.4);
}


/* ── Dialog chrome ─────────────────────────────────────────────── */

.manual-attest-actions__dialog[b-s0kefz2mih] {
    border: none;
    border-radius: var(--radius-lg);
    padding: 0;
    inline-size: min(100%, 32rem);
    background: var(--color-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-xl, var(--shadow-md));
}

    .manual-attest-actions__dialog[b-s0kefz2mih]::backdrop {
        background: rgba(0, 0, 0, 0.45);
    }

.manual-attest-actions__form[b-s0kefz2mih] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5);
}

.manual-attest-actions__title[b-s0kefz2mih] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}

.manual-attest-actions__prompt[b-s0kefz2mih] {
    margin: 0;
    color: var(--color-text-muted);
}

.manual-attest-actions__label[b-s0kefz2mih] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    font-weight: var(--font-weight-semibold);
}

.manual-attest-actions__rationale[b-s0kefz2mih],
.manual-attest-actions__expiry[b-s0kefz2mih] {
    appearance: none;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 0.5rem 0.75rem;
    font-family: inherit;
    /* 16px floor - iOS Safari auto-zooms on focus when font-size < 16px. */
    font-size: max(var(--font-size-md), 1rem);
    font-weight: var(--font-weight-normal);
    background: var(--color-surface);
    color: var(--color-text);
}

.manual-attest-actions__rationale[b-s0kefz2mih] {
    resize: vertical;
    min-height: 6rem;
}

.manual-attest-actions__error[b-s0kefz2mih] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}

.manual-attest-actions__dialog-actions[b-s0kefz2mih] {
    display: flex;
    justify-content: flex-end;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.manual-attest-actions__cancel[b-s0kefz2mih],
.manual-attest-actions__confirm[b-s0kefz2mih] {
    appearance: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    padding: 0.5rem 1.125rem;
    min-height: 2.5rem;
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-md);
    cursor: pointer;
}

.manual-attest-actions__cancel[b-s0kefz2mih] {
    background: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border);
}

    .manual-attest-actions__cancel:hover[b-s0kefz2mih] {
        background: var(--color-surface-sunken, var(--color-surface));
    }

.manual-attest-actions__confirm[b-s0kefz2mih] {
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
}

    .manual-attest-actions__confirm:hover:not(:disabled)[b-s0kefz2mih] {
        filter: brightness(1.08);
    }

.manual-attest-actions__confirm--destructive[b-s0kefz2mih] {
    background: var(--color-danger-surface);
    color: var(--color-danger-on-surface);
}

.manual-attest-actions__confirm:disabled[b-s0kefz2mih] {
    opacity: 0.5;
    cursor: not-allowed;
}

@media (max-width: 599px) {
    .manual-attest-actions[b-s0kefz2mih] {
        flex-direction: column;
        align-items: stretch;
    }

    .manual-attest-actions__primary[b-s0kefz2mih],
    .manual-attest-actions__destructive[b-s0kefz2mih] {
        width: 100%;
    }

    .manual-attest-actions__dialog-actions[b-s0kefz2mih] {
        justify-content: stretch;
    }

        .manual-attest-actions__dialog-actions > button[b-s0kefz2mih] {
            flex: 1 1 auto;
        }
}
/* /Components/Pages/Tenant/Benchmarks/Shared/RemediateAction.razor.rz.scp.css */
/* The island renders one wrapper div around the Remediate button +
   ListConfirmDialog + two FormStatus banners. Sits inside the
   ControlTrend Overview's .form-actions flex row (Run / Remediate /
   View jobs); without display: contents the wrapper would become a
   single flex item, putting the dialog markup + status banners next
   to the button instead of below it. display: contents collapses the
   wrapper so the button participates directly in the parent flex row,
   the dialog (when modal-open) floats out of flow via the native top
   layer, and any FormStatus rendered after the button takes its own
   line via flex-basis: 100%. */
.remediate-action[b-maqavhs56b] {
    display: contents;
}

    /* FormStatus banner takes its own full-width line BELOW the action
       row. order: 99 pushes it past every other flex item (View jobs in
       particular is order: 0 and would otherwise wrap onto the same line
       as the status); flex-basis: 100% forces a wrap so the row reads
       as 'Run / Remediate / View jobs' with the banner stacked under
       it. Mirrors how the page's own Run banner sits below the
       .form-actions div, just routed through the flex order property
       so the parent's markup order stays untouched. */
    .remediate-action[b-maqavhs56b]  .form-status {
        order: 99;
        flex-basis: 100%;
        margin-inline-start: 0;
    }

/* Button styling - mirrors the .secondary outline-button treatment the
   sibling Run submit-button uses (transparent fill, chrome-surface
   border, fills on hover) so the Remediate button reads as a peer of
   Run rather than a stray default-styled <button>. The global rule at
   app.css gates the outline treatment on button[type="submit"], so the
   island redefines it locally for its own type="button" handler
   (the InteractiveServer @onclick can't run on a submit button without
   a wrapping form). Sizing (min-height, padding, border-radius,
   font-weight) matches the global submit-button baseline so the
   Run / Remediate / View jobs row stays vertically aligned. */
.remediate-action__button[b-maqavhs56b] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: transparent;
    color: var(--color-chrome-surface);
    border: 1px solid var(--color-chrome-surface);
    border-radius: var(--radius-md);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    text-align: center;
    box-sizing: border-box;
    cursor: pointer;
    box-shadow: none;
    transition: background var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .remediate-action__button:hover:not(:disabled)[b-maqavhs56b] {
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
    }

    .remediate-action__button:focus-visible[b-maqavhs56b] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

    .remediate-action__button:disabled[b-maqavhs56b] {
        cursor: not-allowed;
        opacity: 0.5;
    }
/* /Components/Pages/Tenant/Benchmarks/Shared/RemediateParametersForm.razor.rz.scp.css */
/* Parameter form rendered inside the host's confirm modal (e.g. the break-glass
   exclusion picker + the CA-policy-state choice). Space the parameters out so adjacent
   controls don't crowd each other; each parameter stacks its label / help / input. */
.remediate-parameters__list[b-ea4vqhusrk] {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    margin-block-start: var(--space-3);
}

.remediate-parameters__item[b-ea4vqhusrk] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

/* Toggle parameter: the sliding switch (.toggle-switch, global) sits inline with its
   label text; the help line stacks below via the __item column. */
.remediate-parameters__toggle[b-ea4vqhusrk] {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    cursor: pointer;
}

/* StringList parameter: committed chips wrap above the text input; typing a word and pressing
   space or comma turns it into a removable chip (the same chip affordance as the principal picker). */
.remediate-parameters__tags[b-ea4vqhusrk] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.remediate-parameters__tags:empty[b-ea4vqhusrk] {
    display: none;
}

.remediate-parameters__tag[b-ea4vqhusrk] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.5rem;
    background: var(--color-brand-subtle);
    border-radius: 1rem;
    font-size: 0.9em;
}

.remediate-parameters__tag-remove[b-ea4vqhusrk] {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.1em;
    line-height: 1;
    padding: 0;
    color: var(--color-text-muted);
}
/* /Components/Pages/Tenant/Benchmarks/Shared/RunReviewPanel.razor.rz.scp.css */
/* Run-review surface - summary tiles, planned-change preview table, and the
   decision / cancel action rows. The summary renders as StatCard tiles (their own
   card chrome) above the content cards the other control tabs use. */

.run-review__tiles[b-uay4yz9inw] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
    gap: var(--space-4, 1rem);
    margin-block-end: var(--space-4, 1rem);
}

.run-review__preview-wrap[b-uay4yz9inw] {
    overflow-x: auto;
    margin-block-start: var(--space-4, 1rem);
}

.run-review__preview[b-uay4yz9inw] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm, 0.875rem);
}

.run-review__preview th[b-uay4yz9inw],
.run-review__preview td[b-uay4yz9inw] {
    padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
    text-align: left;
    border-block-end: 1px solid var(--color-border-subtle);
}

.run-review__preview thead th[b-uay4yz9inw] {
    font-weight: var(--font-weight-semibold, 600);
    color: var(--color-text-muted);
    border-block-end: 2px solid var(--color-border);
    white-space: nowrap;
}

.run-review__preview tbody tr:last-child td[b-uay4yz9inw] {
    border-block-end: none;
}

.run-review__comment[b-uay4yz9inw] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1, 0.25rem);
    margin-block: var(--space-4, 1rem);
}

.run-review__comment-label[b-uay4yz9inw] {
    font-size: var(--font-size-sm, 0.875rem);
    font-weight: var(--font-weight-medium, 500);
    color: var(--color-text);
}

.run-review__comment-input[b-uay4yz9inw] {
    width: 100%;
    padding: var(--space-2, 0.5rem);
    font: inherit;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 0.375rem);
    resize: vertical;
}

.run-review__actions[b-uay4yz9inw] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3, 0.75rem);
    margin-block-start: var(--space-4, 1rem);
}

/* The approve / reject / cancel handlers are InteractiveServer type="button" clicks,
   so the app-shell `button[type="submit"]` styling doesn't reach them - mirror the
   primary (and .danger) submit-button treatment locally so they read as standard
   solution buttons (same approach as RemediateAction.razor.css). */
.run-review__actions button[b-uay4yz9inw] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    text-align: center;
    border: 1px solid transparent;
    border-radius: var(--radius-md, 0.375rem);
    box-sizing: border-box;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: filter var(--motion-duration-fast) var(--motion-easing-standard);
}

    .run-review__actions button:hover:not(:disabled)[b-uay4yz9inw] {
        filter: brightness(1.08);
    }

    .run-review__actions button:active:not(:disabled)[b-uay4yz9inw] {
        filter: brightness(0.92);
    }

    .run-review__actions button:focus-visible[b-uay4yz9inw] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

    .run-review__actions button:disabled[b-uay4yz9inw] {
        cursor: not-allowed;
        opacity: 0.5;
    }

    .run-review__actions button.danger[b-uay4yz9inw] {
        background: var(--color-danger);
        color: var(--color-text-on-accent);
    }

        .run-review__actions button.danger:hover:not(:disabled)[b-uay4yz9inw] {
            filter: brightness(0.92);
        }
/* /Components/Pages/Tenant/Jobs/Jobs.razor.rz.scp.css */
/* Tenant Jobs page - static-SSR chrome around the <JobsTable> island.
   The table itself (rows, filters, pagination) inherits the shared
   ListView styling; this sheet only spaces the toolbar row. */

.jobs__toolbar-row[b-0oo2tcwsm5] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: var(--space-3);
    margin: var(--space-4) 0 var(--space-2);
}
/* /Components/Pages/Tenant/Reports/ReportRunConfirmAction.razor.rz.scp.css */
/* The island renders one wrapper div around the Run button +
   ListConfirmDialog + FormStatus banners, sitting inside ReportDetail's
   .form-actions flex row. display: contents collapses the wrapper so the
   button participates directly in the parent flex row, the dialog floats out
   of flow via the native top layer, and any FormStatus after the button takes
   its own line via flex-basis: 100% - the RemediateAction pattern. */
.report-run-confirm[b-4kepu8vhd0] {
    display: contents;
}

    .report-run-confirm[b-4kepu8vhd0]  .form-status {
        order: 99;
        flex-basis: 100%;
        margin-inline-start: 0;
    }

/* Button styling - mirrors the PRIMARY submit-button treatment (filled
   chrome-surface) the static Run button gets from app.css, because this
   island's button IS the page's Run button for confirmation-required reports.
   The global rule gates on button[type="submit"], so it is redefined locally
   for the island's type="button" handler (the InteractiveServer @onclick
   can't ride a submit button without a wrapping form). margin-top stays 0 -
   the .form-actions row provides the spacing (same fix as the base rule's
   .form-actions override). */
.report-run-confirm__button[b-4kepu8vhd0] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    padding: 0 var(--space-5);
    background: var(--color-chrome-surface);
    color: var(--color-chrome-on-surface);
    font: inherit;
    font-weight: var(--font-weight-semibold);
    text-align: center;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    box-sizing: border-box;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: filter var(--motion-duration-fast) var(--motion-easing-standard);
}

    .report-run-confirm__button:hover:not(:disabled)[b-4kepu8vhd0] {
        filter: brightness(1.08);
        color: var(--color-chrome-on-surface);
    }

    .report-run-confirm__button:active:not(:disabled)[b-4kepu8vhd0] {
        filter: brightness(0.92);
    }

    .report-run-confirm__button:focus-visible[b-4kepu8vhd0] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

    .report-run-confirm__button:disabled[b-4kepu8vhd0] {
        opacity: 0.55;
        cursor: not-allowed;
        filter: grayscale(0.4);
    }
/* /Components/Pages/Tenant/Settings/AuditLog/AuditLog.razor.rz.scp.css */
/* Tenant audit-log page chrome - scoped CSS. Heading + intro now
   live in <ListPageHero>; the toolbar-row aligns the density toggle
   to the right of the page, above the InteractiveServer island.
   Table styling lives in AuditLogTable.razor.css; shared
   list-primitive styling lives in wwwroot/css/lists.css. */

.tenant-audit-log__toolbar-row[b-tpcgxjepso] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}
/* /Components/Pages/Tenant/Settings/Connections/ConnectionCertificateStatusCard.razor.rz.scp.css */
.cert-status[b-pe2vzcghwu] {
    margin-top: var(--space-4);
    padding: var(--space-4);
}

.cert-status__heading[b-pe2vzcghwu] {
    margin: 0 0 var(--space-3);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
}

.cert-status__row[b-pe2vzcghwu] {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-2) var(--space-3);
    padding: var(--space-2) 0;
}

.cert-status__label[b-pe2vzcghwu] {
    min-width: 4rem;
    font-weight: var(--font-weight-medium);
}

.cert-status__thumbprint[b-pe2vzcghwu] {
    max-width: 24ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cert-status__thumbprint--pending[b-pe2vzcghwu] {
    color: var(--color-text-muted);
}

.cert-status__expiry[b-pe2vzcghwu] {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.cert-status__badge[b-pe2vzcghwu] {
    padding: 1px var(--space-2);
    border-radius: var(--radius-pill, 999px);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    white-space: nowrap;
}

.cert-status__badge--valid[b-pe2vzcghwu] {
    background: var(--color-success-surface);
    color: var(--color-success-on-surface);
}

.cert-status__badge--expiring[b-pe2vzcghwu] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
}

.cert-status__badge--expired[b-pe2vzcghwu] {
    background: var(--color-danger-surface);
    color: var(--color-danger-on-surface);
}

.cert-status__badge--pending[b-pe2vzcghwu],
.cert-status__badge--none[b-pe2vzcghwu] {
    background: var(--color-surface-sunken);
    color: var(--color-text-muted);
}

.cert-status__hint[b-pe2vzcghwu] {
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.cert-status__download[b-pe2vzcghwu] {
    margin: var(--space-2) 0 0;
}

/* Actions supplied by the hosting panel (e.g. the Regenerate submit
   button) - one home for every certificate control. ::deep because the
   fragment's elements carry the parent's scope, not this card's. */
.cert-status__actions[b-pe2vzcghwu] {
    margin-top: var(--space-3);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    align-items: center;
}
/* /Components/Pages/Tenant/Settings/Connections/WriteOperationsToggle.razor.rz.scp.css */
.connections-config__write-operations > * + *[b-dpung8posl] {
    margin-block-start: var(--space-3);
}

.connections-config__write-operations-toggle[b-dpung8posl] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

/* Switch + text alignment now comes from the inline-flex parent
   above (gap handles the spacing between switch and label text). */

.connections-config__write-operations-status[b-dpung8posl] {
    margin: 0;
    font-size: var(--font-size-sm);
}

.connections-config__write-operations-status--ok[b-dpung8posl] {
    color: var(--color-success);
}

.connections-config__write-operations-status--error[b-dpung8posl] {
    color: var(--color-danger);
}

.connections-config__write-operations-error[b-dpung8posl] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}
/* /Components/Pages/Tenant/Settings/Notifications/ApprovalEmailPreferenceToggle.razor.rz.scp.css */
.approval-email-pref > * + *[b-2mp5su8og8] {
    margin-block-start: var(--space-3);
}

.approval-email-pref__toggle[b-2mp5su8og8] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.approval-email-pref__hint[b-2mp5su8og8] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.approval-email-pref__status[b-2mp5su8og8] {
    margin: 0;
    font-size: var(--font-size-sm);
}

.approval-email-pref__status--ok[b-2mp5su8og8] {
    color: var(--color-success);
}

.approval-email-pref__status--error[b-2mp5su8og8] {
    color: var(--color-danger);
}

.approval-email-pref__error[b-2mp5su8og8] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}
/* /Components/Pages/Tenant/Settings/Notifications/MyNotificationOptOuts.razor.rz.scp.css */
/* Scoped to this component - Blazor CSS isolation gives each component its own scope attribute,
   so the sibling matrix's styles cannot be inherited even though the markup is near-identical. */
.my-notif__list[b-a7034ynnal] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.my-notif__row[b-a7034ynnal] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.my-notif__text[b-a7034ynnal] {
    display: flex;
    flex-direction: column;
    gap: 0.125rem;
}

.my-notif__name[b-a7034ynnal] {
    font-weight: 600;
}

.my-notif__desc[b-a7034ynnal],
.my-notif__off[b-a7034ynnal] {
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

/* A category the tenant has switched off: the control beside it is disabled, so say why rather
   than leaving a dead switch unexplained. */
.my-notif__off[b-a7034ynnal] {
    color: var(--color-text-muted);
    font-style: italic;
}

.my-notif__actions[b-a7034ynnal] {
    margin-block-start: 1rem;
}

.my-notif__status[b-a7034ynnal],
.my-notif__loading[b-a7034ynnal],
.my-notif__empty[b-a7034ynnal] {
    margin-block-start: 0.75rem;
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

.my-notif__error[b-a7034ynnal] {
    margin-block-start: 0.75rem;
    font-size: 0.875rem;
    color: var(--color-danger);
}
/* /Components/Pages/Tenant/Settings/Notifications/NotificationPreferencesMatrix.razor.rz.scp.css */
.notif-prefs__list[b-rrg2noix88] {
    list-style: none;
    margin: 0;
    padding: 0;
}

.notif-prefs__row[b-rrg2noix88] {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: var(--space-6);
    padding: var(--space-4) 0;
}

    .notif-prefs__row + .notif-prefs__row[b-rrg2noix88] {
        border-top: 1px solid var(--color-border);
    }

.notif-prefs__text[b-rrg2noix88] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.notif-prefs__name[b-rrg2noix88] {
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.notif-prefs__desc[b-rrg2noix88] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.notif-prefs__controls[b-rrg2noix88] {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    justify-self: end;
}

/* Segmented control for the realtime/batched choice - two equal pills, the
   selected one filled with the brand colour. Backed by native radios (one
   group per category) so keyboard, screen readers, and focus all keep working;
   the radio is laid transparently over its pill and the visible state is
   driven purely by :checked. */
.notif-prefs__segmented[b-rrg2noix88] {
    display: inline-flex;
    padding: 2px;
    background: var(--color-surface-sunken);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
}

.notif-prefs__segment[b-rrg2noix88] {
    position: relative;
    margin: 0;
    cursor: pointer;
}

    .notif-prefs__segment input[b-rrg2noix88] {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        margin: 0;
        opacity: 0;
        cursor: pointer;
    }

    .notif-prefs__segment span[b-rrg2noix88] {
        display: block;
        padding: var(--space-1) var(--space-3);
        border-radius: var(--radius-full);
        font-size: var(--font-size-sm);
        font-weight: var(--font-weight-medium);
        color: var(--color-text-muted);
        white-space: nowrap;
        transition: background-color 120ms ease, color 120ms ease;
    }

    .notif-prefs__segment input:checked + span[b-rrg2noix88] {
        background: var(--color-brand);
        color: var(--color-text-on-accent);
        box-shadow: var(--shadow-sm);
    }

    .notif-prefs__segment input:focus-visible + span[b-rrg2noix88] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

    .notif-prefs__segment input:disabled[b-rrg2noix88] {
        cursor: not-allowed;
    }

    .notif-prefs__segment input:disabled + span[b-rrg2noix88] {
        opacity: 0.6;
    }

@media (prefers-reduced-motion: reduce) {
    .notif-prefs__segment span[b-rrg2noix88] {
        transition: none;
    }
}

.notif-prefs__cadence[b-rrg2noix88] {
    margin-block-start: var(--space-5);
    padding-block-start: var(--space-4);
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

    .notif-prefs__cadence label[b-rrg2noix88] {
        font-weight: var(--font-weight-medium);
    }

    .notif-prefs__cadence input[type="number"][b-rrg2noix88] {
        width: 7rem;
    }

.notif-prefs__hint[b-rrg2noix88] {
    margin: 0;
}

.notif-prefs__actions[b-rrg2noix88] {
    margin-block-start: var(--space-5);
}

.notif-prefs__status[b-rrg2noix88] {
    margin: var(--space-3) 0 0;
    font-size: var(--font-size-sm);
}

.notif-prefs__status--ok[b-rrg2noix88] {
    color: var(--color-success);
}

.notif-prefs__status--error[b-rrg2noix88] {
    color: var(--color-danger);
}

.notif-prefs__loading[b-rrg2noix88] {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.notif-prefs__error[b-rrg2noix88] {
    margin: 0;
    font-size: var(--font-size-sm);
    color: var(--color-danger);
}

/* Narrow screens: stack the controls under the label instead of squeezing
   the segmented control + switch into a cramped right rail. */
@media (max-width: 40rem) {
    .notif-prefs__row[b-rrg2noix88] {
        grid-template-columns: 1fr;
        row-gap: var(--space-3);
    }

    .notif-prefs__controls[b-rrg2noix88] {
        justify-self: start;
    }
}
/* /Components/Pages/Tenant/Settings/Notifications/RemediationApprovalNotifyToggle.razor.rz.scp.css */
.remediation-notify-toggle > * + *[b-7nz2ue643i] {
    margin-block-start: var(--space-3);
}

.remediation-notify-toggle__label[b-7nz2ue643i] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
}

.remediation-notify-toggle__hint[b-7nz2ue643i] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.remediation-notify-toggle__status[b-7nz2ue643i] {
    margin: 0;
    font-size: var(--font-size-sm);
}

.remediation-notify-toggle__status--ok[b-7nz2ue643i] {
    color: var(--color-success);
}

.remediation-notify-toggle__status--error[b-7nz2ue643i] {
    color: var(--color-danger);
}

.remediation-notify-toggle__error[b-7nz2ue643i] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}

.remediation-notify-toggle__throttle[b-7nz2ue643i] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-weight: var(--font-weight-medium);
}

.remediation-notify-toggle__throttle input[b-7nz2ue643i] {
    width: 6rem;
}
/* /Components/Pages/Tenant/Settings/SsoConfig/SsoActivityTable.razor.rz.scp.css */
/* Per-row chrome for the SSO activity ListView island. The
   surrounding ListView already styles the table / header / row
   spacing; everything here is cell content rendered via the
   RenderCell fragments. Badge shape + colour cues mirror the
   content-sync audits table so outcome pills read the same across
   admin surfaces. */

.tenant-sso-activity__badge[b-th1vrni7hi] {
    display: inline-block;
    padding: 0 var(--space-2);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    line-height: 1.5;
    border: 1px solid currentColor;
}

.tenant-sso-activity__badge--success[b-th1vrni7hi] {
    color: var(--color-success);
    background: transparent;
}

.tenant-sso-activity__badge--denied[b-th1vrni7hi] {
    color: var(--color-danger);
    background: transparent;
}
/* /Components/Pages/Tenant/Settings/SsoConfig/SsoConfig.razor.rz.scp.css */
/* SSO settings - scoped CSS. The page is composed of three visual
   parts: the form (broken into <fieldset> sections that read like
   cards), the validation-result panel (state-coloured), and the
   danger zone (destructive action separated visually from the
   form). Inputs, textareas, selects, labels, and submit buttons
   inherit the shared rules from wwwroot/css/app.css; everything
   below is page-specific chrome only. */

/* Form layout - vertical stack of section cards with a comfortable
   gap so each <fieldset> reads as a discrete block. */
.sso-config__form[b-7s1wc4b3w6] {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    margin-top: var(--space-4);
    /* Never let the form (or a wide descendant, e.g. the pre-wrapped
       claim-mappings textarea) force the main column wider than its
       track - otherwise the whole form overflows horizontally and the
       last section's controls (the enable toggle) slide off-screen. */
    min-width: 0;
    max-width: 100%;
}

/* Section card. <fieldset> defaults (thin border + inline padding) are
   wiped via the shared .surface-card utility; this scoped rule overrides
   the utility's space-4/space-5 padding with the form's denser space-6
   reading layout, zeros the fieldset margin, and applies a fieldset-only
   min-width guard. */
.sso-config__section[b-7s1wc4b3w6] {
    padding: var(--space-6);
    margin: 0;
    /* A <fieldset> defaults to min-inline-size: min-content, so as a flex
       item in the column form it refuses to shrink and lets wide content
       (the JSON claim-mappings textarea) push past the viewport. Force it
       to shrink to the form width instead - same guard the Connections
       page uses. */
    min-width: 0;
    min-inline-size: 0;
}

/* Breathing room between the field blocks inside a section (Provider ↔
   Sign-in URL, the advanced pair, …) - the bare <div> wrappers carry no
   spacing of their own, which read as cramped. Direct-child selector so
   nested markup (validation messages, help text) is unaffected. */
.sso-config__section > div + div[b-7s1wc4b3w6] {
    margin-block-start: var(--space-5);
}

/* Space between section cards. The form-level flex `gap` can't do this:
   the `.sso-config__form` class is on <EditForm> (a child component), so
   its rendered <form> never receives this page's scoped-CSS attribute and
   the rule silently misses. The <fieldset> sections ARE real markup and
   carry the scope, so set the inter-card spacing on them directly. */
.sso-config__section + .sso-config__section[b-7s1wc4b3w6] {
    margin-block-start: var(--space-8);
}

/* Forced-colors override on the card border + shadow comes from the
   shared .surface-card rule in app.css. The numbered step badge
   (`.step-badge`) and the section legend (`.section-legend` + title /
   hint) are shared utilities in settings-chrome.css - the markup uses
   those class names directly. */

/* Status section is tighter - just one labeled toggle, no second
   field. Reduce padding so the card doesn't feel oversized. */
.sso-config__section--toggle[b-7s1wc4b3w6] {
    padding-bottom: var(--space-5);
}

/* Advanced options - the header (title + hint) reads like every other
   section card; the collapsible <details> holds only the fields, so its
   disclosure control sits on its own line BELOW the section subtext.
   The summary keeps the native list-item marker as the affordance and
   swaps its Show/Hide caption with the open state (pure CSS - works
   under Static SSR without JS). */
details.sso-config__advanced > summary.sso-config__advanced-summary[b-7s1wc4b3w6] {
    display: list-item;
    cursor: pointer;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

details.sso-config__advanced[open] > summary.sso-config__advanced-summary[b-7s1wc4b3w6] {
    margin-bottom: var(--space-4);
}

details.sso-config__advanced:not([open]) .sso-config__advanced-summary-hide[b-7s1wc4b3w6],
details.sso-config__advanced[open] .sso-config__advanced-summary-show[b-7s1wc4b3w6] {
    display: none;
}

/* The advanced fields sit inside <details>, not directly in the section
   card, so re-apply the section's inter-field breathing room here. */
.sso-config__advanced > div + div[b-7s1wc4b3w6] {
    margin-block-start: var(--space-5);
}

/* Static redirect-URI echo - mono so the value reads exactly as it
   must be pasted into the IdP's app registration; a paragraph (not an
   input) because it is informational, never editable. */
.sso-config__callback-url[b-7s1wc4b3w6] {
    margin: 0;
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-text);
    word-break: break-all;
}

/* Mirrors the shared app.css label rule - the callback URL has no form
   control to attach a <label> to, so a span carries the same look. */
.sso-config__static-label[b-7s1wc4b3w6] {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

/* Stored-secret status line under the client-secret input. Muted when
   a secret is stored; warning-toned when missing because sign-in
   cannot complete without one. */
.sso-config__secret-status[b-7s1wc4b3w6] {
    margin: var(--space-2) 0 0;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: var(--line-height-snug, 1.4);
}

.sso-config__secret-status--missing[b-7s1wc4b3w6] {
    color: var(--color-warning, var(--color-text-muted));
}

/* Masked stored-secret echo - mono + a touch of tracking so the
   fingerprint-plus-asterisks run reads as a password hint. */
.sso-config__secret-status--masked[b-7s1wc4b3w6] {
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    letter-spacing: 0.08em;
}

/* The credential blocks' field wrappers sit one level below the section
   card, so the section's own `> div + div` breathing-room rule never
   reaches them - re-apply it here (secret input ↔ expiry date ↔ dev
   secret). */
.sso-config__secret-block > div + div[b-7s1wc4b3w6] {
    margin-block-start: var(--space-5);
}

/* Toggle row. The native <input type="checkbox"> sits inline with
   its label text; the supporting hint paragraph wraps to the next
   line so the assertive label stays visually prominent. */
.sso-config__toggle[b-7s1wc4b3w6] {
    /* Plain block flow - the inline-flex checkbox label sits on its own
       line and the hint paragraph follows beneath via its own top margin
       (no flex column). */
    display: block;
}

.sso-config__checkbox-label[b-7s1wc4b3w6] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: 0;
    cursor: pointer;
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

    /* Checkbox sizing / accent rules have moved to the shared
       `input[type="checkbox"].toggle-switch` rule in app.css; the
       InputCheckbox above now carries that class and renders as a
       sliding switch. Keeping `flex: 0 0 auto` would conflict with the
       toggle-switch's own `flex-shrink: 0`, so nothing local remains. */

.sso-config__toggle-hint[b-7s1wc4b3w6] {
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-snug, 1.4);
}

/* Claim-mappings textarea - JSON content reads better in mono. The
   base input/textarea rule from app.css already applies surface +
   border + radius; only the font family + tabular alignment need
   page-specific override. */
.sso-config__claim-mappings[b-7s1wc4b3w6] {
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    font-size: var(--font-size-sm);
    line-height: 1.5;
    white-space: pre;
    tab-size: 2;
}

/* Action row - flex layout with a gap so Save / Test connection
   sit side-by-side on wide viewports and stack on narrow ones.
   This duplicates the global :has() rule for content-width
   submit-button pairs so the layout works even when the global
   rule's :has() support is degraded. */
.sso-config__actions[b-7s1wc4b3w6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

/* Credential-expiry callout. Renders above the form when the stored
   configuration's active credential (signing certificate or dated
   client secret) expires within 30 days. Warning tone by default,
   danger tone within 7 days / past expiry - same thresholds the daily
   notification sweep applies. Token-driven so HC + dark themes track. */
.sso-config__expiry-callout[b-7s1wc4b3w6] {
    margin-top: var(--space-6);
    /* Bottom margin (not a rule on .sso-config__form) separates the last
       callout from the first section card: the EditForm's rendered <form>
       never carries this page's scoped-CSS attribute, so only the callout
       itself (real markup) can own the gap. Sibling margins collapse, so
       stacked callouts still sit space-8 apart, not 6+8. */
    margin-bottom: var(--space-8);
    padding: var(--space-5) var(--space-6);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border-subtle);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

/* "Manage members" - an anchor that reads as the platform's secondary
   button (the shared button rules key on button[type="submit"], which
   an <a> can never match, so the treatment is mirrored here). */
a.sso-config__members-button[b-7s1wc4b3w6] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 2.75rem;
    /* Breathing room from the guidance paragraph above - the wrapping
       .sso-config__expiry-callout-message zeroes its own margins. */
    margin-top: var(--space-3);
    padding: 0 var(--space-5);
    background: transparent;
    color: var(--color-chrome-surface);
    font-weight: var(--font-weight-semibold);
    text-decoration: none;
    border: 1px solid var(--color-chrome-surface);
    border-radius: var(--radius-md);
    box-sizing: border-box;
    cursor: pointer;
}

    a.sso-config__members-button:hover[b-7s1wc4b3w6] {
        background: var(--color-chrome-surface);
        color: var(--color-chrome-on-surface);
    }

    a.sso-config__members-button:focus-visible[b-7s1wc4b3w6] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 3px;
    }

.sso-config__expiry-callout--warning[b-7s1wc4b3w6] {
    border-color: var(--color-warning);
    background: var(--color-warning-surface, var(--color-surface));
}

.sso-config__expiry-callout--danger[b-7s1wc4b3w6] {
    border-color: var(--color-danger);
    background: var(--color-danger-subtle, var(--color-surface));
}

@media (forced-colors: active) {
    .sso-config__expiry-callout[b-7s1wc4b3w6],
    .sso-config__expiry-callout--warning[b-7s1wc4b3w6],
    .sso-config__expiry-callout--danger[b-7s1wc4b3w6] {
        border: 1px solid CanvasText;
        background: Canvas;
        box-shadow: none;
    }
}

.sso-config__expiry-callout-heading[b-7s1wc4b3w6] {
    margin: 0 0 var(--space-2);
    /* Match the page's dominant heading treatment (.section-legend__title
       in settings-chrome.css): body face + lg size. Without the override
       the global h1-h3 rule set the callout headings in the display face
       at md size - the one heading on the page that didn't match. */
    font-family: var(--font-sans);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    letter-spacing: var(--letter-spacing-tight, -0.01em);
    color: var(--color-text);
}

.sso-config__expiry-callout-message[b-7s1wc4b3w6] {
    margin: 0;
    color: var(--color-text);
    line-height: var(--line-height-snug, 1.4);
}

/* Validation-result panel. Renders below the form when the user
   clicks "Test connection". Two state variants - green for success,
   red for failure - so the outcome is unmistakable at a glance.
   Token-driven so HC + dark themes track. */
.sso-config__validation[b-7s1wc4b3w6] {
    margin-top: var(--space-6);
    padding: var(--space-5) var(--space-6);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border-subtle);
    background: var(--color-surface);
    box-shadow: var(--shadow-sm);
}

.sso-config__validation--ok[b-7s1wc4b3w6] {
    border-color: var(--color-success);
    background: var(--color-success-subtle, var(--color-surface));
}

.sso-config__validation--err[b-7s1wc4b3w6] {
    border-color: var(--color-danger);
    background: var(--color-danger-subtle, var(--color-surface));
}

@media (forced-colors: active) {
    .sso-config__validation[b-7s1wc4b3w6],
    .sso-config__validation--ok[b-7s1wc4b3w6],
    .sso-config__validation--err[b-7s1wc4b3w6] {
        border: 1px solid CanvasText;
        background: Canvas;
        box-shadow: none;
    }
}

.sso-config__validation-heading[b-7s1wc4b3w6] {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.sso-config__validation-summary[b-7s1wc4b3w6] {
    margin: 0;
    color: var(--color-text);
    line-height: var(--line-height-snug, 1.4);
}

.sso-config__validation-details[b-7s1wc4b3w6] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-2) var(--space-4);
    margin: var(--space-4) 0 0;
    font-size: var(--font-size-sm);
}

    .sso-config__validation-details dt[b-7s1wc4b3w6] {
        color: var(--color-text-muted);
        font-weight: var(--font-weight-medium);
    }

    .sso-config__validation-details dd[b-7s1wc4b3w6] {
        margin: 0;
        color: var(--color-text);
        font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
        word-break: break-all;
    }

/* Canonical sm floor (599px) - see tokens.css "Responsive breakpoints"
   for the rationale. The dt/dd grid collapses to a single column on
   phones because the labels are already noun-heavy and pairing them
   side-by-side with the values produces a cramped two-column layout. */
@media (max-width: 599px) {
    .sso-config__validation-details[b-7s1wc4b3w6] {
        grid-template-columns: 1fr;
        gap: 0 0;
    }

        .sso-config__validation-details dt[b-7s1wc4b3w6] {
            margin-top: var(--space-3);
        }
}

/* ── Token-endpoint client auth method ─────────────────────────────
   Single sliding toggle inside the credentials card: checked =
   certificate (private_key_jwt), unchecked = client secret. Static SSR
   has no re-render on input change, so the credential block matching
   the toggle state is revealed with :has() on the credentials fieldset
   (real markup, so it carries the scope attribute - the EditForm's
   rendered <form> does not). Browsers without :has() degrade to
   showing BOTH blocks, which stays fully functional. */
.sso-config__method-choice[b-7s1wc4b3w6] {
    margin: var(--space-4) 0 0;
}

.sso-config__method-legend[b-7s1wc4b3w6] {
    margin: 0 0 var(--space-2);
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

.sso-config__section--credentials:has(#sso-auth-method:not(:checked)) .sso-config__cert-block[b-7s1wc4b3w6] {
    display: none;
}

.sso-config__section--credentials:has(#sso-auth-method:checked) .sso-config__secret-block[b-7s1wc4b3w6] {
    display: none;
}

/* ── SSO signing-certificate block ── */

/* Framed credential zone - same treatment as the Connections page's
   certificate status card (.cert-status: surface-card chrome with the
   tighter space-4 padding) so the certificate display and its
   generate/download/activate controls read as one bounded surface. */
.sso-config__cert-card[b-7s1wc4b3w6] {
    margin-top: var(--space-4);
    padding: var(--space-4);
}

    /* The card's own padding provides the top spacing; the first child
       must not stack its flow margin on top of it. */
    .sso-config__cert-card > :first-child[b-7s1wc4b3w6] {
        margin-top: 0;
    }

.sso-config__cert-intro[b-7s1wc4b3w6],
.sso-config__cert-hint[b-7s1wc4b3w6] {
    margin: var(--space-3) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-snug, 1.4);
}

.sso-config__cert-generated[b-7s1wc4b3w6] {
    margin: var(--space-3) 0 0;
    color: var(--color-text);
    line-height: var(--line-height-snug, 1.4);
}

.sso-config__cert-details[b-7s1wc4b3w6] {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: var(--space-2) var(--space-4);
    margin: var(--space-4) 0 0;
    font-size: var(--font-size-sm);
}

    .sso-config__cert-details dt[b-7s1wc4b3w6] {
        color: var(--color-text-muted);
        font-weight: var(--font-weight-medium);
    }

    .sso-config__cert-details dd[b-7s1wc4b3w6] {
        margin: 0;
        color: var(--color-text);
        word-break: break-all;
    }

.sso-config__cert-expiry[b-7s1wc4b3w6] {
    margin-left: var(--space-3);
    color: var(--color-text-muted);
}

.sso-config__cert-download[b-7s1wc4b3w6] {
    margin: var(--space-3) 0 0;
}

.sso-config__cert-actions[b-7s1wc4b3w6] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-4);
}

@media (max-width: 599px) {
    .sso-config__cert-details[b-7s1wc4b3w6] {
        grid-template-columns: 1fr;
        gap: 0 0;
    }

        .sso-config__cert-details dt[b-7s1wc4b3w6] {
            margin-top: var(--space-3);
        }
}

/* The danger zone (`.danger-zone` + heading) and the forbidden notice
   (`.forbidden-notice`) are shared utilities in settings-chrome.css -
   the markup uses those class names directly. */
/* /Components/Pages/Tenant/TenantLanding.razor.rz.scp.css */
/*
 * /tenant/{Slug} - tenant landing page. Hero with role + status
 * tiles, then a "Quick actions" grid of clickable cards. The hero
 * itself is provided by <PageHeader>; this file styles only the
 * page-scoped section heading + action grid + any not-found chrome.
 */

.tenant-landing__overview[b-mjy5ba2etz] {
    margin-top: var(--space-6);
}

.tenant-landing__quick-actions[b-mjy5ba2etz] {
    margin-top: var(--space-6);
}

.tenant-landing__section-heading[b-mjy5ba2etz] {
    margin: 0 0 var(--space-4);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.tenant-landing__action-grid[b-mjy5ba2etz] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
    gap: var(--space-3);
}
/* /Components/Pages/Tenant/TenantSuspended.razor.rz.scp.css */
/*
    TenantSuspended - the notice a member lands on when their tenant is under a
    commercial hold. Tokens only. No live indicator here (unlike
    TenantUpgrading): nothing is in progress, so a spinner would promise motion
    that is not happening.
*/

.tenant-suspended[b-4r7hbad8vy] {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg, 12px);
    background: var(--color-surface-raised);
}

.tenant-suspended__heading[b-4r7hbad8vy] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

/* The operator's message is free text supplied by a human, so it is set
   apart from our own copy - the reader can tell which words are ours. */
.tenant-suspended__message[b-4r7hbad8vy] {
    margin: 0;
    padding-left: var(--space-4);
    border-left: 3px solid var(--color-warning);
    color: var(--color-text);
    line-height: var(--line-height-relaxed);
}

.tenant-suspended__body[b-4r7hbad8vy] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-relaxed);
}

.tenant-suspended__actions[b-4r7hbad8vy] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-4);
    margin: 0;
    padding: 0;
    list-style: none;
}
/* /Components/Pages/Tenant/TenantUpgrading.razor.rz.scp.css */
/*
    TenantUpgrading - the transient "tenant is upgrading" page a tenant is
    paused on while its database catches up to the app's schema. Tokens only;
    the live indicator is the BrandLoader honeycomb ("Scan" sweep), sized here
    via ::deep - its animation and per-tenant brand colour come from the global
    .brand-loader rules in app.css.
*/

.tenant-upgrading[b-fk86619fdf] {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.tenant-upgrading__live[b-fk86619fdf] {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    padding: var(--space-5);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg, 12px);
    background: var(--color-surface-raised);
}

.tenant-upgrading__live-text[b-fk86619fdf] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.tenant-upgrading__live-heading[b-fk86619fdf] {
    margin: 0;
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.tenant-upgrading__hint[b-fk86619fdf] {
    margin: 0;
    color: var(--color-text-muted);
    line-height: var(--line-height-relaxed);
}

.tenant-upgrading__back[b-fk86619fdf] {
    margin: 0;
}

/* ::deep - the honeycomb <svg> is rendered by the child <BrandLoader>
   component; this page-scoped rule needs ::deep to reach it. Sizing only:
   the "Scan" animation + brand colour (and its gentle reduced-motion sweep)
   come from the global .brand-loader rules in app.css. */
.tenant-upgrading__live[b-fk86619fdf]  .tenant-upgrading__loader {
    flex: 0 0 auto;
    height: 2.25rem;
}
/* /Components/Pages/Tenant/Usage/UsagePanel.razor.rz.scp.css */
.usage-panel > * + *[b-02spsmhxyp] {
    margin-block-start: var(--space-6);
}

.usage-panel__heading[b-02spsmhxyp] {
    margin: 0 0 var(--space-3);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.usage-panel__error[b-02spsmhxyp] {
    margin: 0;
    color: var(--color-danger);
    font-size: var(--font-size-sm);
}

/* Credits hero - one wide meter (or the Unlimited word), then the copy. */
.usage-panel__credits-meter[b-02spsmhxyp] {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-4);
}

.usage-panel__credits-value[b-02spsmhxyp] {
    margin: 0;
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
}

.usage-panel__credits-unlimited[b-02spsmhxyp] {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.usage-panel__credits-used[b-02spsmhxyp],
.usage-panel__credits-resets[b-02spsmhxyp] {
    margin: var(--space-2) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* Per-feature list - no bullets; each row reads label / bar / count. */
.usage-panel__list[b-02spsmhxyp] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

.usage-panel__row[b-02spsmhxyp] {
    display: grid;
    grid-template-columns: minmax(7rem, 12rem) 1fr auto;
    align-items: center;
    gap: var(--space-4);
}

.usage-panel__label[b-02spsmhxyp] {
    font-weight: var(--font-weight-medium);
    color: var(--color-text);
}

.usage-panel__no-cap[b-02spsmhxyp] {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* Reset the native progress chrome and paint it with brand tokens so the
   track + fill match the rest of the app in both themes. */
.usage-panel__bar[b-02spsmhxyp] {
    inline-size: 100%;
    block-size: 0.5rem;
    appearance: none;
    -webkit-appearance: none;
    border: none;
    border-radius: var(--radius-full);
    background-color: var(--color-surface-sunken);
    overflow: hidden;
}

.usage-panel__bar[b-02spsmhxyp]::-webkit-progress-bar {
    background-color: var(--color-surface-sunken);
    border-radius: var(--radius-full);
}

.usage-panel__bar[b-02spsmhxyp]::-webkit-progress-value {
    background-color: var(--color-brand);
    border-radius: var(--radius-full);
}

.usage-panel__bar[b-02spsmhxyp]::-moz-progress-bar {
    background-color: var(--color-brand);
    border-radius: var(--radius-full);
}

.usage-panel__count[b-02spsmhxyp] {
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.usage-panel__intro[b-02spsmhxyp] {
    margin: 0 0 var(--space-3);
    color: var(--color-text-muted);
}

/* Ledger cells render through ListView's RenderFragment pipeline, so they never carry this
   component's scope attribute - ::deep from the scope-carrying .usage-panel__ledger-list
   wrapper is REQUIRED to reach them (the Support.razor.css subject-link convention). */
.usage-panel__ledger-list[b-02spsmhxyp]  .usage-panel__when {
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--color-text-muted);
}

.usage-panel__ledger-list[b-02spsmhxyp]  .usage-panel__kind {
    display: inline-block;
    margin-inline-end: var(--space-2);
    color: var(--color-text-muted);
}

/* Applied by ListView to the credits th + td via Header/CellCssClass, so the numeric column
   keeps its right alignment under the shared table chrome. */
.usage-panel__ledger-list[b-02spsmhxyp]  .usage-panel__units-col {
    text-align: end;
    font-variant-numeric: tabular-nums;
}

/* Run ids read as identifiers, not prose - monospace, slightly muted, never wrapping
   mid-guid. */
.usage-panel__ledger-list[b-02spsmhxyp]  .usage-panel__job-id {
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

.usage-panel__truncated[b-02spsmhxyp] {
    margin: var(--space-3) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* Request form - separated from the data blocks by a hairline. */
.usage-panel__request[b-02spsmhxyp] {
    padding-block-start: var(--space-6);
    border-block-start: 1px solid var(--color-border-subtle);
}

.usage-panel__reason-label[b-02spsmhxyp] {
    display: block;
    margin-block-end: var(--space-2);
    font-weight: var(--font-weight-medium);
}

.usage-panel__reason[b-02spsmhxyp] {
    display: block;
    inline-size: 100%;
    max-inline-size: 36rem;
    padding: var(--space-2) var(--space-3);
    font: inherit;
    color: var(--color-text);
    background-color: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    resize: vertical;
    box-sizing: border-box;
}

.usage-panel__reason:focus-visible[b-02spsmhxyp] {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
    border-color: var(--color-border-strong);
}

.usage-panel__request button:disabled[b-02spsmhxyp] {
    opacity: 0.6;
    cursor: not-allowed;
}

.usage-panel__status[b-02spsmhxyp] {
    margin: var(--space-3) 0 0;
    font-size: var(--font-size-sm);
}

.usage-panel__status--ok[b-02spsmhxyp] {
    color: var(--color-success);
}

.usage-panel__status--error[b-02spsmhxyp] {
    color: var(--color-danger);
}

/* Narrow viewports: label + count on one line, the bar full-width below. */
@media (max-width: 599px) {
    .usage-panel__row[b-02spsmhxyp] {
        grid-template-columns: 1fr auto;
        column-gap: var(--space-3);
    }

    .usage-panel__label[b-02spsmhxyp] {
        grid-column: 1;
        grid-row: 1;
    }

    .usage-panel__no-cap[b-02spsmhxyp] {
        grid-column: 1;
        grid-row: 2;
    }

    .usage-panel__count[b-02spsmhxyp] {
        grid-column: 2;
        grid-row: 1;
        text-align: end;
    }

    .usage-panel__bar[b-02spsmhxyp] {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    .usage-panel__credits-meter[b-02spsmhxyp] {
        grid-template-columns: 1fr;
    }
}
/* /Components/Pages/Tenants/CreateTenant.razor.rz.scp.css */
/*
 * /tenants/create - self-service tenant-creation form. PageHeader
 * drives the hero; this file styles the form-card section + actions.
 * Inputs / labels / submit-button styling inherits from the shell-
 * wide rules in app.css.
 */

.create-tenant__form[b-mt36143181] {
    max-width: 36rem;
    margin-top: var(--space-4);
}

.create-tenant__section[b-mt36143181] {
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-5) var(--space-6);
    margin: 0;
    box-shadow: var(--shadow-sm);
}

.create-tenant__legend[b-mt36143181] {
    display: block;
    width: 100%;
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
    border-bottom: 1px solid var(--color-border-subtle);
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
    letter-spacing: var(--letter-spacing-tight);
}

.create-tenant__actions[b-mt36143181] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    margin-top: var(--space-2);
}

@media (forced-colors: active) {
    .create-tenant__section[b-mt36143181] {
        border: 1px solid CanvasText;
        box-shadow: none;
    }
}

@media (max-width: 599px) {
    .create-tenant__section[b-mt36143181] {
        padding: var(--space-4);
    }
}
/* /Components/Pages/Tenants/TenantCreationStatus.razor.rz.scp.css */
/*
 * /tenants/create/{tenantId}/status - server-side polling status page
 * for the tenant-provisioning flow. PageHeader drives the hero;
 * this file styles the milestone strip, detail callout, and polling
 * controls.
 *
 * Token-driven; light / dark / Windows High Contrast all stay legible.
 */

.tenant-status__intro[b-yqwy03jqed] {
    margin: 0 0 var(--space-5);
    color: var(--color-text-muted);
    line-height: var(--line-height-relaxed);
    max-width: 60ch;
}

/* Milestone strip - three pill rows, connected by a hairline. The
   connector is rendered behind the markers via ::before so it stays
   off-axis on narrow viewports where the pills wrap. */
.tenant-status__milestones[b-yqwy03jqed] {
    list-style: none;
    padding: 0;
    margin: 0 0 var(--space-5);
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

.tenant-status__milestone[b-yqwy03jqed] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-full);
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
}

.tenant-status__milestone-marker[b-yqwy03jqed] {
    display: inline-block;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: var(--radius-full);
    background: var(--color-border);
    flex: 0 0 auto;
}

/* "Done" - brand-tinted background, white-on-brand marker. */
.tenant-status__milestone--done[b-yqwy03jqed] {
    background: var(--color-brand-subtle);
    color: var(--color-brand-hover);
    border-color: color-mix(in srgb, var(--color-brand) 35%, transparent);
}

    .tenant-status__milestone--done .tenant-status__milestone-marker[b-yqwy03jqed] {
        background: var(--color-brand);
    }

/* "Current" - same brand tint with a subtle pulse. */
.tenant-status__milestone--current[b-yqwy03jqed] {
    background: var(--color-brand-subtle);
    color: var(--color-brand-hover);
    border-color: var(--color-brand);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-brand) 12%, transparent);
}

    .tenant-status__milestone--current .tenant-status__milestone-marker[b-yqwy03jqed] {
        background: var(--color-brand);
        animation: tenant-status-pulse-b-yqwy03jqed 1.4s infinite ease-in-out;
    }

@keyframes tenant-status-pulse-b-yqwy03jqed {
    0%, 100% {
        opacity: 1;
        transform: scale(1);
    }
    50% {
        opacity: 0.45;
        transform: scale(1.4);
    }
}

@media (prefers-reduced-motion: reduce) {
    .tenant-status__milestone--current .tenant-status__milestone-marker[b-yqwy03jqed] {
        animation: none;
    }
}

/* Detail callout - outlined card; tints by stage. */
.tenant-status__detail[b-yqwy03jqed] {
    padding: var(--space-4) var(--space-5);
    border-radius: var(--radius-lg);
    border: 1px solid var(--color-border-subtle);
    background: var(--color-surface);
    color: var(--color-text);
    line-height: var(--line-height-relaxed);
}

.tenant-status__detail--ready[b-yqwy03jqed] {
    border-color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 8%, var(--color-surface));
    color: var(--color-success);
}

.tenant-status__detail--timedout[b-yqwy03jqed] {
    border-color: var(--color-warning);
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
}

.tenant-status__elapsed[b-yqwy03jqed] {
    margin-left: var(--space-2);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

.tenant-status__polling-hint[b-yqwy03jqed] {
    margin: var(--space-3) 0 var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

.tenant-status__pause-form[b-yqwy03jqed] {
    margin: 0;
}

@media (forced-colors: active) {
    .tenant-status__milestone[b-yqwy03jqed],
    .tenant-status__detail[b-yqwy03jqed] {
        border: 1px solid CanvasText;
        background: Canvas;
        color: CanvasText;
    }

    .tenant-status__milestone--current[b-yqwy03jqed],
    .tenant-status__milestone--done[b-yqwy03jqed] {
        border: 2px solid CanvasText;
    }
}
/* /Components/Pages/Tenants/Tenants.razor.rz.scp.css */
/* "Your tenants" landing - scoped CSS. Hero (PageHeader + StatCard tiles)
   and the pending-invitations callout reuse global primitives; this sheet
   carries the picker grid, the rich per-card layout (avatar header +
   role-chip footer), and the colored monogram avatars. */

/* Responsive card grid - same recipe as the Dashboard's quick-actions
   layout so the two top-level signed-in landings share one visual
   language. `auto-fit` collapses to one column on narrow viewports
   without a per-breakpoint override. */
.tenants-grid[b-xuk8bvx2a1] {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(20rem, 22rem));
    gap: var(--space-4);
    margin-top: var(--space-6);
    /* Pack cards from the start so a sparse final row left-aligns
       instead of inflating to fill the row width. */
    justify-content: start;
}

/* The EditForm wrapper is display:contents so its <button> becomes the
   actual grid cell; the antiforgery + TenantId hidden inputs render
   nothing. */
.tenants-grid__form[b-xuk8bvx2a1] {
    display: contents;
}

/* One tenant card. `.surface-card` defines the canonical card chrome
   in app.css, but `.app-shell__main button[type="submit"]` (the page-CTA
   skin) has higher specificity and would otherwise paint each selectable
   card chrome-navy with white text. The scoped rule below explicitly
   re-asserts every property the global CTA skin sets - background,
   border, border-radius, box-shadow, the top margin it adds for spacing
   between stacked submits, etc. - so the card surface stays white and
   the head/foot layout breathes. `position: relative` anchors the
   absolute-positioned Current pin in the top-right corner. */
.app-shell__main .tenants-grid .tenants-card[b-xuk8bvx2a1] {
    display: flex;
    flex-direction: column;
    /* Reset align-items/justify-content from the global submit-button
       skin. Default centered both axes; for the column card we want
       children to span the full width and stack from the top so the
       head/foot rows left-align with the card padding. */
    align-items: stretch;
    justify-content: flex-start;
    gap: var(--space-4);
    position: relative;
    width: 100%;
    box-sizing: border-box;
    padding: var(--space-5);
    margin-top: 0;
    min-height: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    font: inherit;
    font-weight: var(--font-weight-regular);
    text-align: left;
    color: var(--color-text);
}

.app-shell__main .tenants-grid button.tenants-card--selectable[b-xuk8bvx2a1] {
    appearance: none;
    cursor: pointer;
}

/* Hover: the .surface-card--interactive lift (translateY + shadow-md)
   already fires. The overrides here suppress the global submit skin's
   `filter: brightness(1.15)` brightness boost and its white text colour
   so the hovered card still reads as a card, not a brightened CTA. */
.app-shell__main .tenants-grid button.tenants-card--selectable:hover[b-xuk8bvx2a1] {
    color: var(--color-text);
    filter: none;
    border-color: var(--color-border);
    background: var(--color-surface);
}

.app-shell__main .tenants-grid button.tenants-card--selectable:focus-visible[b-xuk8bvx2a1] {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
}

.app-shell__main .tenants-grid .tenants-card--provisioning[b-xuk8bvx2a1] {
    cursor: default;
    opacity: 0.75;
}

/* Suspended tenants read as dimmed like provisioning ones, but keep the
   pointer cursor: they ARE still selectable, and selecting one is how the
   member reaches the notice explaining the hold. */
.app-shell__main .tenants-grid .tenants-card--suspended[b-xuk8bvx2a1] {
    opacity: 0.75;
}

/* The current (active) tenant gets a brand left accent + subtle tint
   so the user's selection stands out at a glance, even when the card
   isn't being hovered. */
.app-shell__main .tenants-grid .tenants-card--active[b-xuk8bvx2a1],
.app-shell__main .tenants-grid button.tenants-card--active:hover[b-xuk8bvx2a1] {
    background: var(--color-brand-surface);
    color: var(--color-text);
    box-shadow: var(--shadow-sm), inset 3px 0 0 0 var(--color-brand);
}

/* "Current" pill anchored to the top-right corner so the active card
   reads at a glance during fast scanning without competing with the
   role chip in the footer. */
.tenants-card__pin[b-xuk8bvx2a1] {
    position: absolute;
    top: var(--space-3);
    inset-inline-end: var(--space-3);
}

/* Head row - avatar + identity stack. */
.tenants-card__head[b-xuk8bvx2a1] {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    min-width: 0;
}

.tenants-card__identity[b-xuk8bvx2a1] {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.tenants-card__name[b-xuk8bvx2a1] {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    letter-spacing: var(--letter-spacing-tight, -0.01em);
    color: var(--color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: break-word;
}

/* Slug rendered as a monospace eyebrow under the name - a stable,
   technical identifier that distinguishes two tenants with the same
   display name. Truncates with ellipsis so long slugs don't reflow the
   card. */
.tenants-card__slug[b-xuk8bvx2a1] {
    font-family: var(--font-mono);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Foot row - role chip on the left, chevron on the right. margin-top:
   auto pushes the foot to the card's bottom edge so a varying name
   length doesn't make the footer hop between rows. */
.tenants-card__foot[b-xuk8bvx2a1] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-top: auto;
}

/* Monogram avatar - a rounded tile with the tenant initials. The colour
   is deterministic per tenant (AvatarColorIndex) so each gets a
   stable, distinct identity; the colours are decorative (the tenant
   name is the announced label). */
.tenants-card__avatar[b-xuk8bvx2a1] {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border-radius: var(--radius-lg);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-bold, 700);
    letter-spacing: 0.02em;
    background: color-mix(in srgb, var(--avatar-hue, var(--color-brand)) 16%, var(--color-surface));
    color: var(--avatar-hue, var(--color-brand));
}

.tenants-card__avatar--c0[b-xuk8bvx2a1] { --avatar-hue: #6366f1; }  /* indigo */
.tenants-card__avatar--c1[b-xuk8bvx2a1] { --avatar-hue: #0d9488; }  /* teal   */
.tenants-card__avatar--c2[b-xuk8bvx2a1] { --avatar-hue: #d97706; }  /* amber  */
.tenants-card__avatar--c3[b-xuk8bvx2a1] { --avatar-hue: #db2777; }  /* pink   */
.tenants-card__avatar--c4[b-xuk8bvx2a1] { --avatar-hue: #0284c7; }  /* sky    */

.tenants-card__avatar--muted[b-xuk8bvx2a1] {
    background: var(--color-surface-sunken, var(--color-border-subtle));
    color: var(--color-text-muted);
}

.tenants-card__chevron[b-xuk8bvx2a1] {
    display: inline-flex;
    flex: 0 0 auto;
    color: var(--color-text-muted);
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

button.tenants-card--selectable:hover .tenants-card__chevron[b-xuk8bvx2a1] {
    transform: translateX(2px);
    color: var(--color-brand);
}

@media (prefers-reduced-motion: reduce) {
    button.tenants-card--selectable:hover .tenants-card__chevron[b-xuk8bvx2a1] {
        transform: none;
    }
}

@media (forced-colors: active) {
    /* Base CanvasText border + shadow:none come from .surface-card. */
    .tenants-card--active[b-xuk8bvx2a1] {
        outline: 2px solid Highlight;
        outline-offset: -2px;
    }
}

/* Empty state - the create-tenant ActionCard stacked over the
   wait-for-invite primer. */
.tenants-empty[b-xuk8bvx2a1] {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    margin-top: var(--space-5);
    max-width: 40rem;
}

.tenants-empty__wait[b-xuk8bvx2a1] {
    padding: var(--space-5);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-xl);
    background: var(--color-surface);
}

.tenants-empty__wait-heading[b-xuk8bvx2a1] {
    margin: 0 0 var(--space-2);
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.tenants-empty__wait p[b-xuk8bvx2a1] {
    margin: 0;
    color: var(--color-text-muted);
}

@media (forced-colors: active) {
    .tenants-empty__wait[b-xuk8bvx2a1] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Ui/Breadcrumbs/BreadcrumbTrail.razor.rz.scp.css */
/*
    BreadcrumbTrail - token-driven, theme-aware. The visual separator
    between items renders via `::before` rather than a duplicated
    character node so AT users only hear the link/label text.

    The trailing current-page segment is shown (conventional breadcrumb
    pattern: the trail ends on the current page) as muted non-link text
    with aria-current="page".
*/

.breadcrumbs[b-z7e0aeshxi] {
    margin: var(--space-3) 0;
    /* Smaller + muted - the trail reads as a quiet contextual hint
       above the H1, not a competing UI element. */
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
}

.breadcrumbs__list[b-z7e0aeshxi] {
    list-style: none;
    padding: 0;
    /* Pull the list left by the same amount as the first item's inline
       padding so the first crumb's visible text aligns with the page
       heading below. Without this the breadcrumb appears slightly
       indented (by --space-1 = 4px) relative to the main content. */
    margin: 0 0 0 calc(-1 * var(--space-1));
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
}

.breadcrumbs__item[b-z7e0aeshxi] {
    display: flex;
    align-items: center;
}

.breadcrumbs__item + .breadcrumbs__item[b-z7e0aeshxi]::before {
    content: "/";
    margin: 0 var(--space-2);
    color: var(--color-text-muted);
    aria-hidden: true;
}

.breadcrumbs__link[b-z7e0aeshxi] {
    /* Parent segments - muted + regular weight so the eye reads them
       as subordinate to the page H1 below. The slash separator
       carries the same muted tone. */
    color: var(--color-text-muted);
    font-weight: var(--font-weight-regular);
    text-decoration: none;
    border-radius: var(--radius-sm);
    /* WCAG 2.5.8 - keep breadcrumb hit areas at least 24px tall. */
    min-height: var(--target-size-minimum);
    display: inline-flex;
    align-items: center;
    padding: 0 var(--space-1);
}

    .breadcrumbs__link:hover[b-z7e0aeshxi] {
        color: var(--color-text);
        text-decoration: underline;
    }

    .breadcrumbs__link:focus-visible[b-z7e0aeshxi] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Intermediate label-only segment - same visual weight as a parent
   link, but non-interactive (no hover, no underline, no aria-current).
   Used for the SectionLabelKey segments emitted by BreadcrumbResolver. */
.breadcrumbs__section[b-z7e0aeshxi] {
    color: var(--color-text-muted);
    font-weight: var(--font-weight-regular);
    padding: 0 var(--space-1);
    display: inline-flex;
    align-items: center;
}

/* Current page - the trail's last segment, shown as slightly-emphasised
   non-link text with aria-current="page". Picks up the "/" separator from
   the shared item rule like any other segment. */
.breadcrumbs__current[b-z7e0aeshxi] {
    color: var(--color-text);
    font-weight: var(--font-weight-medium);
    padding: 0 var(--space-1);
    display: inline-flex;
    align-items: center;
}

/* Collapse the nav margin only when the trail has no segments at all
   (AutoBreadcrumbs renders nothing for an unmatched route, so this is a
   belt-and-braces guard). With the current-page leaf now visible there is
   always at least one segment on a matched route. */
.breadcrumbs:not(:has(.breadcrumbs__link, .breadcrumbs__section, .breadcrumbs__current))[b-z7e0aeshxi] {
    margin: 0;
}
/* /Components/Ui/Cards/ActionCard.razor.rz.scp.css */
/*
    ActionCard - clickable card. Renders as an <a> so it stays a real
    navigation target without JS. Hover lifts; focus shows the shared
    ring; reduced-motion flattens both. Forced-colors gets a thick
    border in place of the shadow.
*/

/* Base chrome + hover lift + transitions come from
   `.surface-card.surface-card--interactive` in app.css. ActionCard
   adds its own flex layout, anchor-link styling, brand-coloured
   hover border, focus ring, and pressed state. */
.action-card[b-lk89bp5zh9] {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    min-height: var(--target-size-minimum);
    color: var(--color-text);
    text-decoration: none;
}

    .action-card:hover[b-lk89bp5zh9] {
        border-color: var(--color-brand);
        color: var(--color-text);
        text-decoration: none;
    }

    .action-card:focus-visible[b-lk89bp5zh9] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        text-decoration: none;
    }

    .action-card:active[b-lk89bp5zh9] {
        transform: translateY(0);
        box-shadow: var(--shadow-sm);
    }

.action-card__icon[b-lk89bp5zh9] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 2.5rem;
    width: 2.5rem;
    height: 2.5rem;
    color: var(--color-brand);
    background: var(--color-brand-subtle);
    border-radius: var(--radius-md);
}

    .action-card__icon :is(svg)[b-lk89bp5zh9] {
        width: 1.25rem;
        height: 1.25rem;
    }

.action-card__body[b-lk89bp5zh9] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    flex: 1 1 auto;
}

.action-card__title[b-lk89bp5zh9] {
    font-size: var(--font-size-md);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text);
}

.action-card__description[b-lk89bp5zh9] {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

.action-card__chevron[b-lk89bp5zh9] {
    flex: 0 0 auto;
    color: var(--color-text-muted);
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard);
}

.action-card:hover .action-card__chevron[b-lk89bp5zh9],
.action-card:focus-visible .action-card__chevron[b-lk89bp5zh9] {
    color: var(--color-brand);
    transform: translateX(2px);
}

@media (forced-colors: active) {
    /* .surface-card handles the base 1px CanvasText border + shadow none. */
    .action-card:hover[b-lk89bp5zh9],
    .action-card:focus-visible[b-lk89bp5zh9] {
        border: 2px solid CanvasText;
    }

    .action-card__icon[b-lk89bp5zh9] {
        background: Canvas;
        border: 1px solid CanvasText;
    }
}

@media (prefers-reduced-motion: reduce) {
    /* .surface-card--interactive already flat-stops its own transitions
       under reduced-motion; the chevron animation is page-specific so
       keep its override here. */
    .action-card__chevron[b-lk89bp5zh9] {
        transition: none;
    }
}
/* /Components/Ui/Cards/PrerequisitesCard.razor.rz.scp.css */
/* Prerequisites card - structured connection / Graph-permission /
   secondary-platform-permission / licensing requirements rendered as a
   brand-tinted card grid. Probe-driven tiles carry a granted/missing ✓/✗ glyph;
   the secondary-platform tiles are neutral (no glyph). Shared by the report,
   action, and benchmark control "Prerequisites" tabs (moved here from
   reports.css's report-detail__req-*). */

.prereqs-card__grid[b-8m5oez9xkm] {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    gap: var(--space-3);
}

.prereqs-card__item[b-8m5oez9xkm] {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
    border: 1px solid color-mix(in srgb, var(--color-brand) 22%, transparent);
    border-radius: var(--radius-lg);
    background: color-mix(in srgb, var(--color-brand) 7%, var(--color-surface));
}

.prereqs-card__icon[b-8m5oez9xkm] {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: var(--radius-md);
    background: var(--color-brand);
    color: var(--color-text-on-accent, #fff);
}

.prereqs-card__body[b-8m5oez9xkm] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    min-width: 0;
}

.prereqs-card__label[b-8m5oez9xkm] {
    font-size: var(--font-size-xs, 0.75rem);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
}

.prereqs-card__badges[b-8m5oez9xkm] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.prereqs-card__badge[b-8m5oez9xkm] {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm, 6px);
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    font-size: var(--font-size-sm);
    color: var(--color-text);
    /* Without these the badge sizes to its content and a long label
       (e.g. "RoleManagement.Read.Directory") pushes the badge past
       the card's right edge on narrow viewports - the user sees text
       hanging outside the white box. Cap at the parent's width and
       let long words break instead of overflowing. */
    max-width: 100%;
    overflow-wrap: anywhere;
}

    /* Flex children default to `min-width: auto`, which equals their
       content's intrinsic size and blocks the parent badge's text from
       wrapping. Setting it to 0 lets the per-permission text node
       inside the badge shrink and break per `overflow-wrap: anywhere`
       above; the fixed-size glyph (`.prereqs-card__perm-glyph` has an
       explicit width) is unaffected. */
    .prereqs-card__badge > span[b-8m5oez9xkm] {
        min-width: 0;
    }

.prereqs-card__perm[b-8m5oez9xkm] {
    gap: var(--space-2);
}

.prereqs-card__perm-glyph[b-8m5oez9xkm] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* `flex: none` locks width/height so a long permission label
       (e.g. RoleManagement.Read.Directory) can't squeeze the glyph
       smaller than its sibling ✓ glyphs on shorter labels - without
       it the default `flex-shrink: 1` treats the 1.1rem dimensions
       as flex-basis and the circle visibly shrinks. */
    flex: none;
    width: 1.1rem;
    height: 1.1rem;
    border-radius: 50%;
    font-size: var(--font-size-xs, 0.75rem);
    line-height: 1;
}

.prereqs-card__perm--ok .prereqs-card__perm-glyph[b-8m5oez9xkm] {
    color: var(--color-success);
    background: color-mix(in srgb, var(--color-success) 15%, transparent);
}

.prereqs-card__perm--missing .prereqs-card__perm-glyph[b-8m5oez9xkm] {
    color: var(--color-danger);
    background: color-mix(in srgb, var(--color-danger) 15%, transparent);
}

.prereqs-card__perm--missing[b-8m5oez9xkm] {
    border-color: color-mix(in srgb, var(--color-danger) 40%, var(--color-border-subtle));
}

/* "Connection not ready" hint above the grid (mirrors the report Run-gate note). */
.prereqs-card__hint[b-8m5oez9xkm] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

@media (forced-colors: active) {
    .prereqs-card__item[b-8m5oez9xkm],
    .prereqs-card__badge[b-8m5oez9xkm] {
        border: 1px solid CanvasText;
    }
}
/* /Components/Ui/Cards/StatCard.razor.rz.scp.css */
/*
    StatCard - labelled metric tile. Cards sit inside a grid managed
    by the parent (PageHeader / ListPageHero / a plain grid wrapper);
    the tile itself is a flex row with a left accent stripe, an
    optional icon column, the label+value column, and an optional
    chip column on the right.

    Token-driven; light/dark/HC branches inherit via the cascade.
    Forced-colors gets a CanvasText border in place of the shadow.
*/

/* Base chrome (padding/border/radius/shadow/surface) comes from the
   shared `.surface-card` utility in app.css. StatCard owns its
   flex layout, the absolute accent stripe (which needs the
   relative+overflow), and the transitions. */
.stat-card[b-cqxo5uzxvt] {
    display: flex;
    /* Top-align the icon / body / chip so content starts at the top of the tile rather than
       floating to the vertical centre - keeps a row of mixed-height tiles reading from the top. */
    align-items: flex-start;
    gap: var(--space-3);
    position: relative;
    overflow: hidden;
    /* When the tile is a link (Href set) it renders as <a>; suppress the default hyperlink
       underline + inherit text colour so the tile reads as a card, not a link. */
    text-decoration: none;
    color: inherit;
    transition:
        transform var(--motion-duration-fast) var(--motion-easing-standard),
        box-shadow var(--motion-duration-fast) var(--motion-easing-standard);
}

    .stat-card[b-cqxo5uzxvt]::before {
        content: "";
        position: absolute;
        inset: 0 auto 0 0;
        width: 3px;
        background: var(--_stat-card-accent, var(--color-border));
        border-top-left-radius: var(--radius-lg);
        border-bottom-left-radius: var(--radius-lg);
    }

.stat-card--neutral[b-cqxo5uzxvt] {
    --_stat-card-accent: var(--color-border);
}

.stat-card--brand[b-cqxo5uzxvt] {
    /* The brand tile's leading accent uses --color-chrome-surface (the
       fixed header/sidebar brand blue) rather than --color-brand, so the
       stripe stays the exact header blue in every theme and doesn't drift
       darker under a tenant's custom brand or lighter in dark mode. */
    --_stat-card-accent: var(--color-chrome-surface);
}

.stat-card--success[b-cqxo5uzxvt] {
    --_stat-card-accent: var(--color-success);
}

.stat-card--warning[b-cqxo5uzxvt] {
    --_stat-card-accent: var(--color-warning);
}

.stat-card--danger[b-cqxo5uzxvt] {
    --_stat-card-accent: var(--color-danger);
}

.stat-card__icon[b-cqxo5uzxvt] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 2rem;
    width: 2rem;
    height: 2rem;
    color: var(--_stat-card-accent, var(--color-text-muted));
}

    .stat-card__icon :is(svg)[b-cqxo5uzxvt] {
        width: 1.25rem;
        height: 1.25rem;
    }

.stat-card__body[b-cqxo5uzxvt] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
    flex: 1 1 auto;
}

.stat-card__label[b-cqxo5uzxvt] {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--letter-spacing-wide);
    color: var(--color-text-muted);
}

.stat-card__value[b-cqxo5uzxvt] {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    color: var(--color-text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.stat-card__hint[b-cqxo5uzxvt] {
    margin-top: var(--space-1);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    line-height: var(--line-height-snug);
}

.stat-card__chip[b-cqxo5uzxvt] {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
}

@media (forced-colors: active) {
    /* .surface-card handles the border + shadow override; only the
       accent stripe needs a custom forced-colors mapping. */
    .stat-card[b-cqxo5uzxvt]::before {
        background: CanvasText;
    }
}

@media (prefers-reduced-motion: reduce) {
    .stat-card[b-cqxo5uzxvt] {
        transition: none;
    }
}
/* /Components/Ui/Cards/StatusPill.razor.rz.scp.css */
/*
    StatusPill - inline status badge. Tonal background + bold label;
    optional leading dot or custom icon. The dot variant ensures
    colour isn't the only state signal (WCAG 1.4.1).

    Every tone consumes the paired `--color-<state>-surface` /
    `--color-<state>-on-surface` tokens from tokens.css. The pairs are
    tuned for ≥ 4.5:1 contrast in both light and dark themes - a
    `color-mix(state, surface)` background would otherwise drop the
    text below AA against the lighter pale tints.

    Forced-colors maps every variant to CanvasText on Canvas so the
    OS palette renders a usable pill without per-tone overrides.
*/

.status-pill[b-up347s9boe] {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-snug);
    border-radius: var(--radius-full);
    border: 1px solid transparent;
    white-space: nowrap;
}

.status-pill__dot[b-up347s9boe] {
    display: inline-block;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: var(--radius-full);
    background: currentColor;
    flex: 0 0 auto;
}

.status-pill__icon[b-up347s9boe] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}

    .status-pill__icon :is(svg)[b-up347s9boe] {
        width: 0.875rem;
        height: 0.875rem;
    }

.status-pill__label[b-up347s9boe] {
    color: inherit;
}

.status-pill--neutral[b-up347s9boe] {
    background: var(--color-surface-raised);
    color: var(--color-text-muted);
    border-color: var(--color-border-subtle);
}

.status-pill--brand[b-up347s9boe] {
    background: var(--color-brand-surface);
    color: var(--color-brand-on-surface);
    border-color: color-mix(in srgb, var(--color-brand) 25%, transparent);
}

.status-pill--success[b-up347s9boe] {
    background: var(--color-success-surface);
    color: var(--color-success-on-surface);
    border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
}

.status-pill--warning[b-up347s9boe] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
    border-color: color-mix(in srgb, var(--color-warning) 30%, transparent);
}

.status-pill--danger[b-up347s9boe] {
    background: color-mix(in srgb, var(--color-danger) 12%, var(--color-surface));
    color: var(--color-danger);
    border-color: color-mix(in srgb, var(--color-danger) 30%, transparent);
}

@media (forced-colors: active) {
    .status-pill[b-up347s9boe] {
        background: Canvas;
        color: CanvasText;
        border: 1px solid CanvasText;
        forced-color-adjust: none;
    }

    .status-pill__dot[b-up347s9boe] {
        background: CanvasText;
    }
}
/* /Components/Ui/Charts/ReportChart.razor.rz.scp.css */
/*
 * ReportChart - donut + legend. Lays out side-by-side on wide viewports
 * and stacks (chart above legend) under ~480px so it reads on mobile.
 * All colour comes through the --color-* tokens the segments inline, so
 * theme switching needs no rules here.
 */

.report-chart[b-o7l8irs5il] {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-5, 1.5rem);
    margin: 0;
}

.report-chart__svg[b-o7l8irs5il] {
    flex: 0 0 auto;
    width: 100%;
    max-width: 12rem;
    height: auto;
}

.report-chart__track[b-o7l8irs5il] {
    stroke: var(--color-border, #e2e2e2);
    opacity: 0.4;
}

.report-chart__center-value[b-o7l8irs5il] {
    font-size: 0.5rem;
    font-weight: var(--font-weight-bold, 700);
    fill: var(--color-text, currentColor);
}

.report-chart__center-label[b-o7l8irs5il] {
    font-size: 0.2rem;
    fill: var(--color-text-muted, #6b7280);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.report-chart__legend[b-o7l8irs5il] {
    flex: 1 1 12rem;
    min-width: 0;
}

.report-chart__legend-list[b-o7l8irs5il] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
}

.report-chart__legend-item[b-o7l8irs5il] {
    display: flex;
    align-items: center;
    gap: var(--space-2, 0.5rem);
    font-size: var(--font-size-sm, 0.875rem);
}

.report-chart__legend-swatch[b-o7l8irs5il] {
    flex: 0 0 auto;
    width: 0.75rem;
    height: 0.75rem;
    border-radius: var(--radius-xs, 2px);
}

.report-chart__legend-label[b-o7l8irs5il] {
    flex: 1 1 auto;
    color: var(--color-text, currentColor);
}

.report-chart__legend-value[b-o7l8irs5il] {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: var(--font-weight-medium, 500);
    color: var(--color-text, currentColor);
}

.report-chart--empty[b-o7l8irs5il] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 8rem;
    padding: var(--space-4, 1rem);
    border: 1px dashed var(--color-border, #e2e2e2);
    border-radius: var(--radius-md, 8px);
}

.report-chart__empty-text[b-o7l8irs5il] {
    margin: 0;
    color: var(--color-text-muted, #6b7280);
    font-size: var(--font-size-sm, 0.875rem);
}

@media (max-width: 480px) {
    .report-chart[b-o7l8irs5il] {
        flex-direction: column;
        align-items: stretch;
    }

    .report-chart__svg[b-o7l8irs5il] {
        align-self: center;
    }
}
/* /Components/Ui/Charts/UsageBarChart.razor.rz.scp.css */
/*
 * UsageBarChart - daily credit-spend bars + text summary. All colour
 * comes through the --color-* tokens so theme switching needs no rules
 * here; today is emphasised by intensity (past days sit at reduced
 * opacity) and the desc/summary carry it as text too.
 */

.usage-bar-chart[b-5cuprlnwek] {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2, 0.5rem);
}

.usage-bar-chart__svg[b-5cuprlnwek] {
    width: 100%;
    max-width: 44rem;
    height: auto;
}

.usage-bar-chart__bar[b-5cuprlnwek] {
    fill: var(--color-brand, #0f5fd6);
    opacity: 0.55;
}

.usage-bar-chart__bar--today[b-5cuprlnwek] {
    opacity: 1;
}

.usage-bar-chart__baseline[b-5cuprlnwek] {
    stroke: var(--color-border, #e2e2e2);
    stroke-width: 0.3;
}

/* Names the x-axis. Sits between the plot and the summary, centered on the
   chart it describes and quieter than the summary text below it. */
.usage-bar-chart__axis-label[b-5cuprlnwek] {
    margin: 0;
    text-align: center;
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.usage-bar-chart__summary[b-5cuprlnwek] {
    color: var(--color-text-muted, #6b7280);
    font-size: var(--font-size-sm, 0.875rem);
}

.usage-bar-chart--empty[b-5cuprlnwek] {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 6rem;
    padding: var(--space-4, 1rem);
    border: 1px dashed var(--color-border, #e2e2e2);
    border-radius: var(--radius-md, 8px);
}

.usage-bar-chart__empty-text[b-5cuprlnwek] {
    margin: 0;
    color: var(--color-text-muted, #6b7280);
    font-size: var(--font-size-sm, 0.875rem);
}
/* /Components/Ui/Forms/CadencePicker.razor.rz.scp.css */
/* Cadence-driven row visibility. The wrapping .cadence-picker uses
   :has() to inspect the cadence select's selected <option> and hide
   the rows that don't apply. Operator changes the dropdown → CSS
   does the toggling; no re-render needed. */

.cadence-picker:has(.cadence-picker__cadence option[value="Off"]:checked) .cadence-picker__weekly[b-q3so4wegq2],
.cadence-picker:has(.cadence-picker__cadence option[value="Off"]:checked) .cadence-picker__monthly[b-q3so4wegq2],
.cadence-picker:has(.cadence-picker__cadence option[value="Off"]:checked) .cadence-picker__time[b-q3so4wegq2] {
    display: none;
}

.cadence-picker:has(.cadence-picker__cadence option[value="Daily"]:checked) .cadence-picker__weekly[b-q3so4wegq2],
.cadence-picker:has(.cadence-picker__cadence option[value="Daily"]:checked) .cadence-picker__monthly[b-q3so4wegq2] {
    display: none;
}

.cadence-picker:has(.cadence-picker__cadence option[value="Weekly"]:checked) .cadence-picker__monthly[b-q3so4wegq2] {
    display: none;
}

.cadence-picker:has(.cadence-picker__cadence option[value="Monthly"]:checked) .cadence-picker__weekly[b-q3so4wegq2] {
    display: none;
}

/* Day-of-month preset → hide the custom day number input when the
   "First" or "Last" preset is selected; only the "Custom" choice
   needs a day picker. */
.cadence-picker__monthly:has(.cadence-picker__monthly-preset option[value="first"]:checked) .cadence-picker__monthly-custom[b-q3so4wegq2],
.cadence-picker__monthly:has(.cadence-picker__monthly-preset option[value="last"]:checked) .cadence-picker__monthly-custom[b-q3so4wegq2] {
    display: none;
}
/* /Components/Ui/Forms/CopyToClipboardButton.razor.rz.scp.css */
.copy-to-clipboard__button[b-tc2hy4k57m] {
    display: inline-flex;
    align-items: center;
    padding: var(--space-1) var(--space-3);
    background: var(--color-surface-sunken);
    color: var(--color-text);
    font: inherit;
    font-size: var(--font-size-sm);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
}

    .copy-to-clipboard__button:hover[b-tc2hy4k57m] {
        background: var(--color-surface-raised);
    }

    .copy-to-clipboard__button:focus-visible[b-tc2hy4k57m] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Coarse pointers (touch) get the 44px enhanced target; desktop keeps the
   compact chrome. Mirrors the ThemeToggle pattern. */
@media (pointer: coarse) {
    .copy-to-clipboard__button[b-tc2hy4k57m] {
        min-block-size: var(--target-size-touch);
        padding: var(--space-2) var(--space-4);
    }
}
/* /Components/Ui/Forms/FormStatus.razor.rz.scp.css */
/*
    FormStatus - banner-style live region used at the top of every form.

    The wrapper element renders even when empty so the AT live-region
    semantics stay stable across re-renders. When the wrapper has no
    content the `:empty` rule below collapses the visual chrome so
    the page layout doesn't see ghost spacing.
*/

.form-status[b-39gvc6ac9b] {
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--space-4);
    border: 1px solid transparent;
    border-radius: var(--radius-md);
}

.form-status:empty[b-39gvc6ac9b] {
    display: none;
}

.form-status--alert[b-39gvc6ac9b] {
    background: var(--color-danger-surface);
    color: var(--color-danger-on-surface);
    border-color: var(--color-danger);
}

.form-status--status[b-39gvc6ac9b] {
    background: var(--color-warning-surface);
    color: var(--color-warning-on-surface);
    border-color: var(--color-warning);
}

.form-status__heading[b-39gvc6ac9b] {
    margin: 0 0 var(--space-1) 0;
    font-size: var(--font-size-md);
}

.form-status__message[b-39gvc6ac9b] {
    margin: 0;
    font-size: var(--font-size-md);
    line-height: var(--line-height-snug);
}

/* When the live region holds focus, keep the focus ring visible
   over the coloured surface. */
.form-status:focus-visible[b-39gvc6ac9b] {
    outline: 2px solid var(--color-focus-ring);
    outline-offset: 2px;
}

/* Forced-colors mode loses the surface-colour contrast; rely on a
   visible border so the message kind stays distinguishable. */
@media (forced-colors: active) {
    .form-status[b-39gvc6ac9b] {
        border: 2px solid CanvasText;
        background: Canvas;
        color: CanvasText;
    }
}
/* /Components/Ui/Forms/GroupPicker.razor.rz.scp.css */
/* Token-driven skin for the group picker. The search box deliberately
   carries no border/padding/height rules: the app-wide input skin in
   app.css already wins on specificity, so the field matches every other
   input in the product (44px target, --radius-md, brand focus ring). */

.group-picker[b-f5tq8enkl0] {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.group-picker__search[b-f5tq8enkl0] {
    inline-size: 100%;
}

/* Results read as a menu surface hanging under the field. */
.group-picker__results[b-f5tq8enkl0] {
    list-style: none;
    margin: 0;
    padding: var(--space-1);
    max-block-size: 12rem;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

.group-picker__result[b-f5tq8enkl0] {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    inline-size: 100%;
    padding: var(--space-2) var(--space-3);
    background: none;
    border: 0;
    border-radius: var(--radius-sm);
    text-align: start;
    cursor: pointer;
    font: inherit;
    color: inherit;
    transition: background-color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .group-picker__result:hover:not(:disabled)[b-f5tq8enkl0] {
        background: var(--color-surface-sunken);
    }

    .group-picker__result:focus-visible[b-f5tq8enkl0] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: -2px;
    }

    .group-picker__result:disabled[b-f5tq8enkl0] {
        opacity: 0.5;
        cursor: default;
    }

/* break-word, NOT anywhere - the same rule lists.css already documents for its
   resizable tables. The two render identically, but `anywhere` also counts the
   break opportunities it introduces when the browser computes min-content,
   which flattens this cell's intrinsic floor to roughly one character. Inside
   a table that is permission to squeeze every column back inside the viewport,
   which is how the mapping table ended up rendering its dropdowns half
   visible. `break-word` still breaks a long group name at paint time without
   surrendering the floor. */
.group-picker__name[b-f5tq8enkl0] {
    overflow-wrap: break-word;
}

.group-picker__secondary[b-f5tq8enkl0] {
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

/* Group-type chip. Sentence case, not uppercase - the values are full
   phrases ("Mail-enabled security group"), and the same treatment is
   mirrored by the mapping table's type column. */
.group-picker__badge[b-f5tq8enkl0] {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding-block: 0.0625rem;
    padding-inline: 0.375rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
    white-space: nowrap;
}

.group-picker__result .group-picker__badge[b-f5tq8enkl0] {
    margin-inline-start: auto;
}

.group-picker__badge--read-only[b-f5tq8enkl0] {
    color: var(--color-warning-on-surface);
    background: var(--color-warning-surface);
    border-color: var(--color-warning);
}

.group-picker__selected[b-f5tq8enkl0] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

/* Selection chip - the app's shared chip affordance (principal picker,
   remediation tag input): brand-subtle fill, pill radius. */
.group-picker__chip[b-f5tq8enkl0] {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    padding-block: var(--space-1);
    padding-inline: var(--space-3);
    background: var(--color-brand-subtle);
    border-radius: var(--radius-full);
    font-size: var(--font-size-sm);
    /* See .group-picker__name - `anywhere` would flatten the chip's intrinsic
       width and let the surrounding table collapse the column around it. */
    overflow-wrap: break-word;
}

.group-picker__remove[b-f5tq8enkl0] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: var(--target-size-minimum);
    block-size: var(--target-size-minimum);
    flex: none;
    padding: 0;
    background: none;
    border: 0;
    border-radius: var(--radius-full);
    color: var(--color-text-muted);
    font-size: var(--font-size-md);
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .group-picker__remove:hover[b-f5tq8enkl0] {
        background: var(--color-danger-surface);
        color: var(--color-danger-on-surface);
    }

    .group-picker__remove:focus-visible[b-f5tq8enkl0] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

.group-picker__empty[b-f5tq8enkl0],
.group-picker__note[b-f5tq8enkl0] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}
/* /Components/Ui/Forms/HelpText.razor.rz.scp.css */
/*
    HelpText - supportive hint rendered below a form input.
    Muted body text; verify it stays >= 4.5:1 against
    surface-raised.
*/

.form-help[b-6pdaktrwu7] {
    display: block;
    margin: var(--space-1) 0 0;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    line-height: var(--line-height-snug);
}
/* /Components/Ui/Forms/OtpCodeInput.razor.rz.scp.css */
/* Segmented one-time-code input - scoped CSS. The fallback input shows by
   default (no-JS); once OtpCodeInput.razor.js sets data-enhanced on the host,
   the fallback is hidden and the digit segments take over. Driving visibility
   off data-enhanced (not the [hidden] attribute) avoids the author-vs-UA
   specificity trap where `display:flex` would override `[hidden]`. */

.otp-code-input[b-gejgc73dkn] {
    display: block;
}

.otp-code-input__segments[b-gejgc73dkn] {
    display: none;
    gap: var(--space-2);
    flex-wrap: wrap;
    width: 100%;
}

.otp-code-input[data-enhanced] .otp-code-input__fallback[b-gejgc73dkn] {
    display: none;
}

.otp-code-input[data-enhanced] .otp-code-input__segments[b-gejgc73dkn] {
    display: flex;
}

/* The descendant selector (plus the isolation scope attribute on both
   classes) out-specifies the shell-wide `input[type="text"] { width:100% }`
   rule in app.css - without this the segments inherit full width, become
   flex items that each demand 100%, and wrap one-per-line. flex:1 1 0
   lets the six segments share the row evenly so the OTP input fills the
   available width like the other form fields; min-width pins a sane
   minimum so very narrow viewports still get readable boxes. */
.otp-code-input__segments .otp-code-input__segment[b-gejgc73dkn] {
    flex: 1 1 0;
    min-width: 2.75rem;
    height: 3.25rem;
    padding: 0;
    text-align: center;
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    font-family: var(--font-family-mono, ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace);
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-sizing: border-box;
}

    .otp-code-input__segment:focus-visible[b-gejgc73dkn] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-color: var(--color-brand);
    }

    /* Disabled controls are exempt from WCAG 1.4.x contrast, but a flat
       opacity dim is a weak cue - signal disabled with a distinct
       surface + muted text + subtle border so low-vision users perceive
       it without relying on the opacity shift alone. */
    .otp-code-input__segment:disabled[b-gejgc73dkn] {
        background: var(--color-surface-sunken);
        border-color: var(--color-border-subtle);
        color: var(--color-text-muted);
        cursor: not-allowed;
    }

@media (forced-colors: active) {
    .otp-code-input__segment[b-gejgc73dkn] {
        border: 1px solid CanvasText;
    }

    .otp-code-input__segment:focus-visible[b-gejgc73dkn] {
        outline: 2px solid Highlight;
    }
}
/* /Components/Ui/Forms/PrincipalPicker.razor.rz.scp.css */
.principal-picker[b-dkuusu6b65] {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.principal-picker__search[b-dkuusu6b65] {
    width: 100%;
    padding: 0.4rem 0.6rem;
    border: 1px solid var(--color-border);
    border-radius: 0.375rem;
    font: inherit;
}

.principal-picker__results[b-dkuusu6b65] {
    list-style: none;
    margin: 0;
    padding: 0;
    max-height: 12rem;
    overflow-y: auto;
    border: 1px solid var(--color-border);
    border-radius: 0.375rem;
}

.principal-picker__result[b-dkuusu6b65] {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    width: 100%;
    padding: 0.4rem 0.6rem;
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.principal-picker__result:hover:not(:disabled)[b-dkuusu6b65] {
    background: var(--color-surface-sunken);
}

.principal-picker__result:disabled[b-dkuusu6b65] {
    opacity: 0.5;
    cursor: default;
}

.principal-picker__secondary[b-dkuusu6b65] {
    color: var(--color-text-muted);
    font-size: 0.85em;
}

.principal-picker__kind[b-dkuusu6b65] {
    margin-left: auto;
    font-size: 0.75em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: 0.25rem;
    padding: 0 0.35rem;
}

.principal-picker__selected[b-dkuusu6b65] {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.principal-picker__chip[b-dkuusu6b65] {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.2rem 0.5rem;
    background: var(--color-brand-subtle);
    border-radius: 1rem;
    font-size: 0.9em;
}

.principal-picker__remove[b-dkuusu6b65] {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.1em;
    line-height: 1;
    padding: 0;
    color: var(--color-text-muted);
}

.principal-picker__empty[b-dkuusu6b65],
.principal-picker__note[b-dkuusu6b65] {
    margin: 0;
    color: var(--color-text-muted);
    font-size: 0.85em;
}
/* /Components/Ui/Forms/RichTextEditor.razor.rz.scp.css */
/* RichTextEditor - scoped CSS. The editable surface mirrors the shared
   input/textarea chrome from app.css (surface background, 1px border,
   radius-md, space-2/3 padding, focus ring + brand border) so it sits in a
   form indistinguishably from a textarea; its min-height arrives as an
   inline style computed from the MinRows parameter. Content elements the
   browser creates inside the surface (b/i/u, ul/ol) need ::deep - CSS
   isolation only stamps the scope attribute on markup Blazor renders. */

.rich-text-editor[b-itqdf1e4hq] {
    display: block;
    width: 100%;
}

.rich-text-editor__toolbar[b-itqdf1e4hq] {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-block-end: var(--space-1);
}

.rich-text-editor__button[b-itqdf1e4hq] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    inline-size: 2rem;
    block-size: 2rem;
    padding: 0;
    background: var(--color-surface);
    color: var(--color-text-muted);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background-color var(--motion-duration-fast) var(--motion-easing-standard),
                color var(--motion-duration-fast) var(--motion-easing-standard),
                border-color var(--motion-duration-fast) var(--motion-easing-standard);
}

    .rich-text-editor__button:hover[b-itqdf1e4hq] {
        background: var(--color-surface-sunken);
        color: var(--color-text);
        border-color: var(--color-border-strong);
    }

    .rich-text-editor__button:focus-visible[b-itqdf1e4hq] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

    /* Pressed state - keyed off aria-pressed (the JS bridge keeps it in
       sync with queryCommandState) so the visual and the announced state
       can never disagree. */
    .rich-text-editor__button[aria-pressed="true"][b-itqdf1e4hq] {
        background: var(--color-surface-sunken);
        color: var(--color-text);
        border-color: var(--color-brand);
    }

.rich-text-editor__surface[b-itqdf1e4hq] {
    width: 100%;
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    font: inherit;
    line-height: var(--line-height-normal, 1.5);
    /* Long pasted tokens (URLs, ids) must wrap like they do in a textarea,
       never widen the form column. */
    overflow-wrap: break-word;
    /* Mirror the textarea resize cap: past ~20rem the surface scrolls
       instead of pushing the submit row below the fold. */
    max-block-size: 20rem;
    overflow-y: auto;
    box-sizing: border-box;
    transition: border-color var(--motion-duration-fast) var(--motion-easing-standard),
                box-shadow var(--motion-duration-fast) var(--motion-easing-standard);
}

    /* Editable elements match :focus-visible whenever focused, so this is
       the exact ring the shared input :focus rule paints. */
    .rich-text-editor__surface:focus-visible[b-itqdf1e4hq] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-color: var(--color-brand);
    }

.rich-text-editor__surface[b-itqdf1e4hq]  :is(ul, ol) {
    margin-block: var(--space-2);
    padding-inline-start: var(--space-6);
}

.rich-text-editor__surface[b-itqdf1e4hq]  p {
    margin-block: var(--space-2);
}

@media (forced-colors: active) {
    .rich-text-editor__button[b-itqdf1e4hq],
    .rich-text-editor__surface[b-itqdf1e4hq] {
        border: 1px solid CanvasText;
    }

    .rich-text-editor__button:focus-visible[b-itqdf1e4hq],
    .rich-text-editor__surface:focus-visible[b-itqdf1e4hq] {
        outline: 2px solid Highlight;
    }

    /* Tints are stripped under forced colors, so the pressed state restates
       itself with the system highlight pair. */
    .rich-text-editor__button[aria-pressed="true"][b-itqdf1e4hq] {
        background: Highlight;
        color: HighlightText;
        border-color: Highlight;
    }
}
/* /Components/Ui/Jobs/JobsTable.razor.rz.scp.css */
/* JobsTable island - row action buttons + the action-result status
   banner. The table chrome itself comes from the shared ListView CSS. */

.jobs-table__action[b-j914cy6dg4] {
    appearance: none;
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    color: var(--color-brand);
    cursor: pointer;
    font: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    padding: var(--space-1) var(--space-3);
    min-height: var(--target-size-minimum);
}

    .jobs-table__action:hover[b-j914cy6dg4] {
        background: var(--color-surface-sunken, var(--color-surface));
    }

    .jobs-table__action:focus-visible[b-j914cy6dg4] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

    .jobs-table__action:disabled[b-j914cy6dg4] {
        opacity: 0.55;
        cursor: not-allowed;
    }

/* Destructive variant - force-fail / clear a stuck job. */
.jobs-table__action--danger[b-j914cy6dg4] {
    color: var(--color-danger);
    border-color: var(--color-danger);
}

/* Refresh toolbar - right-aligned above the table; the button reuses the
   shared .jobs-table__action base style. */
.jobs-table__toolbar[b-j914cy6dg4] {
    display: flex;
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}

/* Assessment id - monospace + muted so the long GUID reads as a reference
   value without competing with the Job title column for attention. */
.jobs-table__id[b-j914cy6dg4] {
    font-family: var(--font-mono, ui-monospace, "Cascadia Code", Consolas, monospace);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    white-space: nowrap;
}

.jobs-table__status[b-j914cy6dg4] {
    margin: 0 0 var(--space-3);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border-subtle);
    background: var(--color-surface);
    color: var(--color-text);
}

.jobs-table__status--error[b-j914cy6dg4] {
    border-color: var(--color-danger);
    color: var(--color-danger);
}

.jobs-table__forbidden[b-j914cy6dg4] {
    margin: var(--space-4) 0;
    padding: var(--space-4) var(--space-5);
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-md);
    background: var(--color-surface);
    color: var(--color-text);
}

@media (forced-colors: active) {
    .jobs-table__action[b-j914cy6dg4],
    .jobs-table__status[b-j914cy6dg4],
    .jobs-table__forbidden[b-j914cy6dg4] {
        border: 1px solid CanvasText;
    }
}


/* The failure/result details modal this component renders is styled by the
   SHARED .details-dialog rules in wwwroot/css/lists.css, next to the
   .list-confirm-dialog they mirror - the report run-history table renders the
   same dialog, and a component-scoped copy here is what let the two drift
   (that one ended up with no styling at all). Don't reintroduce scoped
   overrides; change the shared block so both surfaces move together. */
/* /Components/Ui/Layout/PageHeader.razor.rz.scp.css */
/*
    PageHeader - general-purpose page hero (eyebrow + h1 + description
    + optional tiles + actions). Mirrors the visual rhythm of
    ListPageHero so list pages and landing/hub pages share one feel,
    but PageHeader is the primitive for non-list pages.

    Tokens only; light/dark/HC/reduced-motion handled by the cascade.
*/

.page-header[b-di4fig4kte] {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
    margin-bottom: var(--space-6);
}

.page-header__header[b-di4fig4kte] {
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-areas:
        "heading actions"
        "description description";
    column-gap: var(--space-4);
    row-gap: var(--space-2);
    align-items: center;
}

.page-header__heading[b-di4fig4kte] {
    grid-area: heading;
    margin: 0;
    font-size: var(--font-size-3xl);
    font-weight: var(--font-weight-semibold);
    line-height: var(--line-height-tight);
    letter-spacing: var(--letter-spacing-tight);
    color: var(--color-text);
    outline: none;
    /* A long unbroken value - e.g. an email in "Welcome, name@host" - must
       break rather than force a horizontal page scroll. min-width:0 lets this
       grid item shrink below the email's intrinsic width; overflow-wrap then
       breaks the address across lines. */
    min-width: 0;
    overflow-wrap: break-word;
}

.page-header__description[b-di4fig4kte] {
    grid-area: description;
    margin: 0;
    max-width: 65ch;
    color: var(--color-text-muted);
    line-height: var(--line-height-relaxed);
}

.page-header__actions[b-di4fig4kte] {
    grid-area: actions;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
    justify-self: end;
}

.page-header__tiles[b-di4fig4kte] {
    display: grid;
    /* min(14rem, 100%) - without the min() wrapper an auto-fit grid
       forces 14rem tracks even when the parent is narrower than 14rem
       (e.g. a tablet with the secondary rail open), producing a
       horizontal page scrollbar. min() collapses the track to 100%
       of the parent when there isn't room for the ideal width. */
    grid-template-columns: repeat(auto-fit, minmax(min(14rem, 100%), 1fr));
    gap: var(--space-4);
}

@media (max-width: 599px) {
    .page-header__header[b-di4fig4kte] {
        grid-template-columns: 1fr;
        grid-template-areas:
            "heading"
            "description"
            "actions";
    }

    .page-header__actions[b-di4fig4kte] {
        justify-self: stretch;
    }

    .page-header__heading[b-di4fig4kte] {
        font-size: var(--font-size-2xl);
    }
}

/* On the smallest phones (iPhone SE class, ≤ 380px) the 2xl heading
   still consumes a noticeable share of the fold for a two-word title.
   Drop a step so the description + first interactive control land
   closer to the top of the viewport. */
@media (max-width: 380px) {
    .page-header__heading[b-di4fig4kte] {
        font-size: var(--font-size-xl);
    }
}
/* /Components/Ui/Lists/ApprovalActivityTable.razor.rz.scp.css */
/* Approval audit trail table - read-only list of approve/reject votes.
   Mirrors the run-review preview table's dense, scannable treatment. */

.approval-activity__wrap[b-2m3fjbs289] {
    overflow-x: auto;
    margin-block-start: var(--space-4, 1rem);
}

.approval-activity[b-2m3fjbs289] {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm, 0.875rem);
}

.approval-activity th[b-2m3fjbs289],
.approval-activity td[b-2m3fjbs289] {
    padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
    text-align: left;
    vertical-align: top;
    border-block-end: 1px solid var(--color-border-subtle);
}

.approval-activity thead th[b-2m3fjbs289] {
    font-weight: var(--font-weight-semibold, 600);
    color: var(--color-text-muted);
    border-block-end: 2px solid var(--color-border);
    white-space: nowrap;
}

.approval-activity tbody tr:last-child td[b-2m3fjbs289] {
    border-block-end: none;
}
/* /Components/Ui/Navigation/NavIcon.razor.rz.scp.css */
/*
    NavIcon - fixed-size svg slot. Width is fixed (1rem) so the column
    of icons stays aligned across all nav links regardless of label
    length, and the slot still reserves space when the name is unknown
    (so a missing IconName doesn't visually nudge the row).
*/

.nav-icon[b-xqpi0x45ab] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 1rem;
    width: 1rem;
    height: 1rem;
    color: inherit;
}

    .nav-icon :is(svg)[b-xqpi0x45ab] {
        width: 1rem;
        height: 1rem;
    }
/* /Components/Ui/Navigation/ScrollToTop.razor.rz.scp.css */
/* Floating back-to-top button. Fixed to the bottom-inline-end corner, above
   sticky content but below modals. Hidden by default - visibility:hidden keeps
   it out of the tab order and AT tree until the page is scrolled - and fades
   in when JS adds --visible. */
.scroll-to-top[b-z7p7tn5zk5] {
    position: fixed;
    inset-block-end: var(--space-6);
    inset-inline-end: var(--space-6);
    z-index: var(--z-overlay);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 1px solid var(--color-border-subtle);
    border-radius: var(--radius-full, 999px);
    background: var(--color-surface-raised, var(--color-surface));
    color: var(--color-brand);
    box-shadow: var(--shadow-md, 0 4px 12px rgb(0 0 0 / 18%));
    cursor: pointer;

    /* Hidden resting state: faded, nudged down, and pulled out of the tab
       order / AT tree. The visibility transition is delayed so it flips only
       after the fade-out completes. */
    visibility: hidden;
    opacity: 0;
    transform: translateY(0.5rem);
    transition:
        opacity 160ms ease,
        transform 160ms ease,
        visibility 0s linear 160ms;
}

.scroll-to-top--visible[b-z7p7tn5zk5] {
    visibility: visible;
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 160ms ease,
        transform 160ms ease,
        visibility 0s linear 0s;
}

    .scroll-to-top:hover[b-z7p7tn5zk5] {
        background: var(--color-surface);
        border-color: var(--color-brand);
    }

    .scroll-to-top:focus-visible[b-z7p7tn5zk5] {
        outline: 2px solid var(--color-brand);
        outline-offset: 2px;
    }

.scroll-to-top__icon[b-z7p7tn5zk5] {
    width: 1.25rem;
    height: 1.25rem;
}

/* Respect reduced-motion: no slide, and the JS switches the scroll behaviour
   to an instant jump. */
@media (prefers-reduced-motion: reduce) {
    .scroll-to-top[b-z7p7tn5zk5] {
        transform: none;
        transition:
            opacity 120ms ease,
            visibility 0s linear 120ms;
    }

    .scroll-to-top--visible[b-z7p7tn5zk5] {
        transform: none;
        transition:
            opacity 120ms ease,
            visibility 0s linear 0s;
    }
}

@media (forced-colors: active) {
    .scroll-to-top[b-z7p7tn5zk5] {
        border-color: CanvasText;
        color: CanvasText;
    }
}
/* /Components/Ui/Tenants/TenantPicker.razor.rz.scp.css */
/*
 * TenantPicker - sits at the top of the AppShell sidebar (and mobile
 * drawer) as a brand-tinted card. Eyebrow + leading tenant icon +
 * tenant name + dropdown chevron. The panel that opens below carries
 * a search box, the list of memberships, and a divider-separated
 * "+ Create new tenant" link.
 *
 * Static SSR; native <details>/<summary> drives open/close so the
 * primitive is keyboard- and AT-friendly without JS. Token-driven so
 * light / dark / HC / forced-colors / reduced-motion all track.
 *
 * Each option's form posts to /tenants/switch with the chosen
 * TenantId - keeps the picker usable without JS (search degrades to
 * "show everything" but the switch still works).
 */

.tenant-picker[b-zmawp0j31y] {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    padding: var(--space-3);
    /* Translucent white overlay so the card pops as a subtle
       highlight on the navy chrome - no theme-flip token needed
       (rgba is constant across light/dark). The expanded dropdown
       panel below is NOT on the chrome surface; it floats over the
       white content area and keeps the original surface tokens. */
    background: rgba(255, 255, 255, 0.10);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: var(--radius-lg);
    color: var(--color-chrome-on-surface);
    font-family: var(--font-sans);
}

@media (forced-colors: active) {
    .tenant-picker[b-zmawp0j31y] {
        background: Canvas;
        border: 1px solid CanvasText;
        forced-color-adjust: none;
    }
}

.tenant-picker__eyebrow[b-zmawp0j31y] {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: var(--letter-spacing-wide);
    /* Lives on the navy chrome - match the chrome text family so the
       eyebrow stays legible. */
    color: var(--color-chrome-on-surface-muted);
}

.tenant-picker__heading[b-zmawp0j31y] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--target-size-minimum);
}

.tenant-picker__none[b-zmawp0j31y],
.tenant-picker__failed[b-zmawp0j31y] {
    color: var(--color-chrome-on-surface-muted);
    font-size: var(--font-size-sm);
    font-style: italic;
}

.tenant-picker__active[b-zmawp0j31y] {
    /* One step down from body so the tenant name doesn't dominate the
       sidebar card - pairs with the eyebrow above + chevron to the
       right at a single compact type-size. */
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-chrome-on-surface);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    flex: 1 1 auto;
}

.tenant-picker__details[b-zmawp0j31y] {
    position: relative;
}

    /* Hide the default disclosure marker - we render our own chevron. */
    .tenant-picker__details > summary[b-zmawp0j31y] {
        list-style: none;
    }

    .tenant-picker__details > summary[b-zmawp0j31y]::-webkit-details-marker {
        display: none;
    }

.tenant-picker__trigger[b-zmawp0j31y] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2);
    margin: 0 calc(-1 * var(--space-2));
    background: transparent;
    border: 0;
    border-radius: var(--radius-md);
    color: var(--color-chrome-on-surface);
    cursor: pointer;
    font: inherit;
    min-height: var(--target-size-minimum);
}

    .tenant-picker__trigger:hover[b-zmawp0j31y] {
        background: var(--color-chrome-surface-hover);
    }

    .tenant-picker__trigger:focus-visible[b-zmawp0j31y] {
        outline: 2px solid var(--color-chrome-on-surface);
        outline-offset: 2px;
    }

.tenant-picker__chevron[b-zmawp0j31y] {
    color: var(--color-chrome-on-surface-muted);
    font-size: var(--font-size-sm);
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard);
    flex: 0 0 auto;
}

.tenant-picker__details[open] .tenant-picker__chevron[b-zmawp0j31y] {
    transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
    .tenant-picker__chevron[b-zmawp0j31y] {
        transition: none;
    }
}

.tenant-picker__panel[b-zmawp0j31y] {
    position: absolute;
    top: calc(100% + var(--space-2));
    left: 0;
    right: 0;
    /* Lift the panel slightly off the brand-tinted card so it reads
       as a discrete surface; the surface-raised background pairs with
       the brand-subtle card without colour conflict. */
    padding: var(--space-3);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    z-index: var(--z-dropdown);
    /* Smaller text inside the dropdown - the panel is dense by design
       (search + list + actions in a compact card) and the picker
       trigger above already sets context, so the panel doesn't need
       body-size text. `font: inherit` on descendants picks this up. */
    font-size: var(--font-size-sm);
    /* Prevent vertical overflow on short viewports. The list inside
       still scrolls; the panel as a whole won't. */
    max-height: calc(100vh - 6rem);
    overflow-y: auto;
}

@media (forced-colors: active) {
    .tenant-picker__panel[b-zmawp0j31y] {
        box-shadow: none;
        border: 1px solid CanvasText;
        background: Canvas;
    }
}

.tenant-picker__search-label[b-zmawp0j31y] {
    /* Visually hidden - the placeholder + helptext below carry the
       visible affordance. The label still exists for AT users. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.tenant-picker__search[b-zmawp0j31y] {
    padding: var(--space-2) var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text);
    font: inherit;
    /* WCAG 2.5.8 */
    min-height: var(--target-size-minimum);
}

    .tenant-picker__search:focus-visible[b-zmawp0j31y] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-color: var(--color-brand);
    }

.tenant-picker__search-help[b-zmawp0j31y] {
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.tenant-picker__list[b-zmawp0j31y] {
    margin: 0;
    padding: 0;
    list-style: none;
    max-height: min(18rem, 50vh);
    overflow-y: auto;
}

.tenant-picker__option[b-zmawp0j31y] {
    display: block;
    border-radius: var(--radius-sm);
}

    .tenant-picker__option[aria-selected="true"][b-zmawp0j31y] {
        background: var(--color-brand-subtle);
    }

    .tenant-picker__option[hidden][b-zmawp0j31y] {
        display: none;
    }

.tenant-picker__form[b-zmawp0j31y] {
    margin: 0;
}

.tenant-picker__switch[b-zmawp0j31y] {
    display: block;
    width: 100%;
    padding: var(--space-2) var(--space-3);
    background: transparent;
    border: 0;
    border-radius: var(--radius-sm);
    color: var(--color-text);
    cursor: pointer;
    font: inherit;
    text-align: left;
    min-height: var(--target-size-minimum);
}

    .tenant-picker__switch:hover[b-zmawp0j31y] {
        background: var(--color-surface-sunken);
    }

    .tenant-picker__switch:focus-visible[b-zmawp0j31y] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: -2px;
    }

    .tenant-picker__option[aria-selected="true"] .tenant-picker__switch[b-zmawp0j31y] {
        font-weight: var(--font-weight-semibold);
        color: var(--color-brand-hover);
    }

.tenant-picker__no-matches[b-zmawp0j31y] {
    padding: var(--space-2) var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-style: italic;
    margin: 0;
}

/* Divider between the membership list and the create-tenant action.
   Single hairline using the same colour token as the card border. */
.tenant-picker__divider[b-zmawp0j31y] {
    margin: var(--space-2) 0;
    border: 0;
    border-top: 1px solid var(--color-border-subtle);
}

@media (forced-colors: active) {
    .tenant-picker__divider[b-zmawp0j31y] {
        border-top: 1px solid CanvasText;
    }
}

/* Secondary links inside the picker - Create + Manage read as
   siblings, not as primary CTA vs neutral nav. Both share the muted
   neutral treatment in the dropdown panel (white surface). The
   chrome-scoped overrides below re-tint both when they sit directly
   on the navy card (single/empty branches). */
.tenant-picker__create[b-zmawp0j31y],
.tenant-picker__manage[b-zmawp0j31y] {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-regular);
    text-decoration: none;
    border-radius: var(--radius-sm);
    min-height: var(--target-size-minimum);
}

    .tenant-picker__create:hover[b-zmawp0j31y],
    .tenant-picker__manage:hover[b-zmawp0j31y] {
        background: var(--color-surface-sunken);
        color: var(--color-text);
        text-decoration: underline;
    }

    .tenant-picker__create:focus-visible[b-zmawp0j31y],
    .tenant-picker__manage:focus-visible[b-zmawp0j31y] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
    }

/* Direct-child overrides for the navy chrome surface - in the
   single-membership and empty-state branches both links sit outside
   the dropdown panel, painting against the translucent-white-on-navy
   card instead of the white floating panel. Re-tint to the chrome
   colour family so the labels stay legible. Both links share the
   treatment now - create + manage read as siblings. The
   panel-scoped rules above still apply on the white surface
   (descendant of .tenant-picker__panel). */
.tenant-picker > .tenant-picker__create[b-zmawp0j31y],
.tenant-picker > .tenant-picker__manage[b-zmawp0j31y] {
    color: var(--color-chrome-on-surface-muted);
}

    .tenant-picker > .tenant-picker__create:hover[b-zmawp0j31y],
    .tenant-picker > .tenant-picker__manage:hover[b-zmawp0j31y] {
        background: var(--color-chrome-surface-hover);
        color: var(--color-chrome-on-surface);
    }

    .tenant-picker > .tenant-picker__create:focus-visible[b-zmawp0j31y],
    .tenant-picker > .tenant-picker__manage:focus-visible[b-zmawp0j31y] {
        outline: 2px solid var(--color-chrome-on-surface);
    }
/* /Components/Ui/Theming/ThemeToggle.razor.rz.scp.css */
/*
 * Theme cycle button - inline-SVG sun / moon icon. Lives inline inside
 * the AppShellFooter dot-separated band, so the chrome strips back
 * to a transparent inline button that inherits surrounding text
 * styling. Hover bumps the icon slightly to signal interactivity
 * within a row of static text links.
 */

.theme-toggle[b-3m51tf6m9q] {
    display: inline;
    margin: 0;
}

.theme-toggle__button[b-3m51tf6m9q] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    padding: 0;
    margin: 0;
    /* WCAG 2.5.8 Target Size (Minimum): 24×24 on every pointer type. The
       glyph alone is sub-24px, so the floor must be on the base rule, not
       only the coarse-pointer block below (which raises it to 44px). */
    min-block-size: var(--target-size-minimum);
    min-inline-size: var(--target-size-minimum);
    color: inherit;
    cursor: pointer;
    font: inherit;
    line-height: 1;
    transition: transform var(--motion-duration-fast) var(--motion-easing-standard);
}

/* 44×44 touch target on coarse pointers (phones / tablets). Desktop
   keeps the tight glyph-only chrome - pointer-fine input is precise
   enough not to need the extra hit area. */
@media (pointer: coarse) {
    .theme-toggle__button[b-3m51tf6m9q] {
        min-block-size: 2.75rem;
        min-inline-size: 2.75rem;
    }
}

    .theme-toggle__button:hover[b-3m51tf6m9q],
    .theme-toggle__button:focus-visible[b-3m51tf6m9q] {
        transform: scale(1.15);
    }

    .theme-toggle__button:focus-visible[b-3m51tf6m9q] {
        outline: 2px solid var(--color-focus-ring);
        outline-offset: 2px;
        border-radius: var(--radius-sm);
    }

.theme-toggle__glyph[b-3m51tf6m9q] {
    display: inline-flex;
    line-height: 1;
}

    /* Inline SVG icon (sun / moon) - fixed geometry so the toggle renders
       identically on every platform, unlike the emoji glyphs it replaced
       which drew from each OS's own emoji font. currentColor inherits the
       surrounding footer text colour in both shells and themes. */
    .theme-toggle__glyph svg[b-3m51tf6m9q] {
        inline-size: 1.125rem;
        block-size: 1.125rem;
        display: block;
    }

@media (prefers-reduced-motion: reduce) {
    .theme-toggle__button[b-3m51tf6m9q] {
        transition: none;
    }

        .theme-toggle__button:hover[b-3m51tf6m9q],
        .theme-toggle__button:focus-visible[b-3m51tf6m9q] {
            transform: none;
        }
}

@media (forced-colors: active) {
    .theme-toggle__button[b-3m51tf6m9q] {
        color: CanvasText;
    }
}
