﻿/* ═══════════════════════════════════════════════════════════════════════════
   fpmConsole.css — Console primitives layer
   ═══════════════════════════════════════════════════════════════════════════

   PURPOSE
     Single home for the console FPM primitives: shell, nav, cards, stats,
     floating layers, states, node cards and severity rails.

   OWNERSHIP
     - This file consumes `--fpm-*` tokens declared in `design-system/base.css`.
     - This file MUST NOT declare or redeclare any `--fpm-*`, `--il-*`,
       `--td-*`, or `--p-*` token. Token surface is base.css only.
     - This file MUST NOT reference legacy short-form tokens
       (`--text-*`, `--space-*`, `--font-family`, `--font-mono`,
       `--radius-*`, `--accent-*`). Use the `--fpm-*` canon.
     - This file MUST NOT contain raw hex literals or per-element
       `[data-theme="light"]` overrides — primitives style identically
       against either theme via tokens.

   ADDING A NEW PRIMITIVE
     1. Confirm it isn't already in `fpm-templates.css` or any `fpm*.css`
        peer.
     2. Use BEM-ish naming: `.fpm-<area>-<element>--<modifier>`.
        State via ARIA (`[aria-pressed]`, `[aria-current]`, `[aria-expanded]`,
        `[aria-selected]`) where possible — `.is-*` legacy state classes
        are intentionally dropped here.
     3. One-line comment above each rule: what it is + when to use.
     4. Animations live in section 1, named `fpm-anim-<intent>`.
        Every animation has a `prefers-reduced-motion` guard (section 1c).
     5. Keep this file under 1200 lines; put a new component cluster in a
        peer file.

   This file holds sections 1-5b. Sections 6-13 live in fpmConsoleWidgets.css
   and 14-16 in fpmConsoleOverlays.css. Both load immediately after this file,
   before fpmConsoleData.css, as one cascade.

   GROUPING
     1. ANIMATIONS         — shared keyframes
     2. SHELL              — app-shell, page eyebrow, console hero shell
     3. NAV                — left nav primitives
     4. CARDS              — card chrome + chip primitives
     5. STATS              — hero radial / sub-stats / sparkline / heatmap
     5b. AGENT CARDS       — scanning agent progress cards
     6-13.  → fpmConsoleWidgets.css (FEEDS, TABLES, FORMS, RAIL,
             COMMAND-STRIP, UTILITIES, STATES, FLOATING)
     14-16. → fpmConsoleOverlays.css (NODE-CARDS, SEVERITY-EXTRAS,
             FEED + DECORATION EXTRAS)
   ═══════════════════════════════════════════════════════════════════════════ */

/*    1. ANIMATIONS — shared keyframes
   Reduce-motion guards live in section 1c.
*/

/* nav-pulse — gentle opacity breathe on the nav health dot. */

/* scan-pulse — outward ring burst around the live scan status indicator. */

/* hero-rail-breathe — slow halo breathe on the hero left rail. */

/* ip-active — heatmap cell pulse to show "currently scanning". */

/* shimmer — left-to-right gradient sweep used by skeleton placeholders. */

/* fade-in — generic mount animation for floating layers. */

/* slide-in-right — drawer mount from right edge. */

/* slide-in-left — drawer mount from left edge. */

/* slide-in-bottom — drawer mount from bottom edge. */

/* 1c. Reduce-motion guards — disable / shorten anything decorative. */
@media (prefers-reduced-motion: reduce) {
    .fpm-nav-brand-pulse i,
    .fpm-command-strip__status-pulse,
    .fpm-heatmap-cell,
    .fpm-skeleton,
    .fpm-tooltip,
    .fpm-popover,
    .fpm-dropdown,
    .fpm-drawer,
    .fpm-modal,
    .fpm-modal-backdrop { animation: none; transition: none; }
}

/* 2. SHELL — app-shell wrapper, console page wrapper, page eyebrow */

/* App three-column shell: nav | content | rail. */
/* Nav and context rail meet both block edges; the page header meets the top edge. */
.fpm-app-shell { position: relative; display: grid; grid-template-columns: var(--fpm-nav-w) minmax(0, 1fr) var(--fpm-rail-w); gap: var(--fpm-space-md); padding: 0 var(--fpm-space-md); min-height: 100vh; align-items: stretch; }
.fpm-app-shell--viewport { position: relative; flex: 1 1 auto; width: 100%; min-height: 0; overflow: hidden; }
.fpm-console-body--viewport { display: flex; flex-direction: column; height: 100vh; overflow: hidden; }
.fpm-app-shell--viewport > .fpm-rail { position: sticky; top: 0; right: auto; height: 100%; z-index: 4; }

/* Scrollable centre column inside the app shell. */
.fpm-app-main { min-width: 0; height: 100%; padding: var(--fpm-shell-pad-block) var(--fpm-shell-pad-inline); overflow: auto; background: transparent; }
/* Sticky page head: it rises into the column's top gutter on the page colour, so nothing scrolls through above it. */
.fpm-sticky-head { position: sticky; top: calc(-1 * var(--fpm-shell-pad-block)); z-index: 40; margin-top: calc(-1 * var(--fpm-shell-pad-block)); padding-top: var(--fpm-shell-pad-block); padding-bottom: var(--fpm-space-sm); background: transparent; }

@media (max-width: 1200px) {
    .fpm-app-shell--viewport { grid-template-columns: var(--fpm-nav-w) minmax(0, 1fr); }
}

@media (max-width: 1024px) {
    .fpm-app-shell--viewport { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 600px) {
    .fpm-app-shell { padding: 0 var(--fpm-space-sm); gap: var(--fpm-space-sm); }
}

/* PAGE KIT — one composition contract for every console page type; .fpm-console-page pages share its column. */
:is(.fpm-page-kit, .fpm-console-page) { width: 100%; max-width: 1920px; margin-inline: auto; display: flex; flex-direction: column; gap: var(--fpm-space-md); padding-block-end: var(--fpm-space-lg); min-width: 0; }
/* Priority colours for ticket rows and chips on any spec-rendered page. */
.fpm-console-page {
    position: relative;
    --fpm-prio-p0-color: var(--fpm-status-error);
    --fpm-prio-p0-rgb: var(--fpm-status-error-rgb);
    --fpm-prio-p1-color: var(--fpm-status-warn);
    --fpm-prio-p1-rgb: var(--fpm-status-warn-rgb);
    --fpm-prio-p2-color: var(--fpm-accent-secondary);
    --fpm-prio-p2-rgb: var(--fpm-accent-secondary-rgb);
    --fpm-prio-p3-color: var(--fpm-status-inactive);
    --fpm-prio-p3-rgb: var(--fpm-status-inactive-rgb);
}
/* Headers pair status and context with wrapping page actions. */
.fpm-page-kit__header { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: var(--fpm-space-md); min-width: 0; }
/* A lede in the header row sits level with the row's actions. */
.fpm-page-kit__header > p { margin: 0; }
/* Detail headers stack breadcrumb and status/action chrome without changing sticky behavior. */
.fpm-page-kit--detail > .fpm-page-kit__header { flex-direction: column; align-items: stretch; }
/* Toolbars and tab bars retain their native controls and routing semantics. */
.fpm-page-kit__toolbar { flex-wrap: wrap; min-width: 0; }
/* A tab row is a line of tabs on the page over one hairline, never a box. */
.fpm-page-kit__tabs { display: flex; flex-wrap: wrap; gap: var(--fpm-space-xs); min-width: 0; padding-block-end: var(--fpm-space-sm); border-bottom: 1px solid var(--fpm-divider); }
/* Lists and tabbed detail bodies scroll within their available width. */
.fpm-page-kit__body { min-width: 0; display: flex; flex-direction: column; gap: var(--fpm-space-md); }
.fpm-page-kit--list .fpm-table-wrap { max-width: 100%; overflow-x: auto; }
/* Settings use named sections, native validation and a consistent action footer. */
.fpm-page-kit__section { display: flex; flex-direction: column; gap: var(--fpm-space-md); min-width: 0; }
.fpm-page-kit__actions { display: flex; flex-wrap: wrap; gap: var(--fpm-space-sm); justify-content: flex-end; }
/* Widget grids accept framework card hosts without additional page layout CSS. */
.fpm-page-kit__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); gap: var(--fpm-space-md); min-width: 0; }
.fpm-page-kit__grid > * { min-width: 0; }

/* Base page-spec grid: twelve shrinkable columns, rows that grow for content and stretch every card in a row to the same height. */
.fpm-page-grid { --fpm-grid-gap: 18px; display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); grid-auto-rows: minmax(var(--fpm-grid-row, var(--fpm-space-xl)), auto); gap: var(--fpm-grid-gap); min-width: 0; align-content: start; align-items: stretch; }
/* Hosts place by DOM order so a widened card wraps instead of overlapping. A card spans at least 4 of 12 columns, 6 on tablets, and one column on phones. */
.fpm-page-grid > * { grid-column: span max(var(--fpm-w, 12), 4); grid-row: span var(--fpm-h, 1); min-width: 0; }
/* A banner with nothing to say (no agent update to announce) takes no row, so the page has no empty gap. */
.fpm-page-grid > [data-fpm-widget-id]:has(.fpm-banner.fpm-hidden) { display: none; }
/* A compact card holds one number, so it may sit four across. */
.fpm-page-grid > .fpm-card[data-fpm-card-size="compact"] { grid-column: span max(var(--fpm-w, 12), 3); }
/* On a tablet a row holds two halves or one whole: a card wider than half takes the row, so an 8-wide map never
   leaves a 4-column hole that its 6-wide neighbour cannot fill. */
@media (max-width: 1180px) {
    .fpm-page-grid > *, .fpm-page-grid > .fpm-card[data-fpm-card-size="compact"] { grid-column: span round(up, max(var(--fpm-w, 12), 6), 6); }
    /* A height span was sized beside its desktop neighbours; once cards re-pair it would stretch a short card
       down the whole column, so each card takes the height of its own row instead. */
    .fpm-page-grid > * { grid-row: auto; }
    /* Thirds pair up as halves, so an odd run of them leaves its last card beside a hole; that card takes the row. */
    .fpm-page-grid > [data-fpm-span="4"]:nth-child(odd of [data-fpm-span="4"]):not(:has(+ [data-fpm-span="4"])) { grid-column: 1 / -1; }
}
@media (max-width: 700px) {
    .fpm-page-grid { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
    .fpm-page-grid > * { grid-column: 1 / -1; grid-row: auto; }
}

/* Eyebrow row above the console hero — title + crumb + meta. */
.fpm-page-eyebrow { display: flex; align-items: baseline; gap: 14px; padding: 4px 2px 2px; flex-wrap: wrap; }

/* Eyebrow primary title (page H1). */
.fpm-page-eyebrow__title { font-size: var(--fpm-font-page-title); font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-primary); letter-spacing: -0.01em; margin: 0; }

/* Eyebrow breadcrumb / context line — uppercase tracked label. */
.fpm-page-eyebrow__crumb { font-size: var(--fpm-font-label); text-transform: uppercase; letter-spacing: 0.18em; color: var(--fpm-text-muted); font-weight: var(--fpm-weight-semibold); }
.fpm-page-eyebrow__crumb b { color: var(--fpm-text-secondary); font-weight: var(--fpm-weight-semibold); }

/* Eyebrow flex spacer between title and meta. */
.fpm-page-eyebrow__spacer { flex: 1; }

/* Eyebrow right-aligned meta (timestamps / counts in mono). */
.fpm-page-eyebrow__meta { font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); font-family: var(--fpm-font-mono); }
.fpm-page-eyebrow__meta b { color: var(--fpm-text-body); font-weight: var(--fpm-weight-semibold); }

/*    3. OPS SHELL — the operator console's two-column shell and tab rail
   ops (infra/ops/app) is a console of a few tabs with no right rail, so it does
   not use .fpm-app-shell's nav | content | rail grid. Its tabs are real links
   or buttons: state is [aria-current="page"], and native chrome is cleared.
   The read line's moving bar is the only animation, and it stops under reduced motion. */
.fpm-ops-shell { display: grid; grid-template-columns: 15rem minmax(0, 1fr); min-height: 100vh; background: var(--fpm-bg-deep); }
.fpm-ops-nav { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; gap: 2px; padding: var(--fpm-space-lg) var(--fpm-space-sm); background: var(--fpm-L1); border-right: 1px solid var(--fpm-border-light); }
.fpm-ops-nav__brand { padding: 0 var(--fpm-space-md) var(--fpm-space-lg); font-size: var(--fpm-font-card-title); font-weight: var(--fpm-weight-bold); letter-spacing: -0.01em; color: var(--fpm-text-primary); }
.fpm-ops-nav__brand span { color: var(--fpm-accent); }
.fpm-ops-nav__tab { appearance: none; border: 0; background: transparent; font: inherit; text-decoration: none; width: 100%; text-align: left; display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: var(--fpm-space-sm); padding: var(--fpm-space-sm) var(--fpm-space-md); border-radius: var(--fpm-radius-sm); color: var(--fpm-text-body); cursor: pointer; }
.fpm-ops-nav__tab:hover { background: var(--fpm-bg-surface-hover); }
.fpm-ops-nav__tab[aria-current="page"] { background: var(--fpm-accent-dim); color: var(--fpm-accent); }
.fpm-ops-nav__tab:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
.fpm-ops-nav__label { grid-column: 1; font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-semibold); }
.fpm-ops-nav__sub { grid-column: 1; font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); }
.fpm-ops-nav__badge { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
.fpm-ops-nav__foot { margin-top: var(--fpm-space-md); display: flex; align-items: center; gap: var(--fpm-space-sm); padding: var(--fpm-space-md) var(--fpm-space-md) 0; border-top: 1px solid var(--fpm-divider-strong); font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); }
.fpm-ops-nav__foot > :first-child { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.fpm-ops-page { display: flex; flex-direction: column; gap: var(--fpm-space-lg); width: 100%; max-width: 72rem; min-width: 0; padding: var(--fpm-space-xl) var(--fpm-space-2xl) var(--fpm-space-2xl); }
/* Who is signed in, named as such, above the Lock control. */
.fpm-ops-nav__who { display: flex; flex-direction: column; gap: 2px; }
.fpm-ops-nav__who-label { font-size: var(--fpm-font-label-sm); text-transform: uppercase; letter-spacing: 0.06em; color: var(--fpm-text-muted); }
/* The page's read state in one quiet line: a moving bar while sources answer, then when it was read. */
.fpm-ops-readline { display: flex; align-items: center; gap: var(--fpm-space-sm); min-height: 1.75rem; font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); }
.fpm-ops-readline__text { flex: 1; min-width: 0; }
.fpm-ops-readline__bar { position: relative; flex: none; width: 5rem; height: 3px; overflow: hidden; border-radius: 999px; background: var(--fpm-divider-strong); }
.fpm-ops-readline__bar::after { content: ''; position: absolute; inset: 0 auto 0 0; width: 40%; border-radius: inherit; background: var(--fpm-accent); animation: fpm-ops-readline 1.1s ease-in-out infinite; }
@keyframes fpm-ops-readline { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
@media (prefers-reduced-motion: reduce) { .fpm-ops-readline__bar::after { animation: none; width: 100%; opacity: 0.5; } }
/* Jobs waiting on the owner's workstation: one warn band each at the top of every page, saying what
   waits, what happens next and the command that answers it, beside a copy control and the job. */
.fpm-ops-waiting { display: flex; flex-direction: column; gap: var(--fpm-space-sm); }
.fpm-ops-waiting__job { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-space-sm) var(--fpm-space-lg); padding: var(--fpm-space-md) var(--fpm-space-lg); border: 1px solid var(--fpm-status-warn); border-left-width: 4px; border-radius: var(--fpm-radius-md); background: var(--fpm-status-warn-dim); }
.fpm-ops-waiting__text { flex: 1 1 24rem; min-width: 0; display: flex; flex-direction: column; gap: var(--fpm-space-xs); font-size: var(--fpm-font-body-sm); color: var(--fpm-text-body); }
.fpm-ops-waiting__title { font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-semibold); color: var(--fpm-status-warn); }
.fpm-ops-waiting__command { font-family: var(--fpm-font-mono); color: var(--fpm-text-primary); overflow-wrap: anywhere; }
.fpm-ops-waiting__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-space-sm); }
/* A name that is a link to its place (a tenant, a cell, a ledger record), drawn as text. */
.fpm-ops-link { appearance: none; border: 0; background: none; padding: 0; font: inherit; text-decoration: none; color: var(--fpm-accent); text-align: left; cursor: pointer; }
.fpm-ops-link:hover { text-decoration: underline; }
.fpm-ops-link:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); border-radius: var(--fpm-radius-xs); }
/* Narrow screens: the rail becomes a row of tabs above the page. */
@media (max-width: 48rem) {
    .fpm-ops-shell { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto 1fr; }
    .fpm-ops-nav { position: static; height: auto; flex-direction: row; flex-wrap: wrap; align-items: center; padding: var(--fpm-space-sm); border-right: 0; border-bottom: 1px solid var(--fpm-border-light); }
    .fpm-ops-nav__tab { width: auto; display: flex; align-items: center; gap: var(--fpm-space-xs); }
    .fpm-ops-nav__sub, .fpm-ops-nav__brand { display: none; }
    .fpm-ops-nav__foot { margin: 0 0 0 auto; border-top: 0; padding: 0; }
    .fpm-ops-page { padding: var(--fpm-space-lg) var(--fpm-space-lg) var(--fpm-space-xl); }
}

/* 4. CARDS — card chrome + chip primitives */

/* fpm-card widget primitive CSS vars */
/* Every visual property is a CSS custom property. */
.fpm-card {
    --fpm-card-rail-w:      3px;
    --fpm-card-title-track: -0.008em;
    --fpm-card-pad:         var(--fpm-space-lg);
    --fpm-card-dur:         var(--fpm-dur-quick);
}

/* Base card (A1): the glass panel. Translucent fill, 1px edge, inset top highlight, deep soft drop shadow and a blurred backdrop. */
.fpm-card { position: relative; background: var(--fpm-card-bg); border: 1px solid var(--fpm-card-border); border-radius: var(--fpm-card-radius); box-shadow: var(--fpm-card-shadow), var(--fpm-card-ring, 0 0 0 transparent); -webkit-backdrop-filter: var(--fpm-panel-backdrop); backdrop-filter: var(--fpm-panel-backdrop); overflow: hidden; isolation: isolate; padding: var(--fpm-card-pad); transition: box-shadow var(--fpm-card-dur) var(--fpm-ease-standard); }

