/* ══════════════════════════════════════════════════════════════════════════════
   Aeroplan design tokens.

   The semantic layer that markup outside MudBlazor reads. Values are mirrored from
   AeroplanTheme.Design (Theme/AeroplanTheme.cs) — keep the two in step.

   Why a static sheet and not a component that emits these: HeadContent renders in <head>,
   which is earlier in document order than MudThemeProvider's inline <style> in <body>, so it
   could never win a tie. A body-level emitter would have to be mounted in every layout on
   both hosts, i.e. it would recreate the very duplication this file exists to end.

   Definitions live at :root safely, because nothing else in the app or in MudBlazor declares
   --ap-*. Note that a rule here could never override a --mud-* variable at :root: the theme
   provider emits its block inline in the body, later in document order, so it wins any tie.
   Palette values belong in AeroplanTheme, not here.

   Loaded after MudBlazor.min.css on both hosts (App.razor and MAUI index.html).
   ══════════════════════════════════════════════════════════════════════════════ */

:root {
    /* ── Foundation ───────────────────────────────────────────────────────────
       The eight named colours of the Frontend Design Guide (Rev 3 · v3.0). Every role token
       below either resolves to one of these or is a shade the guide does not name. A guide
       colour repeated as a literal is drift, and AeroplanThemeTests fails on it.

       Named by colour, unlike everything after them, because that is how the guide publishes
       them. Mirrored in AeroplanTheme.Design.Foundation. */
    --ap-color-carbon-navy: #091A24;
    --ap-color-graphite-blue: #172F3E;
    --ap-color-mineral-blue: #536F7E;
    --ap-color-safety-orange: #E8792E;
    --ap-color-porcelain: #F7F7F5;
    --ap-color-warm-mist: #E8E7E3;
    --ap-color-graphite-grey: #626B70;
    --ap-color-white: #FFFFFF;

    /* ── Surfaces ─────────────────────────────────────────────────────────── */
    --ap-canvas: var(--ap-color-porcelain);
    --ap-surface: var(--ap-color-white);
    --ap-surface-sunken: #F2F0EC;
    --ap-hairline: #E7E4DE;
    --ap-hairline-strong: #D8D4CC;

    /* The attention signal: small unread and due-soon markers, nothing else. Never a button or
       a surface, and whatever sits on it is written in --ap-ink. */
    --ap-attention: var(--ap-color-safety-orange);

    /* The one hover background for anything interactive on a light surface — rows, menu items
       and quiet buttons alike. There used to be two, a near-invisible tint for rows and the
       sunken surface borrowed for buttons; the guide names a single colour for the job. */
    --ap-hover-bg: var(--ap-color-warm-mist);

    /* ── Ink ──────────────────────────────────────────────────────────────── */
    --ap-ink: var(--ap-color-carbon-navy);
    --ap-ink-muted: var(--ap-color-graphite-grey);

    /* Icons, hairline borders and disabled controls — never meaningful text; the guide has one
       secondary tier and no third below it. Non-text, so WCAG asks 3:1 rather than 4.5:1.
       Hue-matched to Graphite Grey, unlike the warm grey it replaced. */
    --ap-ink-faint: #828C92;

    /* ── Action ───────────────────────────────────────────────────────────────
       Carbon Navy, the anchor the guide assigns to primary actions. Hover steps up to
       Graphite Blue, the next colour of the same family; pressed is a darker shade of
       the anchor, which the guide does not name. */
    --ap-primary: var(--ap-color-carbon-navy);
    --ap-primary-hover: var(--ap-color-graphite-blue);
    --ap-primary-pressed: #050F14;
    --ap-primary-ink: var(--ap-color-white);

    /* ── Sidebar ──────────────────────────────────────────────────────────────
       A dark surface inside the light theme, not a dark mode. Named by role, so a
       future dark mode swaps these values rather than restructuring anything.

       Carbon Navy, the same anchor as --ap-primary. The two used to sit a point and a
       half apart, which reads as a near-miss rather than a choice, so they are now
       deliberately identical. Only the ACTIVE item gets the light slate pill; hover is
       deliberately much subtler, or every row competes with the current one. */
    --ap-sidebar-bg: var(--ap-color-carbon-navy);
    --ap-sidebar-fg: #C3D0D8;
    --ap-sidebar-fg-strong: var(--ap-color-white);
    --ap-sidebar-muted: #6E879A;
    --ap-sidebar-hover-bg: var(--ap-color-graphite-blue);
    --ap-sidebar-active-bg: var(--ap-color-mineral-blue);
    --ap-sidebar-hairline: #1C2E3A;
    --ap-sidebar-mark-bg: #5E7A8C;
    --ap-sidebar-width: 250px;

    /* ── Status ───────────────────────────────────────────────────────────────
       One triple per state: the dot, the pill tint behind it, the pill's own ink. */
    /* Two families, deliberately not one. The dots mirror AeroplanTheme.Design, which also feeds
       MudBlazor's Success/Warning/Info — so alerts and snackbars keep an ink dark enough to carry
       white text. The chips are their own scale, and a chip's dot takes the chip's ink via
       currentColor, so a chip reads as one colour rather than two.

       Each chip ink is as light as it can be while still clearing 4.5:1 against its own tint.
       They were all under it before, between 2.7 and 3.7, which is what happens when a tint and
       an ink are picked to look right together and never measured. AeroplanThemeTests holds the
       pairs to the threshold now. */
    --ap-chip-info-bg: #EDF1F5;
    --ap-chip-info-ink: #445E6C;

    --ap-list-footer-bg: #FAFBFB;

    /* These four were guide colours already, spelled as literals under role names that gave no
       hint of it. Pointing them at the foundation layer is the whole reason that layer exists. */
    --ap-card-title-ink: var(--ap-color-carbon-navy);
    --ap-row-title-ink: var(--ap-color-graphite-blue);
    --ap-stat-label-ink: var(--ap-color-graphite-grey);
    --ap-interactive-ink: var(--ap-color-mineral-blue);

    --ap-input-placeholder: #9BA6AC;

    --ap-status-active-dot: #3E7C5B;
    --ap-status-active-bg: #E3F4ED;
    --ap-status-active-ink: #257A5D;

    --ap-status-locked-dot: #906729;
    --ap-status-locked-bg: #FFF2DE;
    --ap-status-locked-ink: #906729;

    --ap-status-pending-dot: #3E6A9C;
    --ap-status-pending-bg: #E8F0F8;
    --ap-status-pending-ink: #446F97;

    --ap-status-inactive-dot: #8B8A85;
    --ap-status-inactive-bg: #F1F2F3;
    --ap-status-inactive-ink: #627177;

    /* Critical has no chip - nothing tints a row red - but it does have a dot, and the tablet
       paints a whole control with it. Mirrors Design.StatusError, which had no token here at all
       while the other four did. */
    --ap-status-error-dot: #B4453C;

    /* Where a piece of work has got to, which is a different axis from whether a thing is
       usable. A user account is never overdue and a review is never locked, so these are their
       own tokens even where a value matches one above: Completed green and Active green are the
       same colour for different reasons, and collapsing them is how the meaning drifts.

       Hues follow the guide's semantic table - success, warning, critical, information - and
       each ink clears 4.5:1 against its own tint. */
    --ap-workflow-completed-bg: #E3F4ED;
    --ap-workflow-completed-ink: #257A5D;

    --ap-workflow-due-soon-bg: #FFF2DE;
    --ap-workflow-due-soon-ink: #906729;

    --ap-workflow-overdue-bg: #F7E9E8;
    --ap-workflow-overdue-ink: #B4453C;

    --ap-workflow-in-review-bg: #E8F0F8;
    --ap-workflow-in-review-ink: #446F97;

    /* ── Spacing ──────────────────────────────────────────────────────────────
       The guide's 4px base scale. The step number is the multiple, so --ap-space-6 is
       24px, and the gaps the scale skips - 20, 28, 36, 44 - are skipped on purpose.

       Declarations whose every value already sat on the scale now name it. The ones that
       do not are still literals, because snapping them would move component geometry
       rather than rename it. */
    --ap-space-1: 4px;
    --ap-space-2: 8px;
    --ap-space-3: 12px;
    --ap-space-4: 16px;
    --ap-space-6: 24px;
    --ap-space-8: 32px;
    --ap-space-10: 40px;
    --ap-space-12: 48px;

    /* ── Geometry ─────────────────────────────────────────────────────────── */
    --ap-radius-sm: 6px;
    --ap-radius-md: 8px;
    --ap-radius-lg: 12px;
    --ap-radius-pill: 999px;

    /* ── Type ─────────────────────────────────────────────────────────────────
       Both families are self-hosted via @font-face in app.css, so the tablet renders
       them offline. The manual faces are registered there too, and QuestPDF registers
       the same files, which is what keeps the editor and a printed manual identical. */
    --ap-font-display: 'IBM Plex Sans Condensed', 'Arial Narrow', sans-serif;
    --ap-font-ui: 'Source Sans 3', ui-sans-serif, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ══════════════════════════════════════════════════════════════════════════════
   Component classes.

   Prefixed, so they never tie with a .mud-* rule and therefore never depend on where
   this sheet sits relative to MudBlazor.min.css.
   ══════════════════════════════════════════════════════════════════════════════ */

/* ── Surfaces ─────────────────────────────────────────────────────────────── */

/* Cards are MudCard — the recipe lives in the MudBlazor section at the bottom of this file, on
   .mud-card itself, so component markup stays idiomatic MudBlazor rather than carrying a
   parallel .ap-card class that does the same job. */

/* ── Type ─────────────────────────────────────────────────────────────────── */

.ap-display {
    font-family: var(--ap-font-display);
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--ap-ink);
}

