/* =============================================================================
 * Atlas Cloud Tools — Fluent components, painted and sized from atlas-tokens.css
 *
 * CANONICAL COPY. Each tool carries a byte-identical copy; scripts\Sync-AtlasTokens.ps1
 * copies it out and -Check fails the build if a copy has drifted. Edit here only.
 *
 * WHY THIS FILE EXISTS
 * Fluent's components (FAST, both in the React apps via @fluentui/web-components
 * and in the Blazor apps via Microsoft.FluentUI.AspNetCore.Components — they are
 * the same custom elements) render into a SHADOW ROOT. An app stylesheet that
 * says `button { padding: 0 12px }` does not reach the button inside
 * <fluent-button>, which is why layouts collapsed when the markup was converted:
 * the element kept its class, the class kept its rules, and the rules stopped
 * applying to anything that draws.
 *
 * Two mechanisms reach in, and both are used here on purpose.
 *
 *   1. DESIGN TOKENS. Every Fluent colour and metric is a FAST CSSDesignToken,
 *      which is emitted and read as an ordinary CSS custom property — the JS
 *      token API writes exactly the same property. Custom properties inherit
 *      through a shadow boundary, so setting them on :root themes every
 *      component at once, with no script and no interactive render mode. That
 *      last point matters: a statically rendered Blazor layout cannot run
 *      FluentDesignTheme's JS, and this file works there anyway.
 *
 *      Only LEAF tokens are set. Setting --accent-base-color in CSS does
 *      nothing, because the palette it feeds is computed in JS; the leaves it
 *      would have produced are stated directly instead.
 *
 *   2. ::part(). The box model, and any paint the platform defines differently
 *      from Fluent's own recipes. A platform button is Clouds with Midnight Blue
 *      ink and lifts to Wet Asphalt with white ink — that is not Fluent's
 *      neutral or accent button and no token combination produces it.
 *
 * THE SIZING CONTRACT
 * Every host element is laid out by the app's own CSS, exactly as the native
 * element it replaced was. The part inside FILLS the host. So a rule the app
 * already had — `.nav-report-sub { width: 22px }`, `.btn-block { width: 100% }` —
 * keeps working, and app stylesheets do not have to learn about parts.
 * ========================================================================== */


/* =============================================================================
 * 1. Design tokens — the leaves, from atlas-tokens.css
 * ========================================================================== */
:root {
    /* --- Shape ---------------------------------------------------------------
     * Fluent derives control height as
     *     (--base-height-multiplier + --density) * --design-unit px
     * 7.5 * 4 = 30px = --control-h, the one control height on the platform.
     * --design-unit 4 also matches the 4px spacing scale. */
    --design-unit: 4;
    --base-height-multiplier: 7.5;
    --base-horizontal-spacing-multiplier: 3;
    --density: 0;
    --control-corner-radius: 6;         /* --radius, unitless: Fluent multiplies by 1px */
    --layer-corner-radius: 6;
    --stroke-width: 1;
    --focus-stroke-width: 2;

    /* Disabled is a COLOUR on this platform, not a fade — a faded control reads
       as a rendering fault rather than as "not available yet". The opacity is
       neutralised and the disabled paint is applied in §3. */
    --disabled-opacity: 1;

    /* --- Type ---------------------------------------------------------------- */
    --body-font: var(--font-stack);
    --type-ramp-base-font-size: 14px;       /* --font-size-body */
    --type-ramp-base-line-height: 20px;
    --type-ramp-minus-1-font-size: 13px;    /* --font-size-table */
    --type-ramp-minus-1-line-height: 18px;
    --type-ramp-minus-2-font-size: 11px;    /* --font-size-micro */
    --type-ramp-minus-2-line-height: 16px;

    /* --- The accent ----------------------------------------------------------
     * Fluent's accent is the saturated, ink-on-dark end of the scale; on this
     * platform that is the button's HOVER fill, not its rest fill. */
    --accent-fill-rest: var(--color-action-hover);
    --accent-fill-hover: var(--color-action-ink);
    --accent-fill-active: var(--color-action-ink);
    --accent-fill-focus: var(--color-action-hover);
    --accent-foreground-rest: var(--color-action-ink);
    --accent-foreground-hover: var(--color-action-hover);
    --accent-foreground-active: var(--color-action-ink);
    --accent-foreground-focus: var(--color-action-ink);
    --accent-stroke-control-rest: var(--color-action-edge);
    --accent-stroke-control-hover: var(--color-action-edge);
    --accent-stroke-control-active: var(--color-action-edge);
    --accent-stroke-control-focus: var(--color-action-hover);

    /* The ink that sits ON the accent. Clouds, never white — white is not in
       this palette. */
    --foreground-on-accent-rest: var(--color-action-hover-fg);
    --foreground-on-accent-hover: var(--color-action-hover-fg);
    --foreground-on-accent-active: var(--color-action-hover-fg);
    --foreground-on-accent-focus: var(--color-action-hover-fg);
    --foreground-on-accent-rest-large: var(--color-action-hover-fg);
    --foreground-on-accent-hover-large: var(--color-action-hover-fg);
    --foreground-on-accent-active-large: var(--color-action-hover-fg);
    --foreground-on-accent-focus-large: var(--color-action-hover-fg);

    /* --- Text ---------------------------------------------------------------- */
    --neutral-foreground-rest: var(--color-text);
    --neutral-foreground-hover: var(--color-text-strong);
    --neutral-foreground-active: var(--color-text-strong);
    --neutral-foreground-focus: var(--color-text);
    --neutral-foreground-hint: var(--color-text-muted);
    --input-placeholder-rest: var(--color-text-subtle);
    --input-placeholder-hover: var(--color-text-muted);
    --input-filled-placeholder-rest: var(--color-text-subtle);
    --input-filled-placeholder-hover: var(--color-text-muted);

    /* --- Fills ---------------------------------------------------------------
     * An INPUT is white (--color-surface). A neutral BUTTON is Clouds
     * (--color-action). Fluent keeps those on two separate token families,
     * which is exactly the split the platform wants. */
    --fill-color: var(--color-surface);
    --neutral-fill-input-rest: var(--color-surface);
    --neutral-fill-input-hover: var(--color-surface);
    --neutral-fill-input-active: var(--color-surface);
    --neutral-fill-input-focus: var(--color-surface);
    --neutral-fill-input-alt-rest: var(--color-surface);
    --neutral-fill-input-alt-hover: var(--color-surface);
    --neutral-fill-input-alt-active: var(--color-surface);
    --neutral-fill-input-alt-focus: var(--color-surface);

    --neutral-fill-rest: var(--color-action);
    --neutral-fill-hover: var(--color-action-hover);
    --neutral-fill-active: var(--color-action-ink);
    --neutral-fill-focus: var(--color-action);

    --neutral-fill-secondary-rest: var(--color-surface-2);
    --neutral-fill-secondary-hover: var(--color-row-hover);
    --neutral-fill-secondary-active: var(--color-accent-wash);
    --neutral-fill-secondary-focus: var(--color-surface-2);

    /* Stealth is the transparent button — a toolbar icon, a menu row. */
    --neutral-fill-stealth-rest: transparent;
    --neutral-fill-stealth-hover: var(--color-surface-2);
    --neutral-fill-stealth-active: var(--color-accent-wash);
    --neutral-fill-stealth-focus: transparent;
    --neutral-fill-stealth-rest-on-neutral-fill-layer-rest: transparent;
    --neutral-fill-stealth-hover-on-neutral-fill-layer-rest: var(--color-surface-2);
    --neutral-fill-stealth-active-on-neutral-fill-layer-rest: var(--color-accent-wash);

    --neutral-fill-strong-rest: var(--color-text-subtle);
    --neutral-fill-strong-hover: var(--color-text-muted);
    --neutral-fill-strong-active: var(--color-text-muted);
    --neutral-fill-strong-focus: var(--color-text-subtle);

    --neutral-fill-layer-rest: var(--color-surface);
    --neutral-fill-layer-hover: var(--color-surface-3);
    --neutral-fill-layer-active: var(--color-surface-2);
    --neutral-fill-layer-alt-rest: var(--color-surface-3);

    /* The floating layer: a select's open list, a menu, a tooltip. */
    --neutral-layer-floating: var(--color-surface);
    --neutral-layer-card-container: var(--color-surface);
    --neutral-layer-1: var(--color-surface);
    --neutral-layer-2: var(--color-surface-3);
    --neutral-layer-3: var(--color-surface-2);
    --neutral-layer-4: var(--color-surface-2);

    /* --- Strokes -------------------------------------------------------------- */
    --neutral-stroke-rest: var(--color-border);
    --neutral-stroke-hover: var(--color-border-strong);
    --neutral-stroke-active: var(--color-border-strong);
    --neutral-stroke-focus: var(--color-action-hover);
    --neutral-stroke-control-rest: var(--color-action-edge);
    --neutral-stroke-control-hover: var(--color-action-edge);
    --neutral-stroke-control-active: var(--color-action-edge);
    --neutral-stroke-control-focus: var(--color-action-hover);
    --neutral-stroke-input-rest: var(--color-border-strong);
    --neutral-stroke-input-hover: var(--color-text-subtle);
    --neutral-stroke-input-active: var(--color-text-subtle);
    --neutral-stroke-input-focus: var(--color-action-hover);
    --neutral-stroke-divider-rest: var(--color-border);
    --neutral-stroke-layer-rest: var(--color-border);
    --neutral-stroke-layer-hover: var(--color-border-strong);
    --neutral-stroke-layer-active: var(--color-border-strong);
    --neutral-stroke-strong-rest: var(--color-text-muted);
    --neutral-stroke-strong-hover: var(--color-text);
    --neutral-stroke-strong-active: var(--color-text);
    --neutral-stroke-strong-focus: var(--color-action-hover);

    /* --- Focus ---------------------------------------------------------------
     * One focus treatment for the whole platform: the action colour outside,
     * the light ink inside so the ring reads on a dark fill too. */
    --focus-stroke-outer: var(--color-action-hover);
    --focus-stroke-inner: var(--color-action-hover-fg);

    /* --- Elevation ------------------------------------------------------------
     * Fluent's shadows are heavier than the platform's two. */
    --elevation-shadow-card-rest: var(--shadow-sm);
    --elevation-shadow-card-hover: var(--shadow);
    --elevation-shadow-card-active: var(--shadow-sm);
    --elevation-shadow-card-focus: var(--shadow);
    --elevation-shadow-flyout: var(--shadow);
    --elevation-shadow-dialog: var(--shadow);
    --elevation-shadow-tooltip: var(--shadow-sm);
}


/* =============================================================================
 * 2. The sizing contract
 *
 * The host is laid out by the app's CSS; the part fills the host. Every rule an
 * app already had against the native element's class keeps working.
 * ========================================================================== */
fluent-button,
fluent-text-field,
fluent-text-area,
fluent-number-field,
fluent-search,
fluent-select,
fluent-combobox {
    font-family: var(--font-stack);
    font-size: var(--font-size-control);
    vertical-align: middle;
}

/* ONE CONTROL HEIGHT, SET ON THE HOST.
 *
 * The floor used to be min-height on the PART, which no app rule could get under:
 * a 22px icon button in a table row was forced to 30px and broke the row. Height
 * belongs on the host instead, where an app that genuinely needs a different box
 * — a square icon button, a tall search field — overrides it with its own class,
 * and where the part simply fills whatever it is given.
 *
 * A text area is exempt: it is the one control that is not one line tall. */