/* Card with internal padding (use when card content has no internal padding). */
.fpm-card--flush { padding: 16px 18px; }

/* Card with no padding (e.g. table cards where the table owns padding). */
.fpm-card--padding-none { padding: 0; }

/* fpm-card--inner widget primitive CSS vars */
.fpm-card--inner {
    --fpm-card-inner-bg:            var(--fpm-L3);
    --fpm-card-inner-shadow-inset:  var(--fpm-card-shadow-inner);
}
/* Inner card — sits inside a parent card on the L3 surface. */
.fpm-card--inner { background: var(--fpm-card-inner-bg); border-color: var(--fpm-border-light); box-shadow: var(--fpm-card-inner-shadow-inset); }

/* List-row card — divider only, no shadow/radius. */
.fpm-card--item { background: transparent; border-radius: 0; box-shadow: none; border: 0; border-bottom: 1px solid var(--fpm-divider); }

/* Elevation levels: 1 is the default card, 2 raised, 3 floating (detached panels). */
.fpm-card--raised { --fpm-card-shadow: var(--fpm-shadow-2); }
.fpm-card--floating { --fpm-card-shadow: var(--fpm-shadow-3); z-index: var(--fpm-z-popover); }

/* Key card — sits in its own pool of accent light under the card. */
.fpm-card--key { --fpm-card-glow: 0 34px 70px -34px var(--fpm-glow-accent); }

/* Sticky card — keeps top edge pinned while page scrolls. */
.fpm-card--sticky { position: sticky; top: 0; z-index: var(--fpm-z-sticky); }

/* Selectable card — pointer cursor + hover/select states. */
.fpm-card--selectable { cursor: pointer; transition: all var(--fpm-transition-fast); }
.fpm-card--selectable:hover { --fpm-card-ring: 0 0 0 1px var(--fpm-border-accent); }
.fpm-card--selectable[aria-selected="true"] { --fpm-card-ring: 0 0 0 1px var(--fpm-accent); }

/* Hover-lift — translate Y on hover for tile grids. */
.fpm-card--hover-lift {
    transition: transform var(--fpm-transition-fast),
                box-shadow var(--fpm-transition-fast);
}
.fpm-card--hover-lift:hover { transform: translateY(-2px); box-shadow: var(--fpm-card-shadow-hover); }

/* fpm-card--severity widget primitive CSS vars */
.fpm-card--severity-ok,
.fpm-card--severity-warn,
.fpm-card--severity-error {
    --fpm-card-rail-color-ok:       var(--fpm-status-ok);
    --fpm-card-rail-color-warn:     var(--fpm-status-warn);
    --fpm-card-rail-color-error:    var(--fpm-status-error);
    --fpm-card-rail-color-critical: var(--fpm-status-error);
}
/* Severity left-rail accent (3-px); healthy cards keep the normal edge. */
.fpm-card--severity-warn  { --fpm-card-rail: inset var(--fpm-card-rail-w) 0 0 var(--fpm-card-rail-color-warn); --fpm-card-glow: 0 30px 64px -34px var(--fpm-glow-warn); }
.fpm-card--severity-error { --fpm-card-rail: inset var(--fpm-card-rail-w) 0 0 var(--fpm-card-rail-color-error); --fpm-card-glow: 0 30px 64px -34px var(--fpm-glow-crit); }

/* Accent bar on the left edge (4-px brand). */
.fpm-card--accent-bar { border-left: 4px solid var(--fpm-accent); }

/* Padding modifiers. */
.fpm-card--compact { padding: 8px 10px; }
.fpm-card--tight   { padding: 4px 6px; }
.fpm-card--loose   { padding: 22px 26px; }

/* Card header row (title + chips/chips/actions). */
.fpm-card__title-row { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; min-width: 0; }

/* Card title — sentence-case sans in strong ink. */
.fpm-card__title { flex: 1 1 auto; min-width: 0; font-size: var(--fpm-font-card-title); font-weight: 650; letter-spacing: var(--fpm-card-title-track); color: var(--fpm-text-strong); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Inline chip used in card headers — neutral. */

/* fpm-card--accordion widget primitive CSS vars */
.fpm-card--accordion {
    --fpm-card-accord-bar-bg:   var(--fpm-L2);
    --fpm-card-accord-bar-pad:  12px 18px;
    --fpm-card-accord-arrow-dur: var(--fpm-dur-quick);
}
/* Accordion card built on a <details> element. */
.fpm-card--accordion { background: var(--fpm-card-bg, var(--fpm-L2)); border: 1px solid var(--fpm-card-border, var(--fpm-border-medium)); border-radius: var(--fpm-card-radius, var(--fpm-radius-md)); box-shadow: var(--fpm-card-shadow); overflow: hidden; }
.fpm-card--accordion > summary { list-style: none; cursor: pointer; }
.fpm-card--accordion > summary::-webkit-details-marker { display: none; }
.fpm-card--accordion > summary::marker { content: ''; }

/* Accordion header bar inside summary. */
.fpm-card-accordion__bar { display: flex; align-items: center; gap: 16px; padding: var(--fpm-card-accord-bar-pad); cursor: pointer; background: var(--fpm-card-accord-bar-bg); transition: background var(--fpm-card-accord-arrow-dur) ease; }
.fpm-card-accordion__bar:hover { background: color-mix(in srgb, var(--fpm-bg-surface-hover) 60%, var(--fpm-card-accord-bar-bg)); }

/* Accordion title slot. */
.fpm-card-accordion__title { font-size: var(--fpm-font-label); font-weight: var(--fpm-weight-semibold); letter-spacing: 0.14em; text-transform: uppercase; color: var(--fpm-text-secondary); }

/* Accordion summary chip cluster (collapsed-state preview). */
.fpm-card-accordion__chips { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; }

/* Single mono chip inside the accordion summary. */
.fpm-card-accordion__chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; }
.fpm-card-accordion__chip b { color: var(--fpm-text-body); font-weight: var(--fpm-weight-semibold); }

/* Right-side chevron toggle on the accordion header. */
.fpm-card-accordion__toggle { font-family: var(--fpm-font-mono); font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); transition: transform var(--fpm-card-accord-arrow-dur, var(--fpm-transition-fast)); }
.fpm-card--accordion[open] .fpm-card-accordion__toggle { transform: rotate(90deg); color: var(--fpm-accent); }

/* reduce-motion: disable card transitions */
@media (prefers-reduced-motion: reduce) {
    .fpm-card,
    .fpm-card-accordion__bar,
    .fpm-card-accordion__toggle { transition: none; }
}

/* Shared controls: the only button, field and toolbar chrome. */
/* Base button — all fpm-btn variants inherit from this. */
.fpm-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 34px; padding: 0 14px; font-family: var(--fpm-font-family); font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-medium); line-height: 1.2; border-radius: var(--fpm-radius-sm); border: 1px solid var(--fpm-border-strong); background: var(--fpm-btn-bg); box-shadow: none; color: var(--fpm-text-primary); cursor: pointer; white-space: nowrap; transition: background var(--fpm-transition-fast), border-color var(--fpm-transition-fast), color var(--fpm-transition-fast); }
/* Every button has a visible edge at rest; a white button on a white card must still read as a button. */
.fpm-btn:hover:not(:disabled) { background: var(--fpm-btn-hover); }
/* Disabled controls retain readable ink on a neutral surface. */
.fpm-btn:disabled { background: var(--fpm-bg-surface); border-color: var(--fpm-border-light); color: var(--fpm-text-secondary); box-shadow: none; cursor: not-allowed; pointer-events: none; }
.fpm-btn:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
/* A file field's own button is the browser's grey control; it takes the console button look so it reads as one. */
.fpm-input[type="file"] { padding-block: var(--fpm-space-xs); color: var(--fpm-text-secondary); }
.fpm-input[type="file"]::file-selector-button { margin-inline-end: var(--fpm-space-sm); padding: var(--fpm-space-xs) var(--fpm-space-md); border: 1px solid var(--fpm-border-strong); border-radius: var(--fpm-radius-sm); background: var(--fpm-btn-bg); color: var(--fpm-text-primary); font: var(--fpm-weight-medium) var(--fpm-font-body-sm) var(--fpm-font-family); cursor: pointer; }
.fpm-input[type="file"]::file-selector-button:hover { background: var(--fpm-btn-hover); }

/* A button that reads as a word in running text: a group name that opens its drawer. */
.fpm-btn--link { padding: 0; border: 0; background: none; color: inherit; font: inherit; cursor: pointer; text-decoration: underline; text-decoration-color: var(--fpm-border-medium); text-underline-offset: 2px; }
.fpm-btn--link:hover { color: var(--fpm-link-hover); text-decoration-color: currentColor; }
.fpm-btn--link:focus-visible { outline: none; border-radius: var(--fpm-radius-xs); box-shadow: var(--fpm-shadow-focus-ring); }

/* fpm-btn--primary — solid accent fill. Primary save / confirm actions. */
.fpm-btn--primary:not(:disabled) { background: var(--fpm-btn-primary-bg); color: var(--fpm-on-accent); border-color: var(--fpm-border-strong); box-shadow: var(--fpm-btn-primary-shadow); }
.fpm-btn--primary:hover:not(:disabled) { background: var(--fpm-btn-primary-bg); filter: brightness(1.08); }

/* fpm-btn--danger — tinted destructive action. */
.fpm-btn--danger:not(:disabled) { background: var(--fpm-status-error-dim); color: var(--fpm-ink-error); border-color: color-mix(in srgb, var(--fpm-status-error) 45%, transparent); }
.fpm-btn--danger:hover:not(:disabled) { background: color-mix(in srgb, var(--fpm-status-error) 22%, transparent); border-color: color-mix(in srgb, var(--fpm-status-error) 60%, transparent); }
/* Icon-only secondary button: square with the shared height. */
.fpm-btn--icon { width: 34px; min-width: 34px; min-height: 34px; height: 34px; padding: 0; }
.fpm-btn--icon:not(:disabled) { background: var(--fpm-btn-bg); border-color: var(--fpm-border-strong); color: var(--fpm-text-primary); box-shadow: none; }
.fpm-btn--icon:hover:not(:disabled) { background: var(--fpm-btn-hover); border-color: var(--fpm-border-strong); color: var(--fpm-text-primary); }

/* btn-glyph-icon — icon + text label; icon left of label. */
.fpm-btn--glyph-icon i { flex-shrink: 0; font-size: 0.875em; }
.fpm-btn--glyph-icon .fpm-btn__label { flex: 1; }

/* btn-chevron — disclosure trigger; rotates chevron when [aria-expanded=true]. */
.fpm-btn--chevron { gap: 6px; }
.fpm-btn--chevron .fpm-btn__chevron { font-size: 0.7em; transition: transform var(--fpm-transition-fast); flex-shrink: 0; }
.fpm-btn--chevron[aria-expanded="true"] .fpm-btn__chevron { transform: rotate(180deg); }

/* Shared fields: a themed well, readable ink, one teal focus treatment. */
.fpm-input,
.fpm-select,
.fpm-textarea {
    display: block;
    width: 100%;
    min-width: 0;
    padding: var(--fpm-input-pad-y) var(--fpm-input-pad-x);
    background-color: var(--fpm-control-bg);
    border: 1px solid var(--fpm-control-border);
    border-radius: var(--fpm-input-radius);
    color: var(--fpm-control-ink);
    font: var(--fpm-input-fs)/1.4 var(--fpm-font-family);
    transition: border-color var(--fpm-transition-fast), box-shadow var(--fpm-transition-fast);
}
.fpm-input:focus,
.fpm-select:focus,
.fpm-textarea:focus { outline: none; border-color: var(--fpm-accent); box-shadow: var(--fpm-shadow-focus-ring); }
.fpm-input::placeholder,
.fpm-textarea::placeholder { color: var(--fpm-control-muted); opacity: 1; }
.fpm-input:disabled,
.fpm-select:disabled,
.fpm-textarea:disabled { background-color: var(--fpm-bg-surface); color: var(--fpm-text-faint); border-color: var(--fpm-border-light); cursor: not-allowed; }
.fpm-input[aria-invalid="true"],
.fpm-select[aria-invalid="true"],
.fpm-textarea[aria-invalid="true"] { border-color: var(--fpm-status-error); box-shadow: var(--fpm-shadow-focus-error); }
.fpm-input--mini { width: auto; padding: 4px 8px; font-family: var(--fpm-font-mono); font-size: var(--fpm-font-body-sm); }
.fpm-input--mini-num { width: 64px; text-align: right; }
.fpm-textarea { min-height: calc(var(--fpm-textarea-rows, 4) * 1.5em + 14px); resize: vertical; }
.fpm-textarea--mono { font-family: var(--fpm-font-mono); }
.fpm-select {
    padding-right: 30px;
}
.fpm-select[multiple] { padding-right: var(--fpm-input-pad-x); }
.fpm-select option { background: var(--fpm-control-bg); color: var(--fpm-control-ink); }
.fpm-select-wrap { display: block; width: 100%; min-width: 0; }

/* Shared filter toolbar, wrapping naturally on narrow viewports. */
.fpm-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-filter-gap); padding: var(--fpm-filter-pad-y) var(--fpm-filter-pad-x); background: var(--fpm-L2); border-bottom: 1px solid var(--fpm-divider-strong); }
.fpm-toolbar__group { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-space-sm); min-width: 0; }
.fpm-toolbar__group > label { margin: 0; color: var(--fpm-text-secondary); font-size: var(--fpm-font-body-sm); }
.fpm-toolbar__spacer { flex: 1 1 auto; }
/* A control or a quiet note with its own buttons on the same line, so the buttons never stack under it. */
.fpm-input-row { display: flex; align-items: center; gap: var(--fpm-space-xs); min-width: 0; }
.fpm-input-row--wrap { flex-wrap: wrap; }
.fpm-input-row > :is(.fpm-input, .fpm-select, .fpm-textarea, .fpm-field-hint) { flex: 1 1 auto; min-width: 0; margin: 0; }
/* A button that reads as its own text, such as a row's name that opens the row. */
.fpm-btn.fpm-btn--text { justify-content: flex-start; min-height: 0; padding: 0; border: 0; background: none; color: var(--fpm-text-primary); font: inherit; font-weight: var(--fpm-weight-semibold); text-align: start; }
.fpm-btn.fpm-btn--text:hover { background: none; color: var(--fpm-accent); }
.fpm-content-stack { display: flex; flex-direction: column; gap: var(--fpm-space-md); min-width: 0; }
.fpm-content-stack > :is(p, h2, h3) { margin: 0; }
/* A donut in a card stretched by its row sits in the middle of the spare height, not above a gap. */
.fpm-card > .fpm-card__body:has(> .fpm-donut) { display: grid; align-content: center; }
/* A card alone in its section carries no title, since the section heading names it; its empty head takes no space. */
.fpm-card:has(> .fpm-card__head > .fpm-card__title:empty):not(:has(> .fpm-card__head > .fpm-card__subtitle:not(:empty))):not(:has(> .fpm-card__head > :is(.fpm-card__meta, .fpm-card__link):not([hidden]))) { row-gap: 0; }
.fpm-card:has(> .fpm-card__head > .fpm-card__title:empty):not(:has(> .fpm-card__head > .fpm-card__subtitle:not(:empty))):not(:has(> .fpm-card__head > :is(.fpm-card__meta, .fpm-card__link):not([hidden]))) > .fpm-card__head { display: none; }
.fpm-toolbar > .fpm-input { flex: 1 1 220px; width: auto; }
.fpm-toolbar .fpm-select { width: auto; min-width: 5rem; }
/* Compact list filters share one row at desktop widths and wrap on mobile. */
.fpm-toolbar--compact { gap: var(--fpm-space-xs); padding: var(--fpm-space-xs) var(--fpm-space-sm); }
.fpm-toolbar--compact > .fpm-input { flex-basis: 96px; min-width: 96px; }
:where(.fpm-toolbar--compact) :is(.fpm-input, .fpm-select) { min-height: 28px; padding: var(--fpm-space-xs) var(--fpm-space-sm); font-size: var(--fpm-font-body-sm); }
/* A filter chip beside the search field stands as tall as the field, so the row reads as one line of controls. */
@media (min-width: 641px) { :where(.fpm-toolbar--compact) .fpm-filter__chip { min-height: 28px; padding-inline: var(--fpm-space-sm); } }

/* Padded card content composes action panels and form toolbars. */
.fpm-card__body--padded { padding: var(--fpm-space-md); gap: var(--fpm-space-md); }
.fpm-card__body--padded > .fpm-btn { align-self: flex-start; }
.fpm-card__body--padded > .fpm-toolbar { align-items: flex-end; margin: 0; border: 1px solid var(--fpm-border-light); border-radius: var(--fpm-radius-sm); background: var(--fpm-L1); }
.fpm-card__body--padded > .fpm-toolbar > .fpm-form-group { margin: 0; }

/* One semantic chip. Unknown/disabled/cancelled states remain neutral. */

/* Tables share density, alignment, zebra rows, hover and scrolling. */
.fpm-table-wrap { min-width: 0; max-width: 100%; overflow: auto; }
/* Inter's tabular figures also widen the hyphen, period, comma, colon and space,
   which splits names like kvmlink-test-1, so only number columns take them. */
.fpm-table { width: 100%; border-collapse: collapse; color: var(--fpm-text-body); font-size: var(--fpm-font-body-sm); }
.fpm-table [data-align="right"], .fpm-table-widget__td--align-right { font-variant-numeric: tabular-nums; }
.fpm-table th { padding: var(--fpm-row-pad-y) var(--fpm-row-pad-x); border-bottom: 1px solid var(--fpm-border-medium); background: color-mix(in srgb, var(--fpm-L2) 85%, transparent); text-align: left; white-space: nowrap; position: sticky; top: 0; z-index: 1; }
/* Column headers read the same in every table, a <table> or a grid of divs with ARIA roles. */
:is(.fpm-table th, [role=row] > [role=columnheader]) { color: var(--fpm-text-muted); font: var(--fpm-weight-semibold) var(--fpm-font-body-sm)/1.5 var(--fpm-font-family); letter-spacing: 0.01em; }
.fpm-table td { padding: var(--fpm-row-pad-y) var(--fpm-row-pad-x); border-bottom: 1px solid var(--fpm-divider-strong); vertical-align: top; }
.fpm-table tbody tr:nth-child(even) { background: var(--fpm-row-alt); }
.fpm-table tbody tr:hover { background: var(--fpm-row-hover); }
.fpm-table [data-align="right"] { text-align: right; }
.fpm-table [data-align="center"] { text-align: center; }
.fpm-table [data-tone="error"] > td:first-child { box-shadow: inset 2px 0 var(--fpm-status-error); }
.fpm-table [data-clickable] { cursor: pointer; }