/* The wordmark. Wide tracking is what makes it read as a logotype rather than a heading.
   Colour is inherited on purpose so the same class works white on the rail and ink on a
   surface, instead of needing a second variant per background. */
.ap-wordmark {
    font-family: var(--ap-font-ui);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

/* Small-caps section label — "ADMINISTRATION" in the nav, section headers on a page. */
.ap-kicker {
    font-family: var(--ap-font-ui);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ap-ink-muted);
}

.ap-muted {
    color: var(--ap-ink-muted);
}

/* ── Status pills ─────────────────────────────────────────────────────────── */

.ap-status,
.ap-workflow {
    display: inline-flex;
    align-items: center;
    gap: var(--ap-space-1);
    padding: var(--ap-space-1) var(--ap-space-2);
    border-radius: var(--ap-radius-pill);
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 600;
    line-height: 20px;
    white-space: nowrap;
}

.ap-status::before,
.ap-workflow::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    /* The dot is the pill's own ink; nothing overrides it per state. */
    background: currentColor;
    flex-shrink: 0;
}

.ap-status--active {
    background: var(--ap-status-active-bg);
    color: var(--ap-status-active-ink);
}

.ap-status--locked {
    background: var(--ap-status-locked-bg);
    color: var(--ap-status-locked-ink);
}

