@import url('open-iconic/font/css/open-iconic-bootstrap.min.css');

:root {
    --transition-speed-hover: 0.1s;
    --nxs-warning: #b13600;
    --nxs-surface-radius: 1rem;

    /* ── Design tokens (single source of truth; see docs/plans/design-tokens-retrofit.md) ──
       The MudTheme in MainLayout references these; component CSS must use them, not literals. */

    /* Radius — flat scale */
    --nxs-radius-sm: 4px;    /* chips (non-pill), small/inset controls */
    --nxs-radius-md: 6px;    /* default — buttons, inputs, cards */
    --nxs-radius-lg: 8px;    /* panels, grids, modals, large surfaces */
    --nxs-radius-pill: 999px;

    /* Spacing — 4px-based scale for margin / padding / gap. Token number = pixel value;
       value is rem for accessibility (assumes 16px root). Round raw spacing to the nearest
       step. Structural values (vh/vw, calc(), grid track sizes) are NOT spacing — leave them. */
    --nxs-space-2:  0.125rem; /* 2px  — hairline gaps */
    --nxs-space-4:  0.25rem;  /* 4px  */
    --nxs-space-6:  0.375rem; /* 6px  */
    --nxs-space-8:  0.5rem;   /* 8px  */
    --nxs-space-12: 0.75rem;  /* 12px */
    --nxs-space-16: 1rem;     /* 16px — base rhythm */
    --nxs-space-20: 1.25rem;  /* 20px */
    --nxs-space-24: 1.5rem;   /* 24px */
    --nxs-space-32: 2rem;     /* 32px */
    --nxs-space-48: 3rem;     /* 48px — section spacing */

    /* Layout — page width policy (see docs/plans/page-width-layout.md). Content is full-width
       by default (data grids use the space); form/detail pages opt into a capped reading
       column via <NxsReadingColumn>. */
    --nxs-content-gutter: 1.5rem; /* horizontal page padding (replaces the old global px-4) */
    --nxs-reading-max: 1100px;    /* max line length for form/detail reading columns */
    --nxs-chart-height-sm: clamp(320px, 42vh, 440px);
    --nxs-chart-height-md: clamp(420px, 58vh, 560px);
    --nxs-chart-height-lg: clamp(510px, 70vh, 640px);
    --nxs-chart-height-xl: clamp(510px, 78vh, 780px);

    /* Surfaces — neutral dark ladder (tinted darks are NOT surfaces — handled as status tokens) */
    --nxs-bg: #222222;            /* page background */
    --nxs-surface: #121212;       /* primary panel/card surface */
    --nxs-surface-inset: #101010; /* wells/insets (absorbs #0f0f0f/#0d0d0d/#141414/#151515) */
    --nxs-surface-raised: #1a1a1a;/* raised panels (absorbs #161616/#181818/#191919/#1b1b1b/#1d1d1d/#1e1e1e/#1f1f1f) */
    --nxs-surface-40: color-mix(in srgb, var(--nxs-surface) 40%, transparent);
    --nxs-surface-80: color-mix(in srgb, var(--nxs-surface) 80%, transparent);
    --nxs-geometry-surface: var(--nxs-surface-raised); /* canonical geometry viewer / thumbnail surface */
    --nxs-surface-2: #2a2a2a;     /* secondary fills (absorbs #232323/#242424/#262626/#272727/#2b2b2b) */
    --nxs-surface-3: #383838;     /* raised/hover fills (absorbs #333333/#353535/#3a3a3a/#444444) */

    /* Borders / lines */
    --nxs-border: #363636;
    --nxs-border-60: color-mix(in srgb, var(--nxs-border) 60%, transparent);
    --nxs-border-strong: #4f4f4f; /* absorbs #3a3a3a/#5f5f5f */
    --nxs-divider: var(--nxs-overlay-12); /* = white 12% overlay step (see ladder below) */

    /* Text */
    --nxs-text: #ffffff;          /* headings / primary */
    --nxs-text-body: #e6e6e6;     /* body */
    --nxs-text-muted: #9aa3ad;    /* labels / secondary */
    --nxs-text-subtle: #b8c3cf;   /* absorbs #aeb7c2/#cfd6de/#9aa0a6 */

    /* Accent / status */
    --nxs-accent: #00bcd4;
    --nxs-accent-bright: #00d4ee; /* absorbs #00c8ff/#74edff — hover/glow */
    --nxs-danger: #e25656;
    --nxs-danger-strong: #b3261e; /* absorbs #900000 */
    --nxs-danger-bg: #33191b;     /* absorbs #3a1618 */
    --nxs-success: #1f6f43;       /* in-tolerance / pass (absorbs #278a53) */
    --nxs-success-bg: #143522;    /* dark green fill */
    --nxs-info-bg: #0f1720;       /* info/note panels (absorbs #101114/#05070b/#0d1117) */

    /* Status foreground/border — light variants for pass/fail chips on the *-bg fills above
       (the dark --nxs-danger/-success can't be used as foreground text; they're fills). */
    --nxs-success-text: #7ee2a8;   /* pass chip text/icon */
    --nxs-success-border: #23643d; /* pass chip border */
    --nxs-danger-text: #ff9b9b;    /* fail chip text/icon */
    --nxs-danger-border: #713134;  /* fail chip border */

    /* Info / highlight — bright sky-blue foreground (pairs with --nxs-info-bg); absorbs the
       drifting #67d5ff/#7dc9ff/#54d8e6 highlight blues. Tints via color-mix, like the accent. */
    --nxs-info: #67d5ff;
    --nxs-info-8:  color-mix(in srgb, var(--nxs-info) 8%, transparent);
    --nxs-info-20: color-mix(in srgb, var(--nxs-info) 20%, transparent);

    /* White overlays — fixed opacity ladder. Round any raw rgba(255,255,255,a) to the nearest
       step. NOTE: higher white-alphas (>=~0.42) are muted/near-opaque TEXT, not overlays —
       use the --nxs-text-* ladder for those, not these tokens. */
    --nxs-overlay-3:  rgba(255, 255, 255, 0.03); /* faintest fills / zebra (absorbs 0.02–0.04) */
    --nxs-overlay-8:  rgba(255, 255, 255, 0.08); /* hover / active fill (absorbs 0.06–0.10) */
    --nxs-overlay-12: rgba(255, 255, 255, 0.12); /* dividers / hairlines */
    --nxs-overlay-20: rgba(255, 255, 255, 0.20); /* visible borders (absorbs 0.16–0.24) */
    --nxs-overlay-32: rgba(255, 255, 255, 0.32); /* strong borders / emphasis (absorbs 0.28–0.35) */

    /* Back-compat aliases — existing names now map onto the ladder steps */
    --nxs-overlay-subtle: var(--nxs-overlay-3);
    --nxs-overlay-hover:  var(--nxs-overlay-8);

    /* Accent tints — brand accent at low alpha, derived from --nxs-accent so they stay in sync.
       Same step numbers as the white ladder. */
    --nxs-accent-8:  color-mix(in srgb, var(--nxs-accent) 8%, transparent);  /* faint wash (absorbs 0.08–0.12) */
    --nxs-accent-20: color-mix(in srgb, var(--nxs-accent) 20%, transparent); /* selected fill (absorbs 0.15–0.18) */
    --nxs-accent-30: color-mix(in srgb, var(--nxs-accent) 30%, transparent); /* strong selected fill (absorbs 0.30–0.35) */

    /* Scrims / shadow — black-alpha axis */
    --nxs-scrim:  rgba(0, 0, 0, 0.6);  /* modal / backdrop scrim (absorbs 0.35–0.72) */
    --nxs-shadow: rgba(0, 0, 0, 0.22); /* drop shadows (absorbs 0.2/0.24) */
    --nxs-surface-veil: rgba(18, 18, 18, 0.35); /* translucent dark veil for in-content loading/disabled overlays (absorbs 0.28–0.38) */

}