/* Payloads are readable data, never clipped status labels. */
.fpm-details { min-width: 12rem; max-width: 52rem; }
.fpm-details > summary { cursor: pointer; color: var(--fpm-accent); padding: 3px 0; font-size: var(--fpm-font-body-sm); }
.fpm-details > summary:focus-visible { outline: 2px solid var(--fpm-accent); outline-offset: 2px; }
.fpm-kv-list { display: grid; grid-template-columns: minmax(5rem, auto) minmax(0, 1fr); gap: 4px 12px; margin: var(--fpm-space-sm) 0; white-space: normal; }
.fpm-kv-list dt { color: var(--fpm-text-secondary); font-weight: var(--fpm-weight-semibold); }
.fpm-kv-list dd { margin: 0; overflow-wrap: anywhere; white-space: pre-wrap; font-family: var(--fpm-font-mono); }
.fpm-kv-list dd.fpm-kv-list__value--text { font-family: var(--fpm-font-family); letter-spacing: normal; }
.fpm-stat-tile .fpm-stat-tile__trend--error { color: var(--fpm-ink-error); }

/* Every decorative transition in the shared controls has a static mode. */
@media (prefers-reduced-motion: reduce) {
    .fpm-btn, .fpm-btn--icon, .fpm-btn__chevron,
    .fpm-input, .fpm-select, .fpm-textarea { transition: none; }
}
/*
   §6  .fpm-toggle — CSS switch (CANONICAL)
   Design contract. Replaces production text-button pattern everywhere.
   Every new feature uses this markup. The old .toggle-switch / .toggle-slider in forms.css and
   .fpm-list-toggle in fpmListComponents.css are legacy — do not use for new work.

   Markup (minimal):
     <label class="fpm-toggle">
       <input type="checkbox">
       <span class="fpm-toggle__track">
         <span class="fpm-toggle__thumb"></span>
       </span>
     </label>

   Markup (labelled row):
     <label class="fpm-toggle__row">
       <span class="fpm-toggle__row-label">Feature name</span>
       <span class="fpm-toggle">
         <input type="checkbox">
         <span class="fpm-toggle__track">
           <span class="fpm-toggle__thumb"></span>
         </span>
       </span>
     </label>
*/

.fpm-toggle {
    --fpm-toggle-w:          40px;
    --fpm-toggle-h:          22px;
    --fpm-toggle-thumb-sz:   16px;
    --fpm-toggle-travel:     18px;
    --fpm-toggle-track-off:  var(--fpm-toggle-bg-off);
    --fpm-toggle-track-on:   var(--fpm-toggle-bg-on);
    --fpm-toggle-border-off: var(--fpm-toggle-border);
    --fpm-toggle-border-on:  var(--fpm-toggle-border);
    --fpm-toggle-thumb-off:  var(--fpm-toggle-knob);
    --fpm-toggle-thumb-on:   var(--fpm-toggle-knob);

    position: relative;
    display: inline-block;
    /* The switch has no text, so on the baseline it rides above the words beside it; centre it on the line. */
    vertical-align: middle;
    width: var(--fpm-toggle-w);
    height: var(--fpm-toggle-h);
    flex-shrink: 0;
}

/* Hide native input — accessibility retained, invisible to paint. */
.fpm-toggle > input[type="checkbox"] {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
    margin: 0;
}

.fpm-toggle__track {
    position: absolute;
    inset: 0;
    background: var(--fpm-toggle-track-off);
    border: 1px solid var(--fpm-toggle-border-off);
    border-radius: calc(var(--fpm-toggle-h) / 2);
    transition:
        background      var(--fpm-transition-fast),
        border-color    var(--fpm-transition-fast);
}

.fpm-toggle__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: var(--fpm-toggle-thumb-sz);
    height: var(--fpm-toggle-thumb-sz);
    border-radius: 50%;
    background: var(--fpm-toggle-thumb-off);
    box-shadow: var(--fpm-shadow-knob);
    transition:
        transform    var(--fpm-transition-fast),
        background   var(--fpm-transition-fast),
        box-shadow   var(--fpm-transition-fast);
}

/* Checked — track and thumb flip to accent. */
.fpm-toggle > input[type="checkbox"]:checked + .fpm-toggle__track {
    background: var(--fpm-toggle-track-on);
    border-color: var(--fpm-toggle-border-on);
}

.fpm-toggle > input[type="checkbox"]:checked + .fpm-toggle__track .fpm-toggle__thumb {
    transform: translateX(var(--fpm-toggle-travel));
    background: var(--fpm-toggle-thumb-on);
}

/* Focus ring on keyboard navigation. */
.fpm-toggle > input[type="checkbox"]:focus-visible + .fpm-toggle__track {
    box-shadow: 0 0 0 2px var(--fpm-accent-dim);
}

/* Disabled. */
.fpm-toggle > input[type="checkbox"]:disabled + .fpm-toggle__track {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Labelled row — toggle + descriptive text side-by-side. */
.fpm-toggle__row {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    user-select: none;
}

.fpm-toggle__row-label {
    font-size: var(--fpm-font-body-sm);
    color: var(--fpm-text-body);
    font-weight: var(--fpm-weight-semibold);
    flex: 1 1 auto;
    min-width: 0;
}

/* On a phone a switch is smaller than a fingertip, so an invisible square around it takes the touch at the 44px minimum. */
@media (max-width: 640px) {
    .fpm-toggle::after { content: ""; position: absolute; inset-block-start: 50%; inset-inline-start: 50%; width: var(--fpm-touch-target); height: var(--fpm-touch-target); transform: translate(-50%, -50%); }
}

/* Mini inline variant — narrower, for dense data rows. */
.fpm-toggle--mini {
    --fpm-toggle-w:        28px;
    --fpm-toggle-h:        16px;
    --fpm-toggle-thumb-sz: 12px;
    --fpm-toggle-travel:   12px;
}
.fpm-gap-lg { gap:var(--fpm-space-lg); }
.fpm-items-center { align-items:center; }
.fpm-wrap { flex-wrap:wrap; }
.fpm-items-start { align-items:flex-start; }
.fpm-flex { display:flex; }
.fpm-column { flex-direction:column; }
.fpm-color-status-error { color:var(--fpm-status-error); }
.fpm-color-status-warn { color:var(--fpm-status-warn); }
.fpm-gap-sm { gap:var(--fpm-space-sm); }
.fpm-grid { display:grid; }
.fpm-color-text-muted { color:var(--fpm-text-muted); }
.fpm-grid-auto-280 { grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); }
.fpm-gap-md { gap:var(--fpm-space-md); }
.fpm-width-full { width:100%; }
.fpm-max-width-none { max-width:none; }
.fpm-margin-top-sm { margin-top:var(--fpm-space-sm); }
.fpm-mono { font-family:var(--fpm-font-mono); }
.fpm-align-self-start { align-self:flex-start; }
.fpm-max-width-720px { max-width: 720px; }
.fpm-table-widget { max-height: var(--fpm-table-max-body-height, none); overflow-y: auto; }
/* Inside a card a table is one height (--fpm-list-h) and scrolls, so rows arriving never resize the card; a table card's own body already bounds it, so its inner table is left uncapped. Full-page tables (reports) and the tables of a whole screen in a bare card stay uncapped. */
:is(.fpm-card:not([data-fpm-card-style=bare]), .fpm-widget) .fpm-table-widget { block-size: var(--fpm-list-h); max-height: none; }
.fpm-table-card__body .fpm-table-widget { block-size: auto; max-height: none; }
:is(.fpm-card, .fpm-widget) .fpm-table-widget.fpm-table-widget--document { block-size: auto; max-height: none; }
.fpm-table-widget__th { width: var(--fpm-table-column-width, auto); }
.fpm-table-card__body { max-height: var(--fpm-table-card-max-body-height, var(--fpm-list-h)); overflow-y: auto; }
.fpm-stack-bar__seg { flex: var(--fpm-stack-bar-segment-flex, 0 1 0); }
.fpm-vbar__bar-fill { height: var(--fpm-vbar-fill, 0%); }
.fpm-clickable { cursor: pointer; }
.fpm-chart-tooltip { left: var(--fpm-tooltip-left, 0); top: var(--fpm-tooltip-top, 0); }
/* SVG variant of the shared badge primitive, with centered count text. */
.fpm-badge--svg { pointer-events: auto; }
.fpm-badge--svg circle { fill: var(--fpm-L2); stroke: var(--fpm-border-strong); }
.fpm-badge--svg text { fill: var(--fpm-text-primary); font: var(--fpm-weight-bold) var(--fpm-font-meta)/1 var(--fpm-font-mono); text-anchor: middle; dominant-baseline: central; }
/* Geographic view: a reusable dark stage with accessible detail and legend. */
.fpm-geo-view { min-width: 0; overflow: clip; }
.fpm-geo-view__stage { width: 100%; height: clamp(28rem, 52vw, 52rem); position: relative; background: var(--fpm-geo-view-background); }
.fpm-geo-view__canvas { width: 100%; height: 100%; touch-action: none; cursor: grab; }
.fpm-geo-view__canvas:active { cursor: grabbing; }
.fpm-geo-view__clusters { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.fpm-tooltip.fpm-geo-view__tooltip { position: absolute; inset: var(--fpm-space-md) var(--fpm-space-md) auto auto; left: auto; top: var(--fpm-space-md); max-width: min(22rem, calc(100% - 2 * var(--fpm-space-md))); white-space: normal; }
.fpm-geo-view__detail { min-height: 3em; padding: var(--fpm-space-md); border-top: 1px solid var(--fpm-border-light); }
.fpm-geo-view__tooltip-content { display: flex; flex-direction: column; gap: var(--fpm-space-xs); min-width: 15rem; white-space: normal; }
.fpm-geo-view__fields { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--fpm-space-xs) var(--fpm-space-sm); margin: 0; }
.fpm-geo-view__fields dt { color: var(--fpm-text-secondary); font-weight: var(--fpm-weight-regular); }
.fpm-geo-view__fields dd { margin: 0; overflow-wrap: anywhere; }
.fpm-geo-view__sources { max-width: none; padding: 0 var(--fpm-space-md) var(--fpm-space-md); border-top: 1px solid var(--fpm-border-light); }
.fpm-geo-view__sources-list { padding-top: var(--fpm-space-sm); }
.fpm-geo-view__legend { display: flex; flex-wrap: wrap; gap: var(--fpm-space-md); }
.fpm-geo-view__legend [data-plane="web"] { color: var(--fpm-geo-view-web); }
.fpm-geo-view__legend [data-plane="mcp"] { color: var(--fpm-geo-view-mcp); }
.fpm-geo-view__legend [data-plane="agent"] { color: var(--fpm-geo-view-agent); }
.fpm-geo-view__legend [data-plane="ops"] { color: var(--fpm-geo-view-ops); }
.fpm-geo-view__legend [data-plane="mesh"] { color: var(--fpm-geo-view-mesh); }
.fpm-chart-canvas { min-height: var(--fpm-chart-min-height, 180px); }
.fpm-chart-canvas--compact { min-height: 170px; }
.fpm-chart-fill { position: absolute; inset: 0; }
.fpm-clickable { cursor: var(--fpm-action-cursor, pointer); }

/* Desktop and file-transfer dynamic geometry. */
.fpm-os-window { z-index: var(--fpm-window-z-index); top: var(--fpm-window-top); left: var(--fpm-window-left); width: var(--fpm-window-width); height: var(--fpm-window-height); transform: var(--fpm-window-transform); }
.fpm-os-window[data-motion="open"] { animation: windowOpen var(--fpm-dur-quick) var(--fpm-ease-standard); }
.fpm-os-window[data-motion="close"] { animation: windowClose var(--fpm-dur-quick) var(--fpm-ease-standard); }
.fpm-os-window[data-motion="minimize"] { animation: windowMinimize var(--fpm-dur-quick) var(--fpm-ease-standard); }

/* Core widget migrations: table, tree, overlays, collapsible cards, hardware. */
.fpm-table th { width: var(--fpm-table-column-width, auto); }
.fpm-table th[data-align="left"], .fpm-table td[data-align="left"] { text-align: left; }
.fpm-table th[data-align="center"], .fpm-table td[data-align="center"] { text-align: center; }
.fpm-table th[data-align="right"], .fpm-table td[data-align="right"] { text-align: right; }
.fpm-table__row--clickable { cursor: pointer; }
.fpm-overlay-capture { position: fixed; inset: 0; z-index: var(--fpm-z-dropdown); }
.fpm-drawer__header { display: flex; align-items: center; justify-content: space-between; padding: var(--fpm-space-md) var(--fpm-space-lg); border-bottom: 1px solid var(--fpm-border-medium); }
.fpm-drawer__title { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; color: var(--fpm-text-primary); font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-medium); }
.fpm-drawer__close { min-width: auto; padding: var(--fpm-space-xs); }
.fpm-drawer__body { flex: 1; overflow-y: auto; padding: var(--fpm-space-lg); }

@media (max-width: 640px) {
    .fpm-drawer__header { position: sticky; top: 0; z-index: 1; flex-shrink: 0; background: var(--fpm-L2); }
    .fpm-drawer__close { min-width: var(--fpm-touch-target); min-height: var(--fpm-touch-target); flex-shrink: 0; }
    .fpm-drawer__body { min-height: 0; min-width: 0; overscroll-behavior: contain; }
}

.fpm-popover { top: var(--fpm-popover-top); left: var(--fpm-popover-left); width: var(--fpm-popover-width); }
.fpm-dropdown { position: fixed; top: var(--fpm-dropdown-top); left: var(--fpm-dropdown-left); min-width: var(--fpm-dropdown-min-width); }

/* File browsing layout; common controls use the FPM components. */
:is(.stb-toolbar, .fbm-toolbar) { display: flex; align-items: center; gap: 10px; padding: 8px 12px; background: transparent; }
:is(.stb-nav-buttons, .fbm-nav-buttons) { display: flex; gap: 4px; }
:is(.stb-nav-btn, .fbm-nav-btn) { width: 30px; height: 30px; display: flex; align-items: center; justify-content: center; background: transparent; border: 1px solid color-mix(in srgb, var(--fpm-white) 8%, transparent); border-radius: 6px; color: var(--fpm-accent); cursor: pointer; transition: all 0.15s ease; }
:is(.stb-nav-btn, .fbm-nav-btn):hover:not(:disabled) { background: color-mix(in srgb, var(--fpm-white) 4%, transparent); border-color: color-mix(in srgb, var(--fpm-white) 15%, transparent); color: var(--fpm-text-muted); }
:is(.stb-nav-btn, .fbm-nav-btn):disabled { opacity: 0.35; cursor: not-allowed; }
:is(.stb-nav-btn, .fbm-nav-btn) i { font-size: 12px; }
:is(.stb-breadcrumb, .fbm-breadcrumb) { flex: 1; display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: color-mix(in srgb, var(--fpm-black) 15%, transparent); border: 1px solid color-mix(in srgb, var(--fpm-white) 6%, transparent); border-radius: 6px; min-height: 30px; overflow-x: auto; overflow-y: hidden; }
:is(.stb-breadcrumb, .fbm-breadcrumb)::-webkit-scrollbar { height: 4px; }
:is(.stb-breadcrumb, .fbm-breadcrumb)::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--fpm-white) 15%, transparent); border-radius: 2px; }
:is(.stb-breadcrumb-item, .fbm-breadcrumb-item) { background: transparent; border: none; color: var(--fpm-accent); font-size: 13px; cursor: pointer; padding: 4px 8px; border-radius: 4px; white-space: nowrap; transition: all 0.15s ease; }
:is(.stb-breadcrumb-item, .fbm-breadcrumb-item):hover { background: color-mix(in srgb, var(--fpm-white) 6%, transparent); color: var(--fpm-text-muted); }
:is(.stb-breadcrumb-item, .fbm-breadcrumb-item).active { color: var(--fpm-text-muted); font-weight: 500; cursor: default; }
:is(.stb-breadcrumb-separator, .fbm-breadcrumb-separator) { font-size: 10px; color: var(--fpm-accent); }
:is(.stb-breadcrumb-empty, .fbm-breadcrumb-empty) { color: var(--fpm-accent); font-size: 13px; }
:is(.stb-actions, .fbm-actions) { display: flex; gap: 8px; padding: 6px 12px; background: transparent; border-bottom: 1px solid color-mix(in srgb, var(--fpm-white) 6%, transparent); }
:is(.stb-action-buttons, .fbm-action-buttons) { display: flex; gap: 8px; align-items: center; }
:is(.stb-toolbar-btn, .fbm-toolbar-btn) { display: flex; align-items: center; gap: 6px; padding: 6px 12px; background: transparent; border: 1px solid color-mix(in srgb, var(--fpm-white) 8%, transparent); border-radius: 6px; color: var(--fpm-accent); font-size: 0.75rem; font-weight: 500; letter-spacing: 0.01em; cursor: pointer; transition: all 0.15s ease; }
:is(.stb-toolbar-btn, .fbm-toolbar-btn):hover:not(:disabled) { background: color-mix(in srgb, var(--fpm-white) 4%, transparent); border-color: color-mix(in srgb, var(--fpm-white) 15%, transparent); color: var(--fpm-text-muted); }
:is(.stb-toolbar-btn, .fbm-toolbar-btn):disabled { opacity: 0.35; cursor: not-allowed; }
:is(.stb-toolbar-btn, .fbm-toolbar-btn).danger { color: var(--fpm-status-error); }
:is(.stb-toolbar-btn, .fbm-toolbar-btn).danger:hover:not(:disabled) { background: color-mix(in srgb, var(--fpm-status-error) 12%, transparent); border-color: color-mix(in srgb, var(--fpm-status-error) 30%, transparent); color: var(--fpm-status-warn); }
:is(.stb-toolbar-separator, .fbm-toolbar-separator) { width: 1px; height: 20px; background: color-mix(in srgb, var(--fpm-white) 8%, transparent); margin: 0 6px; }
:is(.stb-toolbar-btn, .fbm-toolbar-btn) i { font-size: 12px; opacity: 0.8; }
:is(.stv-tree, .fbm-tree) { font-size: 13px; user-select: none; }

            :is(.stv-node, .fbm-node) {
                /* Container for item + children */
            }