fluent-button,
fluent-text-field,
fluent-number-field,
fluent-search,
fluent-select,
fluent-combobox {
    height: var(--control-h);
}

/* A FIELD IN A FORM GRID FILLS ITS COLUMN.
 *
 * A Fluent field sizes to its own content, so a field in a grid column that is
 * wider than it leaves the remainder as dead space INSIDE the column — and the
 * eye reads that remainder as the gap to the next field. ACH's Vendor ACH row
 * was the case that showed it: a 280px select in a col-md-4, which at the
 * content cap is a ~530px column, put roughly 250px of nothing between Vendor
 * and Bank account while every other pair in the row was 8px apart. The gap was
 * never set anywhere — it was left over.
 *
 * The column already IS the width the layout intends, so the field takes it and
 * the only gap left is the grid's own gutter. This also means a field's width is
 * a layout decision in the markup, never a pixel value on the component.
 *
 * Scoped to a grid column or a .field wrapper: a Fluent control that is
 * deliberately sized — a search box in the app bar, an icon button — is not in
 * one and is untouched. */
:is([class*="col-"], .field, .form-group) > :is(
    fluent-text-field,
    fluent-number-field,
    fluent-search,
    fluent-select,
    fluent-combobox
) {
    width: 100%;
}

/* THE HOST DOES NOT PAINT.
 *
 * This is the other half of the contract and it is not optional. A Fluent
 * element's host box is behind the part that draws, so when app CSS — or an
 * inline style — puts a background, a border or padding on the host, BOTH show:
 * the app's dark box, and the platform's control sitting inside it, inset by the
 * host's padding. That is not a subtle mismatch; it reads as a broken control,
 * and it is what a converted button looked like anywhere its old paint was left
 * on the host.
 *
 * !important because the rules being neutralised are class selectors and inline
 * styles, which otherwise win. It is safe to be absolute here: the host CANNOT
 * paint anything the user should see, so there is no case where honouring it is
 * correct. Everything the app wants painted is carried to the part instead —
 * Fix-FluentCss.js does that for stylesheets, and §3 below is the platform's own
 * default for anything not carried.
 *
 * Layout is untouched: width, height, margin, display, flex and position still
 * belong to the host, which is what keeps every existing layout rule working. */
fluent-button,
fluent-text-field,
fluent-text-area,
fluent-number-field,
fluent-search,
fluent-select,
fluent-combobox,
fluent-checkbox,
fluent-radio,
fluent-switch {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
}

fluent-button::part(control),
fluent-text-field::part(root),
fluent-number-field::part(root),
fluent-search::part(root),
fluent-select::part(control),
fluent-combobox::part(control) {
    box-sizing: border-box;
    width: 100%;
    height: 100%;
    /* No minimum here — the HOST carries the control height, so a control the app
       deliberately made smaller stays smaller. */
    min-height: 0;
    min-width: 0;
    border-radius: var(--radius);
    font-family: inherit;
    font-size: inherit;
}

/* A TEXTAREA IS THE ONE CONTROL THAT IS NOT ONE LINE TALL.
 *
 * Apps give their fields a shared class — .field__input, .form-control — that
 * carries the platform's single control height. On a text area that height
 * applies to the HOST, and the multi-line control inside is then clipped to one
 * line: the Statements message body showed three lines of template in a 30px
 * box. The host cannot be one line tall, whatever class it carries, so this is
 * absolute; `rows` governs the height from there. */
fluent-text-area {
    display: inline-block;
    height: auto !important;
    min-height: calc(var(--control-h) * 2);
}

/* A text area has NO root part — only label and control. Every box rule aimed
   at ::part(root) therefore painted nothing, which is why it came out with no
   border and no fill while every field beside it had both. The box lives on the
   control. */
fluent-text-area::part(control) {
    box-sizing: border-box;
    width: 100%;
    height: auto;
    border-radius: var(--radius);
}

fluent-text-area::part(control) {
    box-sizing: border-box;
    width: 100%;
    height: auto;
    min-height: calc(var(--control-h) * 2);
    padding: var(--space-3);
    font-family: inherit;
    font-size: inherit;
    resize: vertical;
}

/* The label a Fluent field draws for itself. Every app draws its own, so this
   only fires where a component was given a label attribute. */
fluent-text-field::part(label),
fluent-text-area::part(label),
fluent-number-field::part(label),
fluent-select::part(label),
fluent-checkbox::part(label),
fluent-search::part(label) {
    font-size: var(--font-size-micro);
    font-weight: 600;
    letter-spacing: .02em;
    text-transform: uppercase;
    color: var(--color-text-muted);
    padding-bottom: var(--space-2);
}


/* =============================================================================
 * 3. The controls, one by one
 * ========================================================================== */

/* --- Button ------------------------------------------------------------------
 *
 * ONE BUTTON. Light grey at rest, steel blue on hover. Every button in every
 * tool: the Save under a settings section, the icon in a table row, the toggle
 * in a nav strip, the menu button in the dark app bar, the Cancel in a modal.
 * Same fill, same edge, same ink, same height, same radius, same padding, same
 * type, same hover.
 *
 * There are no variants here on purpose. Fluent ships appearance="accent",
 * "outline", "stealth" and "lightweight"; the platform had a quiet icon button,
 * a text button, a compact button and a translucent one for the dark bar. Each
 * was defensible on its own and the result was a screen with four kinds of
 * button on it. Emphasis comes from POSITION and WORDING.
 *
 * What survives is STATE, not style:
 *   pressed    the button is being clicked
 *   latched    a toggle that is currently on, a view that is selected
 *   disabled   the action is not available — and must never look like it is
 *
 * ORDER MATTERS. ::part() rules compete on ordinary specificity, so the states
 * come after the base and disabled comes last.
 * ========================================================================== */
fluent-button {
    display: inline-flex;
    height: var(--control-h);
}

/* --- Clearance around --------------------------------------------------------
 * A BUTTON never sits hard against whatever is next to it — above, below, or
 * the button beside it. Buttons were landing flush under the control or the
 * paragraph they follow and flush on top of the table below, and each app had
 * patched its own gap into its own markup, so the same Save had a different
 * space around it in ACH than in Warranty. The clearance is the air a table
 * already puts around its rows, so a button and a row read on the same rhythm.
 * One declaration on the host puts it under every tool, and retuning it is one
 * token.
 *
 * On the HOST, not ::part(control): a margin inside the shadow root would move
 * the fill away from the button's own box and take the focus ring with it.
 *
 * The flat affordances are excluded. An ICON in a table row, a ROW in a menu, a
 * text LINK and a FIELD TRIGGER are not buttons — a margin on them opens a gap
 * mid-list, or drops a trigger below the fields it sits beside. A button in the
 * dark bar is excluded for the same reason: the bar centres its contents in a
 * fixed height, so a top margin there is an off-centre button, not clearance. */
fluent-button:not(
    .icon-btn, .icon-btn--danger, .cr-iconbtn, .cr-iconbtn2, .nav-report-sub,
    .nav-toggle-btn-header, .search-clear-btn, .rpm__x, .update-toast__x, .pwl-upgrade-x,
    .btn-close, .views-menu-del,
    .rpm__item, .views-menu-item, .cr-menu__item, .cr-viewrow__name,
    .app-bar__menu-item, .nav-folder-header, .nav-report-item, .dropdown-item,
    .btn-link, .cr-link, .sched__link, .mfa-link, .forgot-link, .link,
    .atlas-picker__trigger, .atlas-picker__action, .app-bar__btn,
    /* A TILE IN A LIST SPACES ITSELF THROUGH ITS CONTAINER. These two rules
       give a button air by putting margin ON THE BUTTON, which is right for a
       pair of actions in a form but wrong for a stacked list: the portal grid
       already has gap:12px, and the adjacent-sibling margin then indented
       tiles two through six by 8px against the first. */
    .atlas-card-button, .application-card, .search-report-card
):not(:is(.app-header, .app-bar, .header-wrapper, .header-content, .header-inner) *) {
    margin-block: var(--button-gap, 0.5em);
}

/* Two buttons side by side get the same air between them. Stated on the
   adjacent sibling rather than as a gap on the container, because the
   containers are per app — a form's action row, a toolbar, the pair under the
   logo — and there is no one class to hang a gap on. */
fluent-button + fluent-button:not(
    .icon-btn, .icon-btn--danger, .cr-iconbtn, .cr-iconbtn2, .nav-report-sub,
    .nav-toggle-btn-header, .search-clear-btn, .rpm__x, .update-toast__x, .pwl-upgrade-x,
    .btn-close, .views-menu-del,
    .rpm__item, .views-menu-item, .cr-menu__item, .cr-viewrow__name,
    .app-bar__menu-item, .nav-folder-header, .nav-report-item, .dropdown-item,
    .btn-link, .cr-link, .sched__link, .mfa-link, .forgot-link, .link,
    .atlas-picker__trigger, .atlas-picker__action, .app-bar__btn,
    /* A TILE IN A LIST SPACES ITSELF THROUGH ITS CONTAINER. These two rules
       give a button air by putting margin ON THE BUTTON, which is right for a
       pair of actions in a form but wrong for a stacked list: the portal grid
       already has gap:12px, and the adjacent-sibling margin then indented
       tiles two through six by 8px against the first. */
    .atlas-card-button, .application-card, .search-report-card
):not(:is(.app-header, .app-bar, .header-wrapper, .header-content, .header-inner) *) {
    margin-inline-start: var(--button-gap, 0.5em);
}

/* --- Rest ------------------------------------------------------------------- */
fluent-button::part(control) {
    /* The host carries the height, and the part fills it — but a host set to
       display:contents generates no box at all, and then the part has nothing to
       fill and shrinks to its label. One minimum here keeps every button the same
       height whatever its host does. */
    min-height: var(--control-h);
    padding: var(--control-pad-y) var(--control-pad-x);
    /* GAP ZERO HERE, AND ON ::part(content) INSTEAD. Fluent's shadow root always
       renders an empty <span part="start"> and <span part="end"> around the
       content, width 0 but still flex items — so a gap on the control is
       charged TWICE for slots that hold nothing, and every React button came
       out 2 × gap wider than the Blazor button with the same label (52px vs
       64px for OK). It is why the two sides still did not measure the same
       after the box tokens were unified. The glyph a tool puts in the button is
       in the DEFAULT slot, inside part=content, so the gap belongs there. */
    gap: 0;
    background: var(--color-action);
    color: var(--color-action-fg);
    border: 1px solid var(--color-action-edge);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    font-family: var(--font-stack);
    font-size: var(--font-size-control);
    font-weight: 500;
    line-height: 1.4;
    text-decoration: none;
    cursor: pointer;
    transition: background-color .12s ease, color .12s ease, border-color .12s ease;
}

fluent-button::part(content) {
    display: inline-flex;
    align-items: center;
    gap: var(--control-gap);
}

/* --- Card button -------------------------------------------------------------
 * A FIFTH AFFORDANCE: a full-width tile that acts. The portal's app list is six
 * of them, and Fluent cannot be told to be one from the host.
 *
 * .application-card was a <fluent-button> carrying display:flex, gap, padding,
 * a white fill and an edge — every one of them on the HOST, where none of them
 * reaches anything. The box a button draws is ::part(control) inside the shadow
 * root and the slotted children land inside ::part(content); so the tile
 * rendered as an ordinary 30px button with its icon, title and chevron spilling
 * out of a grey pill. The host rules had been there long enough to look
 * deliberate, which is why the tile was never questioned.
 *
 * Everything the tile needs is therefore said on the two parts. The one thing
 * the host still has to do is stop being an inline-sized button: a tile is as
 * wide as the column it sits in. */