/* NxsChip<T> — the site's standard chip primitive. Semantic wrappers such as
   NxsResultChip and NxsPercentChip compose this, so the baseline chrome lives here. */
.nxs-chip.mud-chip {
    border: 1px solid var(--nxs-border-strong);
    border-radius: var(--nxs-radius-pill);
    background: var(--nxs-overlay-8);
    color: var(--nxs-text-body);
    font-weight: 700;
}

/* NxsChip<T> selected state — neutral selectable pills use MudChip's built-in Selected
   property plus this shared visual treatment on the whole chip. */
.nxs-chip.is-selected.mud-chip {
    border-color: var(--nxs-accent);
    color: var(--nxs-text);
    opacity: 1;
}

.nxs-chip.nxs-result-chip--pass {
    border-color: var(--nxs-success-border);
    background: color-mix(in srgb, var(--nxs-success) 20%, transparent);
    color: var(--nxs-success-text);
}

.nxs-chip.nxs-result-chip--fail {
    border-color: var(--nxs-danger-border);
    background: color-mix(in srgb, var(--nxs-danger) 20%, transparent);
    color: var(--nxs-danger-text);
}

/* NxsDataGrid<T> — the site's standard data grid: one cohesive dark rounded panel
   (toolbar + header + rows), matching the metrology grids. Striping off / elevation 0 /
   outlined are forced in the component; the rules here cover what props can't express. */