:is(.stv-item, .fbm-item) { display: flex; align-items: center; gap: 8px; padding: 6px 10px; border-radius: 6px; cursor: pointer; transition: all 0.15s ease; color: var(--fpm-text-secondary); margin: 2px 0; }
:is(.stv-item, .fbm-item):hover { background: var(--fpm-row-hover); color: var(--fpm-text-primary); }
:is(.stv-item, .fbm-item).selected { background: var(--fpm-accent-dim); border: 1px solid var(--fpm-accent); color: var(--fpm-text-primary); }
:is(.stv-expand-btn, .fbm-expand-btn) { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; flex-shrink: 0; border-radius: 4px; margin: -4px 0; }
:is(.stv-expand-btn, .fbm-expand-btn):hover { background: var(--fpm-border-medium); }
:is(.stv-expand-icon, .fbm-expand-icon) { font-size: 11px; color: var(--fpm-text-secondary); text-align: center; }
:is(.stv-icon, .fbm-icon) { width: 18px; text-align: center; flex-shrink: 0; }
:is(.stv-label, .fbm-label) { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; }
:is(.stv-name, .fbm-name) { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.stv-badge, .fbm-badge) { font-size: 11px; padding: 2px 6px; border-radius: 4px; background: var(--fpm-bg-surface); flex-shrink: 0; }
:is(.stv-size, .fbm-size) { font-size: 11px; color: var(--fpm-text-secondary); flex-shrink: 0; }
:is(.stv-children, .fbm-children) { margin-left: 22px; }
:is(.stv-empty, .fbm-empty) { text-align: center; padding: 20px; color: var(--fpm-accent); }
:is(.stv-empty, .fbm-empty) i { font-size: 2em; margin-bottom: 10px; opacity: 0.5; display: block; }
:is(.stv-dragging, .fbm-dragging) { opacity: 0.5; }
:is(.stv-name, .fbm-name):is(.stv-editing, .fbm-editing) { background: color-mix(in srgb, var(--fpm-accent) 20%, transparent); outline: 2px solid var(--fpm-accent); border-radius: 4px; padding: 2px 6px; }
:is(.stv-item, .fbm-item).disabled { opacity: 0.6; cursor: default; }
:is(.stv-item, .fbm-item).disabled:hover { background: transparent; color: var(--fpm-accent); }
:is(.stv-phantom, .fbm-phantom) :is(.stv-item, .fbm-item) { opacity: 0.7; background: color-mix(in srgb, var(--fpm-accent) 10%, transparent); border: 1px dashed color-mix(in srgb, var(--fpm-accent) 50%, transparent); }
:is(.stv-phantom, .fbm-phantom) :is(.stv-name, .fbm-name) { font-style: italic; }
:is(.sfp-file-list, .fbm-file-list) { background: var(--fpm-bg-deep); border: 1px solid var(--fpm-border-light); border-radius: 8px; overflow: hidden; }
:is(.sfp-file-header, .fbm-file-header) { display: flex; align-items: center; gap: 10px; padding: 10px 12px; background: var(--fpm-bg-surface); border-bottom: 1px solid var(--fpm-border-medium); font-size: 12px; font-weight: 600; color: var(--fpm-text-secondary); text-transform: uppercase; letter-spacing: 0.5px; }
:is(.sfp-file-item, .fbm-file-item) { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--fpm-divider); transition: background 0.15s ease; font-size: 13px; cursor: pointer; user-select: none; }
:is(.sfp-file-item, .fbm-file-item):last-child { border-bottom: none; }
:is(.sfp-file-item, .fbm-file-item):hover { background: var(--fpm-row-hover); }
:is(.sfp-file-icon, .fbm-file-icon) { width: 20px; text-align: center; flex-shrink: 0; }
:is(.sfp-file-name, .fbm-file-name) { flex: 2; color: var(--fpm-text-primary); min-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:is(.sfp-file-type, .fbm-file-type) { flex: 0.8; color: var(--fpm-text-secondary); font-size: 12px; min-width: 80px; }
:is(.sfp-file-size, .fbm-file-size) { flex: 0.7; color: var(--fpm-text-secondary); font-size: 12px; min-width: 80px; text-align: right; }
:is(.sfp-file-date, .fbm-file-date) { flex: 1; color: var(--fpm-text-secondary); font-size: 12px; min-width: 140px; }
:is(.sfp-file-owner, .fbm-file-owner) { flex: 0.9; color: var(--fpm-text-secondary); font-size: 12px; min-width: 100px; text-align: right; }
:is(.sfp-phantom, .fbm-phantom) { background: var(--fpm-accent-dim); border-left: 3px solid var(--fpm-accent); animation: PREFIX-fadeIn 0.2s ease; }
:is(.sfp-file-name, .fbm-file-name)[contenteditable="true"] { background: var(--fpm-border-medium); padding: 2px 6px; border-radius: 4px; outline: 2px solid var(--fpm-accent); outline-offset: 2px; }
:is(.sfp-empty, .fbm-empty) { padding: 40px; text-align: center; }
:is(.sfe-explorer, .fbm-explorer) { height: 100%; display: flex; flex-direction: column; background: var(--fpm-bg-surface); border-left: 1px solid var(--fpm-border-medium); border-right: 1px solid var(--fpm-border-medium); border-bottom: 1px solid var(--fpm-border-medium); border-top: 2px solid var(--fpm-accent, var(--fpm-accent)); border-radius: 12px; overflow: hidden; }
:is(.sfe-content, .fbm-content) { flex: 1; display: flex; min-height: 0; }
:is(.sfe-sidebar, .fbm-sidebar) { width: 380px; background: var(--fpm-bg-surface); border-right: 1px solid var(--fpm-border-medium); display: flex; flex-direction: column; }
:is(.sfe-tree, .fbm-tree) { flex: 1; overflow-y: auto; padding: 10px; }
:is(.sfe-main, .fbm-main) { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
:is(.sfe-view, .fbm-view) { flex: 1; overflow-y: auto; padding: 14px; }
.fpm-remote-terminal-window { top: 8%; left: 12%; width: 820px; height: 520px; }
.fpm-is-expanded { transform: rotate(90deg); }
.fpm-window--opening { animation: windowOpen .3s ease-out; }
.fpm-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: var(--fpm-space-sm) 0; color: var(--fpm-text-secondary); text-align: center; }
td.fpm-empty { display: table-cell; }
/* A notice that stands in for a whole page sits below the top gutter with room around it, not on the top edge. */
.fpm-empty--page { gap: var(--fpm-space-sm); padding: var(--fpm-space-3xl) var(--fpm-space-xl); }
.fpm-empty.error { color: var(--fpm-status-error); }
.fpm-text-warn { color: var(--fpm-status-warn); }
.fpm-text-error { color: var(--fpm-status-error); }
.fpm-padding-space-md { padding: var(--fpm-space-md); }
.fpm-flex { display: flex; }
.fpm-items-center { align-items: center; }
.fpm-justify-center { justify-content: center; }
.fpm-margin-bottom-space-md { margin-bottom: var(--fpm-space-md); }
.fpm-color-status-warn { color: var(--fpm-status-warn); }
.fpm-column { flex-direction: column; }
.fpm-margin-bottom-space-lg { margin-bottom: var(--fpm-space-lg); }
.fpm-shrink-0 { flex-shrink: 0; }
.fpm-is-pending { opacity: .4; pointer-events: none; }
.fpm-margin-left-sm { margin-left: var(--fpm-space-sm); }
.fpm-color-status-warn { color: var(--fpm-status-warn); }
.fpm-color-status-error { color: var(--fpm-status-error); }
.fpm-table__mono { font-family: var(--fpm-font-mono); }
.fpm-table__status { white-space: nowrap; }
/* Names, hostnames and cell ids read as one token; on a narrow screen the table scrolls instead. */
.fpm-table td.fpm-table__id { white-space: nowrap; }
.fpm-toolbar__group:has(> .fpm-input) { flex: 1; }
.fpm-toolbar__group > .fpm-input { flex: 1; min-width: 180px; }
.fpm-toolbar__group > .fpm-select { width: auto; min-width: 76px; }
/* A printed QR label: a square QR over its permanent code, name and site, so the label still reads with no
 * signal. Paper is white in every theme, so the ink is black. Every length follows the label size, so the
 * on-screen preview is true size and the 25 mm label keeps the same proportions as the 50 mm one. */
.fpm-qr__sheet { --fpm-qr-label-size: 38mm; --fpm-qr-label-height: 50mm; display: grid; grid-template-columns: repeat(auto-fit, var(--fpm-qr-label-size)); justify-content: center; gap: var(--fpm-space-sm); inline-size: 100%; }
.fpm-qr__sheet[data-size="sm"] { --fpm-qr-label-size: 25mm; --fpm-qr-label-height: 33mm; }
.fpm-qr__sheet[data-size="lg"] { --fpm-qr-label-size: 50mm; --fpm-qr-label-height: 66mm; }
.fpm-qr-print { display: block; box-sizing: border-box; inline-size: var(--fpm-qr-label-size); block-size: var(--fpm-qr-label-height); margin: 0; padding: 0; font-family: var(--fpm-font-family); text-align: center; background: var(--fpm-white); color: var(--fpm-black); overflow-wrap: normal; }
/* The vector QR carries the complete four-module quiet zone, so scaling the whole image keeps it at every
 * label size without another border around the code. */
.fpm-qr-print img { display: block; box-sizing: border-box; inline-size: var(--fpm-qr-label-size); block-size: var(--fpm-qr-label-size); margin: 0 auto; background: var(--fpm-white); }
/* Names wrap at word boundaries, stop at two lines and ellipsize an overlong hostname without splitting it.
 * The four text lines fit below the QR even on 25 × 33 mm stock. */
.fpm-qr-print h1 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; text-overflow: ellipsis; margin: 0; padding-inline: calc(var(--fpm-qr-label-size) * 0.04); font-size: calc(var(--fpm-qr-label-size) * 0.075); line-height: 1.1; font-weight: var(--fpm-weight-semibold); }
.fpm-qr-print p { overflow: hidden; margin: 0; padding-inline: calc(var(--fpm-qr-label-size) * 0.04); font-size: calc(var(--fpm-qr-label-size) * 0.06); line-height: 1.1; white-space: nowrap; text-overflow: ellipsis; }
.fpm-qr-print .fpm-qr-print__code { font-family: var(--fpm-font-mono); font-size: calc(var(--fpm-qr-label-size) * 0.075); font-weight: var(--fpm-weight-semibold); font-variant-numeric: tabular-nums; }
/* Named pages, so a label size applies only to the label and never to printing the console itself. */
@page fpm-qr-label-sm { size: 25mm 33mm; margin: 0; }
@page fpm-qr-label-md { size: 38mm 50mm; margin: 0; }
@page fpm-qr-label-lg { size: 50mm 66mm; margin: 0; }
@page fpm-qr-sheet { size: A4; margin: 10mm; }
/* An on-screen code to scan: a fixed-size white tile (cameras need the quiet zone), a caption and its actions. */
.fpm-qr { display: flex; flex-direction: column; align-items: center; gap: var(--fpm-space-sm); margin-block: var(--fpm-space-md); }
@media print {
  .fpm-qr { display: block; margin: 0; background: var(--fpm-white); color: var(--fpm-black); }
  .fpm-qr::before { content: none; }
  .fpm-qr__sheet { page: fpm-qr-sheet; }
  .fpm-qr__sheet[data-single="true"] { page: fpm-qr-label-md; gap: 0; }
  .fpm-qr__sheet[data-single="true"][data-size="sm"] { page: fpm-qr-label-sm; }
  .fpm-qr__sheet[data-single="true"][data-size="lg"] { page: fpm-qr-label-lg; }
  .fpm-qr-print { break-inside: avoid; overflow: hidden; }
  .fpm-qr__sheet[data-single="false"] .fpm-qr-print { position: relative; }
  .fpm-qr__sheet[data-single="false"] .fpm-qr-print::after { content: ''; position: absolute; inset: 0; border: 0.25pt solid var(--fpm-border-light); pointer-events: none; }
}
.fpm-qr__code { display: block; inline-size: 200px; block-size: 200px; padding: var(--fpm-space-sm); background: var(--fpm-white); border-radius: var(--fpm-radius-md); }
.fpm-qr__caption { margin: 0; font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); font-variant-numeric: tabular-nums; }
.fpm-qr__actions { display: flex; gap: var(--fpm-space-xs); }
.fpm-node-card--clickable { cursor: pointer; }
.fpm-settings-modal { width: var(--fpm-settings-modal-width, 31.25rem); }

.module-dot--storage { background: var(--fpm-module-storage); }
.module-dot--vms { background: var(--fpm-module-vms); }
.module-dot--network { background: var(--fpm-module-network); }
.fpm-security-email { font-family: var(--fpm-font-family); max-width: 37.5rem; margin: 0 auto; }
.fpm-security-email__header { background: var(--fpm-status-error); color: var(--fpm-on-accent); padding: var(--fpm-space-lg) var(--fpm-space-xl); border-radius: var(--fpm-radius-lg) var(--fpm-radius-lg) 0 0; }
.fpm-security-email__title { margin: 0; font-size: var(--fpm-font-lg); }
.fpm-security-email__content { background: var(--fpm-bg-surface-raised); color: var(--fpm-text-primary); padding: var(--fpm-space-xl); border-radius: 0 0 var(--fpm-radius-lg) var(--fpm-radius-lg); }
.fpm-security-email__message { margin: 0 0 var(--fpm-space-lg); }
.fpm-security-email__details { font-size: var(--fpm-font-sm); border-collapse: collapse; }
.fpm-security-email__key { padding: var(--fpm-space-xs) var(--fpm-space-md) var(--fpm-space-xs) 0; color: var(--fpm-text-muted); }
.fpm-security-email__value { padding: var(--fpm-space-xs) 0; }
.fpm-security-email__meta { margin: var(--fpm-space-lg) 0 0; color: var(--fpm-text-muted); font-size: var(--fpm-font-xs); }

/* Assistant conversation: shared drawer, message and action-card patterns. */
.fpm-drawer.fpm-assistant-drawer { width: min(560px, 100vw); }
.fpm-assistant-drawer > .fpm-drawer__body { display: flex; min-height: 0; padding: 0; overflow: hidden; }
.fpm-assistant { display: flex; flex: 1; flex-direction: column; min-width: 0; min-height: 0; gap: var(--fpm-space-sm); padding: var(--fpm-space-lg); }
.fpm-assistant__context { margin: 0; color: var(--fpm-text-primary); font-size: var(--fpm-font-body-sm); overflow-wrap: anywhere; }
.fpm-assistant__meta { margin: 0; color: var(--fpm-text-muted); font-size: var(--fpm-font-meta); overflow-wrap: anywhere; }
.fpm-assistant__messages { display: flex; flex: 1; flex-direction: column; gap: var(--fpm-space-md); min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.fpm-assistant__message { padding-block: var(--fpm-space-xs); }
.fpm-assistant__label { margin: 0 0 var(--fpm-space-xs); color: var(--fpm-text-primary); font-size: var(--fpm-font-body-sm); font-weight: var(--fpm-weight-semibold); }
.fpm-assistant__text { margin: 0; color: var(--fpm-text-body); font-size: var(--fpm-font-body-sm); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.fpm-assistant__tool { padding: var(--fpm-space-sm) var(--fpm-space-md); color: var(--fpm-text-muted); font-size: var(--fpm-font-body-sm); }
.fpm-assistant__tool > summary { cursor: pointer; }
.fpm-assistant__proposal { display: flex; flex-direction: column; flex-shrink: 0; gap: var(--fpm-space-sm); }
.fpm-assistant__target { margin: 0; color: var(--fpm-text-primary); font-size: var(--fpm-font-body-sm); overflow-wrap: anywhere; }
.fpm-assistant__device-id { color: var(--fpm-text-muted); font-family: var(--fpm-font-mono); font-size: var(--fpm-font-meta); overflow-wrap: anywhere; }
.fpm-assistant__code { margin: 0; padding: var(--fpm-space-sm); border: 1px solid var(--fpm-border-subtle); border-radius: var(--fpm-radius-sm); background: var(--fpm-L1); color: var(--fpm-text-primary); font-family: var(--fpm-font-mono); font-size: var(--fpm-font-body-sm); line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
.fpm-assistant__code > code { font: inherit; }
.fpm-assistant__actions { display: flex; flex-wrap: wrap; gap: var(--fpm-space-sm); }
.fpm-assistant__actions[hidden] { display: none; }
.fpm-assistant__error { margin: 0; color: var(--fpm-status-error); font-size: var(--fpm-font-body-sm); overflow-wrap: anywhere; }
/* Inline controls and composer can be used in any compact dialog. */
.fpm-inline-controls { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-space-sm); }
.fpm-inline-composer { display: flex; align-items: flex-end; flex-shrink: 0; gap: var(--fpm-space-sm); padding-top: var(--fpm-space-sm); border-top: 1px solid var(--fpm-border-subtle); }
:where(.fpm-inline-composer) > .fpm-textarea { flex: 1; min-width: 0; min-height: calc(1.5em + var(--fpm-space-md)); resize: vertical; max-height: 180px; }
.fpm-pill-bar.fpm-pill-bar--compact { padding: var(--fpm-space-xs); gap: 0; }
.fpm-pill-bar--compact .fpm-pill-bar__pill { padding: var(--fpm-space-xs); font-size: var(--fpm-font-meta); }
.fpm-assistant__proposal.fpm-assistant__proposal--sensitive,
.fpm-assistant__proposal.fpm-assistant__proposal--irreversible { border-color: var(--fpm-status-error); background: var(--fpm-status-error-dim); }
.fpm-assistant__proposal.fpm-assistant__proposal--irreversible { box-shadow: inset 4px 0 0 var(--fpm-status-error); }
.fpm-assistant__proposal--sensitive > .fpm-assistant__label,
.fpm-assistant__proposal--irreversible > .fpm-assistant__label { color: var(--fpm-status-error); }
.fpm-assistant__risk { margin: 0; color: var(--fpm-text-primary); font-size: var(--fpm-font-body-sm); font-weight: var(--fpm-weight-semibold); overflow-wrap: anywhere; }
.fpm-assistant__confirm { display: flex; flex-direction: column; gap: var(--fpm-space-xs); }
.fpm-assistant__toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--fpm-space-sm); }