fluent-button.atlas-card-button,
fluent-button.search-report-card,
fluent-button.application-card {
    display: block;
    width: 100%;
    height: auto;
    min-height: 0;
}

fluent-button.atlas-card-button::part(control),
fluent-button.search-report-card::part(control),
fluent-button.application-card::part(control) {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    width: 100%;
    height: auto;
    /* A tile is as tall as its content, not one control high. */
    min-height: 0;
    /* --space-6 --space-5: 24 by 16, the tile's own air. --space-4 made it
       12 all round and the row read as a list item rather than a card. */
    padding: var(--space-5) var(--space-6);
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: none;
    font-size: var(--font-size-base);
    font-weight: 400;
    /* A button centres its label and refuses to wrap. A tile is a paragraph. */
    text-align: left;
    white-space: normal;
}

/* The slot is inside part=content, so the tile's own row — icon, text, chevron —
   is laid out HERE. It has to fill the control or the chevron sits against the
   text instead of the far edge. */
fluent-button.atlas-card-button::part(content),
fluent-button.search-report-card::part(content),
fluent-button.application-card::part(content) {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    width: 100%;
}

fluent-button.atlas-card-button:hover::part(control),
fluent-button.search-report-card:hover::part(control),
fluent-button.application-card:hover::part(control) {
    background: var(--color-surface);
    color: var(--color-text);
    border-color: var(--color-border-strong);
    box-shadow: var(--shadow);
}

/* --- Small ------------------------------------------------------------------
 * One button HEIGHT platform-wide; small tightens the horizontal padding only.
 * Both tools had this on the host, where padding does nothing. */
fluent-button.btn--sm::part(control),
fluent-button.cr-btn--sm::part(control) {
    padding: var(--control-pad-y) var(--control-pad-x-tight);
}


/* --- Page tab ----------------------------------------------------------------
 * NOT the app bar tab: that one sits on Midnight. This is a tab strip on the
 * page — no box at all, just a label that grows an edge underneath when it is
 * the current one. BIReports' schedule editor declared the whole thing on the
 * host, so all three tabs rendered as ordinary filled buttons in a row. */
fluent-button.sched__tab::part(control) {
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    border-radius: 0;
    box-shadow: none;
    padding: var(--space-3) var(--control-pad-x);
    color: var(--color-text-muted);
    font-size: var(--font-size-control);
    font-weight: 600;
}

fluent-button.sched__tab:hover::part(control) {
    background: none;
    border-bottom-color: var(--color-border-strong);
    color: var(--color-text-strong);
}

fluent-button.sched__tab--on::part(control),
fluent-button.sched__tab.is-on::part(control) {
    color: var(--color-action-ink);
    border-bottom-color: var(--color-action-edge);
}


/* --- Round close -------------------------------------------------------------
 * The dismiss on a toast. Same bare icon as every other close, but round,
 * because it sits inside a rounded strip rather than in a row of controls. */
fluent-button.send-toast__close::part(control) {
    background: transparent;
    border: 0;
    box-shadow: none;
    border-radius: 50%;
    padding: var(--control-pad-y);
    min-height: 0;
    color: inherit;
}

fluent-button.send-toast__close:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: inherit;
}


/* --- Small outlined ----------------------------------------------------------
 * A button that clears a filter sits INSIDE a summary line, so it cannot be a
 * filled action competing with the line it is part of. Outlined, on the page
 * surface, one step down in size. */
fluent-button.summary-bar__filter-clear::part(control) {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: none;
    color: var(--color-text);
    font-size: var(--font-size-table);
    font-weight: 400;
    padding: var(--space-1) var(--control-pad-x-tight);
    min-height: 0;
}

fluent-button.summary-bar__filter-clear:hover::part(control) {
    background: var(--color-surface-3);
    border-color: var(--color-border-strong);
    color: var(--color-text-strong);
}

fluent-button.summary-bar__filter-clear--all::part(control) {
    font-weight: 600;
    color: var(--color-text-muted);
}

fluent-button.summary-bar__filter-clear--compact::part(control) {
    font-size: var(--font-size-micro);
    padding: var(--space-1) var(--space-3);
}

fluent-button.summary-bar__filter-clear--compact::part(content) { gap: var(--space-2); }


/* --- Heading button ----------------------------------------------------------
 * A section title that also acts. It carries no box: it IS the heading, and
 * only the pointer says it does anything. */
fluent-button.preview-panel__title-btn::part(control) {
    background: none;
    border: 0;
    box-shadow: none;
    padding: 0;
    min-height: 0;
    color: inherit;
    font: inherit;
}

fluent-button.preview-panel__title-btn:hover::part(control) {
    background: none;
    color: var(--color-action-hover);
}

fluent-button.preview-panel__title-btn:disabled::part(control) {
    background: none;
    color: var(--color-text-muted);
}


/* --- Icon --------------------------------------------------------------------
 * A GLYPH IS NOT A BOX. An icon action repeats down a table column and sits
 * inside toolbars and toasts; drawn as a filled button it turns a quiet column
 * of affordances into a wall of grey chips, which is what ACH Tools' vendor
 * table looked like.
 *
 * atlas-theme.css has said this for the Blazor tools since ACT-70 — but only
 * for a NATIVE <button class="icon-btn">. Every one of these is a
 * <fluent-button> now, and the only ::part rule for .icon-btn in this file was
 * scoped to .atlas-popup. So inside a menu the icons were right and everywhere
 * else they wore the default button. Same treatment, no scope.
 *
 * Square, because a glyph has no label to set its width. The ink is muted at
 * rest and the surface only appears under the pointer. */
fluent-button.icon-btn::part(control),
fluent-button.icon-btn--danger::part(control),
fluent-button.cr-iconbtn::part(control),
fluent-button.cr-iconbtn2::part(control),
fluent-button.nav-report-sub::part(control),
fluent-button.search-clear-btn::part(control),
fluent-button.update-toast__x::part(control),
fluent-button.rpm__x::part(control),
fluent-button.pwl-upgrade-x::part(control),
fluent-button.btn-close::part(control),
fluent-button.views-menu-del::part(control) {
    width: var(--control-h);
    min-width: var(--control-h);
    height: var(--control-h);
    min-height: var(--control-h);
    padding: 0;
    justify-content: center;
    background: none;
    border: 1px solid transparent;
    border-radius: var(--radius);
    box-shadow: none;
    color: var(--color-text-muted);
}

fluent-button.icon-btn:hover::part(control),
fluent-button.icon-btn--danger:hover::part(control),
fluent-button.cr-iconbtn:hover::part(control),
fluent-button.cr-iconbtn2:hover::part(control),
fluent-button.nav-report-sub:hover::part(control),
fluent-button.search-clear-btn:hover::part(control),
fluent-button.update-toast__x:hover::part(control),
fluent-button.rpm__x:hover::part(control),
fluent-button.pwl-upgrade-x:hover::part(control),
fluent-button.btn-close:hover::part(control),
fluent-button.views-menu-del:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: var(--color-text-strong);
}


/* EXPAND ALL / COLLAPSE ALL IS A BUTTON, NOT AN ICON.
 *
 * It was in the ICON list above — no fill, no edge — while atlas-theme.css
 * defined the very same class as a FILLED button, under a comment saying the
 * two copies must be retuned together. Nobody could satisfy both: BIReports
 * renders a <fluent-button> and took the ICON version, so it came out as a bare
 * chevron floating in the gutter beside Paginated, Pin and Subscriptions, all
 * three of them filled buttons; ACH and Warranty render a native <button> and
 * took the filled one. Same control, two looks, and the file that says they
 * must match is the one they diverged in.
 *
 * Settled the way atlas-theme.css already states it: it is an action, so it is
 * a button, square because its glyph has no label. */
fluent-button.toggle-expand-btn::part(control) {
    width: var(--control-h);
    min-width: var(--control-h);
    height: var(--control-h);
    min-height: var(--control-h);
    padding: 0;
    justify-content: center;
    background: var(--color-action);
    border: 1px solid var(--color-action-edge);
    border-radius: var(--radius);
    box-shadow: none;
    color: var(--color-action-fg);
}

fluent-button.toggle-expand-btn:hover::part(control) {
    background: var(--color-action-hover);
    border-color: var(--color-action-hover);
    color: var(--color-action-hover-fg);
}

fluent-button.icon-btn:disabled::part(control),
fluent-button.icon-btn--danger:disabled::part(control),
fluent-button.cr-iconbtn:disabled::part(control),
fluent-button.cr-iconbtn2:disabled::part(control),
fluent-button.nav-report-sub:disabled::part(control),
fluent-button.search-clear-btn:disabled::part(control),
fluent-button.update-toast__x:disabled::part(control),
fluent-button.rpm__x:disabled::part(control),
fluent-button.pwl-upgrade-x:disabled::part(control),
fluent-button.btn-close:disabled::part(control),
fluent-button.views-menu-del:disabled::part(control),
fluent-button.toggle-expand-btn:disabled::part(control) {
    background: none;
    border-color: transparent;
    color: var(--color-disabled-fg);
}

/* A destructive glyph says so under the pointer, never at rest: a table full of
   red icons reads as a table full of errors. */
fluent-button.icon-btn--danger:hover::part(control),
fluent-button.icon-btn.danger:hover::part(control),
fluent-button.views-menu-del:hover::part(control) {
    background: var(--color-danger-bg);
    color: var(--color-danger);
    border-color: transparent;
}


/* --- Hover ------------------------------------------------------------------ */
fluent-button:hover::part(control) {
    background: var(--color-action-hover);
    color: var(--color-action-hover-fg);
    border-color: var(--color-action-hover);
    text-decoration: none;
}

/* --- Pressed, and latched --------------------------------------------------
 * PRESSED is the moment of the click: the button goes dark under the pointer.
 *
 * LATCHED is a toggle that is currently on, and it CANNOT be the hover colour.
 * It was, and the result was Paginated sitting in steel blue beside a light grey
 * Pin — the on button looking exactly like the one you happen to be hovering, so
 * hovering Pin made it look latched too.
 *
 * NOR CAN IT BE ITS OWN EDGE. Latched briefly carried a Midnight border, and
 * that put a second border colour on a light page: Paginated came out ringed in
 * near-black beside a silver-ringed Pin and Subscriptions, which reads as two
 * kinds of button rather than one button in two states. THE BORDER IS SILVER ON
 * EVERY BUTTON ON A LIGHT GROUND, in every state except the pointer's own
 * (hover and pressed, which are the same on all of them). Latched is carried by
 * the heavier label alone. */
fluent-button:active::part(control) {
    background: var(--color-action-ink);
    color: var(--color-action-hover-fg);
    border-color: var(--color-action-ink);
}

fluent-button.is-on::part(control),
fluent-button.is-active::part(control),
fluent-button.is-pinned::part(control),
fluent-button.is-open::part(control),
fluent-button.active::part(control),
fluent-button.selected::part(control),
fluent-button[aria-pressed=true]::part(control),
fluent-button[aria-expanded=true]::part(control) {
    background: var(--color-action);
    color: var(--color-action-fg);
    border-color: var(--color-action-edge);
    font-weight: 600;
}