.nxs-grid.mud-table {
    background: var(--nxs-surface);
    border-radius: var(--nxs-radius-lg);
    overflow: hidden; /* clip the square table to the rounded panel corners */
}

.nxs-grid .mud-table-container,
.nxs-grid .mud-table-body .mud-table-row {
    background: var(--nxs-surface);
}

/* The root panel does ALL the rounding (overflow:hidden clip). Everything inside stays
   square — inner radii draw curved seams where they meet the optional toolbar. Square=true
   in the component disables Mud's normal panel rounding, but FixedHeader grids get a
   SEPARATE rounding from `.mud-table-sticky-header * ... .mud-table-cell:first-child`
   (specificity 0,5,0 — independent of Square), so the sticky-header selectors below must
   carry 0,6,0 to win. */
.nxs-grid .mud-table-container,
.nxs-grid .mud-table-toolbar,
.nxs-grid.mud-table-sticky-header .mud-table-root .mud-table-head .mud-table-cell:first-child,
.nxs-grid.mud-table-sticky-header .mud-table-root .mud-table-head .mud-table-cell:last-child,
.nxs-grid .mud-table-head .mud-table-cell:first-child,
.nxs-grid .mud-table-head .mud-table-cell:last-child {
    border-radius: 0;
}

/* Toolbar geometry is OURS. Mud's .mud-toolbar sets a FIXED height (64px) and gutter
   padding (0 8px 0 16px) — both read unbalanced next to the content. Content-driven
   height, uniform 12/16 padding. */
.nxs-grid .mud-table-toolbar {
    height: auto;
    min-height: 0;
    padding: 12px 16px;
    gap: 12px;
    border-bottom: 1px solid var(--nxs-border);
}

/* Standard search field (NxsSearchField): fixed width WHEREVER it appears — a default
   MudTextField is full-width and stretches edge-to-edge. Pages may override per layout
   (e.g. full-width on narrow screens) via a ::deep rule on their own class. */
.nxs-search {
    flex: 0 1 360px;
    width: 360px;
    min-width: 180px;
}

/* MudSelect popovers render outside the component subtree, so NxsFilterDropdown
   supplies this class via PopoverClass rather than relying on scoped CSS. */
.nxs-filter-dropdown__popover,
.nxs-filter-dropdown__popover .mud-paper,
.nxs-filter-dropdown__popover .mud-list {
    border-top-left-radius: 0 !important;
    min-width: 190px;
    max-width: min(320px, calc(100vw - var(--nxs-space-32)));
}

.nxs-filter-dropdown__popover .mud-list-item,
.nxs-filter-dropdown__popover .mud-list-item-text {
    min-width: 0;
}