.ap-status--pending {
    background: var(--ap-status-pending-bg);
    color: var(--ap-status-pending-ink);
}

.ap-status--inactive {
    background: var(--ap-status-inactive-bg);
    color: var(--ap-status-inactive-ink);
}

.ap-workflow--completed {
    background: var(--ap-workflow-completed-bg);
    color: var(--ap-workflow-completed-ink);
}

.ap-workflow--due-soon {
    background: var(--ap-workflow-due-soon-bg);
    color: var(--ap-workflow-due-soon-ink);
}

.ap-workflow--overdue {
    background: var(--ap-workflow-overdue-bg);
    color: var(--ap-workflow-overdue-ink);
}

.ap-workflow--in-review {
    background: var(--ap-workflow-in-review-bg);
    color: var(--ap-workflow-in-review-ink);
}

/* Whether an account's second factor is ready, in a table row: tinted text rather than a pill. It is a
   property of the account, not its lifecycle, so it neither borrows .ap-status's dot nor competes with the
   status pill beside it for attention. */
.ap-mfa-state {
    font-family: var(--ap-font-ui);
    font-size: 12px;
    font-weight: 600;
    line-height: 20px;
    white-space: nowrap;
}

.ap-mfa-state--configured {
    color: var(--ap-status-active-ink);
}

.ap-mfa-state--not-configured {
    color: var(--ap-status-locked-ink);
}

/* A tag without a state: function and group labels in a table row. */
.ap-tag {
    display: inline-flex;
    align-items: center;
    padding: var(--ap-space-1) var(--ap-space-2);
    border-radius: var(--ap-radius-sm);
    background: var(--ap-chip-info-bg);
    color: var(--ap-chip-info-ink);
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 600;
    line-height: 20px;
    white-space: nowrap;
}

/* A tag that carries a tint but no dot, for a value that is notable rather than a lifecycle
   state — an MFA exception, say. The dot in .ap-status means "this is the thing's status",
   so a non-status value should not borrow it. Declared after .ap-tag: same specificity, so
   order is what lets it win. */
.ap-tag--warning {
    background: var(--ap-status-locked-bg);
    color: var(--ap-status-locked-ink);
}

/* ── Panels and summary rows ───────────────────────────────────────────────────
   The dashboard's vocabulary, kept general: a card with a header and a way out of the bottom, rows
   inside it, a subject band above it. Nothing here knows it is on the dashboard. */

.ap-icon-tile {
    display: inline-grid;
    place-items: center;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    border-radius: var(--ap-radius-md);
    background: var(--ap-surface-sunken);
    color: var(--ap-ink-muted);
}

.ap-icon-tile .mud-icon-root {
    font-size: 18px;
}

.ap-icon-tile--warning {
    background: var(--ap-status-locked-bg);
    color: var(--ap-status-locked-ink);
}

.ap-icon-tile--active {
    background: var(--ap-status-active-bg);
    color: var(--ap-status-active-ink);
}

.ap-icon-tile--pending {
    background: var(--ap-status-pending-bg);
    color: var(--ap-status-pending-ink);
}

.ap-count-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    height: 22px;
    padding: 0 var(--ap-space-2);
    border-radius: var(--ap-radius-sm);
    background: var(--ap-surface-sunken);
    color: var(--ap-ink);
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 700;
    line-height: 22px;
}

.ap-count-badge--warning {
    background: var(--ap-status-locked-bg);
    color: var(--ap-status-locked-ink);
}

.ap-count-badge--active {
    background: var(--ap-status-active-bg);
    color: var(--ap-status-active-ink);
}

.ap-count-badge--pending {
    background: var(--ap-status-pending-bg);
    color: var(--ap-status-pending-ink);
}

/* Laid out the same whether the row is an anchor or not. MudLink is used rather than MudNavLink
   because the latter wraps everything in one text div, which stacks the sections instead of
   ranging them across the row; its link colour and weight are unset here. */
.ap-summary-row,
.ap-panel-row {
    display: flex;
    align-items: center;
    gap: var(--ap-space-4);
    width: 100%;
    min-height: 0;
    margin: 0;
    background: transparent;
    color: var(--ap-ink);
    font-size: 13px;
    font-weight: 400;
}

a.ap-summary-row,
a.ap-panel-row {
    text-decoration: none;
}

.ap-summary-row {
    padding: var(--ap-space-4) 20px;
    border-bottom: 1px solid var(--ap-hairline);
}

/* Inside an anchor everything inherits the link colour unless it says otherwise, which is what
   left the stats reading as a row of differently coloured links. */
.ap-summary-stat-label,
.ap-summary-row-title,
.ap-panel-row-title {
    color: inherit;
}

/* What the count is of. Regular weight against the badge's bold, so the number carries the row and
   the label stays a caption. */