fluent-button.is-on:hover::part(control),
fluent-button.is-active:hover::part(control),
fluent-button.is-pinned:hover::part(control),
fluent-button.is-open:hover::part(control),
fluent-button.active:hover::part(control),
fluent-button.selected:hover::part(control),
fluent-button[aria-pressed='true']:hover::part(control),
fluent-button[aria-expanded='true']:hover::part(control) {
    /* Hover is steel blue on EVERY button, latched included — a latched button
       that hovered to midnight was a third colour in a two-colour system, and
       it read as a different kind of control. The edge follows the fill, exactly
       as it does on a button that is not latched: a hovered button looks the
       same whether or not it is on, and the heavier label is what still says
       on. */
    background: var(--color-action-hover);
    color: var(--color-action-hover-fg);
    border-color: var(--color-action-hover);
}

/* =============================================================================
 * NOT EVERY CLICKABLE THING IS A BUTTON
 *
 * A button is the right ELEMENT for anything that acts — it focuses, it takes
 * the keyboard, it can be disabled — so the platform builds three different
 * affordances on it. They are not three button variants: they are a button, an
 * icon, and a row, and each has to look like what it is.
 *
 *   BUTTON   a command. Light grey, steel blue on hover. Defined above.
 *   ICON     a glyph in a toolbar or a table row. No fill, no edge, no shadow —
 *            just the glyph, tinting on hover. A row of grey boxes down an
 *            Actions column is noise, and it makes Delete look like Edit.
 *   ROW      a line in a list: a report to pick, a view to load, a menu entry.
 *            Full width, text on the left, no box at all. A picker rendered as
 *            a stack of pills is unreadable.
 *
 * These come after the button's own states and before disabled, which still has
 * the last word.
 * ========================================================================== */

/* --- Icon ------------------------------------------------------------------- */

/* A destructive icon says so under the pointer, not at rest: a table full of red
   is a table nobody reads. */
fluent-button.icon-btn--danger:hover::part(control),
fluent-button.icon-btn.danger:hover::part(control),
fluent-button.views-menu-del:hover::part(control) {
    background: var(--color-danger-bg);
    color: var(--color-danger);
    border-color: transparent;
}

/* An icon ON THE DARK BAR is light, not muted-dark: the same Asbestos that
   reads as quiet on a white toolbar disappears against #1f2937. Light grey at
   rest, white under the pointer, and no tint behind it — the bar is the
   background. */
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar) fluent-button.nav-toggle-btn-header::part(control),
fluent-button.nav-toggle-btn-header::part(control) {
    color: var(--color-shell-fg-dim);
    background: transparent;
    border-color: transparent;
}

fluent-button.nav-toggle-btn-header:hover::part(control) {
    /* Ink alone moved too little to notice against the bar, so the hover also
       takes the shell's own faint field tint. */
    color: var(--color-shell-fg);
    background: var(--color-shell-field-bg);
    border-color: transparent;
}

/* --- Row -------------------------------------------------------------------- */
/* A ROW FILLS ITS LIST. ::part(control) is width:100% OF THE HOST, and Fluent
   hosts are inline-flex — so a row whose host was left alone shrank to its
   label and rendered as a centred pill in the middle of the nav. The host has
   to be a block before the part can fill anything. */
fluent-button.rpm__item,
fluent-button.views-menu-item,
fluent-button.cr-menu__item,
fluent-button.cr-viewrow__name,
fluent-button.app-bar__menu-item,
fluent-button.nav-folder-header,
fluent-button.nav-report-item,
fluent-button.dropdown-item {
    display: block;
    width: 100%;
    height: auto;
    min-height: 0;
}

fluent-button.rpm__item::part(control),
fluent-button.views-menu-item::part(control),
fluent-button.cr-menu__item::part(control),
fluent-button.cr-viewrow__name::part(control),
fluent-button.app-bar__menu-item::part(control),
fluent-button.nav-folder-header::part(control),
fluent-button.nav-report-item::part(control),
fluent-button.dropdown-item::part(control) {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    border-radius: 0;
    color: var(--color-text);
    width: 100%;
    justify-content: flex-start;
    text-align: left;
    padding: 0 var(--space-3);
    font-weight: 400;
}

fluent-button.rpm__item:hover::part(control),
fluent-button.views-menu-item:hover::part(control),
fluent-button.cr-menu__item:hover::part(control),
fluent-button.cr-viewrow__name:hover::part(control),
fluent-button.app-bar__menu-item:hover::part(control),
fluent-button.nav-folder-header:hover::part(control),
fluent-button.nav-report-item:hover::part(control),
fluent-button.dropdown-item:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: var(--color-text-strong);
}

/* The row that is currently chosen keeps the platform's selected surface, the
   same one an option in a list box takes. */
fluent-button.rpm__item.is-active::part(control),
fluent-button.views-menu-item.is-active::part(control),
fluent-button.cr-menu__item.is-active::part(control),
fluent-button.cr-viewrow__name.is-active::part(control),
fluent-button.app-bar__menu-item.is-active::part(control),
fluent-button.nav-folder-header.is-active::part(control),
fluent-button.nav-report-item.is-active::part(control),
fluent-button.dropdown-item.is-active::part(control),
fluent-button.rpm__item.selected::part(control),
fluent-button.views-menu-item.selected::part(control),
fluent-button.cr-menu__item.selected::part(control),
fluent-button.cr-viewrow__name.selected::part(control),
fluent-button.app-bar__menu-item.selected::part(control),
fluent-button.nav-report-item.selected::part(control),
fluent-button.dropdown-item.selected::part(control) {
    background: var(--color-surface-2);
    color: var(--color-text-strong);
    border-color: transparent;
    font-weight: 600;
}


/* A row that is a SECTION HEAD. Same row, three differences: it carries a tint
   so the list reads as grouped, it is heavier, and it is denser — a head is
   not a target the way a report row is. */
fluent-button.nav-folder-header::part(control) {
    background: var(--color-surface-3);
    color: var(--color-shell-bg);
    font-weight: 600;
    font-size: var(--font-size-control);
    padding: var(--space-2) var(--space-3);
    min-height: 0;
}

fluent-button.nav-folder-header:hover::part(control) {
    background: var(--color-border);
    color: var(--color-shell-bg);
}

/* A folder with nothing in it still lists, but says so. */
fluent-button.nav-folder-header.empty-folder::part(control) { color: var(--color-text-subtle); }

/* The row of a folder head is label-then-count, left, with the caret first. */
fluent-button.nav-folder-header::part(content) {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    width: 100%;
}

/* --- Text ------------------------------------------------------------------- */
fluent-button.btn-link::part(control),
fluent-button.cr-link::part(control),
fluent-button.sched__link::part(control),
fluent-button.mfa-link::part(control),
fluent-button.forgot-link::part(control),
fluent-button.link::part(control) {
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: var(--color-link);
    padding: 0 var(--space-1);
    font-weight: 400;
    text-decoration: underline;
}

fluent-button.btn-link:hover::part(control),
fluent-button.cr-link:hover::part(control),
fluent-button.sched__link:hover::part(control),
fluent-button.mfa-link:hover::part(control),
fluent-button.forgot-link:hover::part(control),
fluent-button.link:hover::part(control) {
    background: transparent;
    border-color: transparent;
    color: var(--color-link-hover);
    text-decoration: underline;
}

/* --- The picker's trigger ------------------------------------------------------
 * IT IS A BUTTON. It used to be a fourth affordance — white, a field stroke, a
 * hover that darkened the stroke — on the reasoning that a dropdown sitting in a
 * row of fields should read as one of them. It does not: it sits beside Filters
 * and Export and Views, it opens a panel the way they do, and a white chip among
 * grey buttons read as the one control that had been missed.
 *
 * So there is no paint here. Everything below this comment is LAYOUT — the rules
 * that make a button hold a summary on the left and a caret on the right, and
 * fill the column it is given. The fill, the edge, the corner, the height, the
 * hover, the disabled tint and the latched weight all come from
 * fluent-button::part(control) above, unchanged, which is what makes it the same
 * button and keeps it the same button when that one is retuned.
 *
 * `[disabled]` needs no rule for the same reason. */
fluent-button.atlas-picker__trigger::part(control) {
    width: 100%;
    justify-content: space-between;
}

/* An open picker is a LATCHED button, and the platform's latched button is the
   same fill and the same silver edge with weight 600 — the label is the whole
   signal. Never the hover colour, or an open picker looks like the one under the
   pointer. */
fluent-button.atlas-picker__trigger.is-open::part(control),
fluent-button.atlas-picker__trigger[aria-expanded='true']::part(control) {
    font-weight: 600;
}

/* --- Disabled, last --------------------------------------------------------- */
fluent-button[disabled]::part(control),
fluent-button[disabled]:hover::part(control),
fluent-button[disabled]:active::part(control),
fluent-button[disabled].is-on::part(control),
fluent-button[disabled].is-active::part(control) {
    background: var(--color-disabled);
    color: var(--color-disabled-fg);
    border-color: var(--color-disabled);
    box-shadow: none;
    cursor: not-allowed;
    /* Fluent fades its own disabled control to 30%. The platform already says
       disabled in the fill and the ink, and the two together left Preview a
       ghost you could barely read. The paint is the whole statement. */
    opacity: 1;
}

/* A disabled ICON, ROW or LINK is still not a button.
   The grey fill above is the disabled BUTTON. Painting it on a flat affordance
   puts a solid grey box in a column of bare glyphs — the first ↑ in the column
   builder read as a control in its own right rather than as an arrow that has
   nothing above it to swap with. Flat things stay flat and go quiet instead. */

/* --- A disabled FIELD, last ---------------------------------------------------
 * The button had a disabled treatment; the field did not, so on the Warranty
 * settings page 180 disabled dropdowns were pixel-identical to the 73 live
 * ones and the only difference was the cursor. A field that cannot be edited
 * says so: the white goes to the tint the platform uses for an inert surface,
 * the ink drops to the washed-out grey, and the stroke softens. */
fluent-text-field[disabled]::part(root),
fluent-number-field[disabled]::part(root),
fluent-search[disabled]::part(root),
fluent-select[disabled]::part(control),
fluent-combobox[disabled]::part(control),
fluent-text-area[disabled]::part(control) {
    background: var(--color-surface-2);
    border-color: var(--color-border);
    color: var(--color-disabled-fg);
    cursor: not-allowed;
    opacity: 1;
}

fluent-text-field[disabled]::part(control),
fluent-number-field[disabled]::part(control),
fluent-search[disabled]::part(control),
fluent-select[disabled]::part(selected-value),
fluent-combobox[disabled]::part(selected-value) {
    color: var(--color-disabled-fg);
    cursor: not-allowed;
}

/* An unchecked box that cannot be ticked, and a ticked one that cannot be
   cleared: both go quiet rather than keeping the live steel blue. */
fluent-checkbox[disabled]::part(control),
fluent-radio[disabled]::part(control) {
    background: var(--color-surface-2);
    border-color: var(--color-border);
    cursor: not-allowed;
    opacity: 1;
}

fluent-checkbox[disabled].checked::part(control),
fluent-checkbox[disabled][checked]::part(control),
fluent-radio[disabled].checked::part(control),
fluent-radio[disabled][checked]::part(control) {
    background: var(--color-disabled);
    border-color: var(--color-disabled);
}