.nxs-filter-dropdown__popover .nxs-filter-dropdown__option-text {
    display: block;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Uniform with toolbar + rows; row hover is the only lift. The sticky-header variant must
   carry 0,5,0 specificity: FixedHeader grids get their header background from Mud's
   `.mud-table-sticky-header * .mud-table-root .mud-table-head * .mud-table-cell` (0,4,0),
   which beats a plain 0,3,0 override. Keep this OPAQUE — rows scroll under the sticky head. */
.nxs-grid .mud-table-head .mud-table-cell,
.nxs-grid.mud-table-sticky-header .mud-table-root .mud-table-head .mud-table-cell {
    background: var(--nxs-surface);
}

.nxs-grid .mud-table-body .mud-table-row:hover > .mud-table-cell {
    background: var(--nxs-surface-raised);
}

/* No-records and loading rows: Mud paints both var(--mud-palette-surface) — a lighter
   shade than the grid panel, so they read as a stray band. Pin them to the panel surface.
   The sticky-header loading selector needs 0,5,0 to beat Mud's 0,4,0 (same story as the
   header cells above). */
.nxs-grid .mud-table-empty-row,
.nxs-grid.mud-table-sticky-header .mud-table-root .mud-table-head .mud-table-loading {
    background-color: var(--nxs-surface);
}

/* MudSwitch unchecked track: Mud paints it var(--mud-palette-black) at 48% opacity — and
   our palette Black IS --nxs-surface, so on surface panels the track is invisible (only the
   thumb shows). Lift it to the raised-fill token, full opacity. Checked state is unaffected:
   Mud's .mud-checked rules out-specify this and keep the accent track. */
.mud-switch-span .mud-switch-track {
    background-color: var(--nxs-surface-3);
    opacity: 1;
}

/* NxsButton — the standard primary action button: accent fill, dark text.
   .mud-button-root included for specificity over Mud's filled-primary colours. */
.mud-button-root.nxs-btn {
    background: var(--nxs-accent);
    color: var(--nxs-surface);
}

.mud-button-root.nxs-btn:hover,
.mud-button-root.nxs-btn:focus-visible {
    background: var(--nxs-accent-bright);
}

/* NxsButton secondary (Kind="Secondary"): outlined accent for actions beside a primary button. */
.mud-button-root.nxs-btn-secondary {
    background: transparent;
    color: var(--nxs-accent);
    border: 1px solid var(--nxs-border-strong);
}

.mud-button-root.nxs-btn-secondary:hover,
.mud-button-root.nxs-btn-secondary:focus-visible {
    background: var(--nxs-accent-8);
    border-color: var(--nxs-accent);
    color: var(--nxs-accent-bright);
}

/* NxsCard — the site's standard content card: outlined, padded, rounded panel with an
   optional titled header (MudText + divider) and an optional divider-anchored footer.
   Chrome is token-driven; lives here (global) so it reaches the MudPaper root without ::deep. */
.mud-paper.nxs-card {
    padding: var(--nxs-space-24);
    background: var(--nxs-surface-raised);
    border: 1px solid var(--nxs-border);
    border-radius: var(--nxs-radius-lg);
}

/* Chart cards keep NxsCard spacing/chrome, but use the same surface as Plotly charts so
   chart margins and surrounding card padding read as one continuous chart surface. */
.mud-paper.nxs-card.nxs-chart-card {
    background: var(--nxs-surface);
}

.nxs-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--nxs-space-16);
    margin-bottom: var(--nxs-space-16);
    padding-bottom: var(--nxs-space-12);
    border-bottom: 1px solid var(--nxs-border);
}

.nxs-card__title {
    margin: 0;
    font-weight: 600;
}

.nxs-card__header-actions {
    display: flex;
    align-items: center;
    gap: var(--nxs-space-8);
    flex-shrink: 0;
}

.nxs-card__actions {
    margin-top: var(--nxs-space-24);
    padding-top: var(--nxs-space-16);
    border-top: 1px solid var(--nxs-border);
    display: flex;
    flex-wrap: wrap;
    gap: var(--nxs-space-12);
}

@media (max-width: 900px) {
    .mud-paper.nxs-card {
        padding: var(--nxs-space-20);
    }
}

/* Standard grid empty state — calm, muted, centered. NxsDataGrid renders this by default;
   pages only override the wording (keep this class on the override). */
.nxs-grid-empty {
    padding: var(--nxs-space-24);
    text-align: center;
    color: var(--nxs-text-muted);
    font-size: 0.9rem;
}

/* ── NxsTabs — the site's shared tab strip ─────────────────────────────────────────
   Two variants, one modifier:
     --primary    framed rounded bar; page-level sections.
     --secondary  dense hairline strip; sub-sections inside an already-framed area.
     --contained  (modifier, Contained="true") bar + panel area join into one bordered
                  panel — the bar is the top edge, content shares the raised surface.
                  Tab-bar toolbars go in MudTabs' native Header slot, which renders
                  inline inside the bar (no overlay/reserved-width tricks). */
.nxs-tabs {
    min-width: 0;
}

.nxs-tabs > .mud-tabs-panels > div {
    min-width: 0;
}

/* Header slot (MudTabs Header fragment, HeaderPosition defaults to After): inline
   toolbar at the right end of the bar row. */
.nxs-tabs .mud-tabs-header {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    justify-content: flex-end;
    min-width: 0;
    gap: 8px;
    padding: 4px 12px 4px 16px;
}