.ap-summary-stat-label {
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 400;
    color: var(--ap-stat-label-ink);
}

.ap-summary-row:last-child {
    border-bottom: none;
}

.ap-summary-row:hover {
    background: var(--ap-hover-bg);
}

.ap-summary-row-subject {
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    flex: 0 0 200px;
    min-width: 0;
}

.ap-summary-row-title {
    font-size: 14px;
    font-weight: 600;
    color: var(--ap-ink);
}

/* Columns, not a packed row: every row lays its stats on the same grid, so "Awaiting internally"
   starts where "All" does however long the label before it happens to be. A flex row would set each
   row's positions from its own content and none of them would line up. */
.ap-summary-row-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 240px));
    align-items: center;
    flex: 1 1 auto;
    min-width: 0;
}

.ap-summary-row-trailing {
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    margin-left: auto;
    flex-shrink: 0;
    color: var(--ap-ink-muted);
    font-size: 13px;
}

.ap-summary-row-chevron.mud-icon-root {
    font-size: 20px;
    color: var(--ap-ink-faint);
}

.ap-summary-stat {
    display: inline-flex;
    align-items: center;
    gap: var(--ap-space-2);
    color: var(--ap-ink-muted);
    font-size: 13px;
}

.ap-summary-stat.mud-typography {
    color: var(--ap-ink-muted);
}

/* Clips its children to the card's radius, so a full-width rule meets the rounded corner instead
   of running past it. */
.ap-panel {
    overflow: hidden;
}

.ap-panel .mud-card-header.ap-panel-head {
    padding: 20px 20px var(--ap-space-4);
    align-items: flex-start;
}

/* Inset by the card's own gutter, so the rule starts under the headline rather than at the card's
   edge — the block is narrowed rather than padded, which is what carries the border in with it. */
.ap-panel-header-extra {
    margin: 0 20px;
    border-bottom: 1px solid var(--ap-hairline);
}

/* The first label lines up with the card's headline above it; the tab's own padding would push it
   in by its own amount. */
.ap-panel-header-extra .mud-tab:first-of-type {
    padding-left: 0;
}

.ap-panel .ap-panel-head .mud-card-header-actions:empty {
    display: none;
}

.ap-panel-title-line {
    display: flex;
    align-items: baseline;
    gap: var(--ap-space-2);
    flex-wrap: wrap;
}

/* The headline of a card, wherever a card has one — the panels here and any MudCardHeader
   elsewhere, so a title does not change size depending on which component drew it. */
.ap-card-title,
.ap-panel-title.mud-typography,
.mud-card > .mud-card-header .mud-typography-h5,
.mud-card > .mud-card-header .mud-typography-h6 {
    font-family: var(--ap-font-display);
    font-size: 22px;
    font-weight: 600;
    line-height: 25.3px;
    letter-spacing: -0.33px;
    color: var(--ap-card-title-ink);
}

/* The qualifier beside a card's headline — "Assigned to you". The UI face, not the display one:
   it is a note about the title rather than part of it. */
/* A link sitting opposite a card's headline, quiet enough not to compete with it. */
.ap-panel-head-link.mud-typography {
    font-family: var(--ap-font-ui);
    font-size: 14px;
    color: var(--ap-interactive-ink);
}

.ap-panel-subtitle {
    font-family: var(--ap-font-ui);
    font-size: 13px;
    color: var(--ap-ink-muted);
}

.ap-panel > .mud-card-content.ap-panel-body {
    padding: 0;
}

.ap-panel--padded > .mud-card-content.ap-panel-body {
    padding: 20px;
}

/* A padded body sits under the headline's own rule rather than straight under the headline. */
.ap-panel--padded .mud-card-header.ap-panel-head {
    border-bottom: 1px solid var(--ap-hairline);
    margin: 0 20px;
    padding: 20px 0 var(--ap-space-4);
}

.ap-panel .mud-card-actions.ap-panel-foot {
    position: relative;
    padding: 0;
    color: var(--ap-interactive-ink);
}

.ap-panel .ap-panel-foot::before {
    content: '';
    position: absolute;
    inset: 0 20px auto;
    height: 1px;
    background: var(--ap-hairline);
}

.ap-panel-foot-link.mud-typography {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: var(--ap-space-4) 20px;
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 600;
    color: var(--ap-interactive-ink);
}

.ap-panel-foot-link .mud-icon-root {
    font-size: 20px;
    color: var(--ap-interactive-ink);
}

.ap-panel-foot-link:hover {
    background: var(--ap-hover-bg);
}

.ap-panel-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    padding: var(--ap-space-4) 20px;
}

/* The rule is drawn inset while the row itself stays full-bleed, so hover fills the card's width
   and only the hairline is indented. A border on the row would have to choose one or the other. */
.ap-panel-row::after {
    content: '';
    position: absolute;
    inset: auto 20px 0;
    height: 1px;
    background: var(--ap-hairline);
}

/* The last row meets the footer's own rule, or the card's edge — either way it draws no second one. */
.ap-panel-row:last-child::after {
    content: none;
}

a.ap-panel-row:hover {
    background: var(--ap-hover-bg);
}

.ap-panel-row-mark.ap-icon-tile {
    width: 40px;
    height: 40px;
}