.fpm-progress__native { inline-size: 100%; block-size: 6px; accent-color: var(--fpm-accent); }
.fpm-assistant__toolbar-actions { display: flex; align-items: center; gap: var(--fpm-space-xs); margin-left: auto; }
.fpm-assistant__icon { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.fpm-assistant__alert:not([hidden]) { display: flex; align-items: center; gap: var(--fpm-space-sm); }
.fpm-assistant__autonomy { margin: 0; padding: var(--fpm-space-sm) var(--fpm-space-md); border: 1px solid var(--fpm-status-warn); border-left-width: 4px; border-radius: var(--fpm-radius-sm); background: var(--fpm-status-warn-dim); color: var(--fpm-text-primary); font-size: var(--fpm-font-body-sm); font-weight: var(--fpm-weight-semibold); overflow-wrap: anywhere; }
.fpm-assistant__autonomy[data-mode="full_auto"] { border-color: var(--fpm-status-error); background: var(--fpm-status-error-dim); }
.fpm-assistant__grant:not([hidden]) { display: flex; flex-direction: column; gap: var(--fpm-space-sm); padding: var(--fpm-space-md); border: 1px solid var(--fpm-status-error); border-radius: var(--fpm-radius-md); background: var(--fpm-L2); }
.fpm-assistant__scope { display: flex; flex-direction: column; gap: var(--fpm-space-xs); max-height: 160px; margin: 0; padding: 0; border: 0; overflow-y: auto; }
.fpm-assistant__approval { margin: 0; color: var(--fpm-text-muted); font-size: var(--fpm-font-meta); font-weight: var(--fpm-weight-semibold); }
.fpm-assistant__approval[data-kind="automatic"] { color: var(--fpm-status-warn); }
.fpm-assistant__plan { display: flex; flex-direction: column; flex-shrink: 0; gap: var(--fpm-space-sm); border-color: var(--fpm-status-warn); }
.fpm-assistant__steps { display: flex; flex-direction: column; gap: var(--fpm-space-sm); margin: 0; padding-left: var(--fpm-space-lg); }
.fpm-assistant__step { display: flex; flex-direction: column; gap: var(--fpm-space-xs); }
.fpm-assistant__notice { margin: 0; padding: var(--fpm-space-xs) var(--fpm-space-sm); border-left: 3px solid var(--fpm-border-strong); color: var(--fpm-text-muted); font-size: var(--fpm-font-meta); overflow-wrap: anywhere; }
.fpm-assistant__notice[data-mode="auto"], .fpm-assistant__notice[data-mode="full_auto"] { border-left-color: var(--fpm-status-warn); color: var(--fpm-text-body); }

/* Canonical modal chrome (formerly in Widgets). */
.fpm-modal-backdrop {
    --fpm-modal-bd-bg:   var(--fpm-overlay-bg);
    --fpm-modal-bd-blur: 0px;
    --fpm-modal-bd-z:    var(--fpm-z-modal-backdrop);
    --fpm-modal-bd-dur:  var(--fpm-dur-quick);
}
.fpm-modal-backdrop { position: fixed; inset: 0; z-index: var(--fpm-modal-bd-z); background: var(--fpm-modal-bd-bg); backdrop-filter: blur(var(--fpm-modal-bd-blur)); animation: fpm-anim-fade-in var(--fpm-modal-bd-dur) var(--fpm-ease-out); }
.fpm-modal-backdrop--strong { --fpm-modal-bd-bg: var(--fpm-overlay-strong); }
.fpm-modal-backdrop { animation: none; }
/* Tool windows share a passive viewport layer; only each window accepts input. */
.fpm-modal-backdrop.fpm-tool-layer { z-index: var(--fpm-z-modal-stacked); pointer-events: none; background: transparent; backdrop-filter: none; }
.fpm-modal-backdrop.fpm-tool-layer[hidden] { visibility: hidden; }
.fpm-os-window.fpm-tool-window[hidden] { visibility: hidden; }
.fpm-tool-layer > .fpm-tool-window { pointer-events: auto; z-index: auto; }
.fpm-os-window.fpm-tool-window { z-index: var(--fpm-z-modal-stacked); }
.fpm-tool-window:where(.fpm-os-window) { top: 50%; left: 50%; transform: translate(-50%, -50%); }
.fpm-tool-window .fpm-window-control[hidden] { visibility: hidden; width: 0; padding: 0; }
:where(.fpm-modal-backdrop.fpm-tool-layer) > .fpm-tool-window:where(.fpm-modal:not([data-positioned])) {
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
}
/* Embedded remote content in a shared floating window. */
.fpm-os-window:has(> .fpm-frame-view) { --fpm-window-width: min(1000px, calc(100vw - 2 * var(--fpm-space-lg))); --fpm-window-height: min(720px, calc(100dvh - 2 * var(--fpm-space-xl))); min-width: min(var(--fpm-window-min-width), calc(100vw - 2 * var(--fpm-space-lg))); }
.fpm-os-window:has(> .fpm-frame-view) > .fpm-window-header { flex: 0 0 auto; }
.fpm-os-window:has(> .fpm-frame-view) .fpm-window-title { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.fpm-os-window:has(> .fpm-frame-view) .fpm-window-control { width: auto; min-width: var(--fpm-space-xl); padding-inline: var(--fpm-space-sm); }
.fpm-frame-view { position: relative; display: flex; flex: 1; min-height: 0; overflow: hidden; }
.fpm-frame-view > iframe { width: 100%; height: 100%; border: 0; }
.fpm-frame-view__status { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--fpm-space-md); padding: var(--fpm-space-lg); overflow: auto; background: var(--fpm-L1); color: var(--fpm-text-primary); opacity: 1; transition: opacity var(--fpm-dur-quick) var(--fpm-ease-standard), visibility var(--fpm-dur-quick); }
.fpm-frame-view__status[aria-hidden="true"] { opacity: 0; visibility: hidden; pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
    .fpm-frame-view__status { transition: none; }
}
.fpm-tool-window__minimize { flex: 0 0 auto; margin-left: auto; }
.fpm-tool-tray { position: fixed; right: var(--fpm-space-lg); bottom: var(--fpm-space-lg); z-index: var(--fpm-z-topmost); display: flex; flex-wrap: wrap; gap: var(--fpm-space-sm); max-width: calc(100vw - 2 * var(--fpm-space-lg)); padding: var(--fpm-space-sm); border: 1px solid var(--fpm-border-medium); border-radius: var(--fpm-radius-md); background: var(--fpm-L2); box-shadow: var(--fpm-shadow-floating); }
.fpm-tool-tray__item { display: flex; align-items: center; border: 1px solid var(--fpm-border-medium); border-radius: var(--fpm-radius-sm); background: var(--fpm-L1); }
.fpm-tool-tray__item--active { border-color: var(--fpm-border-accent); }
.fpm-tool-tray__item--minimized { opacity: .7; }
.fpm-tool-tray :is(button) { border: 0; background: transparent; color: var(--fpm-text-primary); font: inherit; cursor: pointer; }
.fpm-tool-tray :is(button):hover { background: var(--fpm-L3); }
.fpm-tool-tray :is(button):focus-visible { outline: 2px solid var(--fpm-accent); outline-offset: 2px; }
.fpm-tool-tray__switch { max-width: 14rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: var(--fpm-space-xs) var(--fpm-space-sm); }
.fpm-tool-tray__action { padding: var(--fpm-space-xs) var(--fpm-space-sm); }
.fpm-modal {
    position: fixed;
    z-index: var(--fpm-z-modal);
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: var(--fpm-L2);
    border: 1px solid var(--fpm-pop-border);
    border-radius: var(--fpm-radius-md);
    box-shadow: var(--fpm-pop-shadow);
    width: min(560px, calc(100vw - 32px));
    max-height: calc(100vh - 32px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    animation: fpm-anim-fade-in var(--fpm-dur-base) var(--fpm-ease-emphasized);
}
.fpm-modal--420 { width: min(420px, calc(100vw - 32px)); }
.fpm-modal--460 { width: min(460px, calc(100vw - 32px)); }
.fpm-modal--severity-error {
    border-color: color-mix(in srgb, var(--fpm-status-error) 50%, var(--fpm-border-medium));
}
.fpm-modal--severity-warn {
    border-color: color-mix(in srgb, var(--fpm-status-warn) 50%, var(--fpm-border-medium));
}
.fpm-modal-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 22px 22px 0;
    font-size: 17px;
    font-weight: var(--fpm-weight-title);
    color: var(--fpm-text-strong);
    flex-shrink: 0;
}
.fpm-modal-header i { color: var(--fpm-accent); }
.fpm-modal-body {
    padding: 14px 22px;
    overflow-y: auto;
    color: var(--fpm-text-secondary);
    flex: 1;
}
.fpm-modal-body p { margin: 0; line-height: 1.5; }
.fpm-modal-footer {
    display: flex;
    justify-content: flex-end;
    gap: var(--fpm-space-sm);
    padding: 0 22px 22px;
    flex-shrink: 0;
}
.fpm-modal-close {
    margin-left: auto;
    padding: 0.35rem 0.5rem;
    background: transparent;
    border: none;
    color: var(--fpm-text-muted);
    font-size: 0.9rem;
    cursor: pointer;
    border-radius: var(--fpm-radius-sm);
    transition: background var(--fpm-dur-quick) ease, color var(--fpm-dur-quick) ease;
    line-height: 1;
}
.fpm-modal-close:hover { background: var(--fpm-bg-surface-hover); color: var(--fpm-text-primary); }
/* One semantic scale. Unknown, requested, disabled and informational categories stay neutral. */
.fpm-chip { --fpm-chip-edge: var(--fpm-border-strong); --fpm-chip-ink: var(--fpm-text-secondary); display: inline-flex; align-items: center; gap: 5px; max-width: 100%; padding: 2px 8px; border: 1px solid var(--fpm-chip-edge); border-radius: var(--fpm-radius-sm); background: transparent; color: var(--fpm-chip-ink); font: var(--fpm-weight-normal) 11px/1.5 var(--fpm-font-family); white-space: nowrap; }
/* A row of chips (U1) that wraps; the table's chips cell and the dialogs use it. */
.fpm-chip-row { display: inline-flex; flex-wrap: wrap; gap: var(--fpm-space-xs); }
.fpm-chip--wrap { white-space: normal; overflow-wrap: anywhere; box-sizing: border-box; }
.fpm-chip:is([data-tone="ok"], .fpm-chip--ok, .success, .online, .enabled, [data-st="ok"], [data-st="success"], [data-st="completed"], [data-st="running"], [data-st="online"], [data-st="enabled"], [data-st="up"]) { --fpm-chip-edge: color-mix(in srgb, var(--fpm-status-ok) 45%, transparent); --fpm-chip-ink: var(--fpm-ink-ok); }
.fpm-chip:is([data-tone="info"], .fpm-chip--info, .pending, [data-st="pending"], [data-st="loading"], [data-st="scanning"]) { --fpm-chip-edge: color-mix(in srgb, var(--fpm-status-info) 45%, transparent); --fpm-chip-ink: var(--fpm-ink-info); }
.fpm-chip:is([data-tone="warn"], .fpm-chip--warn, .warning, [data-st="warning"], [data-st="warn"], [data-st="cancelled"]) { --fpm-chip-edge: color-mix(in srgb, var(--fpm-status-warn) 45%, transparent); --fpm-chip-ink: var(--fpm-ink-warn); }
.fpm-chip:is([data-tone="error"], .fpm-chip--error, .error, .failed, [data-st="failed"], [data-st="failure"], [data-st="error"], [data-st="down"]) { --fpm-chip-edge: color-mix(in srgb, var(--fpm-status-error) 45%, transparent); --fpm-chip-ink: var(--fpm-ink-error); }
/* A chip that is a BUTTON: the chip's compact look plus the pointer, hover, focus and selected
   states a control needs. A bare .fpm-chip is a static label, and a button wearing only that
   works but looks dead. The source guard refuses a button
   carrying .fpm-chip without this modifier. Selection is aria-pressed="true". */
.fpm-chip--action { cursor: pointer; transition: background var(--fpm-dur-micro), border-color var(--fpm-dur-micro), color var(--fpm-dur-micro); }
.fpm-chip--action:hover { color: var(--fpm-ink-ok); background: var(--fpm-accent-dim); border-color: var(--fpm-border-accent); }
.fpm-chip--action:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
.fpm-chip--action[aria-pressed="true"] { color: var(--fpm-ink-ok); background: var(--fpm-accent-dim); border-color: var(--fpm-border-accent); }
.fpm-chip--action:disabled { opacity: .45; cursor: not-allowed; }
@media (prefers-reduced-motion: reduce) { .fpm-chip--action { transition: none; } }
/* Shared tabs retain page layout and express selection through ARIA or legacy state hooks. */
.fpm-tab { display: inline-flex; align-items: center; justify-content: center; gap: 6px; padding: 6px 12px; background: transparent; color: var(--fpm-text-secondary); border: 1px solid transparent; border-radius: var(--fpm-radius-sm); font: var(--fpm-weight-normal) var(--fpm-font-body)/1.5 var(--fpm-font-family); white-space: nowrap; text-decoration: none; cursor: pointer; }
.fpm-tab:hover { color: var(--fpm-text-primary); background: var(--fpm-bg-surface-hover); }
.fpm-tab:is([aria-current="location"], [aria-selected="true"], [aria-pressed="true"], .active, .is-active), input:checked + .fpm-tab { background: var(--fpm-bg-surface-raised); color: var(--fpm-text-strong); font-weight: var(--fpm-weight-semibold); border-color: var(--fpm-border-medium); box-shadow: inset 0 1px 0 var(--fpm-edge); }
/* A tab's count is a small mono badge; a failing tab carries a pulsing light instead. */
.fpm-tab > :is(.fpm-chip, .fpm-count-badge) { padding: 1px 6px; border: 0; border-radius: var(--fpm-radius-xs); background: var(--fpm-track); color: var(--fpm-text-secondary); font: var(--fpm-weight-semibold) 10px/1.5 var(--fpm-font-mono); }
.fpm-tab:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
.fpm-tab:disabled { opacity: .45; cursor: not-allowed; }
.fpm-tab[data-availability="not_applicable"] { color: var(--fpm-text-muted); }
.fpm-tab__marker { color: inherit; font-family: var(--fpm-font-mono); }
.fpm-modal--small { width: min(420px, calc(100vw - 32px)); }
.fpm-modal--medium { width: min(560px, calc(100vw - 32px)); }
.fpm-modal--large { width: min(900px, calc(100vw - 32px)); }
/* break-word keeps whole words in the column's min-content width, so narrow columns widen and the table scrolls in its wrap instead of splitting words; anywhere let auto layout shrink columns to one letter. */
.fpm-table td { overflow-wrap: break-word; }
/* Machine values carry no word boundaries, so they break anywhere to stay inside their column. */
.fpm-table td :is(code, .fpm-table__mono), .fpm-table td.fpm-table__mono { overflow-wrap: anywhere; }
.fpm-check { accent-color: var(--fpm-accent); }
.fpm-check:focus-visible { outline: 2px solid var(--fpm-accent); outline-offset: 2px; }
/* Semantic alert email markup also renders in the console preview. */
.fpm-email { font-family: var(--fpm-font-family); max-width: 600px; margin: 0 auto; }
.fpm-email__head { color: var(--fpm-white); padding: 16px 24px; border-radius: var(--fpm-radius-md) var(--fpm-radius-md) 0 0; }
.fpm-email__head--info { background: var(--fpm-accent); }
.fpm-email__head--warning { background: var(--fpm-status-warn); }
.fpm-email__head--critical { background: var(--fpm-status-error); }
.fpm-email__head--neutral { background: var(--fpm-text-muted); }
.fpm-email__body { background: var(--fpm-L2); color: var(--fpm-text-primary); padding: 24px; border-radius: 0 0 var(--fpm-radius-md) var(--fpm-radius-md); }
.fpm-email h2, .fpm-email p { margin: 0 0 var(--fpm-space-md); }
.fpm-email__meta { color: var(--fpm-text-muted); font-size: var(--fpm-font-meta); }

/* Shared section headings and freely positioned modal geometry. */
.fpm-section-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--fpm-border-subtle, rgba(var(--fpm-white-rgb), 0.05));
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--fpm-text-primary);
    text-shadow: var(--fpm-text-shadow, 0 1px 2px rgba(var(--fpm-black-rgb), 0.3));
}
.fpm-section-header i {
    color: var(--fpm-accent);
    opacity: 0.9;
}
/* A section heading must not inherit the global page-heading scale. */
.fpm-section-header > h2 { margin: 0; font: inherit; text-shadow: none; }
.fpm-modal--positioned { position: absolute; transform: none; }
.fpm-modal--contained { position: relative; inset: auto; transform: none; z-index: auto; }

/* Device dialog geometry belongs with the shared modal primitive. */
.fpm-modal-backdrop > .fpm-modal { overflow-y: auto; overflow-x: hidden; }
@media (min-width: 641px) {
    .fpm-modal { max-height: 85vh; }
    .fpm-modal-backdrop > .fpm-modal { max-height: 90vh; }
    .fpm-modal-backdrop > .fpm-modal.fpm-tool-window {
        width: 78vw; height: 60vh;
        max-width: 98vw; max-height: 98vh;
        min-width: 400px; min-height: 300px;
    }
}

/* Phone dialogs share one viewport sheet, after all modal geometry variants. */
@media (max-width: 640px) {
    .fpm-modal,
    .fpm-tool-window {
        position: fixed;
        inset: 0;
        transform: none;
        width: 100%;
        min-width: 0;
        max-width: 100%;
        height: 100dvh;
        max-height: 100dvh;
        margin: 0;
        border-radius: 0;
    }
    .fpm-modal-header { position: sticky; top: 0; z-index: 1; flex-shrink: 0; background: var(--fpm-L2); }
    .fpm-modal-close { min-width: var(--fpm-touch-target); min-height: var(--fpm-touch-target); flex-shrink: 0; }
    .fpm-modal-body { min-height: 0; min-width: 0; overscroll-behavior: contain; }
    .fpm-modal-footer { flex-wrap: wrap; }
}

/* Canvas launcher defaults and an unmistakable impersonation notice. */
.fpm-impersonation-banner { position: fixed; inset: 0 0 auto; z-index: 9999; background: var(--fpm-status-error); color: var(--fpm-white); font: var(--fpm-weight-medium) var(--fpm-font-body-sm)/1.5 var(--fpm-font-family); text-align: center; padding: 7px 16px; box-shadow: var(--fpm-shadow-window); letter-spacing: .01em; }
.fpm-impersonation-banner--flow { position: relative; inset: auto; flex: 0 0 auto; width: 100%; }
.fpm-impersonation-banner__exit { color: var(--fpm-white); text-decoration: underline; font-weight: var(--fpm-weight-bold); cursor: pointer; }
body:has(> .fpm-impersonation-banner) { padding-top: var(--fpm-impersonation-offset, 0px); }
.fpm-os-window[id="nodeRegistry-window"] { --fpm-window-top: 10%; --fpm-window-left: 10%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="software-window"] { --fpm-window-top: 12%; --fpm-window-left: 12%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="storage-window"] { --fpm-window-top: 16%; --fpm-window-left: 16%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="vm-window"] { --fpm-window-top: 18%; --fpm-window-left: 18%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="network-window"] { --fpm-window-top: 20%; --fpm-window-left: 20%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="terminal-window"] { --fpm-window-top: 22%; --fpm-window-left: 22%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="users-window"] { --fpm-window-top: 28%; --fpm-window-left: 28%; --fpm-window-width: 65%; --fpm-window-height: 65%; }
.fpm-os-window[id="fileManager-window"] { --fpm-window-top: 14%; --fpm-window-left: 14%; --fpm-window-width: 70%; --fpm-window-height: 70%; }