.nxs-tabs--primary > .mud-tabs-tabbar {
    background: var(--nxs-surface-raised);
    border: 1px solid var(--nxs-border);
    border-radius: var(--nxs-radius-lg);
    overflow: hidden;
}

/* Tab cells must fill the bar's FULL height even when Header content (toolbars) makes
   the bar taller than the tabs — the active underline is the cell's bottom edge and has
   to sit on the bar's bottom border. Mud breaks the height-stretch chain in two places:
   .mud-tabs-tabbar-content is inline-block, and each tab sits in a `d-inline-block`
   utility wrapper (display:inline-block !important — hence the !important here). */
.nxs-tabs .mud-tabs-tabbar .mud-tabs-tabbar-inner {
    min-height: 0;
    align-items: stretch;
}

.nxs-tabs .mud-tabs-tabbar-content {
    display: flex;
    align-items: stretch;
}

.nxs-tabs .mud-tabs-tabbar-content .mud-tabs-tabbar-wrapper {
    align-items: stretch;
}

.nxs-tabs .mud-tabs-tabbar-wrapper > div {
    display: inline-flex !important;
    align-items: stretch;
}

.nxs-tabs .mud-tab {
    flex: 0 0 auto;
    min-height: var(--nxs-tabs-tab-min-height, 38px);
    padding: var(--nxs-tabs-tab-padding, 6px 14px);
    font-size: var(--nxs-tabs-tab-font-size, inherit);
    color: var(--nxs-text-subtle);
    transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
                color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}

/* The active underline is drawn on the tab cell itself (inset shadow), not Mud's
   JS-measured .mud-tab-slider — the slider is positioned from pixel measurements that
   drift out of line with the cell (and with the hover highlight, which IS the cell).
   Same element for highlight and underline = aligned by construction. */
/* Specificity must beat the wrapper-children stretch rule below (also !important, and
   its `> div` type selector adds 0,2,1 — a bare .nxs-tabs .mud-tab-slider at 0,2,0
   LOSES and the slider quietly comes back). */
.nxs-tabs .mud-tabs-tabbar-wrapper > div.mud-tab-slider {
    display: none !important;
}

.nxs-tabs .mud-tab.mud-tab-active {
    color: var(--nxs-text);
    box-shadow: inset 0 -2px 0 var(--nxs-accent);
}

@media (hover: hover) and (pointer: fine) {
    .nxs-tabs .mud-tab:hover {
        background-color: var(--nxs-overlay-hover);
        color: var(--nxs-text);
    }

    .nxs-tabs .mud-tab.mud-tab-active:hover {
        background-color: var(--nxs-overlay-hover);
        box-shadow: inset 0 -2px 0 var(--nxs-accent);
    }
}

/* The bar's children stretch (so tab cells reach the bottom border) — the scroll-button
   wrappers stretch too, so they must centre their fixed-size chevrons themselves. */
.nxs-tabs .mud-tabs-scroll-button {
    display: flex;
    align-items: center;
}

.nxs-tabs .mud-tabs-scroll-button .mud-button-root {
    width: 36px;
    height: 36px;
    border-radius: var(--nxs-radius-pill);
    color: var(--nxs-text-subtle);
}

@media (hover: hover) and (pointer: fine) {
    .nxs-tabs .mud-tabs-scroll-button .mud-button-root:hover {
        background: var(--nxs-overlay-hover);
        color: var(--nxs-text);
    }
}

/* Secondary: dense strip anchored by a hairline so it never reads as floating text. */
.nxs-tabs--secondary > .mud-tabs-tabbar {
    background: transparent;
    border-bottom: 1px solid var(--nxs-divider);
}

.nxs-tabs--secondary .mud-tab {
    font-weight: 600;
}

.nxs-tabs--secondary .mud-tabs-scroll-button .mud-button-root {
    width: 36px;
    height: 36px;
}

/* Contained: bar + panels join into one framed panel. The bar keeps only its top
   corners; the panel area carries the remaining frame and its own padding (the strip's
   pt-* gap utility is suppressed by the component in this mode). */
.nxs-tabs--contained {
    --nxs-tabs-panel-pad: 16px;
}

.nxs-tabs--contained > .mud-tabs-tabbar {
    border-radius: var(--nxs-radius-lg) var(--nxs-radius-lg) 0 0;
}