/* Focus. Fluent draws its own ring inside the control; the platform's sits
   outside it, so it is never clipped by a tight parent.
   A BUTTON asks for :focus-visible, a field for :focus-within. :focus-within
   fires on a mouse click as well as on the keyboard, which left a halo around
   the menu toggle after every click — a focus ring is for finding where the
   keyboard is, and a pointer already knows. :has() carries it from the inner
   control, which is what actually takes focus. */
/* A SELECT ASKS LIKE A BUTTON, NOT LIKE A FIELD.
   It was grouped with the text inputs on :focus-within, and :focus-within fires
   on a mouse click — so every click on the tenant picker left a ring around it
   that no other control in the bar showed, and it sat there for as long as the
   list was open. That is the halo. A select is not typed into; it is a control
   you press to open a panel, and the open panel is already the indicator. It
   joins fluent-button on :has(:focus-visible), which is the keyboard-only
   question. The text inputs keep :focus-within — a caret in a field with no
   ring around it is the case that rule exists for. */
/* A FIELD CHANGES ITS OWN LINE; IT DOES NOT GROW A SECOND ONE.
   The ring is drawn outside the control at a 1px offset, and a field already
   has a 1px border of its own — so a focused input showed the border, a 1px
   white gap and then the ring: three edges where the design has one. A button
   has no border of its own for the ring to double up on, which is why it keeps
   it. The fields move to a border-colour change, below with the hover rule they
   belong with. */
fluent-button:has(:focus-visible)::part(control),
fluent-select:has(:focus-visible)::part(control),
fluent-combobox:has(:focus-visible)::part(control) {
    outline: var(--focus-ring-w) solid var(--color-focus-ring);
    outline-offset: var(--focus-ring-offset);
}


/* --- Text field, textarea, number field, search ------------------------------ */
fluent-text-field::part(root),
fluent-number-field::part(root),
fluent-search::part(root),
fluent-text-area::part(control) {
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    color: var(--color-text);
}

fluent-text-field::part(control),
fluent-number-field::part(control),
fluent-search::part(control) {
    padding: 0 var(--space-3);
    background: transparent;
    color: var(--color-text);
    height: 100%;
}

/* THE BLUE LINE ALONG THE BOTTOM OF A FOCUSED FIELD, AND WHERE IT COMES FROM.
 *
 * FAST's text-field draws an accent underline as a pseudo-element ON THE HOST:
 *   :host(:not([disabled]):focus-within)::after { left: 0; width: 100%; }
 * over a base ::after of position: absolute; bottom: 0; height: 2px with
 * border-bottom-color: var(--accent-fill-rest). This file maps that token to
 * the platform's action colour, so the line came out #5A738E and read as a
 * field that was underlined rather than outlined.
 *
 * It is on :host, not .root — which is why ::part(root)::after does not reach
 * it and why it survived every rule written against ::part(root). The host is
 * an ordinary element in the light DOM, so this plain selector does reach it,
 * and a normal declaration in the outer tree beats a :host rule in the shadow
 * tree whatever its specificity — no !important needed.
 *
 * Removed, not recoloured: the active state is the fill below, and an
 * underline is the one thing it must not also be. */
fluent-text-field::after,
fluent-number-field::after,
fluent-search::after,
fluent-text-area::after {
    display: none;
}

/* THE FIELD UNDER THE POINTER FILLS TOO — a lighter step than the active fill.
   The field had no hover at all once the stroke-darkening hover went (the
   border never changes), so it did not answer the pointer (Audit-HoverStates).
   Not on a disabled or read-only field, and not on the field you are in, which
   keeps the active fill. */
/* :where() keeps these at the specificity of a bare `fluent-text-field:hover`,
   so any contextual field rule still outranks them. */
fluent-text-field:where(:not([disabled], [readonly], :focus-within)):hover::part(root),
fluent-number-field:where(:not([disabled], [readonly], :focus-within)):hover::part(root),
fluent-search:where(:not([disabled], [readonly], :focus-within)):hover::part(root),
fluent-text-area:where(:not([disabled], [readonly], :focus-within)):hover::part(control) {
    background: var(--color-field-hover-bg);
    border-color: var(--color-border-strong);
}

/* THE ACTIVE FIELD FILLS. THE BORDER IS NEVER TOUCHED.
   Not at rest, not on hover, not here. Every version of this that repainted the
   border — thicker, a second line, an outline outside it — came back as a
   gradient down one edge or a bottom run that missed the corner radius, because
   the border is what carries the rounding and it does not repaint cleanly at
   fractional display scaling.
   border-color is pinned to the resting colour rather than simply left out,
   because Fluent's own shadow styles repaint it on focus. */
fluent-text-field:focus-within::part(root),
fluent-number-field:focus-within::part(root),
fluent-search:focus-within::part(root),
fluent-text-area:focus-within::part(control) {
    background: var(--color-field-active-bg);
    border-color: var(--color-border-strong);
    outline: none;
    box-shadow: none;
}

fluent-text-field[disabled]::part(root),
fluent-text-area[disabled]::part(control),
fluent-number-field[disabled]::part(root),
fluent-search[disabled]::part(root),
fluent-text-field[readonly]::part(root),
fluent-text-area[readonly]::part(control) {
    background: var(--color-surface-2);
    border-color: var(--color-border);
    color: var(--color-text-muted);
}

/* The number field's steppers, and the search field's clear button: both are
   drawn inside the control and both default to Fluent's own accent. */
fluent-number-field::part(step-up),
fluent-number-field::part(step-down),
fluent-search::part(clear-button) {
    color: var(--color-text-muted);
    background: transparent;
}

fluent-number-field::part(step-up):hover,
fluent-number-field::part(step-down):hover,
fluent-search::part(clear-button):hover {
    color: var(--color-action-ink);
    background: var(--color-surface-2);
}


/* --- Select, combobox, listbox, option ---------------------------------------
 * The closed control is a field. The open list is a page-level popup and takes
 * the page's surface, not the field's. */
fluent-select::part(control),
fluent-combobox::part(control) {
    padding: 0 var(--space-3);
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    color: var(--color-text);
}

/* A closed select is a field, so it hovers like one: the fill, never the line —
   the same as the platform dropdown button beside it. :where() keeps this at
   (0,1,2) so the tenant picker's dark hover in the bar (atlas-appbar.css, 0,2,2)
   still wins. */
fluent-select:where(:not([disabled])):hover::part(control),
fluent-combobox:where(:not([disabled])):hover::part(control) {
    background: var(--color-field-hover-bg);
    border-color: var(--color-border-strong);
}

fluent-select::part(indicator),
fluent-combobox::part(indicator) {
    fill: var(--color-text-muted);
    color: var(--color-text-muted);
}

fluent-select::part(selected-value) {
    color: var(--color-text);
}

fluent-select::part(listbox),
fluent-combobox::part(listbox),
fluent-listbox {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    color: var(--color-text);
    padding: var(--space-1) 0;
    /* AN OPEN LIST IS A PANEL, NOT A COLUMN DOWN THE PAGE.
       Fluent gives the drop-down no height limit, so it is as tall as its
       options: the ACH vendor picker has 3,126 of them and opened a listbox
       100,000px tall, over the form, the buttons and everything below. It is
       capped to a panel that scrolls, which is what every other drop-down on
       the platform does. */
    max-height: min(40vh, 320px);
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
}

/* THE LIST HANGS OFF THE FIELD, WITH NO GAP UNDER IT.
 * Fluent positions the drop-down at top: 40px — its own idea of a control's
 * height, computed inside the shadow root from the token values FAST writes
 * there as an inline style, so the platform's 30px never reaches it. The result
 * was a 10px slot between the field and the list through which the Save and
 * Cancel buttons underneath showed, which reads as a list with no background.
 * Setting the offset directly wins: an outer ::part() rule beats the shadow
 * tree's own, and the inline style only carries custom properties. */
fluent-select::part(listbox),
fluent-combobox::part(listbox) {
    /* Flush, not nearly flush. Fluent also puts a 1px margin on the list, and
       between that and a 1px offset there was a 2px slot left over — enough to
       show a sliver of whatever sits under the field, which is exactly what the
       Cancel button did on the vendor form. */
    top: var(--control-h);
    bottom: auto;
    margin: 0;
}

fluent-select[position='above']::part(listbox),
fluent-combobox[position='above']::part(listbox) {
    top: auto;
    bottom: var(--control-h);
    margin: 0;
}

/* The chosen row's marker and its hover come from Fluent's accent, and FAST
   writes that token as an inline style on <html> — an inherited inline value
   beats the theme's :root rule, so the bar down the selected option arrived in
   Fluent's blue. Declared here, on the elements themselves, it is the
   platform's. Same fix as the calendar. */
fluent-select::part(listbox),
fluent-combobox::part(listbox),
fluent-listbox,
fluent-option {
    --accent-fill-rest: var(--color-action-hover);
    --accent-fill-hover: var(--color-action-ink);
    --accent-fill-active: var(--color-action-ink);
    --accent-foreground-rest: var(--color-action-ink);
    --foreground-on-accent-rest: var(--color-action-hover-fg);
}

/* A multi-select is a LIST BOX — it is drawn in the page, keeps its own height
   and scrolls. Fluent sizes the popup form by default, which is why a multiple
   select rendered as a floating panel on top of its own grid cell. */
fluent-select[multiple]::part(listbox),
fluent-select[size]::part(listbox),
fluent-listbox {
    position: static;
    /* An inline list box is sized by its own box, not by the drop-down cap. */
    max-height: none;
    height: 100%;
    overflow-y: auto;
    /* A list box scrolls DOWN, never sideways: a row that is a few pixels wider
       than the box — Fluent's own option margin is enough — otherwise adds a
       horizontal bar under a list of short codes. */
    overflow-x: hidden;
    box-shadow: none;
}

fluent-select[multiple],
fluent-select[size],
fluent-listbox {
    display: block;
    width: 100%;
}

fluent-option {
    background: var(--color-surface);
    color: var(--color-text);
    padding: var(--space-2) var(--space-3);
    font-size: var(--font-size-control);
    border-radius: 0;
}

/* AN OPTION'S INK IS SET THREE WAYS AND ALL THREE HAVE TO SAY THE SAME THING.
 *
 * `color` on the host is enough for @fluentui/web-components v2 — measured on
 * the deployed React bundle, the option's `part="content"` inherits it and
 * comes back rgb(52,73,94). It is NOT enough everywhere: Fluent Blazor v4 wraps
 * the same components but ships its own template, and a shadow part that
 * declares its own colour never sees the host's. That is why the ACH vendor
 * list read blue against a dark list in the React tools — one stack inherited,
 * the other did not, from one rule that looked correct in both.
 *
 * So: the host `color` above, the parts below, and the tokens the shadow
 * resolves against. A part rule from outside beats the shadow tree's own, and a
 * token declared ON the element beats the inline one FAST writes on <html>. */
fluent-option::part(content),
fluent-option::part(start),
fluent-option::part(end) {
    color: inherit;
}

fluent-option {
    --neutral-foreground-rest: var(--color-text);
    --neutral-foreground-hover: var(--color-text-strong);
    --neutral-foreground-active: var(--color-text-strong);
    --accent-foreground-rest: var(--color-text);
    --accent-foreground-hover: var(--color-text-strong);
    --accent-foreground-active: var(--color-text-strong);
}

/* A LIST BOX IS A COLUMN. Fluent's option is inline-flex, which is right inside
   a dropdown's popup and wrong in a page-drawn list: the ACH claim targets came
   out as a wrapped row of chips instead of a list you can run your eye down.
   Only inside a list box, so the dropdown popup is untouched. */