.ap-panel-row-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

/* What a row is about, on the UI face rather than the display one: a row names a thing, it does
   not head a section. Shared by every PanelRow, so the panels beside My work match it. */
.ap-panel-row-title {
    font-family: var(--ap-font-ui);
    font-size: 15px;
    font-weight: 600;
    color: var(--ap-row-title-ink);
    overflow-wrap: anywhere;
}

.ap-panel-row-sub {
    margin-top: var(--ap-space-1);
    font-family: var(--ap-font-ui);
    font-size: 13px;
    color: var(--ap-ink-muted);
}

.ap-panel-row-trailing {
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    margin-left: auto;
    flex-shrink: 0;
    color: var(--ap-row-title-ink);
}

/* A value that belongs to the row but is not its subject — an address beside a name. */
.ap-panel-row-aside {
    font-size: 12px;
    color: var(--ap-ink-muted);
    overflow-wrap: anywhere;
}

.ap-panel-row-action.mud-typography {
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 600;
    color: var(--ap-row-title-ink);
}

/* A verdict rather than a count: words, and the quiet of something being fine. */
.ap-summary-verdict {
    display: inline-flex;
    align-items: center;
    gap: var(--ap-space-1);
    color: var(--ap-ink-muted);
    font-size: 13px;
}

.ap-summary-verdict .mud-icon-root {
    font-size: 16px;
    color: var(--ap-ink-faint);
}

.ap-summary > .mud-card-content {
    padding: 0;
}

/* A list page's table wears the canvas tint behind its column labels, because there the table is
   the page and the band separates it from the canvas. A table that is merely a card's content does
   not: the cards on the dashboard carry no band at all, and one holding a table should not look
   different from one holding rows. The labels keep their rule and their weight.
   The flush cards are the exception — they are the list pattern, where the band belongs. */
.ap-panel .mud-table .mud-table-head .mud-table-cell,
.mud-card:not(.ap-card--flush) .mud-table .mud-table-head .mud-table-cell {
    background-color: transparent;
}

/* A line of prose introducing a card's rows. The body itself is unpadded so the rows run to the
   card's edges, so the prose brings its own gutter. */
/* A card's own filter bar: under the headline, above what it narrows, indented to the same gutter
   as the header's rule so the two read as one stack. */
.ap-panel-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ap-space-2);
    margin: 0 20px;
    padding: var(--ap-space-3) 0;
    border-bottom: 1px solid var(--ap-hairline);
}

.ap-panel-lead {
    margin: 0;
    padding: var(--ap-space-4) 20px var(--ap-space-1);
    font-family: var(--ap-font-ui);
    font-size: 14px;
    color: var(--ap-ink-muted);
}

/* A switch and the word for what it switches, kept together so a row can carry two of them without
   a column header to explain which is which. */
.ap-switch-field {
    display: inline-flex;
    align-items: center;
    gap: var(--ap-space-1);
}

.ap-switch-label {
    font-family: var(--ap-font-ui);
    font-size: 13px;
    color: var(--ap-ink-muted);
}

/* Names what an expanded table row is showing. Small and quiet: it labels a nested table, it does
   not head a card. */
.ap-nested-label {
    margin: 0 0 var(--ap-space-1);
    font-family: var(--ap-font-ui);
    font-size: 12px;
    font-weight: 600;
    color: var(--ap-ink-muted);
}

.ap-panel-empty {
    padding: var(--ap-space-4) 20px 20px;
    color: var(--ap-ink-muted);
    font-size: 13px;
}

@media (max-width: 960px) {
    .ap-summary-row {
        flex-wrap: wrap;
        gap: var(--ap-space-3);
    }

    .ap-summary-row-subject {
        flex: 1 1 100%;
    }

    .ap-summary-row-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--ap-space-3) 20px;
    }
}

/* ── Sidebar ──────────────────────────────────────────────────────────────── */

.ap-sidebar {
    width: var(--ap-sidebar-width);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background: var(--ap-sidebar-bg);
    color: var(--ap-sidebar-fg);
    font-family: var(--ap-font-ui);
}

.ap-sidebar-brand {
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    padding: var(--ap-space-6) 20px var(--ap-space-6);
    color: var(--ap-sidebar-fg-strong);
}

/* The mark: a rounded slate tile carrying the initial, which is what keeps the brand block
   from reading as just another nav row. */
.ap-sidebar-mark {
    display: grid;
    place-items: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    background: var(--ap-sidebar-mark-bg);
    color: var(--ap-sidebar-fg-strong);
    font-family: var(--ap-font-display);
    font-weight: 700;
    font-size: 19px;
    line-height: 1;
    flex-shrink: 0;
}

.ap-sidebar-section {
    padding: var(--ap-space-6) var(--ap-space-6) var(--ap-space-2);
    color: var(--ap-sidebar-muted);
}

.ap-sidebar-link {
    display: flex;
    align-items: center;
    gap: var(--ap-space-3);
    min-height: 40px;
    margin: var(--ap-space-1) var(--ap-space-2);
    padding: 0 var(--ap-space-3);
    border-radius: var(--ap-radius-md);
    color: var(--ap-sidebar-fg);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
}

/* Hover is deliberately far subtler than active: they share a column, so if hover used the
   same light slate every row would look like the current one. */