/* Generic catalogue / settings composition: shared facet rail and responsive main. */
.fpm-filter-layout { display: flex; flex-wrap: wrap; gap: var(--fpm-space-lg); align-items: start; }
.fpm-filter-layout__main { flex: 1 1 var(--fpm-filter-main-min); min-width: 0; }
.fpm-filter-layout .fpm-facet-rail { flex: 0 1 var(--fpm-filter-rail-basis); min-width: 0; }

/* Native navigation controls share row chrome without browser button surfaces. */
.fpm-nav-item:is(button, a) { appearance: none; background: transparent; border-top: 0; border-right: 0; border-bottom: 0; width: 100%; font-family: inherit; text-align: left; text-decoration: none; }

/* Ordered editors keep their controls beside the document being composed. */
.fpm-editor-preview { display: grid; grid-template-columns: minmax(280px, 1fr) minmax(0, 2fr); gap: var(--fpm-space-md); align-items: start; }
.fpm-editor-preview__controls { display: flex; flex-direction: column; gap: var(--fpm-space-md); min-width: 0; }
.fpm-editor-preview__document { min-width: 0; }
/* A sentence of inline controls ("Send [Monthly] on [1st] at [07:00]"): words and fields wrap as one line. */
.fpm-field-sentence { display: flex; flex-wrap: wrap; align-items: center; gap: var(--fpm-space-xs) var(--fpm-space-sm); }
.fpm-field-sentence > :is(.fpm-input, .fpm-select) { width: auto; }
/* A drag handle in a reorderable list row's leading slot. */
.fpm-list-handle { cursor: grab; }
.fpm-brand-lockup { display: flex; align-items: center; gap: var(--fpm-space-sm); }
.fpm-brand-lockup__logo { max-width: 120px; max-height: 48px; object-fit: contain; }
.fpm-table-widget { overflow-x: auto; }
@media (max-width: 900px) { .fpm-editor-preview { grid-template-columns: minmax(0, 1fr); } }
/* The sidebar is one charcoal rail in every theme; its surface and every text slot sit on sidebar tokens. */
.fpm-nav.fpm-nav--sidebar { background: var(--fpm-sidebar); box-shadow: var(--fpm-sidebar-shadow); color: var(--fpm-sidebar-text); border: 0; border-inline-end: 1px solid var(--fpm-sidebar-edge); border-radius: var(--fpm-radius-md); font-size: 13px; }
.fpm-nav--sidebar .fpm-nav-brand { display: grid; grid-template-columns: 30px minmax(0, 1fr); align-items: center; column-gap: 10px; row-gap: 0; padding: 18px 14px 16px; border-color: transparent; }
/* The mark is a solid cyan tile beside the wordmark and the tenant caption. */
.fpm-nav--sidebar .fpm-nav-brand::before { content: "IL"; grid-row: 1 / span 2; width: 30px; height: 30px; display: grid; place-items: center; border-radius: var(--fpm-radius-sm); background: var(--fpm-sidebar-brand-fill); color: var(--fpm-sidebar-brand-ink); font-size: 13px; font-weight: var(--fpm-weight-bold); }
.fpm-nav--sidebar .fpm-nav-brand-mark, .fpm-nav--sidebar .fpm-nav-foot-name { color: var(--fpm-sidebar-text); }
.fpm-nav--sidebar .fpm-nav-brand-mark { font-size: 20px; }
.fpm-nav--sidebar .fpm-nav-brand-mark span { color: inherit; }
.fpm-nav--sidebar .fpm-nav-brand-pulse { margin-left: 0; color: var(--fpm-sidebar-text-dim); font-family: var(--fpm-font-family); font-size: 9px; letter-spacing: 0.08em; text-transform: uppercase; }
.fpm-nav--sidebar :is(.fpm-nav-section, .fpm-nav-section-add, .fpm-nav-tree-arrow, .fpm-nav-foot-role, .fpm-nav-tool-glyph) { color: var(--fpm-sidebar-text-dim); }
.fpm-nav--sidebar .fpm-nav-section-line { background: transparent; }
.fpm-nav.fpm-nav--sidebar .fpm-nav-item .fpm-nav-item-badge { color: var(--fpm-sidebar-accent); background: transparent; font-weight: var(--fpm-weight-medium); }
.fpm-nav.fpm-nav--sidebar :is(.fpm-nav-tree-counts, .fpm-nav-tree-counts b) { color: var(--fpm-sidebar-text-muted); background: transparent; font-weight: var(--fpm-weight-medium); }
/* Rows are quiet at rest; the current row takes a translucent blue-teal panel, a narrow cyan edge marker and a pale label. */
.fpm-nav.fpm-nav--sidebar .fpm-nav-body { padding: var(--fpm-space-sm); }
.fpm-nav.fpm-nav--sidebar :is(.fpm-nav-item, .fpm-nav-tree-node) { position: relative; min-height: 36px; padding-block: 0; padding-inline: 12px; border-left: 0; border-radius: var(--fpm-radius-sm); color: var(--fpm-sidebar-text-muted); font-size: 13px; }
.fpm-nav.fpm-nav--sidebar .fpm-nav-body > .fpm-nav-item + .fpm-nav-item { margin-top: 6px; }
.fpm-nav.fpm-nav--sidebar :is(.fpm-nav-item, .fpm-nav-tree-node):hover { color: var(--fpm-sidebar-text); background: var(--fpm-sidebar-hover-bg); }
/* Icons sit muted in the row colour, not in tone tiles. */
.fpm-nav.fpm-nav--sidebar .fpm-nav-item-glyph[data-fpm-tone] { background: transparent; color: inherit; }
.fpm-nav.fpm-nav--sidebar .fpm-nav-section { padding: var(--fpm-space-lg) 12px var(--fpm-space-xs); font-size: 10px; font-weight: var(--fpm-weight-medium); letter-spacing: 0.08em; }
.fpm-nav.fpm-nav--sidebar .fpm-nav-body [aria-current="page"] { color: var(--fpm-sidebar-text); background: var(--fpm-sidebar-active-bg); box-shadow: none; font-weight: var(--fpm-weight-medium); }
.fpm-nav.fpm-nav--sidebar .fpm-nav-body [aria-current="page"]::before { content: ""; position: absolute; inset-block: 0; inset-inline-start: 0; width: 3px; border-start-start-radius: var(--fpm-radius-sm); border-end-start-radius: var(--fpm-radius-sm); background: var(--fpm-sidebar-active-marker); }
.fpm-nav.fpm-nav--sidebar .fpm-nav-body [aria-current="page"] .fpm-nav-item-glyph { color: var(--fpm-sidebar-text); }
.fpm-nav--sidebar .fpm-nav-tree-dot { width: 6px; height: 6px; }
.fpm-nav--sidebar [aria-expanded="true"] > .fpm-nav-tree-arrow { color: var(--fpm-sidebar-text-muted); }
/* Tree depth stays with the container's indent and guide rule; nested rows keep their own start padding, and their edge marker sits inside the row so it follows the depth. */
.fpm-nav.fpm-nav--sidebar .fpm-nav-tree-children > :not(.fpm-nav-tree-children) { padding-inline-start: 8px; }
.fpm-nav--sidebar .fpm-nav-tree-children > :not(.fpm-nav-tree-children) { color: var(--fpm-sidebar-text-secondary); }
.fpm-nav--sidebar .fpm-nav-tree-children::before { background: var(--fpm-sidebar-guide); }
/* The nav fills the shell's row (not the window) so its footer is never pushed below the fold; only the body scrolls. */
.fpm-app-shell--viewport > .fpm-nav--sidebar { height: 100%; min-height: 0; }
.fpm-nav--sidebar .fpm-nav-body { display: flex; flex-direction: column; min-height: 0; }
.fpm-nav--sidebar .fpm-nav-foot { flex-shrink: 0; background: transparent; border-color: var(--fpm-sidebar-divider); margin-inline: 12px; padding-inline: 4px; }
.fpm-nav--sidebar .fpm-nav-tools { margin-top: auto; }
.fpm-nav--sidebar .fpm-nav-tool { background: transparent; color: var(--fpm-sidebar-text-muted); border-color: transparent; }
.fpm-nav--sidebar .fpm-nav-tool:hover { background: var(--fpm-sidebar-hover-bg); color: var(--fpm-sidebar-text); }

/* Generic code surfaces. */
    .fpm-code {
        margin: 0;
        padding: var(--fpm-space-sm) 0;
        list-style: none;
        counter-reset: fpm-code-line;
        background: var(--fpm-L1);
        border: 1px solid var(--fpm-border-subtle);
        border-radius: var(--fpm-radius-sm);
        font-family: var(--fpm-font-mono);
        font-size: var(--fpm-font-body-sm);
        line-height: 1.65;
        color: var(--fpm-text-primary);
        overflow: auto;
        max-height: 26rem;
        min-width: 0;
    }
    .fpm-code:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
    .fpm-code__line {
        counter-increment: fpm-code-line;
        display: block;
        min-width: max-content;
        min-height: 1.65em;
        padding-right: var(--fpm-space-md);
        white-space: pre;
    }
    .fpm-code__line::before {
        content: counter(fpm-code-line);
        position: sticky;
        left: 0;
        display: inline-block;
        box-sizing: border-box;
        width: 3.25em;
        margin-right: var(--fpm-space-sm);
        padding-right: var(--fpm-space-sm);
        border-right: 1px solid var(--fpm-border-subtle);
        background: var(--fpm-L1);
        color: var(--fpm-text-muted);
        text-align: right;
        user-select: none;
    }
    .fpm-code__line[data-lint="warn"] { background: var(--fpm-status-warn-dim); }
    .fpm-code__line[data-lint="warn"]::before { color: var(--fpm-status-warn); box-shadow: inset 3px 0 0 var(--fpm-status-warn); }
    .fpm-code__line[data-lint="error"] { background: var(--fpm-status-error-dim); }
    .fpm-code__line[data-lint="error"]::before { color: var(--fpm-status-error); box-shadow: inset 3px 0 0 var(--fpm-status-error); }
    .fpm-code__line[data-diff="add"] { background: var(--fpm-status-ok-dim); }
    .fpm-code__line[data-diff="add"]::before { content: "+"; color: var(--fpm-status-ok); }
    .fpm-code__line[data-diff="del"] { background: var(--fpm-status-error-dim); }
    .fpm-code__line[data-diff="del"]::before { content: "\2212"; color: var(--fpm-status-error); }
    .fpm-code__line[data-stream="err"] { color: var(--fpm-status-error); }
    .fpm-code--output .fpm-code__line { padding-left: var(--fpm-space-md); }
    .fpm-code--output .fpm-code__line::before { content: none; }
    .fpm-code__tok[data-tok="kw"]  { color: var(--fpm-accent); font-weight: var(--fpm-weight-semibold); }
    .fpm-code__tok[data-tok="cmd"] { color: var(--fpm-text-primary); font-weight: var(--fpm-weight-bold); }
    .fpm-code__tok[data-tok="str"] { color: var(--fpm-status-ok); }
    .fpm-code__tok[data-tok="var"] { color: var(--fpm-accent-secondary); }
    .fpm-code__tok[data-tok="num"] { color: var(--fpm-status-warn); }
    .fpm-code__tok[data-tok="com"] { color: var(--fpm-text-muted); font-style: italic; }
    .fpm-code__tok[data-tok="tpl"] { color: var(--fpm-accent); background: var(--fpm-accent-dim); border-radius: var(--fpm-radius-xs); }
    .fpm-code mark { color: inherit; background: var(--fpm-status-warn-dim); box-shadow: 0 0 0 1px var(--fpm-status-warn); border-radius: var(--fpm-radius-xs); }

/* Generic guided flows and selectable card collections. */
.fpm-steps { display: flex; flex-direction: column; gap: var(--fpm-space-xs); margin: 0; padding-inline-start: var(--fpm-space-lg); font-size: var(--fpm-font-body-sm); line-height: 1.45; color: var(--fpm-text-primary); }
.fpm-steps > li::marker { color: var(--fpm-text-secondary); font-variant-numeric: tabular-nums; }
.fpm-steps a { color: var(--fpm-accent); text-underline-offset: 2px; }

.fpm-code-editor { position: relative; min-width: 0; }
.fpm-code-editor > .fpm-code { min-height: 20rem; height: 26rem; }
.fpm-code-editor__input { position: absolute; inset: 0; box-sizing: border-box; width: 100%; height: 100%; margin: 0; padding: var(--fpm-space-sm) var(--fpm-space-md) var(--fpm-space-sm) calc(3.25em + var(--fpm-space-sm)); font: inherit; font-family: var(--fpm-font-mono); font-size: var(--fpm-font-body-sm); line-height: 1.65; color: transparent; caret-color: var(--fpm-text-primary); background: transparent; border: 1px solid transparent; resize: none; white-space: pre; }
.fpm-code-editor__input:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }

/* SVG graph surface: the renderer supplies viewBox and geometry; a map smaller than the view sits centred. */
.fpm-graph {
    --fpm-series-1: var(--fpm-accent-secondary);
    --fpm-series-2: var(--fpm-status-warn);
    --fpm-series-3: var(--fpm-status-ok);
    --fpm-series-4: var(--fpm-status-purple);
    --fpm-series-5: var(--fpm-status-error);
    display: flex; min-width: 0; overflow: auto;
}
.fpm-graph__svg { display: block; flex-shrink: 0; margin: auto; }
.fpm-graph__lane-label { fill: var(--fpm-text-secondary); font: var(--fpm-weight-semibold) var(--fpm-font-label) var(--fpm-font-mono); letter-spacing: .14em; text-transform: uppercase; }
.fpm-graph-port-label { fill: var(--fpm-text-secondary); font: var(--fpm-weight-semibold) var(--fpm-font-meta) var(--fpm-font-mono); pointer-events: none; }
/* Observed links are solid; a link the server only inferred is dotted. */
.fpm-graph-link { fill: none; stroke: var(--fpm-text-muted); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.fpm-graph-link[data-seen="false"] { stroke-dasharray: 0 5; stroke-width: 2; }
.fpm-graph-link[data-series="1"] { stroke: var(--fpm-series-1); }
.fpm-graph-link[data-series="2"] { stroke: var(--fpm-series-2); }
.fpm-graph-link[data-series="3"] { stroke: var(--fpm-series-3); }
.fpm-graph-link[data-series="4"] { stroke: var(--fpm-series-4); }
.fpm-graph-link[data-series="5"] { stroke: var(--fpm-series-5); }
.fpm-graph-link[data-hot="true"] { stroke: var(--fpm-accent-light); }

/* A node button fills its SVG foreignObject; the card primitive supplies chrome. */
.fpm-graph__vertex { position: static; display: flex; width: 100%; height: 100%; box-sizing: border-box; text-align: left; font: inherit; color: inherit; }
.fpm-graph__vertex[data-dim="true"] { opacity: .3; }
.fpm-graph__vertex[data-unknown="true"] { border-color: var(--fpm-status-warn); }
.fpm-graph__vertex[data-hot="true"] { border-color: var(--fpm-accent-light); }
.fpm-graph__vertex[data-match="true"] { outline: 2px solid var(--fpm-accent-secondary); outline-offset: 2px; }
.fpm-graph__vertex[data-match="current"] { outline: 2px solid var(--fpm-accent); outline-offset: 2px; }

/* The overview floats in the map's lower right corner, outside the scrolling SVG; zoom controls are one outlined row. */
.fpm-graph__viewport { position: relative; display: grid; min-width: 0; height: clamp(22rem, 55vh, 46rem); }
.fpm-graph__viewport > .fpm-graph { min-height: 0; }
.fpm-graph__row { display: inline-flex; align-items: center; gap: 2px; padding: 1px; border: 1px solid var(--fpm-border-medium); border-radius: var(--fpm-radius-sm); }
.fpm-graph__row > .fpm-btn { min-width: 28px; justify-content: center; }
.fpm-minimap { position: absolute; right: var(--fpm-space-md); bottom: var(--fpm-space-md); display: block; width: 168px; height: 100px; border: 1px solid var(--fpm-border-medium); border-radius: var(--fpm-radius-md); background: var(--fpm-L2); box-shadow: var(--fpm-shadow-dropdown); cursor: crosshair; }
.fpm-minimap__point { fill: var(--fpm-text-muted); }

/* Full-width settings shells compose the same navigation without a utility rail. */
.fpm-app-shell--no-rail { grid-template-columns: var(--fpm-nav-w) minmax(0, 1fr); }
@media (max-width: 1024px) {
    .fpm-app-shell--viewport.fpm-app-shell--no-rail { grid-template-columns: minmax(0, 1fr); }
}

/* Bounded scroll region: a list that must not grow its page. Height cap is --fpm-scroll-region-max (default 24rem). */
.fpm-scroll-region { max-height: var(--fpm-scroll-region-max, 24rem); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--fpm-scrollbar-thumb) transparent; }
/* Inside a card a list follows its rows up to one height (--fpm-list-h), then scrolls; the grid row already makes
   neighbouring cards equal, so a short list never leaves a blank card. A whole screen in a bare card keeps the page-level cap. */
:is(.fpm-card:not([data-fpm-card-style=bare]), .fpm-widget) .fpm-scroll-region {
    flex: 1 1 auto;
    min-block-size: 0;
    max-height: var(--fpm-list-h);
}
/* Rows fade out at an edge only while more rows lie past it. A mask suits the translucent card in every theme,
   where a painted cover drew a pale bar; a list that cannot scroll has no active timeline, so it has no fade. */