fluent-listbox fluent-option,
fluent-select[multiple] fluent-option,
fluent-select[size] fluent-option {
    display: flex;
    width: auto;
    margin: 0;
    box-sizing: border-box;
}

fluent-option:hover,
fluent-option[aria-selected='true']:hover {
    background: var(--color-surface-3);
    color: var(--color-text-strong);
}

/* Fluent marks a chosen row with a .selected CLASS as well as the ARIA state,
   and in a multi-select it is the class that is set. Without it the row kept the
   surface and only Fluent's own edge bar changed, which is not enough to see
   which claim targets are on. */
fluent-option[aria-selected='true'],
fluent-option[selected],
fluent-option.selected {
    background: var(--color-surface-2);
    color: var(--color-text-strong);
    font-weight: 600;
}

fluent-option.selected:hover {
    background: var(--color-row-hover);
}

fluent-option[disabled] {
    color: var(--color-disabled-fg);
}


/* --- Checkbox, radio, switch --------------------------------------------------
 * The tick is the same slate as a hovered button, never the browser's blue. */
/* A TICK IS 16px. Fluent derives it from the control height — (7.5/2 + 4) * 4,
   which lands at 18-19px — and against 14px label text that reads as oversized,
   especially in a table row where a column of them is the first thing you see.
   16 sits with the type. */
fluent-checkbox::part(control),
fluent-radio::part(control) {
    width: 16px;
    height: 16px;
    min-width: 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    /* Almost square. At --radius a 16px box is 37% corner and reads as a pill,
       which is the switch sitting two rows down. The radio overrides to 50%. */
    border-radius: var(--radius-tight);
}

/* THE DOT SITS OFF CENTRE IF THE RING IS A BORDER, and by a whole pixel, which
   is plainly visible at this size — measured on the live page as a 5px gap on
   the left of the dot against 3px on the right.
 *
 * Fluent slots a fixed `<svg width="16" height="16">` with `<circle cx="8"
   cy="8" r="4">` as the checked indicator, and that svg carries no viewBox, so
   it never scales: the circle is painted at x=8 of the svg's own box wherever
   that box lands. With `box-sizing: border-box` and a 1px border the control's
   CONTENT box is only 14px wide, so the svg is squeezed to 14 and starts 1px in
   — putting the dot's centre 9px from the left edge of a 16px control. Its
   height is unconstrained, which is why it looked wrong horizontally and right
   vertically.
 *
 * Painting the ring as an inset shadow instead of a border leaves the content
   box the full 16px. The svg is then 16 wide, the circle lands at 8, and the
   gaps measure 4px on all four sides. The control is still 16px, so nothing
   else moves. */
fluent-radio::part(control) {
    border-radius: 50%;
    border: 0;
    box-shadow: inset 0 0 0 1px var(--color-border-strong);
}

/* The pointer's colour is the platform hover, here as everywhere; a TICKED box
   keeps --color-check (its checked rule below outranks this). */
fluent-checkbox:hover::part(control) {
    border-color: var(--color-action-hover);
}

fluent-radio:hover::part(control) {
    box-shadow: inset 0 0 0 1px var(--color-action-hover);
}

/* A TICKED BOX IS FILLED, and its tick is light. It was a dark tick on white:
   thin, low contrast, and hard to pick out down a column. Fluent marks the state
   in more than one way depending on how the value arrived — a class, an
   attribute, the ARIA state — so all of them are matched.
   The tick itself is an <svg> inside the part, which cannot be selected from
   here; it is painted by inheriting --neutral-foreground-rest, so that token is
   repointed on the host for the checked case. */
fluent-checkbox.checked,
fluent-checkbox[checked],
fluent-checkbox[aria-checked='true'],
fluent-radio.checked,
fluent-radio[checked],
fluent-radio[aria-checked='true'] {
    --neutral-foreground-rest: var(--color-action-hover-fg);
}

fluent-checkbox.checked::part(control),
fluent-checkbox[checked]::part(control),
fluent-checkbox[aria-checked='true']::part(control),
fluent-radio.checked::part(control),
fluent-radio[checked]::part(control),
fluent-radio[aria-checked='true']::part(control) {
    background: var(--color-check);
    border-color: var(--color-check);
    fill: var(--color-action-hover-fg);
    color: var(--color-action-hover-fg);
}

/* The radio's ring is an inset shadow, not a border, so border-color above is
   inert for it — see the centring note. Same colour, stated the way this
   control actually draws it. */
fluent-radio.checked::part(control),
fluent-radio[checked]::part(control),
fluent-radio[aria-checked='true']::part(control) {
    box-shadow: inset 0 0 0 1px var(--color-check);
}

/* Disabled, restated here rather than beside the other disabled rules: those sit
   above the base radio rule in this file, and at equal specificity the later one
   wins, so up there they would be overwritten by the resting ring. */
fluent-radio[disabled]::part(control) {
    box-shadow: inset 0 0 0 1px var(--color-border);
}

fluent-radio[disabled].checked::part(control),
fluent-radio[disabled][checked]::part(control) {
    box-shadow: inset 0 0 0 1px var(--color-disabled);
}

/* Some call sites put the text INSIDE the checkbox and some put it beside it as
   a sibling <label>. The part padding covers the first; a gap on the host covers
   the second, so the tick never sits hard against its words. */
fluent-checkbox,
fluent-radio,
fluent-switch {
    gap: var(--space-3);
}

fluent-checkbox::part(label),
fluent-radio::part(label),
fluent-switch::part(label) {
    color: var(--color-text);
    font-size: var(--font-size-control);
    font-weight: 400;
    letter-spacing: normal;
    text-transform: none;
    padding-inline-start: var(--space-3);
}

fluent-checkbox[disabled]::part(control),
fluent-radio[disabled]::part(control),
fluent-switch[disabled]::part(switch) {
    background: var(--color-disabled);
    border-color: var(--color-disabled);
}

fluent-checkbox[disabled]::part(label),
fluent-radio[disabled]::part(label),
fluent-switch[disabled]::part(label) {
    color: var(--color-disabled-fg);
}

fluent-switch::part(switch) {
    background: var(--color-disabled);
    border-color: var(--color-border-strong);
}

fluent-switch[aria-checked='true']::part(switch),
fluent-switch[checked]::part(switch) {
    background: var(--color-check);
    border-color: var(--color-check);
}

/* A SWITCH ANSWERS THE POINTER. It was the one tick-family control with no
   hover at all — a checkbox and a radio both darken their stroke to
   --color-check and the switch beside them did nothing, so the same gesture got
   an answer from two controls out of three. The checked case keeps its fill and
   only the stroke moves, for the same reason a latched button keeps its. */
fluent-switch:hover:not([disabled])::part(switch) {
    border-color: var(--color-action-hover);
}

fluent-switch[aria-checked='true']:hover:not([disabled])::part(switch),
fluent-switch[checked]:hover:not([disabled])::part(switch) {
    background: var(--color-action-ink);
    border-color: var(--color-action-ink);
}

fluent-switch::part(checked-message),
fluent-switch::part(unchecked-message),
fluent-switch::part(status-message) {
    color: var(--color-text-muted);
    font-size: var(--font-size-micro);
}


/* --- Calendar -----------------------------------------------------------------
 * The selected day is the platform's action colour. Fluent paints it with its
 * own accent, which arrives as a brighter blue than anything else on the page. */
fluent-calendar {
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--space-3);
}

/* Fluent renders the title as <span part="month">September</span><span
   part="year">2026</span> with NOTHING between them, so every calendar on the
   platform read "September2026". A gap on the title is the separator; the two
   spans are its flex items. */
fluent-calendar::part(title) {
    color: var(--color-text-strong);
    font-weight: 600;
    display: flex;
    gap: var(--space-2);
}

fluent-calendar::part(week-day) {
    color: var(--color-text-muted);
    font-size: var(--font-size-micro);
    text-transform: uppercase;
}

/* ONE CALENDAR, ONE CELL. The hand-built grid in atlas-components.css draws a
   38px cell at --font-size-body in a 316px panel, and this one was left at
   Fluent's own 42px in a 324px panel — a Blazor date field and a React one put
   two different calendars under the same field. The comment over .atlas-date-day
   already claimed they matched; measuring them is what showed they did not. */
fluent-calendar {
    width: 316px;
    box-sizing: border-box;
}

fluent-calendar::part(day) {
    color: var(--color-text);
    border-radius: var(--radius-sm);
    /* border-box, or Fluent's 1px cell border is added to the 38 and the cell
       measures 40 against the hand-built grid's 38. */
    box-sizing: border-box;
    height: 38px;
    min-height: 38px;
    font-size: var(--font-size-body);
}

/* …and one hover colour. This was --color-row-hover while the hand-built grid
   used --color-surface-3, so the same gesture landed two different greys. */
fluent-calendar::part(day):hover {
    background: var(--color-surface-3);
    color: var(--color-text-strong);
}

/* The day cells carry state as CLASSES inside the shadow root, so neither a
   descendant selector nor a qualified ::part() can reach them: today's ring and
   the selected day are painted by Fluent's own rules, from --accent-fill-rest.
   §1 repoints that token, but FAST writes its design tokens as an INLINE style
   on <html>, and an inherited inline value beats a :root rule — which is why
   today's date kept arriving as a saturated blue circle. Declaring the token ON
   the calendar wins: a direct declaration always beats an inherited one. */
fluent-calendar {
    --accent-fill-rest: var(--color-action-hover);
    --accent-fill-hover: var(--color-action-ink);
    --accent-fill-active: var(--color-action-ink);
    --accent-foreground-rest: var(--color-action-ink);
    --foreground-on-accent-rest: var(--color-action-hover-fg);
    --neutral-fill-rest: var(--color-surface-2);
    --neutral-fill-hover: var(--color-surface-3);
}

fluent-calendar .inactive {
    color: var(--color-text-subtle);
}


/* --- Menu, dialog, tooltip, accordion, tabs, progress -------------------------- */
fluent-menu {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: var(--space-1) 0;
    min-width: 180px;
}

fluent-menu-item {
    color: var(--color-text);
    font-size: var(--font-size-control);
}

fluent-menu-item:hover,
fluent-menu-item:focus-within {
    background: var(--color-surface-3);
    color: var(--color-text-strong);
}

fluent-dialog::part(control) {
    background: var(--color-surface);
    color: var(--color-text);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

fluent-dialog::part(overlay) {
    background: rgba(31, 41, 55, .45);   /* --color-shell-bg, dimmed */
}

/* The HOST is a zero-size anchor; the bubble is ::part(tooltip). Painted on the
   host, every control with a tooltip drew an empty dark pill beside it (a
   dialog's close button) — ACT-112. */
fluent-tooltip::part(tooltip) {
    background: var(--color-shell-bg);
    color: var(--color-shell-fg);
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--font-size-micro);
    padding: var(--space-2) var(--space-3);
}

fluent-accordion-item::part(heading) {
    color: var(--color-text-strong);
}

fluent-accordion-item::part(button) {
    background: var(--color-surface-2);
    color: var(--color-text-strong);
    font-weight: 600;
}

fluent-accordion-item::part(button):hover {
    background: var(--color-row-hover);
}