.ap-sidebar-link:hover {
    background: var(--ap-sidebar-hover-bg);
    color: var(--ap-sidebar-fg-strong);
}

.ap-sidebar-link.ap-active {
    background: var(--ap-sidebar-active-bg);
    color: var(--ap-sidebar-fg-strong);
    font-weight: 600;
}

.ap-sidebar-user {
    display: flex;
    align-items: center;
    gap: var(--ap-space-2);
    padding: var(--ap-space-3) var(--ap-space-4);
    border-top: 1px solid var(--ap-sidebar-hairline);
    cursor: pointer;
}

.ap-sidebar-user:hover {
    background: var(--ap-sidebar-hover-bg);
}

/* min-width:0 lets the two lines below ellipsize instead of forcing the rail wider. */
.ap-sidebar-user-text {
    min-width: 0;
}

.ap-sidebar-user-name {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-size: 14px;
    font-weight: 600;
    color: var(--ap-sidebar-fg-strong);
}

/* The row opens the menu; this says so on hover and on keyboard focus, and stays out of the way
   the rest of the time so the rail's resting state is just a name. */
.ap-sidebar-user-more {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    margin-left: auto;
    flex-shrink: 0;
    border-radius: var(--ap-radius-sm);
    background: var(--ap-sidebar-active-bg);
    color: var(--ap-sidebar-fg-strong);
    opacity: 0;
    transition: opacity .12s ease;
}

.ap-sidebar-user:hover .ap-sidebar-user-more,
.ap-sidebar-user:focus-visible .ap-sidebar-user-more {
    opacity: 1;
}

.ap-sidebar-user-more .mud-icon-root {
    font-size: 18px;
}

/* The account menu is a light surface hanging off a dark rail, so it states its own shape and
   colours rather than taking whatever the popover and the rail happen to give it. */
.ap-account-menu.mud-popover {
    /* The activator is the full width of the rail, so the popover anchors at its left edge and the
       menu ends up flush against the screen. Offset by the rail's own gutter instead, and lifted
       clear of the row it belongs to. */
    margin-left: var(--ap-space-2);
    margin-bottom: var(--ap-space-1);
    /* The rail's width less a gutter each side. Reads the same variable the rail itself does — and
       its resize override — so a dragged rail keeps the menu in proportion rather than stranding a
       fixed width inside it. */
    width: calc(var(--bl-nav-w, var(--ap-sidebar-width)) - 20px);
    min-width: 0;
    max-width: none;
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-radius-lg);
    background: var(--ap-surface);
    /* Clips the items to the radius, so the first and last do not square off its corners. */
    overflow: hidden;
}

.ap-account-menu .mud-list {
    padding: var(--ap-space-1) 0;
}

.ap-account-menu .mud-list-item {
    padding: var(--ap-space-2) var(--ap-space-4);
    font-family: var(--ap-font-ui);
    font-size: 14px;
    color: var(--ap-ink);
}

.ap-account-menu .mud-list-item:hover {
    background: var(--ap-hover-bg);
}

.ap-account-menu .mud-divider {
    margin: var(--ap-space-1) 0;
    border-color: var(--ap-hairline);
}

.ap-account-menu .ap-account-menu-danger .mud-list-item-text,
.ap-account-menu .ap-account-menu-danger {
    color: var(--mud-palette-error);
}

/* The menu's activator wrapper must not shrink the block or intercept its layout. */
.ap-sidebar-user-menu,
.ap-sidebar-user-menu > .mud-menu-activator {
    display: block;
    width: 100%;
}

.ap-avatar {
    display: grid;
    place-items: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--ap-surface-sunken);
    color: var(--ap-ink);
    font-family: var(--ap-font-ui);
    font-size: 12px;
    font-weight: 600;
    flex-shrink: 0;
}

/* Keyed to the user block, not to .ap-sidebar: the real rail is .bl-nav, so a rule scoped to the
   style-guide mock's class would leave the live avatar pale on a dark ground. */
.ap-sidebar .ap-avatar,
.ap-sidebar-user .ap-avatar {
    background: var(--ap-sidebar-active-bg);
    color: var(--ap-sidebar-fg-strong);
}

/* ══════════════════════════════════════════════════════════════════════════════
   MudBlazor components.

   Geometry the theme cannot express — height, padding, weight, per-component radius —
   plus the few colour rules MudBlazor derives from a palette slot that does not fit.
   Everything reads a token, so these follow the palette instead of freezing a copy of it.
   ══════════════════════════════════════════════════════════════════════════════ */

/* Buttons are flat. Deliberately NOT applied to .mud-paper: MudCard renders as a paper, and
   so does every elevated surface, so a blanket reset would also flatten menus and dialogs,
   which need a shadow to read as floating. Elevation still resolves through --mud-elevation-N. */
.mud-button-root {
    box-shadow: none;
}

/* Keyboard focus. MudBlazor has no ring of its own; the one this replaces lived in app.css. */
.mud-button:focus-visible,
.mud-icon-button:focus-visible {
    outline: 2px solid var(--ap-primary);
    outline-offset: 2px;
}

/* ── Cards ────────────────────────────────────────────────────────────────────
   The card recipe, on MudCard itself: white, hairline, 12px, flat. Applied to
   .mud-card rather than a variant class so a plain <MudCard> is already correct
   and callers do not have to remember Outlined="true" Elevation="0". */