@supports (animation-timeline: scroll()) {
    :is(.fpm-card:not([data-fpm-card-style=bare]), .fpm-widget) .fpm-scroll-region {
        mask-image: linear-gradient(transparent, var(--fpm-L2) var(--fpm-scroll-fade-start), var(--fpm-L2) calc(100% - var(--fpm-scroll-fade-end)), transparent);
        /* Longhands, not the animation shorthand: the build would fold a timeline into the shorthand, which browsers reject. */
        animation-name: fpm-anim-scroll-fade;
        animation-timing-function: linear;
        animation-fill-mode: both;
        animation-timeline: scroll(self);
    }
}
@keyframes fpm-anim-scroll-fade {
    from { --fpm-scroll-fade-start: 0px; --fpm-scroll-fade-end: var(--fpm-space-lg); }
    10%, 90% { --fpm-scroll-fade-start: var(--fpm-space-lg); --fpm-scroll-fade-end: var(--fpm-space-lg); }
    to { --fpm-scroll-fade-start: var(--fpm-space-lg); --fpm-scroll-fade-end: 0px; }
}
@media (prefers-reduced-motion: reduce) {
    :is(.fpm-card:not([data-fpm-card-style=bare]), .fpm-widget) .fpm-scroll-region { animation: none; }
}
.fpm-card__body > :has(> .fpm-scroll-region) { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* On a phone the segment, pill and subtab rows scroll sideways; the same mask fades an edge while more options lie
   past it, so a cut-off last option reads as "more this way". Reduced motion keeps a still fade at the far edge. */
@media (max-width: 640px) {
    @supports (animation-timeline: scroll()) {
        :is(.fpm-segment, .fpm-page-header__filters .fpm-pill-bar, .fpm-page-header__subtabs) {
            mask-image: linear-gradient(to right, transparent, var(--fpm-L2) var(--fpm-scroll-fade-start), var(--fpm-L2) calc(100% - var(--fpm-scroll-fade-end)), transparent);
            animation-name: fpm-anim-scroll-fade;
            animation-timing-function: linear;
            animation-fill-mode: both;
            animation-timeline: scroll(self inline);
        }
    }
}
@media (max-width: 640px) and (prefers-reduced-motion: reduce) {
    :is(.fpm-segment, .fpm-page-header__filters .fpm-pill-bar, .fpm-page-header__subtabs) {
        animation: none;
        --fpm-scroll-fade-end: var(--fpm-space-lg);
        mask-image: linear-gradient(to right, var(--fpm-L2) calc(100% - var(--fpm-scroll-fade-end)), transparent);
    }
}
/* A list in the only card on a screen fills the main column's height and scrolls inside the card, so a short
   list keeps its own height and a long one never grows the page. The host, page and grid become a column that
   ends at the viewport; the card shrinks to that space only when its rows need more. Phones keep page scrolling. */
@media (min-width: 641px) {
    .fpm-app-main > div:has(> .fpm-console-page > .fpm-page-grid > .fpm-card .fpm-scroll-region):not(:has(> .fpm-console-page > .fpm-page-grid > .fpm-card ~ .fpm-card)),
    .fpm-console-page:has(> .fpm-page-grid > .fpm-card .fpm-scroll-region):not(:has(> .fpm-page-grid > .fpm-card ~ .fpm-card)) { height: 100%; }
    .fpm-console-page:has(> .fpm-page-grid > .fpm-card .fpm-scroll-region):not(:has(> .fpm-page-grid > .fpm-card ~ .fpm-card)) { display: flex; flex-direction: column; }
    .fpm-page-grid:has(> .fpm-card .fpm-scroll-region):not(:has(> .fpm-card ~ .fpm-card)) { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
    .fpm-page-grid:has(> .fpm-card .fpm-scroll-region):not(:has(> .fpm-card ~ .fpm-card)) > .fpm-card { flex: 0 1 auto; min-height: 0; }
    .fpm-page-grid:has(> .fpm-card .fpm-scroll-region):not(:has(> .fpm-card ~ .fpm-card)) .fpm-scroll-region { max-height: none; }
}
.fpm-scroll-region::-webkit-scrollbar { width: 6px; }
.fpm-scroll-region::-webkit-scrollbar-thumb { background: var(--fpm-scrollbar-thumb); border-radius: var(--fpm-radius-sm); }
.fpm-scroll-region::-webkit-scrollbar-thumb:hover { background: var(--fpm-scrollbar-thumb-hover); }
.fpm-scroll-region:focus-visible { outline: 2px solid var(--fpm-accent); outline-offset: -2px; }

/* Map: a Leaflet container drawn from bundled vector shapes, coloured by theme tokens. CSS beats Leaflet's SVG attributes. */
.fpm-map { width: 100%; flex: 1 1 auto; min-height: calc(var(--fpm-h, 4) * var(--fpm-grid-row, var(--fpm-space-xl)) + (var(--fpm-h, 4) - 1) * var(--fpm-space-md)); }
.fpm-map.leaflet-container { background: var(--fpm-map-water); }
.fpm-map .fpm-map__land { fill: var(--fpm-map-land); fill-opacity: 1; stroke: none; }
.fpm-map .fpm-map__water { fill: var(--fpm-map-water); fill-opacity: 1; stroke: none; }
.fpm-map .fpm-map__border { fill: none; stroke: var(--fpm-map-border); stroke-width: 1; }
.fpm-map .fpm-map__state-line { fill: none; stroke: var(--fpm-map-state-line); stroke-width: 1; }
.fpm-map .fpm-map__land { filter: drop-shadow(0 0 14px var(--fpm-glow-accent)); }
/* Pins: a status dot with a soft halo; problems pulse so they read from across the room. */
.fpm-map-pin { --fpm-pin: var(--fpm-status-ok); position: relative; width: 18px; height: 18px; display: grid; place-items: center; }
.fpm-map-pin::before { content: ""; width: 10px; height: 10px; border-radius: 50%; background: var(--fpm-pin); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fpm-pin) 25%, transparent), 0 0 14px var(--fpm-pin); }
.fpm-map-pin::after { content: ""; position: absolute; inset: 0; border-radius: 50%; border: 2px solid var(--fpm-pin); opacity: 0; }
.fpm-map-pin:is([data-st="warn"], [data-st="warning"]) { --fpm-pin: var(--fpm-status-warn); }
.fpm-map-pin:is([data-st="error"], [data-st="offline"], [data-st="crit"]) { --fpm-pin: var(--fpm-status-error); }
.fpm-map-pin:not([data-st="ok"])::after { animation: fpm-anim-pin-pulse 2s var(--fpm-ease-standard, ease-out) infinite; }
@keyframes fpm-anim-pin-pulse { from { transform: scale(0.6); opacity: 0.9; } to { transform: scale(2.2); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .fpm-map-pin::after { animation: none; } }
/* Popups and zoom controls float on the menu material instead of Leaflet's white. */
.fpm-map .leaflet-popup-content-wrapper { background: var(--fpm-menu-bg); color: var(--fpm-text-primary); border: 1px solid var(--fpm-card-border); border-radius: var(--fpm-radius-md); box-shadow: var(--fpm-shadow-floating); }
.fpm-map .leaflet-popup-tip { background: var(--fpm-menu-bg); box-shadow: none; }
.fpm-map .leaflet-popup-content { margin: 10px 14px; }
.fpm-map .leaflet-container a.leaflet-popup-close-button, .fpm-map a.leaflet-popup-close-button { color: var(--fpm-text-muted); }
.fpm-map-pop { display: flex; flex-direction: column; gap: 2px; }
.fpm-map-pop__label { font-size: 13px; font-weight: var(--fpm-weight-semibold); }
.fpm-map-pop__detail { font-size: 12px; color: var(--fpm-text-muted); }
.fpm-map .leaflet-bar { border: 1px solid var(--fpm-card-border); border-radius: var(--fpm-radius-md); box-shadow: var(--fpm-shadow-floating); overflow: hidden; }
.fpm-map .leaflet-bar a, .fpm-map .leaflet-bar a:hover { background: var(--fpm-menu-bg); color: var(--fpm-text-primary); border-bottom-color: var(--fpm-card-border); }
.fpm-map .leaflet-bar a.leaflet-disabled { color: var(--fpm-text-muted); background: var(--fpm-menu-bg); }
/* On a phone the zoom buttons meet the 44px touch minimum. */
@media (max-width: 640px) { .fpm-map.leaflet-container .leaflet-bar a { width: var(--fpm-touch-target); height: var(--fpm-touch-target); line-height: var(--fpm-touch-target); } }

/* A destructive menu item reads in the error colour so it is never mistaken for a routine action. */
.fpm-dropdown__item[data-tone="error"] { color: var(--fpm-status-error); }

/* Theme look hooks: each is driven by a token that is transparent or none in the dark theme. */
.fpm-status-dot:is([data-st="ok"], [data-st="online"], [data-st="running"]), .fpm-status-dot--sm.fpm-status-dot--ok { box-shadow: var(--fpm-halo-ok); }
.fpm-status-dot:is([data-st="warn"], [data-st="warning"]), .fpm-status-dot--sm.fpm-status-dot--warn { box-shadow: var(--fpm-halo-warn); }
.fpm-status-dot:is([data-st="error"], [data-st="offline"]), .fpm-status-dot--sm.fpm-status-dot--error { box-shadow: var(--fpm-halo-error); }

/* Site map: the map fills the card and the top-level sites float over its top left on the glass
   material. Rows carry state in a dot, health as a toned number and counts on a quiet second line. */
.fpm-site-map { position: relative; display: flex; flex: 1 1 auto; min-height: 0; border-radius: var(--fpm-radius-md); overflow: hidden; box-shadow: inset 0 0 0 1px var(--fpm-card-border); }
.fpm-site-map__map { flex: 1 1 auto; min-height: 0; display: flex; }
.fpm-site-map__list { position: absolute; z-index: 800; top: var(--fpm-space-md); left: var(--fpm-space-md); width: min(320px, 52%); max-height: calc(100% - 2 * var(--fpm-space-md)); overflow: auto; display: flex; flex-direction: column; gap: 2px; padding: var(--fpm-space-xs); background: var(--fpm-glass-bg); border: 1px solid var(--fpm-glass-border); border-radius: var(--fpm-radius-md); box-shadow: var(--fpm-shadow-floating); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); }
.fpm-site-map__row { --fpm-row-tone: var(--fpm-status-ok); display: grid; grid-template-columns: 8px minmax(0, 1fr) auto auto; grid-template-areas: "dot name score open" ". meta score open"; align-items: center; column-gap: 10px; row-gap: 2px; padding: 9px 6px 9px 10px; border-radius: var(--fpm-radius-sm); cursor: pointer; transition: background var(--fpm-transition-fast); }
.fpm-site-map__row::before { content: ""; grid-area: dot; width: 8px; height: 8px; border-radius: 50%; background: var(--fpm-row-tone); box-shadow: 0 0 0 3px color-mix(in srgb, var(--fpm-row-tone) 22%, transparent), 0 0 10px var(--fpm-row-tone); }
.fpm-site-map__row[data-state="warn"] { --fpm-row-tone: var(--fpm-status-warn); }
.fpm-site-map__row[data-state="error"] { --fpm-row-tone: var(--fpm-status-error); }
.fpm-site-map__row:hover { background: var(--fpm-L3); }
.fpm-site-map__row[aria-selected="true"] { background: color-mix(in srgb, var(--fpm-accent) 12%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fpm-accent) 35%, transparent); }
.fpm-site-map__row:focus-visible { outline: 2px solid var(--fpm-accent); outline-offset: -2px; }
.fpm-site-map__name { grid-area: name; font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fpm-site-map__meta { grid-area: meta; font-size: var(--fpm-font-body-sm); color: var(--fpm-text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fpm-site-map__score { grid-area: score; font-size: 18px; font-weight: var(--fpm-weight-semibold); line-height: 1; font-variant-numeric: tabular-nums; color: var(--fpm-row-tone); text-align: right; }
.fpm-site-map__score small { font-size: 11px; margin-left: 1px; color: var(--fpm-text-muted); font-weight: var(--fpm-weight-medium); }
.fpm-site-map__open { grid-area: open; color: var(--fpm-text-muted); font-size: 18px; line-height: 1; padding: 0 4px; cursor: pointer; border-radius: var(--fpm-radius-sm); }
.fpm-site-map__open:hover { color: var(--fpm-accent); }
/* Pin names: small glass chips beside each pin, always shown. */
.fpm-map .leaflet-tooltip.fpm-map-label { padding: 2px 8px; font-size: 12px; font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-primary); background: var(--fpm-glass-bg); border: 1px solid var(--fpm-glass-border); border-radius: 999px; box-shadow: var(--fpm-shadow-floating); white-space: nowrap; }
.fpm-map .leaflet-tooltip.fpm-map-label::before { border-color: transparent; }
@media (max-width: 700px) {
  .fpm-site-map { flex-direction: column; overflow: visible; box-shadow: none; }
  .fpm-site-map__map { min-height: 260px; border-radius: var(--fpm-radius-md); overflow: hidden; box-shadow: inset 0 0 0 1px var(--fpm-card-border); }
  .fpm-site-map__list { position: static; width: auto; max-height: none; margin-top: var(--fpm-space-sm); background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
}
.fpm-map-pop__open { margin-top: 8px; align-self: flex-start; }

/* Right rail as the console's side panel
   A raised glass panel like the nav: lit top edge, drop shadow, the canvas showing through. The
   page's own context elements stack inside it as sections, so a card there keeps no box of its
   own; its rows are raised rows; clocks read in glowing mono digits. */
.fpm-rail { background: var(--fpm-rail-bg); border: 1px solid var(--fpm-panel-border); box-shadow: var(--fpm-shadow-rail); -webkit-backdrop-filter: var(--fpm-panel-backdrop); backdrop-filter: var(--fpm-panel-backdrop); }
.fpm-rail__item { min-width: 0; }
/* Only a rail list gives up height when the rail is full; a fixed block such as Ticket priority keeps all of its rows. */
.fpm-rail > .fpm-rail__item:not(:has(.fpm-scroll-region)) { flex-shrink: 0; }
/* A rail section is as tall as its rows, and each row is a raised row. */
.fpm-app-shell > .fpm-rail { gap: 0; }
.fpm-rail > .fpm-rail__item.fpm-card[data-fpm-card-style] { --fpm-card-pad: 0; --fpm-list-h: auto; --fpm-card-body-h: 0px; --fpm-widget-bg: var(--fpm-rail-bg); background: none; border: 0; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
.fpm-rail > .fpm-rail__item.fpm-card[data-fpm-primitive] { --fpm-card-body-h: 0px; }
.fpm-rail__item .fpm-list { gap: 6px; }
.fpm-rail__item .fpm-list-item { padding: 8px 10px; }
/* The rail is narrow: a row keeps room for its words and moves its button to a line of its own, at the end. */
.fpm-rail__item .fpm-list-item:has(> :is(.fpm-list-fix, .fpm-list-open):not([hidden])) { flex-wrap: wrap; row-gap: var(--fpm-space-xs); }
.fpm-rail__item .fpm-list-item:has(> :is(.fpm-list-fix, .fpm-list-open):not([hidden])) > .fpm-list-label-group { flex-basis: 9rem; }
.fpm-rail__item .fpm-list-item > .fpm-list-fix:not([hidden]), .fpm-rail__item .fpm-list-item > .fpm-list-fix[hidden] + .fpm-list-open { margin-inline-start: auto; }
/* A phone is as narrow as the rail, so every list row with a button wraps the same way; without it the text column
   could shrink to one letter a line. */
@media (max-width: 640px) {
    .fpm-list-item:has(> :is(.fpm-list-fix, .fpm-list-open):not([hidden])) { flex-wrap: wrap; row-gap: var(--fpm-space-xs); }
    .fpm-list-item:has(> :is(.fpm-list-fix, .fpm-list-open):not([hidden])) > .fpm-list-label-group { flex-basis: 10rem; }
    .fpm-list-item > .fpm-list-fix:not([hidden]), .fpm-list-item > .fpm-list-fix[hidden] + .fpm-list-open { margin-inline-start: auto; }
}
.fpm-rail > .fpm-rail__item + .fpm-rail__item.fpm-card[data-fpm-card-style] { margin-top: var(--fpm-space-md); padding-top: var(--fpm-space-md); border-top: 1px solid var(--fpm-border-subtle); }
/* Clocks */
.fpm-rail .fpm-clock-time { font-family: var(--fpm-font-mono); font-size: 15px; color: var(--fpm-text-primary); text-shadow: 0 0 12px var(--fpm-glow-accent); font-variant-numeric: tabular-nums; }
.fpm-rail .fpm-clock:first-child .fpm-clock-time { color: var(--fpm-accent); }
.fpm-rail .fpm-clock-loc { font-size: 10px; letter-spacing: 0.08em; color: var(--fpm-text-muted); }

/* Status chips and toned rows, shared by every list and table
   A status word is a small lit chip; a row takes a left rail in the colour of its worst status,
   so a page of rows reads as green, amber and red before anything is read. */
.fpm-list-status[data-tone] { --fpm-chip: var(--fpm-text-secondary); display: inline-flex; align-items: center; gap: 6px; padding: 2px 9px 2px 7px; border-radius: 999px; font-size: 11.5px; line-height: 1.6; color: var(--fpm-chip); background: color-mix(in srgb, var(--fpm-chip) 13%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fpm-chip) 26%, transparent); }
.fpm-list-status[data-tone]::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; box-shadow: 0 0 8px currentColor; }
.fpm-list-status[data-tone="neutral"]::before { box-shadow: none; opacity: 0.6; }
.fpm-list-status[data-tone="ok"] { --fpm-chip: var(--fpm-status-ok); }
.fpm-list-status[data-tone="warn"] { --fpm-chip: var(--fpm-status-warn); }
.fpm-list-status[data-tone="error"] { --fpm-chip: var(--fpm-status-error); }
.fpm-list-status[data-tone="info"] { --fpm-chip: var(--fpm-accent-secondary); }
/* Rows */
.fpm-list-item { background: none; transition: background var(--fpm-transition-fast); }
.fpm-list-item:hover { background: var(--fpm-row-hover); }
.fpm-list-item:has(.fpm-list-status[data-tone="warn"]) { box-shadow: inset 3px 0 0 var(--fpm-status-warn); }
.fpm-list-item:has(.fpm-list-status[data-tone="error"]) { box-shadow: inset 3px 0 0 var(--fpm-status-error), inset 40px 0 40px -40px color-mix(in srgb, var(--fpm-status-error) 25%, transparent); }
.fpm-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--fpm-row-alt) 60%, transparent); }
.fpm-table tbody tr { transition: background var(--fpm-transition-fast); }
.fpm-table tbody tr:has(.fpm-list-status[data-tone="warn"]) > td:first-child { box-shadow: inset 3px 0 0 var(--fpm-status-warn); }
.fpm-table tbody tr:has(.fpm-list-status[data-tone="error"]) > td:first-child { box-shadow: inset 3px 0 0 var(--fpm-status-error); }
.fpm-table td { vertical-align: middle; }