/* THE USER-MENU CARET IS AN ICON ON THE BAR, AND IT HAD NO ::part RULE AT ALL.
 *
 * atlas-appbar.css states the caret's flat treatment on `.dropdown-icon` —
 * background:none, border:none, box-shadow:none. In BIReports the caret is a
 * <fluent-button>, so all of that landed on the HOST, which draws nothing. The
 * bar's own button paint above excludes `.dropdown-icon` by name, so nothing
 * painted the part either and it fell through to the platform's default button:
 * measured 45×30, Clouds fill, 1px silver edge, 6px corner — a light grey box
 * on the Midnight bar, beside a Return to Tools link with no box at all.
 *
 * Audit-HostPaint did not catch it because `.dropdown-icon` is used on a <span>
 * in the Blazor tools as well as on a <fluent-button> here, and an ambiguous
 * class is one it deliberately skips.
 *
 * The part now takes the same flat treatment the host rule always described. */
fluent-button.dropdown-icon::part(control) {
    background: none;
    border: 1px solid transparent;
    box-shadow: none;
    border-radius: var(--radius);
    color: var(--color-shell-fg-dim);
    min-height: 0;
    padding: var(--space-2) var(--space-3);
}

fluent-button.dropdown-icon:hover::part(control),
.user-dropdown:hover fluent-button.dropdown-icon::part(control),
.user-dropdown:focus-within fluent-button.dropdown-icon::part(control) {
    background: var(--color-shell-field-bg);
    border-color: transparent;
    color: var(--color-shell-fg);
}

fluent-accordion-item::part(region) {
    background: var(--color-surface);
    color: var(--color-text);
}

fluent-tab {
    color: var(--color-text-muted);
}

fluent-tab[aria-selected='true'] {
    color: var(--color-text-strong);
    border-bottom: 2px solid var(--color-action-hover);
}

fluent-progress::part(determinate),
fluent-progress-ring::part(determinate) {
    stroke: var(--color-action-hover);
    background: var(--color-action-hover);
}

fluent-progress::part(background) {
    background: var(--color-surface-2);
}


/* =============================================================================
 * 4. The dark app bar
 *
 * A control in the bar is on --color-shell-bg, not on a card, so it inverts:
 * the fill is the dark ink and hover LIFTS to the slate. That is the opposite
 * direction to a button on a light page, and it is what reads as a response
 * against a dark ground.
 * ========================================================================== */
/* Every shell wrapper in ONE selector. The five tools name the bar differently
   — .app-header, .header-wrapper, .header-content, .header-inner, .app-bar — and
   a rule that lists only some of them leaves a Clouds chip sitting on the dark
   bar in the tools it missed, which is how BIReports' menu toggle ended up as a
   white box. */
/* The TENANT picker opts out: .company-dropdown is painted in atlas-appbar.css,
   flat, because a filled panel on the bar reads as a box round the tenant name.
   Every other fluent-select that lands in a bar still takes the Midnight
   treatment below. */
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-select:not(.company-selector *)::part(control) {
    background: var(--color-action-ink);
    border-color: var(--color-action-ink);
    color: var(--color-action-hover-fg);
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-select:not(.company-selector *):hover::part(control) {
    background: var(--color-action-hover);
    border-color: var(--color-action-hover);
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-select::part(selected-value) {
    color: var(--color-action-hover-fg);
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-select::part(indicator) {
    fill: var(--color-shell-fg-muted);
    color: var(--color-shell-fg-muted);
}

/* The open list is drawn on the page, not in the bar. */
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-select::part(listbox) {
    background: var(--color-surface);
    color: var(--color-text);
}

/* --- The date field's trigger --------------------------------------------------
 * The calendar button that sits inside the date field. It is a Fluent button like
 * every other, so its paint goes on the part; atlas-theme.css positions the host.
 * Small, square and icon-only, so none of the platform button's chrome applies.
 */
/* The one sized exception, and it is not a standalone button: the calendar
   trigger sits INSIDE a field, where a 30px control cannot fit. Its host is
   placed and sized by atlas-theme.css; only the minimum is lifted here. */
fluent-button.atlas-date-trigger::part(control) {
    min-height: 0;
    /* Sized by the host, which atlas-theme.css places inside the field. Paint is
       the one button's — no transparent exception. */
    padding: 0;
    gap: 0;
}


/* --- The user menu ------------------------------------------------------------
 * Every tool's header ends in a caret that opens a one-item menu. It was
 * <details>, which draws a UA triangle and sits outside the component set;
 * it is now Fluent's accordion, which opens itself in the browser — so the
 * statically rendered Blazor layouts still need no circuit to toggle it, and
 * the React app still needs no state.
 *
 * An accordion expands IN FLOW. A header menu has to float, so its region is
 * positioned as a dropdown here, and the accordion's own chrome — the full-width
 * heading button, its divider, its +/- glyph — is taken off, because the caret
 * beside the user's name is the affordance.
 */
.user-dropdown,
.app-bar__menu {
    position: relative;
    background: transparent;
    border: none;
}

/* The ITEM's host paints too. An accordion item is a panel on a page and FAST
   fills it with the card layer, which in the dark app bar reads as a white strip
   down the right-hand edge beside the user's name. In the bar it is a caret and
   nothing else. */
.user-dropdown-item,
.app-bar__menu-item-host {
    background: transparent;
    border: none;
    box-shadow: none;
}

.user-dropdown-item::part(heading),
.app-bar__menu-item-host::part(heading) {
    background: transparent;
    border: none;
    height: auto;
}

.user-dropdown-item::part(button),
.app-bar__menu-item-host::part(button) {
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 4px 2px 4px 4px;
    min-height: 0;
    height: auto;
    width: auto;
    color: var(--color-shell-fg);
    cursor: pointer;
}

.user-dropdown-item::part(button):hover,
.app-bar__menu-item-host::part(button):hover {
    background: var(--color-shell-field-bg);
}

/* The accordion's own glyph. The caret in the heading is the platform's. */
.user-dropdown-item::part(icon),
.user-dropdown-item::part(expanded-icon),
.user-dropdown-item::part(collapsed-icon),
.app-bar__menu-item-host::part(icon),
.app-bar__menu-item-host::part(expanded-icon),
.app-bar__menu-item-host::part(collapsed-icon) {
    display: none;
}

.user-dropdown-item::part(region),
.app-bar__menu-item-host::part(region) {
    position: absolute;
    right: 0;
    top: 100%;
    margin-top: var(--space-2);
    width: 150px;
    min-width: 150px;
    padding: 0;
    border: none;
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    box-shadow: var(--shadow);
    z-index: 1000;
}

/* A BUTTON ON THE DARK BAR TAKES THE BAR'S OWN FIELD TREATMENT.
 *
 * It was Midnight (#2C3E50) at rest on the shell's #1f2937 — 1.30:1, which is
 * not a low-contrast button, it is a button you cannot see the edges of. The
 * reasoning behind it was right and the value was wrong: the tenant picker
 * WAS the thing to match, and the picker does not use Midnight. It uses the
 * shell's field tokens — white at 10% over the bar, a white-30% edge, Clouds
 * for the label — which is how it reads as a control sitting IN the dark strip
 * instead of a chip laid on top of it. A fill has to differ from the ground it
 * sits on; naming a dark token on a dark bar only moved the problem.
 *
 * Latched is the platform's steel blue, which lifts clearly off both.
 *
 * TWO FAMILIES OF SELECTOR. A fluent-button paints inside a shadow root and is
 * reached through ::part(control); a plain <button> paints on itself. The menu
 * triggers are plain buttons now that AtlasMenu renders them, so a rule naming
 * only fluent-button would have left half the bar unstyled.
 *
 * The :not() list keeps the bar's flat affordances flat — the menu toggle, the
 * user-menu rows and text links are not buttons and are painted above. */
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link) {
    background: var(--color-shell-control-bg);
    border-color: var(--color-shell-field-border);
    color: var(--color-shell-fg);
    box-shadow: none;
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link):hover::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link):hover {
    background: var(--color-shell-control-bg-hover);
    border-color: var(--color-shell-field-border);
    color: var(--color-shell-fg);
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).is-on::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).is-on,
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).is-active::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).is-active,
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).active::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link).active,
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-pressed='true']::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-pressed='true'],
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-current='page']::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-current='page'],
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-expanded='true']::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[aria-expanded='true'] {
    background: var(--color-action-hover);
    border-color: var(--color-action-hover);
    color: var(--color-action-hover-fg);
    font-weight: 600;
}

:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[disabled]::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link)[disabled],
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) fluent-button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link):disabled::part(control),
:is(.app-header, .header-wrapper, .header-content, .header-inner, .app-bar, .company-selector) button:not(.atlas-popup *):not(.app-bar__menu-item):not(.dropdown-icon):not(.app-bar__tab):not(.nav-toggle-btn-header):not(.dropdown-item):not(.btn-link):not(.forgot-link):not(.cr-link):not(.mfa-link):not(.link):disabled {
    background: transparent;
    border-color: var(--color-shell-field-border);
    color: var(--color-shell-fg-muted);
}


/* --- THE GLOBAL ERROR OVERLAY -------------------------------------------------
 * One bus, one overlay, one set of rules — ACT-80.
 *
 * All three React tools shipped a byte-identical GlobalErrorOverlay built
 * entirely from inline styles: #fff, #323130, #605e5c, an 8px corner and a hand-
 * rolled shadow. None of it was reachable by a token, and none of it was visible
 * to a gate: Audit-Shape reads CSS, so an 8px radius written in JSX sat in three
 * apps for as long as the component existed while every stylesheet on the
 * platform said 6px. It is the exact defect the inline-style audit was written
 * to find, and it is the one worth stating in full.
 *
 * The scrim is the busy overlay's, so the two dimmers on the platform are the
 * same dimmer. */
.atlas-error-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(31, 41, 55, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    /* Above the app bar's own lift, which is scoped to a scrim being present. */
    z-index: 2000;
}

.atlas-error-overlay__card {
    max-width: 600px;
    margin: 0 var(--space-5);
    padding: var(--space-6);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    text-align: center;
}

/* The mark is a glyph, so it keeps its own size rather than the type scale's. */
.atlas-error-overlay__mark {
    font-size: 40px;
    line-height: 1;
    margin-bottom: var(--space-4);
}

.atlas-error-overlay__title {
    margin: 0 0 var(--space-4);
    color: var(--color-text-strong);
}

.atlas-error-overlay__body {
    margin: 0;
    color: var(--color-text);
    font-size: var(--font-size-body);
    line-height: 1.5;
}

.atlas-error-overlay__dismiss {
    margin-top: var(--space-6);
}

/* The same card standing in the page rather than over it — ReportViewer's error
   state. Only the placement differs, so only the placement is restated. */
.atlas-error-overlay__card--inline {
    margin: 80px auto;
}

.atlas-error-overlay__actions {
    margin-top: var(--space-6);
    display: flex;
    gap: var(--space-4);
    justify-content: center;
}