.nxs-tabs--contained > .mud-tabs-panels {
    padding: var(--nxs-tabs-panel-pad);
    background: var(--nxs-surface-raised);
    border: 1px solid var(--nxs-border);
    border-top: 0;
    border-radius: 0 0 var(--nxs-radius-lg) var(--nxs-radius-lg);
}

/* A secondary strip LEADING a contained panel (Docked="true") sits flush under the
   parent's tab bar while keeping its divider aligned to the same inset as the content
   below. The pad var inherits from the containing .nxs-tabs--contained. */
.nxs-tabs--docked > .mud-tabs-tabbar {
    margin-block: calc(-1 * var(--nxs-tabs-panel-pad, 16px)) var(--nxs-tabs-panel-pad, 16px);
    margin-inline: 0;
    padding: 0;
}

/* ── NxsTabHeader — one frame for a two-row tab header ────────────────────────────
   NxsTabs still owns tab selection; rows render strip-only (their empty Mud panel
   areas are hidden). Page content lives OUTSIDE the stack.

   Geometry: deliberately simple. The whole stack is ONE bordered rounded panel on
   the raised surface; the rows are separated by a hairline divider. Active tabs use
   the standard .nxs-tabs accent underline in both rows — same indicator as the rest
   of the app. Grouping is communicated by containment, not per-tab borders. */
.nxs-tab-header {
    min-width: 0;
    background: var(--nxs-surface-raised);
    border: 1px solid var(--nxs-border);
    border-radius: var(--nxs-radius-lg);
    overflow: hidden; /* clip row hover overlays to the rounded corners */
}

.nxs-tab-header__row {
    display: flex;
    align-items: stretch;
    min-width: 0;
}

.nxs-tab-header__tabs {
    flex: 1 1 auto;
    min-width: 0;
}

/* Rows host bare strips: the stack owns the chrome, so strip chrome comes off and
   the (empty) panel areas are hidden. */
.nxs-tab-header__tabs > .nxs-tabs,
.nxs-tab-header__tabs > .nxs-tabs > .mud-tabs-tabbar {
    height: 100%;
    min-width: 0;
}

.nxs-tab-header__tabs > .nxs-tabs > .mud-tabs-tabbar {
    background: transparent;
    border: 0;
    border-radius: 0;
}

.nxs-tab-header__tabs > .nxs-tabs > .mud-tabs-panels {
    display: none;
}

/* With a child row present, the parent's selection is shown by the shared highlight
   alone (active tab + sub row share the same fill) — the accent underline belongs to
   the child row only, so it comes OFF the parent here, including on hover (the shared
   .nxs-tabs :hover rule would otherwise re-add it). */
.nxs-tab-header--has-subtabs .nxs-tabs--primary .mud-tab.mud-tab-active {
    background-color: var(--nxs-surface-2);
    box-shadow: none;
}

@media (hover: hover) and (pointer: fine) {
    .nxs-tab-header--has-subtabs .nxs-tabs--primary .mud-tab.mud-tab-active:hover {
        background-color: var(--nxs-surface-2);
        box-shadow: none;
    }
}

/* No divider between the rows: the sub row's lighter fill separates them tonally, and
   a hairline would cut through the active tab's connection to its sub row (they share
   the same fill so the selection reads as one region). */
.nxs-tab-header__row--subtabs {
    background-color: var(--nxs-surface-2);
}

html, body {
    font-family: Roboto, serif;
    /* Lock the window so the only vertical scrollbar is the content area's (article.content),
       not a full-height window scrollbar running behind the fixed app bar. */
    height: 100%;
    overflow: hidden;
}

/* Opt-in reading column for form/detail content — caps line length and centres within the
   full-width page. Grids/tables stay full-width (the page default) and must not use this. */
.nxs-reading-column {
    width: 100%;
    max-width: var(--nxs-reading-max);
    margin-inline: auto;
}

table {
    width: auto;
    border-collapse: collapse;
}

td {
    vertical-align: middle;
    border: none;
}

input {
    width: 100%;
    height: 100%;
    padding-left: 1em;
    
    background-color: var(--bs-secondary-bg);
    border: none;
}

select {
    background-color: var(--bs-secondary-bg);
    border: none;
}

input[type="file"] {
    padding: 0;
    border: 2px solid #444444;
    border-radius: var(--nxs-radius-lg);

    &:hover {
        cursor: pointer;
    }

    &::file-selector-button {
        margin-right: 1em;
        padding: 0.75em;
        border: none;

        color: var(--nxs-text);
        background-color: var(--nxs-surface-3);
    }

    &::file-selector-button:hover {
        cursor: pointer;
    }
}