.mud-card {
    background-color: var(--ap-surface);
    border: 1px solid var(--ap-hairline);
    border-radius: var(--ap-radius-lg);
    box-shadow: none;
}

.mud-card > .mud-card-content {
    padding: var(--ap-space-6);
}

/* A card wrapping a full-bleed table: the table's own hairlines run to the card edge. */
.mud-card.ap-card--flush {
    overflow: hidden;
}

.mud-card.ap-card--flush > .mud-card-content {
    padding: 0;
}

/* A card small enough that 24px of padding would crowd it — a swatch, a compact tile. */
.mud-card.ap-card--tight > .mud-card-content {
    padding: var(--ap-space-2);
}

/* ── List page ──────────────────────────────────────────────────────────
   Filter bar, status tabs, table and footer, as one card. Shared vocabulary rather than one
   page's private classes: this is the shape every list in the app is converging on. */

.ap-list-filters {
    padding: 20px;
    border-bottom: 1px solid var(--ap-hairline);
}

/* The filter controls read as part of the bar, not as a form: hairline border, the app's control
   text size, and a border that darkens on focus instead of MudBlazor's 2px primary ring. Scoped
   to the bar so ordinary forms keep MudBlazor's defaults. */
.ap-list-filters .mud-input.mud-input-outlined .mud-input-outlined-border {
    border-color: var(--ap-hairline);
    border-radius: var(--ap-radius-md);
}

.ap-list-filters .mud-input.mud-input-outlined:not(.mud-disabled):not(:focus-within):hover .mud-input-outlined-border {
    border-color: var(--ap-hairline-strong);
}

.ap-list-filters .mud-input.mud-input-outlined:focus-within > .mud-input-outlined-border {
    border-width: 1px;
    border-color: var(--ap-ink);
}

.ap-list-filters .mud-input,
.ap-list-filters .mud-input-root {
    font-size: 13px;
    color: var(--ap-ink);
}

/* Dense is what the pages ask for; this is that height at this text size — about 44px. */
.ap-list-filters .mud-input > input.mud-input-root-outlined.mud-input-root-margin-dense,
.ap-list-filters div.mud-input-slot.mud-input-root-outlined.mud-input-root-margin-dense {
    padding-top: var(--ap-space-3);
    padding-bottom: var(--ap-space-3);
}

/* Matches the specificity of MudBlazor's own placeholder rule, which fades currentColor to .42
   and would otherwise win. Unscoped: what a placeholder looks like is a property of the design,
   not of the filter bar. */
.mud-input > input.mud-input-root::placeholder,
.mud-input div.mud-input-slot.mud-input-root::placeholder,
div.mud-input-slot.mud-input-root::placeholder {
    color: var(--ap-input-placeholder);
    opacity: 1;
}

.ap-list-filters .mud-input-adornment .mud-icon-root,
.ap-list-filters .mud-select .mud-input-adornment .mud-icon-root {
    font-size: 18px;
    color: var(--ap-ink-faint);
}

/* The chevron is an affordance, not an action — no ripple target around it. */
.ap-list-filters .mud-select .mud-input-adornment .mud-button-root {
    padding: var(--ap-space-1);
    background-color: transparent;
}

/* The tabs filter the single table below rather than switching between panels, so the panel
   container is collapsed. MudTabs still earns its place for the keyboard handling. */
.ap-list-tab-panels {
    display: none;
}

.ap-list-tab-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 var(--ap-space-1);
    border-radius: var(--ap-radius-pill);
    background: var(--ap-surface-sunken);
    color: var(--ap-ink-muted);
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
}

.mud-tab-active .ap-list-tab-count {
    background: var(--ap-ink);
    color: var(--ap-surface);
}

.ap-list-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--ap-ink);
}

.ap-list-sub {
    font-size: 12px;
    color: var(--ap-ink-muted);
}

/* A place, under the thing that happened there. Block-level rather than inline, so it takes its own
   line whatever precedes it — an inline-flex one sat beside a bare "Never" instead of under it.
   The line is always drawn, dash and all, so a column of timestamps does not go ragged over the rows
   whose origin could not be resolved. */
.ap-list-place {
    display: flex;
    align-items: center;
    gap: var(--ap-space-1);
    margin-top: var(--ap-space-1);
    font-size: 12px;
    line-height: 16px;
    color: var(--ap-ink-muted);
}

.ap-list-place .mud-icon-root {
    font-size: 14px;
    color: var(--ap-ink-faint);
}

.ap-list-muted {
    color: var(--ap-ink-muted);
}

/* An action column carries no header text, so it should claim no more width than its controls. */
.ap-list-actions-col {
    width: 1%;
    text-align: right;
    white-space: nowrap;
}

.ap-list-actions-col .mud-icon-button {
    color: var(--ap-interactive-ink);
}

/* Unread count on the bell. Orange rather than red because the guide separates the two: red is
   critical, blocked or overdue, while "you have not read this yet" is an attention marker. The
   count is Carbon Navy — white on this orange is 2.9:1, which the guide names explicitly. */
.ap-badge-attention .mud-badge {
    background-color: var(--ap-attention);
    color: var(--ap-ink);
}