/* --- A PANEL THE BAR OPENS IS NOT PART OF THE BAR -----------------------------
 * ACT-85. The bar inverts a button that sits ON it — Midnight at rest, steel
 * blue on hover — and it decides that by DESCENT: any fluent-button under
 * .header-inner and friends, minus a hand-kept list of exceptions
 * (.app-bar__menu-item, .dropdown-item, .btn-link, .cr-link, .mfa-link, .link).
 *
 * That list is the defect. A menu the bar opens hangs BELOW the bar, on the
 * page, and every item in it is a fluent-button under the same ancestors — so
 * it inverted too, and My Views came out dark on a white panel while every
 * other dropdown on the platform was dark-on-white. ReportViewer.css had said
 * `background: none; color: var(--color-text)` on those items all along and was
 * simply losing: it styles the HOST, the bar rule paints ::part(control) inside
 * the shadow root, and a part rule from outside beats the host's own.
 *
 * Adding .views-menu-item to the blacklist would fix that one menu and leave the
 * next one to be found by eye — which is how this was found. So the rule is
 * stated the other way round, once: the inversion does not cross into a popup.
 * A panel marks itself .atlas-popup and everything inside it takes the page's
 * treatment, whatever its classes are and whoever writes it next.
 *
 * .atlas-popup is also the panel itself: surface, edge, corner and lift, said
 * here instead of in each app's own copy. */
.atlas-popup {
    background: var(--color-surface);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

/* An item in a popup is a ROW: full width, left-aligned, no box, and the LIST
   hover rather than a button's fill. The four affordances again — a menu entry
   was never a BUTTON, whichever element it is built from. */
/* The host's ink, at ZERO class specificity. `color: inherit` on the part below
   resolves against the HOST, and a fluent-button host with no page rule on it
   falls back to FAST's own :host colour — measured rgb(26,26,26), which is not a
   colour on this platform. So the host is given the platform ink here, through
   :where() so it carries no weight at all: an item that says something else
   about itself (.views-menu-save's accent, .views-menu-del's Pomegranate) still
   wins with a single class, which a normal descendant selector would have
   silently outranked. */
:where(.atlas-popup) fluent-button:not(.icon-btn) {
    color: var(--color-text);
}

.atlas-popup fluent-button:not(.icon-btn)::part(control) {
    justify-content: flex-start;
    width: 100%;
    background: transparent;
    border-color: transparent;
    /* INHERIT, not a token. The panel sets the base ink and an item may say
       something else about itself — Save current view is the accent, Delete is
       Pomegranate. Naming a colour here would flatten both, which is the same
       mistake one layer down from the one this block exists to fix. */
    color: inherit;
    box-shadow: none;
    font-weight: inherit;
}

.atlas-popup fluent-button:not(.icon-btn):hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: inherit;
}

.atlas-popup fluent-button[disabled]::part(control),
.atlas-popup fluent-button[disabled]:hover::part(control) {
    background: transparent;
    border-color: transparent;
    color: var(--color-disabled-fg);
}

/* A ROW IS A ROW WHATEVER ELEMENT IT IS BUILT FROM. The portal's user menu and
   BIReports' were <div onClick> — not focusable, not reachable by keyboard, and
   announced as nothing. They are <button> now, which means this file has to
   paint a plain button in a popup as well as a fluent one, or the two menus
   would have gone back to looking different the moment the markup was fixed. */
.atlas-popup button,
.atlas-popup .atlas-popup__item {
    display: block;
    width: 100%;
    text-align: left;
    background: none;
    border: none;
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
    font: inherit;
    font-size: var(--font-size-control);
    color: inherit;
    cursor: pointer;
}

.atlas-popup button:hover:not(:disabled),
.atlas-popup .atlas-popup__item:hover {
    background: var(--color-surface-3);
}

.atlas-popup button:focus-visible,
.atlas-popup .atlas-popup__item:focus-visible {
    outline: var(--focus-ring-w) solid var(--color-focus-ring);
    /* Inside a panel the ring has nowhere to bleed, so it sits on the edge. */
    outline-offset: calc(var(--focus-ring-offset) * -1);
}

.atlas-popup button:disabled {
    color: var(--color-disabled-fg);
    cursor: not-allowed;
}

/* AN ICON IN A POPUP IS STILL AN ICON. The row rules above make an item full
   width and left-aligned, which is right for a menu entry and wrong for the
   star and bin that sit at the end of one. They opt out by naming the
   affordance they already are — .icon-btn — rather than by being listed here,
   so the next row-level glyph is covered without touching this file. */
.atlas-popup fluent-button.icon-btn::part(control) {
    width: var(--control-h);
    min-width: var(--control-h);
    padding: 0;
    background: none;
    border-color: transparent;
    box-shadow: none;
    color: inherit;
    justify-content: center;
}

.atlas-popup fluent-button.icon-btn:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
}

/* The one destructive row action warms its own ground, never the list hover —
   the same pairing .icon-btn.danger uses on the Bootstrap side. */
.atlas-popup fluent-button.views-menu-del:hover::part(control) {
    background: var(--color-danger-bg);
}

/* A LONG LABEL IN A POPUP ROW TRUNCATES — it does not paint over its neighbours.
 * Measured on the deployed bundle: the boxes were already correct (the apply
 * button ended at 197, the star began at 197), but the LABEL drew straight past
 * its own box and across the star and the bin. Two causes, both the same one as
 * `minmax(0, 1fr)` in the app bar: a flex item's default minimum is its
 * min-content width, and Fluent's content part has no overflow rule of its own.
 * So the host is allowed to shrink and the label is given somewhere to stop. */
.atlas-popup fluent-button:not(.icon-btn) {
    min-width: 0;
}

.atlas-popup fluent-button:not(.icon-btn)::part(control) {
    overflow: hidden;
}

.atlas-popup fluent-button:not(.icon-btn)::part(content) {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


/* --- THE MENU ------------------------------------------------------------------
 * ACT-87. Geometry only: the panel's PAINT is .atlas-popup above, which every
 * one of these already carries. atlas-menu.jsx owns the behaviour. Between the
 * two there is nothing left for an app to describe about a dropdown, which is
 * the point — five apps describing it five times is what this replaces. */
/* align-self: center IS THE GAP FIX, and it is not cosmetic.
 *
 * The panel is positioned `top: 100%` — the bottom of THIS container, not of the
 * trigger inside it. A menu in a toolbar is a flex item, `align-items` defaults
 * to `stretch`, and the container therefore grows to the tallest thing in the
 * row: measured 48px against a 30px trigger. The button centres in it and the
 * panel opens 9px below the button, which is the gap that survived setting
 * --popup-gap to zero — the token was right and the box it measured from was
 * wrong.
 *
 * align-self stops the stretch, so the container is the trigger's height and
 * `top: 100%` is the trigger's bottom edge in any layout an app drops it into. */
.atlas-menu {
    position: relative;
    display: inline-flex;
    align-items: center;
    align-self: center;
}

/* The gap between a trigger and what it opens is --popup-gap, and it is zero.
   Every panel on the platform reads that one token — this menu, the picker, the
   hand-built select and the date grid. */
.atlas-menu__panel {
    position: absolute;
    top: calc(100% + var(--popup-gap));
    min-width: 180px;
    padding: var(--space-1);
    /* Above the app bar, which the bar-anchored menus hang out of. */
    z-index: 1101;
}

.atlas-menu__panel--end { right: 0; }
.atlas-menu__panel--start { left: 0; }

/* A panel whose entries are DATA, not commands — saved view names, a tenant
   list — needs room the fixed min-width does not give it. BIReports had this as
   .cr-menu__pop--wide in its own stylesheet, which is how its menu ended up a
   different width and a different row height from every other menu. */
.atlas-menu__panel--wide { min-width: 250px; max-width: 320px; }

/* A MENU ENTRY IS A ROW, AND IT IS A NATIVE <button>.
 *
 * atlas-menu.jsx renders <button class="atlas-menu__item">, and nothing in the
 * sheets the React tools load painted it. The ROW treatment is written for
 * fluent-button on ::part(control); the generic `button` rule that would have
 * caught a native one lives in atlas-theme.css, and Statements, BIReports and
 * UnifiedLogin do not load atlas-theme.css — only the three Bootstrap tools do.
 *
 * So every entry in every AtlasMenu in the React half of the platform was a
 * user-agent default button. In BIReports' Views menu that is why the star and
 * the delete icon sat hard against the view's name instead of at the row's
 * right edge: three unstyled inline buttons in a row, sized by their glyphs.
 *
 * The same applies to a native .icon-btn, below. */
/* THE HOST, and it has to be here rather than inline on the element.
   ::part(control)'s width:100% resolves against the HOST, and a fluent-button
   host is inline-flex, so without this a row shrinks to its label. An ICON in
   the same menu needs the opposite — and that is the whole reason this is a
   stylesheet rule: written as an inline style in atlas-menu.jsx it could not be
   overridden, and the star and delete glyphs in a Views row each took a third of
   the row instead of sitting at its right edge. Display and width SIZE the host,
   which the Fluent boundary allows; nothing here paints. */
fluent-button.atlas-menu__item,
fluent-button.atlas-picker__row {
    display: block;
    width: 100%;
}

fluent-button.atlas-menu__item.icon-btn {
    display: inline-flex;
    flex: 0 0 auto;
    width: var(--control-h);
}

fluent-button.atlas-menu__item::part(control) {
    justify-content: flex-start;
    width: 100%;
    min-height: var(--menu-row-h);
    padding: var(--space-2) var(--space-3);
    background: none;
    border: 1px solid transparent;
    box-shadow: none;
    font-weight: 400;
    text-align: left;
    color: var(--color-text);
}

fluent-button.atlas-menu__item:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: var(--color-text-strong);
}

/* An ICON inside a menu is square and sized by its glyph, not by the row, so it
   has to beat the width above. The .icon-btn family is painted once, further up
   this file; only the sizing is restated here, because .atlas-menu__item and
   .icon-btn land on the same element and the row's width would win on order. */
fluent-button.atlas-menu__item.icon-btn::part(control) {
    justify-content: center;
    width: var(--control-h);
    min-width: var(--control-h);
    height: var(--control-h);
    min-height: var(--control-h);
    padding: 0;
}

/* A PICKER OPTION IS THE SAME ROW. .atlas-picker__row in atlas-components.css
   still paints the multi-select rows, which are <label>s wrapping a real
   checkbox — a native element doing a native job, not a rebuilt control. The
   single-select rows are fluent-buttons, so the same geometry is stated here on
   the part. Both read the same tokens, so the two stay one row. */
fluent-button.atlas-picker__row::part(control) {
    justify-content: flex-start;
    width: 100%;
    min-height: var(--menu-row-h);
    padding: var(--space-3) var(--space-4);
    background: none;
    border: 1px solid transparent;
    border-radius: 0;
    box-shadow: none;
    font-weight: 400;
    text-align: left;
    color: var(--color-text);
}

fluent-button.atlas-picker__row:hover::part(control) {
    background: var(--color-surface-3);
    border-color: transparent;
    color: var(--color-text-strong);
}

fluent-button.atlas-picker__row.is-selected::part(control) {
    background: var(--color-surface-2);
    font-weight: 600;
}

/* One entry in a menu may lead — "+ Save current view…" above the list of saved
   ones. Emphasis only; the row is still a row. */
.atlas-menu__item--accent { color: var(--color-link); font-weight: 600; }

.atlas-menu__sep {
    border-top: 1px solid var(--color-border);
    margin: var(--space-1) 0;
}

/* A menu that is taller than the window scrolls rather than running off it —
   the 3,126-option case, one control down.

   THE HEIGHT ITSELF IS SET BY atlas-menu.jsx, not here. It was
   calc(100vh - --app-bar-h - --space-6), which is only correct for a menu that
   hangs off the app bar; BIReports' 25-row columns menu hangs off a toolbar
   part-way down the page and that arithmetic put its last row below the fold.
   Only the component knows where its trigger is, so it measures on open. */
.atlas-menu__panel {
    overflow-y: auto;
    overflow-x: hidden;
}