ul, .submenu{
    list-style: none;
}

textarea {
    height: 10em;
    min-height: 10em;
    max-height: 25em;

    padding: 0.5em;
    border: none;
    background-color: var(--bs-secondary-bg);
}

select {
    padding-left: 1em;
}

h1:focus {
    outline: none;
}

a, .btn-link {
    text-decoration: none;
    color: var(--nxs-accent);
}

.warning{
    color: orange;
}

.nxs-button {
    width: 100%;
}

.nxs-section {
    padding: 3em;
    border-radius: var(--nxs-radius-lg);

    background-color: var(--bs-tertiary-bg);
    box-shadow: 0 0 5px var(--bs-box-shadow);
    /*border: 1px var(--bs-emphasis-color) solid;*/

    transition: box-shadow 0.1s;
    margin-bottom: 4em;
}

.nxs-section-label {
    padding-left: 0.5em;
    font-weight: bold;
    margin-bottom: 0.5em;
}

.nxs-section-as-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3em;
}

.nxs-section-as-flex {
    display: flex;
    flex-direction: column;
    gap: 3em;
}

.nxs-section-as-grid-triple {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    row-gap: 3em;
    column-gap: 3em;
}

.nxs-section-as-grid-quad {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr);
    row-gap: 3em;
    column-gap: 2em;
}

.nxs-section-item {
    flex: auto;
    display: flex;
    flex-direction: column;
    row-gap: 0.5em;
    max-width: 100%;
}

.airtable-source-selector {
    width: 100%;
}

.airtable-source-selector__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1em;
    width: 100%;
}

.airtable-source-selector__label-row {
    display: inline-flex;
    align-items: center;
    gap: 0.5em;
    min-width: 0;
}

.airtable-source-selector__show-all {
    display: inline-flex;
    align-items: center;
    gap: 0.4em;
    margin-left: auto;
    white-space: nowrap;
    font-weight: normal;
}

.airtable-source-selector__checkbox[type="checkbox"] {
    width: 1rem;
    height: 1rem;
    padding-left: 0;
    margin: 0;
    flex: 0 0 auto;
}

.nxs-section-chart {
    width: 45em;
    height: 45em;
    align-self: center;
}

.nxs-section-item-read-only-value {
    padding: 0.75em;
    background-color: var(--bs-body-bg);

    box-shadow: 0 0 10px var(--bs-box-shadow);
    border-radius: var(--nxs-radius-md);
    user-select: none;

    overflow: hidden;
    text-overflow: ellipsis;

}


.nxs-section-item-read-only-value:hover {
    cursor: pointer;
    box-shadow: 0 0 10px 2px var(--bs-box-shadow);
}

.nxs-section-item-read-only-value:active {
    box-shadow: 0 0 5px 0 var(--bs-box-shadow);
}

.nxs-section-item-read-only-note {
    padding: 0.75em;
    background-color: var(--bs-body-bg);
    box-shadow: 0 0 10px var(--bs-box-shadow);
    border-radius: var(--nxs-radius-md);
    height: 10em;
    white-space: pre-wrap;
    user-select: none;
    overflow: hidden;
    text-overflow: ellipsis;
}
.nxs-section-item-read-only-note:hover {
    cursor: pointer;
    box-shadow: 0 0 10px 2px var(--bs-box-shadow);
}

.nxs-section-item-read-only-note:active {
    box-shadow: 0 0 5px 0 var(--bs-box-shadow);
}



.nxs-center-content-vertically {
    display: flex;
    flex-direction: column;
    justify-content: center;
    
    height: 100%;
}

.nxs-center-content-horizontally {
    margin: auto;
}

.nxs-row-flex {
    display: flex;
    flex-direction: row;
    column-gap: 1em;
}

/* ----- Anemometer Diagram ----- */

.AnemometerDiagram {
    display: grid;
    width: 34em;
    grid-template-rows: 2em 32em;
    align-content: center;
}

.AnemometerDiagram-row {
    display: grid;
    grid-template-columns: 32em 2em;
    align-items: center;
}

/* ------------------------------ */


/* -------- Renderer CSS -------- */

.center-in-container {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
}