/* Work area with an inspector: the main column scrolls with the page while the inspector stays in view
   beside it; below 980px of host width the inspector drops under the main column. */
.fpm-with-inspector { display: grid; grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); gap: var(--fpm-space-lg); align-items: start; container-type: inline-size; }
.fpm-with-inspector__main { min-width: 0; display: flex; flex-direction: column; gap: var(--fpm-space-md); }
.fpm-inspector { position: sticky; top: var(--fpm-space-md); display: flex; flex-direction: column; gap: var(--fpm-space-sm); padding: var(--fpm-space-md); border-radius: var(--fpm-radius-lg); background: var(--fpm-card-bg); border: 1px solid var(--fpm-card-border); box-shadow: var(--fpm-card-shadow); -webkit-backdrop-filter: var(--fpm-panel-backdrop); backdrop-filter: var(--fpm-panel-backdrop); max-height: calc(100vh - 2 * var(--fpm-space-md)); overflow-y: auto; }
.fpm-inspector__title { margin: 0; font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-strong); }
.fpm-inspector__fields { display: flex; flex-direction: column; gap: var(--fpm-space-sm); }
.fpm-inspector__tools { display: flex; gap: var(--fpm-space-sm); justify-content: space-between; padding-top: var(--fpm-space-sm); border-top: 1px solid var(--fpm-divider); }
@media (max-width: 980px) { .fpm-with-inspector { grid-template-columns: minmax(0, 1fr); } .fpm-inspector { position: static; max-height: none; } }

@media (max-width: 640px) {
    .fpm-page-grid > *,
    .fpm-page-grid > .fpm-card[data-fpm-card-size="compact"] {
        grid-column: 1 / -1;
        grid-row: auto;
    }
    :is(.fpm-card:not([data-fpm-card-style=bare]), .fpm-widget) .fpm-scroll-region {
        block-size: auto;
        flex: none;
    }
    .fpm-card[data-fpm-primitive="feed"][data-fpm-state]:not([data-fpm-state="live"]) > .fpm-card__body {
        min-block-size: 0;
    }
    .fpm-list-item { flex-shrink: 0; }
    .fpm-list-sub { overflow-wrap: anywhere; }
    /* The in-page inspector stays in document flow, so it needs no dismiss action. */
    .fpm-inspector {
        position: relative;
        inset: 0;
        width: 100%;
        min-width: 0;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
        overscroll-behavior: contain;
    }
    .fpm-inspector__title { position: sticky; top: 0; background: var(--fpm-card-bg); }
}

/* A sentence of clickable chips that reads what a configured thing does ("When … , then …"). */
.fpm-sentence { margin: 0; display: flex; flex-wrap: wrap; align-items: center; gap: 6px 6px; font-size: var(--fpm-font-body); line-height: 1.9; color: var(--fpm-text-secondary); }
.fpm-sentence__word { font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-muted); }
.fpm-sentence__chip { font: inherit; font-weight: var(--fpm-weight-semibold); color: var(--fpm-accent); background: var(--fpm-accent-dim); border: 1px solid color-mix(in srgb, var(--fpm-accent) 35%, transparent); border-radius: var(--fpm-radius-sm); padding: 1px 8px; cursor: pointer; }
.fpm-sentence__chip:hover { border-color: var(--fpm-accent); }
.fpm-sentence__chip:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }

/* Step spine: an ordered list of step cards on one lit vertical line, with a + between steps and
   side-by-side lanes where the flow forks. */
.fpm-spine { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; align-items: stretch; position: relative; }
.fpm-spine::before { content: ""; position: absolute; left: 27px; top: 18px; bottom: 18px; width: 2px; border-radius: 2px; background: linear-gradient(var(--fpm-accent), color-mix(in srgb, var(--fpm-accent) 25%, transparent)); box-shadow: 0 0 12px var(--fpm-glow-accent-soft); }
.fpm-spine__step { position: relative; }
.fpm-spine__card { width: 100%; display: flex; align-items: center; gap: var(--fpm-space-md); padding: 12px 14px; text-align: left; font: inherit; color: inherit; cursor: pointer; border-radius: var(--fpm-radius-lg); background: var(--fpm-card-bg); border: 1px solid var(--fpm-card-border); box-shadow: var(--fpm-card-shadow); transition: transform var(--fpm-transition-fast), box-shadow var(--fpm-transition-fast); }
.fpm-spine__card:hover { transform: translateY(-1px); }
.fpm-spine__card[aria-pressed="true"] { box-shadow: var(--fpm-card-shadow), 0 0 0 2px var(--fpm-accent), 0 0 26px var(--fpm-glow-accent-soft); }
.fpm-spine__card:focus-visible { outline: none; box-shadow: var(--fpm-card-shadow), var(--fpm-shadow-focus-ring); }
.fpm-spine__icon { flex: none; display: grid; place-items: center; inline-size: 28px; block-size: 28px; border-radius: var(--fpm-radius-md); color: var(--fpm-accent); background: var(--fpm-accent-dim); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fpm-accent) 40%, transparent), 0 0 14px var(--fpm-glow-accent-soft); }
.fpm-spine__step--trigger .fpm-spine__icon { color: var(--fpm-on-accent); background: var(--fpm-accent); }
.fpm-spine__step--branch .fpm-spine__icon { color: var(--fpm-status-warn); background: color-mix(in srgb, var(--fpm-status-warn) 14%, transparent); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fpm-status-warn) 40%, transparent); }
.fpm-spine__text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.fpm-spine__kicker { font-size: var(--fpm-font-meta); font-weight: var(--fpm-weight-semibold); letter-spacing: 0.06em; color: var(--fpm-text-muted); }
.fpm-spine__title { font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-strong); }
.fpm-spine__summary { font-size: var(--fpm-font-body-sm); color: var(--fpm-text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.fpm-spine__badge { flex: none; }
.fpm-spine__badge:not(:last-child) { margin-right: 0; }
.fpm-spine__add { display: flex; padding: 6px 0 6px 15px; }
.fpm-spine__plus { position: relative; z-index: 1; display: grid; place-items: center; inline-size: 26px; block-size: 26px; border-radius: 50%; border: 1px solid var(--fpm-border-strong); background: var(--fpm-L2); color: var(--fpm-text-muted); cursor: pointer; transition: color var(--fpm-transition-fast), border-color var(--fpm-transition-fast), box-shadow var(--fpm-transition-fast); }
.fpm-spine__plus:hover, .fpm-spine__plus[aria-pressed="true"] { color: var(--fpm-accent); border-color: var(--fpm-accent); box-shadow: 0 0 14px var(--fpm-glow-accent-soft); }
.fpm-spine__plus:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }
.fpm-spine__fork { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--fpm-space-md); padding: 8px 0 0 28px; }
.fpm-spine__lane { padding: 10px; border-radius: var(--fpm-radius-lg); border: 1px dashed var(--fpm-border-medium); }
.fpm-spine__lane::before { left: 37px; top: 40px; }
.fpm-spine__lane-label { font-size: var(--fpm-font-meta); font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-muted); padding: 2px 0 4px 4px; }
.fpm-spine__join { font-size: var(--fpm-font-body-sm); color: var(--fpm-text-muted); padding: 4px 0 4px 44px; }
@container (max-width: 640px) { .fpm-spine__fork { grid-template-columns: minmax(0, 1fr); padding-left: 12px; } }
@media (prefers-reduced-motion: reduce) { .fpm-spine__card, .fpm-spine__plus { transition: none; } .fpm-spine__card:hover { transform: none; } }

/* Picker: a searchable list of choices with an icon, a name and one line of detail, grouped by heading. */
.fpm-picker { display: flex; flex-direction: column; gap: 4px; }
.fpm-picker__group { margin: var(--fpm-space-sm) 0 2px; font-size: var(--fpm-font-meta); font-weight: var(--fpm-weight-semibold); color: var(--fpm-text-muted); }
.fpm-picker__item { display: flex; align-items: center; gap: var(--fpm-space-sm); padding: 8px 10px; text-align: left; font: inherit; color: inherit; cursor: pointer; border-radius: var(--fpm-radius-md); border: 1px solid transparent; background: transparent; }
.fpm-picker__item:hover:not(:disabled) { background: var(--fpm-bg-surface-hover); border-color: var(--fpm-border-medium); }
.fpm-picker__item:disabled { opacity: 0.45; cursor: not-allowed; }
.fpm-picker__item:focus-visible { outline: none; box-shadow: var(--fpm-shadow-focus-ring); }

/* Palette: tones, raised rows, icon tiles, lit status
   A tone is one of accent, second, crit, warn, good, info or neutral. An element declares it with
   data-fpm-tone and every component below reads the same five slots, so a colour is chosen once. */
[data-fpm-tone] { --fpm-t-solid: var(--fpm-text-muted); --fpm-t-ink: var(--fpm-tone-neutral-ink); --fpm-t-soft: var(--fpm-tone-neutral-soft); --fpm-t-edge: var(--fpm-border-light); --fpm-t-glow: transparent; }
[data-fpm-tone="accent"] { --fpm-t-solid: var(--fpm-tone-accent); --fpm-t-ink: var(--fpm-tone-accent-ink); --fpm-t-soft: var(--fpm-tone-accent-soft); --fpm-t-edge: var(--fpm-tone-accent-edge); --fpm-t-glow: var(--fpm-tone-accent-glow); }
[data-fpm-tone="second"] { --fpm-t-solid: var(--fpm-tone-second); --fpm-t-ink: var(--fpm-tone-second-ink); --fpm-t-soft: var(--fpm-tone-second-soft); --fpm-t-edge: var(--fpm-tone-second-edge); --fpm-t-glow: var(--fpm-tone-second-glow); }
[data-fpm-tone="crit"] { --fpm-t-solid: var(--fpm-tone-crit); --fpm-t-ink: var(--fpm-tone-crit-ink); --fpm-t-soft: var(--fpm-tone-crit-soft); --fpm-t-edge: var(--fpm-tone-crit-edge); --fpm-t-glow: var(--fpm-tone-crit-glow); }
[data-fpm-tone="warn"] { --fpm-t-solid: var(--fpm-tone-warn); --fpm-t-ink: var(--fpm-tone-warn-ink); --fpm-t-soft: var(--fpm-tone-warn-soft); --fpm-t-edge: var(--fpm-tone-warn-edge); --fpm-t-glow: var(--fpm-tone-warn-glow); }
[data-fpm-tone="good"] { --fpm-t-solid: var(--fpm-tone-good); --fpm-t-ink: var(--fpm-tone-good-ink); --fpm-t-soft: var(--fpm-tone-good-soft); --fpm-t-edge: var(--fpm-tone-good-edge); --fpm-t-glow: var(--fpm-tone-good-glow); }
[data-fpm-tone="info"] { --fpm-t-solid: var(--fpm-tone-info); --fpm-t-ink: var(--fpm-tone-info-ink); --fpm-t-soft: var(--fpm-tone-info-soft); --fpm-t-edge: var(--fpm-tone-info-edge); --fpm-t-glow: var(--fpm-tone-info-glow); }

/* Raised row: a lit, translucent line that sits above its panel. */
.fpm-rail__item .fpm-list-item { background: var(--fpm-row-fill); border: 1px solid var(--fpm-row-edge); border-radius: var(--fpm-radius-sm); box-shadow: var(--fpm-row-shadow); transition: background var(--fpm-transition-fast), box-shadow var(--fpm-transition-fast); }
.fpm-rail__item .fpm-list-item:hover { background: var(--fpm-row-fill-hover); }

/* Icon tile: a small rounded square holding a line icon in the tone's ink. */
.fpm-nav-item-glyph[data-fpm-tone], .fpm-card__icon { display: inline-grid; place-items: center; flex: none; width: var(--fpm-tile-size, 24px); height: var(--fpm-tile-size, 24px); border-radius: var(--fpm-radius-md); background: var(--fpm-t-soft); color: var(--fpm-t-ink); }
.fpm-nav-item-glyph[data-fpm-tone] > svg { width: 14px; height: 14px; }
.fpm-card__icon { --fpm-tile-size: 30px; }

/* A card that names a tone gets a soft corner glow in it and a toned icon tile beside its title. */
.fpm-card[data-fpm-tone]::before { content: ""; position: absolute; inset: -44px -44px auto auto; width: 150px; height: 150px; border-radius: 50%; background: radial-gradient(circle, var(--fpm-t-glow), transparent 70%); opacity: var(--fpm-tone-glow-strength); pointer-events: none; z-index: -1; }
.fpm-card[data-fpm-tone] { overflow: hidden; }
/* A rail card draws no box, so its corner glow would float on the rail as a smudge; the toned icon tile carries the tone. */
.fpm-rail > .fpm-rail__item.fpm-card[data-fpm-tone]::before { content: none; }
.fpm-card__head:has(> .fpm-card__icon) { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }

/* Progress tray: a floating stack of transfer rows, each a name, byte count, bar and cancel
   A row's fill is its --fpm-progress custom property (0 to 100), set by script with setProperty. */
.fpm-progress-tray { display: flex; flex-direction: column; gap: var(--fpm-space-xs); min-width: 260px; max-width: 360px; padding: var(--fpm-space-sm); background: var(--fpm-bg-surface); border: 1px solid var(--fpm-border-light); border-radius: var(--fpm-radius-lg); box-shadow: var(--fpm-shadow-floating); }
.fpm-progress-tray__row { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-areas: "name cancel" "bytes cancel" "bar bar"; column-gap: var(--fpm-space-sm); row-gap: calc(var(--fpm-space-xs) / 2); padding: calc(var(--fpm-space-xs) * 1.5) var(--fpm-space-sm); border-radius: var(--fpm-radius-md); }
.fpm-progress-tray__name { grid-area: name; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fpm-text-primary); }
.fpm-progress-tray__bytes { grid-area: bytes; font-family: var(--fpm-font-mono); font-variant-numeric: tabular-nums; color: var(--fpm-text-secondary); }
.fpm-progress-tray__cancel { grid-area: cancel; align-self: center; }
.fpm-progress-tray__bar { grid-area: bar; height: var(--fpm-space-xs); margin-top: var(--fpm-space-xs); overflow: hidden; border-radius: var(--fpm-radius-xs); background: var(--fpm-border-light); }
.fpm-progress-tray__bar::after { content: ""; display: block; height: 100%; width: calc(var(--fpm-progress, 0) * 1%); background: var(--fpm-accent); transition: width var(--fpm-transition-fast); }
.fpm-progress-tray__row[data-fpm-tone] .fpm-progress-tray__bar::after { background: var(--fpm-t-solid); }
@media (prefers-reduced-motion: reduce) { .fpm-progress-tray__bar::after { transition: none; } }

/* Ordered rows: draggable grip, content, count and actions. */
.fpm-ordered-row { display: grid; grid-template-columns: auto minmax(0, 1fr) repeat(5, auto); align-items: center; gap: var(--fpm-space-xs); padding: var(--fpm-space-sm); border-bottom: 1px solid var(--fpm-border-subtle); }
.fpm-ordered-row--selected { background: var(--fpm-bg-surface-hover); }
.fpm-ordered-row__grip { cursor: grab; color: var(--fpm-text-muted); }
.fpm-ordered-row > button { white-space: normal; overflow-wrap: anywhere; }
@media (max-width: 640px) {
    .fpm-ordered-row { grid-template-columns: auto minmax(0, 1fr); }
}

/* Filters that belong to one card: a row between its title and its body, so a list's own controls live with the list. */
.fpm-card > .fpm-card__filters { grid-column: 1; grid-row: 2; min-width: 0; padding: 0 var(--fpm-space-md) var(--fpm-space-sm); }
.fpm-card:has(> .fpm-card__filters) { grid-template-rows: auto auto minmax(0, 1fr); }
.fpm-card:has(> .fpm-card__filters) > :is(.fpm-card__body, .fpm-card__state) { grid-row: 3; }

/* A launcher: one button pinned to the viewport's bottom-right corner, like a chat entry, opening its popover above it. */
.fpm-launcher { position: fixed; inset-block-end: var(--fpm-space-lg); inset-inline-end: var(--fpm-space-lg); z-index: var(--fpm-z-sticky); box-shadow: var(--fpm-shadow-floating);
    inline-size: 52px; block-size: 52px; padding: 0; border-radius: 50%; border: 0; display: grid; place-items: center;
    background: var(--fpm-accent); color: var(--fpm-on-accent); }
.fpm-launcher:hover { background: var(--fpm-accent-dark); }
.fpm-launcher__count { position: absolute; inset-block-start: calc(var(--fpm-space-xs) * -1); inset-inline-end: calc(var(--fpm-space-xs) * -1);
    min-inline-size: 20px; block-size: 20px; padding-inline: var(--fpm-space-xs); box-sizing: border-box; border-radius: 10px;
    display: grid; place-items: center; background: var(--fpm-status-error); color: var(--fpm-text-on-danger);
    font: var(--fpm-weight-bold) var(--fpm-font-meta)/1 var(--fpm-font-mono); }
.fpm-launcher__panel { display: flex; flex-direction: column; gap: var(--fpm-space-md); }

/* A decision card: who asks and when it expires, one plain question, two large answers, then the full detail behind a native disclosure. */
.fpm-decision { gap: var(--fpm-space-md); }
.fpm-decision[data-tone="warn"] { border-inline-start: 3px solid var(--fpm-status-warn); }
.fpm-decision[data-tone="error"] { border-inline-start: 3px solid var(--fpm-status-error); }
.fpm-decision__meta { margin: 0; font-size: var(--fpm-font-body-sm); color: var(--fpm-text-muted); }
.fpm-decision__question { margin: 0; font-size: var(--fpm-font-xl); font-weight: var(--fpm-weight-semibold); line-height: 1.3; color: var(--fpm-text-primary); overflow-wrap: anywhere; }
.fpm-decision__actions { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--fpm-space-sm); }
.fpm-decision__actions > .fpm-btn { min-height: 52px; font-size: var(--fpm-font-body); font-weight: var(--fpm-weight-semibold); }
.fpm-decision > .fpm-details { min-width: 0; max-width: none; display: flex; flex-direction: column; gap: var(--fpm-space-sm); }
.fpm-decision > .fpm-details > summary { display: flex; align-items: center; min-height: var(--fpm-touch-target); }
.fpm-decision > .fpm-list-status { align-self: flex-start; }