/* A list row is clickable, so it is an interactive element on a light surface and takes the
   guide's hover background. The rule has to be written here: MudBlazor ships no hover rule for
   table rows and nothing in it reads --mud-palette-table-hover, so a clickable row had no hover
   at all. */
.ap-list-table .mud-table-body tr:hover {
    background: var(--ap-hover-bg);
}

.mud-table-body tr:hover .ap-list-actions-col .mud-icon-button {
    color: var(--ap-ink);
}

.ap-list-empty {
    padding: 56px var(--ap-space-6);
    text-align: center;
}

/* Tinted, so the card's chrome — header band and footer — frames the rows between them rather
   than reading as more rows. The .ap-muted override goes with it: the footer sets one ink for
   everything in it, and a caption carrying that class would otherwise fall back to body muted. */
.ap-list-footer,
.ap-list-footer .ap-muted {
    color: var(--ap-ink-muted);
}

.ap-list-footer {
    padding: var(--ap-space-3) 20px;
    border-top: 1px solid var(--ap-hairline);
    background: var(--ap-list-footer-bg);
}

/* ── Tabs ─────────────────────────────────────────────────────────────────────
   Sentence case, muted until active, with a thin ink underline instead of
   MudBlazor's primary-coloured slider. */

.mud-tab {
    min-height: 48px;
    padding: 0 var(--ap-space-4);
    gap: var(--ap-space-2);
    text-transform: none;
    font-family: var(--ap-font-ui);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0;
    color: var(--ap-ink-muted);
}

/* State is carried by the label's weight and colour and by the slider underneath. MudBlazor
   fills the whole tab with --mud-palette-action-default-hover instead, which lands as a grey
   block sitting on the card. */
.mud-tab:hover,
.mud-tab:focus,
.mud-tab.mud-tab-active:hover {
    background-color: transparent;
}

.mud-tab:hover {
    color: var(--ap-ink);
}

.mud-tab.mud-tab-active {
    color: var(--ap-ink);
    font-weight: 600;
}

.mud-tab-slider {
    height: 2px;
    background: var(--ap-ink);
}

/* ── Tables ───────────────────────────────────────────────────────────────────
   Hairline rules, muted small-caps-ish header, roomy rows. The last row drops its
   rule so the table can sit flush inside a card without doubling the border. */

/* The header band carries the canvas tint, so the labels read as a rule over the rows rather
   than as a first, emptier row of data. It is also what keeps a pinned header opaque. */
.mud-table .mud-table-head .mud-table-cell {
    padding: var(--ap-space-3) var(--ap-space-4);
    background-color: var(--ap-canvas);
    border-bottom: 1px solid var(--ap-hairline);
    font-size: 12px;
    font-weight: 600;
    color: var(--ap-ink-muted);
}

.mud-table .mud-table-body .mud-table-cell {
    padding: var(--ap-space-4);
    border-bottom: 1px solid var(--ap-hairline);
    vertical-align: middle;
}

.mud-table .mud-table-body tr:last-child .mud-table-cell {
    border-bottom: none;
}

/* ── Buttons ──────────────────────────────────────────────────────────────────
   Height, padding, weight and icon gap are not expressible through MudTheme —
   LayoutProperties only carries a radius, and MudBlazor 9 dropped the global
   component defaults that would have set the rest. So the geometry has to be CSS.

   What makes this different from the button re-skin in app.css: every value is a
   token, so the buttons follow the palette instead of freezing a copy of it. */

.mud-button-root.mud-button {
    min-height: 40px;
    padding: 0 var(--ap-space-4);
    border-radius: var(--ap-radius-md);
    font-weight: 600;
    letter-spacing: 0;
}

/* MudBlazor prefixes the size class with the variant — mud-button-filled-size-small,
   mud-button-outlined-size-small, mud-button-text-size-small — so match on the suffix
   rather than repeating the rule three times. */
.mud-button-root.mud-button[class*="-size-small"] {
    min-height: 32px;
    padding: 0 var(--ap-space-3);
}

.mud-button-root.mud-button[class*="-size-large"] {
    min-height: 46px;
    padding: 0 var(--ap-space-6);
}

.mud-button-root .mud-button-icon-start {
    margin-right: var(--ap-space-2);
    margin-left: -2px;
}

.mud-button-root .mud-button-icon-end {
    margin-left: var(--ap-space-2);
    margin-right: -2px;
}

.mud-button-filled-primary {
    background-color: var(--ap-primary);
    color: var(--ap-primary-ink);
}

.mud-button-filled-primary:hover {
    background-color: var(--ap-primary-hover);
}

.mud-button-filled-primary:active {
    background-color: var(--ap-primary-pressed);
}

/* The secondary action: white, hairline, near-black label. MudBlazor's outlined-default
   would otherwise take its text from ActionDefault, which is the muted ink. */
.mud-button-outlined {
    border-width: 1px;
}

.mud-button-outlined-default {
    border-color: var(--ap-hairline);
    background-color: var(--ap-surface);
    color: var(--ap-ink);
}

.mud-button-outlined-default:hover {
    border-color: var(--ap-hairline-strong);
    background-color: var(--ap-hover-bg);
}

.mud-button-text-default {
    color: var(--ap-ink-muted);
}

.mud-button-text-default:hover {
    background-color: var(--ap-hover-bg);
    color: var(--ap-ink);
}