.part-listbox {
    position: absolute;
    margin-left: 1em;
    margin-top: 1em;
    
    max-height: calc(100% - 2.5em) !important;
}



/* ------------------------------ */


.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
    box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}

.content {
    padding-top: 1.1rem;
}

.valid.modified:not([type=checkbox]) {
    outline: 1px solid var(--nxs-success);
}

.invalid {
    outline: 1px solid var(--nxs-danger);
}

.italic {
    font-style: italic;
}

.validation-message {
    color: var(--nxs-danger);
}

.fill-splitter-pane {
    height: 100% !important;
}

.file-input-zone {
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: var(--nxs-accent);
    color: black;
    border-color: black;
    cursor: pointer;
    position: relative;
    text-transform: uppercase;
    font-weight: 500;
    padding-block: 8px;
    padding-inline: 18px;
    font-size: 14px;
    line-height: 1.4285714286;
    box-sizing: border-box;
    border-width: 1px;
    border-style: solid;
    gap: 8px;
    border-radius: var(--nxs-radius-sm);
}

    .file-input-zone:hover {
        background-color: var(--nxs-accent);
    }

    .file-input-zone input[type=file] {
        position: absolute;
        width: 100%;
        height: 100%;
        opacity: 0;
        cursor: pointer;
    }



/* --- Blazor Overrides --- */

.combo-box-input-text {
    display: inline-block;
    border: none;
    border-radius: var(--nxs-radius-sm) 0 0 var(--nxs-radius-sm);
}

.combo-box-input-text:focus {
    outline: none;
}

/* --- Measurement Grid Scrollbars (match home search style) --- */

.measurement-grid-scroll {
    width: 100%;
    min-width: 0;
}

.measurement-grid-scroll .k-table,
.measurement-grid-scroll .k-grid-table {
    min-width: 100%;
}

.measurement-grid-scroll .k-grid-content,
.measurement-grid-scroll .k-grid-content-locked,
.measurement-grid-scroll .k-grid-header-wrap,
.measurement-grid-scroll .k-grid-footer-wrap,
.measurement-grid-scroll .k-scrollbar {
    scrollbar-color: var(--nxs-overlay-20) var(--nxs-surface);
}

.measurement-grid-scroll .k-grid-content::-webkit-scrollbar-track,
.measurement-grid-scroll .k-grid-content-locked::-webkit-scrollbar-track,
.measurement-grid-scroll .k-grid-header-wrap::-webkit-scrollbar-track,
.measurement-grid-scroll .k-grid-footer-wrap::-webkit-scrollbar-track,
.measurement-grid-scroll .k-scrollbar::-webkit-scrollbar-track {
    background-color: var(--nxs-surface);
}

.measurement-grid-scroll .k-grid-content::-webkit-scrollbar-corner,
.measurement-grid-scroll .k-grid-content-locked::-webkit-scrollbar-corner,
.measurement-grid-scroll .k-grid-header-wrap::-webkit-scrollbar-corner,
.measurement-grid-scroll .k-grid-footer-wrap::-webkit-scrollbar-corner,
.measurement-grid-scroll .k-scrollbar::-webkit-scrollbar-corner {
    background-color: var(--nxs-surface);
}


/* For japanese localization font override */
.lang-ja {
    --bs-font-sans-serif: "Roboto", "Noto Sans JP", sans-serif;
}

.lang-ja,
.lang-ja body,
.lang-ja button,
.lang-ja input,
.lang-ja select,
.lang-ja textarea,
.lang-ja .mud-typography,
.lang-ja .k-widget {
    font-family: "Roboto", "Noto Sans JP", sans-serif !important;
}

/* --- App shell chrome (MudAppBar/MudDrawer are component roots, so scoped
       ::deep rules from MainLayout.razor.css cannot reach them) --- */

.mud-appbar.app-header {
    border-bottom: 1px solid var(--nxs-border);
}

.mud-drawer.app-nav-drawer {
    border-right: 1px solid var(--nxs-border);
}

/* Confine scrolling to the content area below the fixed app bar. The layout fills the viewport;
   main-content fills the layout and keeps MudBlazor's app-bar-height top padding but does NOT
   scroll itself — the inner article (article.content, a plain element that already sits below the
   bar) is the scroll container. So its scrollbar spans only from the bar's bottom edge down. */
.mud-layout {
    height: 100vh;
}

.mud-main-content {
    height: 100%;
    box-sizing: border-box;
    overflow: hidden;
}
