/* ==========================================================================
   NELMS design system
   Tokens and component styles ported from the original Next.js/shadcn UI
   (src/app/(frontend)/globals.css and src/components/ui/* in commit cc121f0).
   Dark mode is class-based: wwwroot/js/nelms.js toggles `dark` on <html>.
   ========================================================================== */

:root {
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --card: oklch(1 0 0);
    --card-foreground: oklch(0.145 0 0);
    --popover: oklch(1 0 0);
    --popover-foreground: oklch(0.145 0 0);
    --primary: oklch(0.596 0.145 163);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
    --muted: oklch(0.97 0 0);
    --muted-foreground: oklch(0.556 0 0);
    --accent: oklch(0.97 0 0);
    --accent-foreground: oklch(0.205 0 0);
    --destructive: oklch(0.577 0.245 27.325);
    --destructive-foreground: oklch(0.985 0 0);
    /* The brand primary is itself a green (hue 163), so "success" needs a visibly different hue
       (a more vivid grass-green, hue 145) to read as distinct from an ordinary default button. */
    --success: oklch(0.6 0.18 145);
    --success-foreground: oklch(0.985 0 0);
    --border: oklch(0.922 0 0);
    --input: oklch(0.922 0 0);
    --ring: oklch(0.596 0.145 163);
    --radius: 4px;
    --sidebar: oklch(0.97 0 0);
    --sidebar-foreground: oklch(0.145 0 0);
    --sidebar-primary: oklch(0.596 0.145 163);
    --sidebar-primary-foreground: oklch(0.985 0 0);
    --sidebar-accent: oklch(93.935% 0.04927 163.803 / 0.721);
    --sidebar-accent-foreground: oklch(0.45 0.13 163);
    --sidebar-border: oklch(0.922 0 0);
    --sidebar-ring: oklch(0.596 0.145 163);
    --table-row: oklch(0.32 0.06 163);

    /* Chart colours: six domain series in fixed order (validated for colour-vision
       safety in light and dark), plus status and chart chrome. */
    --viz-1: #2a78d6;
    --viz-2: #eb6834;
    --viz-3: #1baf7a;
    --viz-4: #eda100;
    --viz-5: #e87ba4;
    --viz-6: #008300;
    --viz-critical: #d03b3b;
    --viz-warning: #fab219;
    --viz-good: #0ca30c;
    --viz-grid: #e1e0d9;
    --viz-muted: #898781;
    --viz-growth-bg: #f7f1c3;
    --tone-good: #006300;
    --tone-bad: #d03b3b;

    --sidebar-width: 16rem;
    --sidebar-width-icon: 4.5rem;
    --sidebar-width-mobile: 18rem;
    --font-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

    /* Type scale. Named steps for the font-sizes already in use across the file, so new/edited
       rules reference a step instead of a fresh magic number. Screen UI only — the printable
       documents' letterhead/table typography (.nl-print-*) is tuned for paper and stays literal. */
    --text-2xs: 0.625rem;
    --text-xs: 0.75rem;
    --text-sm: 0.8125rem;
    --text-base: 0.875rem;
    --text-md: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;

    /* Spacing scale (4px steps), for new/edited gap and padding rules. */
    --space-1: 0.25rem;
    --space-2: 0.5rem;
    --space-3: 0.75rem;
    --space-4: 1rem;
    --space-5: 1.25rem;
    --space-6: 1.5rem;
    --space-7: 1.75rem;
    --space-8: 2rem;

    /* Elevation scale, consolidating the box-shadow values already repeated across the file. */
    --shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
    --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05), 0 0 0 1px color-mix(in oklab, var(--foreground) 5%, transparent);
    --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1), 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent);
    --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
    /* A 1px outline rendered as a shadow (so it doesn't affect box sizing) — used for Card's and
       similar surfaces' "border". */
    --shadow-ring: 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent);

    --radius-full: 9999px;
    --transition-fast: 150ms;
    --transition-base: 200ms;
}

/* Canonical breakpoints (plain numbers, since custom properties can't be used inside a media
   query condition) — every @media rule in this file should match one of these exactly:
     640px               — toolbar/breadcrumbs/auth-card single-column fallback
     min-width: 768px / max-width: 767px — the sidebar/table/stepper desktop-vs-mobile pair;
                            written this way (not 767.98px) so the two sides stay exact integer
                            complements with no gap or overlap */

.dark {
    --background: oklch(0.145 0 0);
    --foreground: oklch(0.985 0 0);
    --card: oklch(0.205 0 0);
    --card-foreground: oklch(0.985 0 0);
    --popover: oklch(0.205 0 0);
    --popover-foreground: oklch(0.985 0 0);
    --primary: oklch(0.696 0.155 163);
    --primary-foreground: oklch(0.145 0 0);
    --secondary: oklch(0.269 0 0);
    --secondary-foreground: oklch(0.985 0 0);
    --muted: oklch(0.269 0 0);
    --muted-foreground: oklch(0.708 0 0);
    --accent: oklch(0.269 0 0);
    --accent-foreground: oklch(0.985 0 0);
    --destructive: oklch(0.704 0.191 22.216);
    --destructive-foreground: oklch(0.145 0 0);
    --success: oklch(0.72 0.17 145);
    --success-foreground: oklch(0.145 0 0);
    --border: oklch(1 0 0 / 10%);
    --input: oklch(1 0 0 / 15%);
    --ring: oklch(0.696 0.155 163);
    --sidebar: oklch(0.145 0 0);
    --sidebar-foreground: oklch(0.985 0 0);
    --sidebar-primary: oklch(0.696 0.155 163);
    --sidebar-primary-foreground: oklch(0.145 0 0);
    --sidebar-accent: oklch(0.3 0.09 163);
    --sidebar-accent-foreground: oklch(0.88 0.12 163);
    --sidebar-border: oklch(1 0 0 / 10%);
    --sidebar-ring: oklch(0.696 0.155 163);
    --table-row: oklch(0.88 0.05 163);

    --viz-1: #3987e5;
    --viz-2: #d95926;
    --viz-3: #199e70;
    --viz-4: #c98500;
    --viz-5: #d55181;
    --viz-6: #008300;
    --viz-critical: #e66767;
    --viz-warning: #fab219;
    --viz-good: #0ca30c;
    --viz-grid: #2c2c2a;
    --viz-muted: #898781;
    --viz-growth-bg: #3a3016;
    --tone-good: #0ca30c;
    --tone-bad: #e66767;
}

/* ---------------------------------------------------------------- Base */

*, *::before, *::after {
    box-sizing: border-box;
    border: 0 solid var(--border);
}

html {
    height: 100%;
    font-family: var(--font-sans);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    color-scheme: light;
}

html.dark { color-scheme: dark; }

html body {
    margin: 0;
    min-height: 100%;
    background: var(--background);
    color: var(--foreground);
    font-family: var(--font-sans);
    font-size: var(--text-md);
    line-height: 1.5;
}

h1, h2, h3, h4, p { margin: 0; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; padding: 0; }
:focus-visible { outline: 2px solid color-mix(in oklab, var(--ring) 50%, transparent); outline-offset: 2px; }
/* Blazor focuses the page heading after navigation (FocusOnNavigate) for screen readers; no visible ring. */
h1[tabindex="-1"]:focus, h1:focus { outline: none; }
.tabular-nums { font-variant-numeric: tabular-nums; }
.text-muted { color: var(--muted-foreground); }
.text-destructive { color: var(--destructive); }
.ml-auto { margin-left: auto; }
.self-end { align-self: flex-end; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; }

.nl-icon { display: inline-block; flex-shrink: 0; width: 1rem; height: 1rem; }

/* ---------------------------------------------------------------- App shell */

.nl-app {
    display: flex;
    width: 100%;
    min-height: 100svh;
}

.nl-sidebar-gap {
    flex-shrink: 0;
    width: var(--sidebar-width);
    transition: width var(--transition-base) linear;
}

.nl-sidebar {
    position: fixed;
    inset-block: 0;
    left: 0;
    z-index: 10;
    display: flex;
    flex-direction: column;
    width: var(--sidebar-width);
    height: 100svh;
    background: var(--sidebar);
    color: var(--sidebar-foreground);
    border-right: 1px solid var(--sidebar-border);
    transition: width var(--transition-base) linear, transform var(--transition-base) ease;
}

.nl-sidebar__header { padding: 0.75rem; }

.nl-sidebar__brand-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding-inline: 0.25rem;
}

.nl-sidebar__brand {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-width: 0;
}

.nl-sidebar__brand img { width: 2rem; height: 2rem; flex-shrink: 0; }
.nl-sidebar__brand span { font-size: var(--text-base); line-height: 1.25rem; font-weight: 600; letter-spacing: -0.025em; }

.nl-collapse-btn {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border: 1px solid var(--sidebar-border);
    border-radius: var(--radius);
    background: var(--background);
    color: color-mix(in oklab, var(--sidebar-foreground) 70%, transparent);
    box-shadow: var(--shadow-xs);
}

.nl-collapse-btn:hover { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-collapse-btn .nl-icon { width: 0.875rem; height: 0.875rem; }

.nl-collapse-btn--rail {
    position: absolute;
    top: 1rem;
    right: 0;
    z-index: 20;
    display: none;
    transform: translateX(50%);
}

.nl-sidebar__content {
    display: flex;
    flex: 1;
    flex-direction: column;
    min-height: 0;
    overflow: auto;
}

.nl-nav-group {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    min-width: 0;
    padding: 0.5rem;
}

.nl-nav-group__label {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    height: 2rem;
    padding-inline: 0.5rem;
    border-radius: var(--radius);
    font-size: var(--text-xs);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.025em;
    color: color-mix(in oklab, var(--sidebar-foreground) 40%, transparent);
}

.nl-nav-group__label .is-short { display: none; }

.nl-nav-menu { display: flex; flex-direction: column; width: 100%; min-width: 0; margin: 0; padding: 0; list-style: none; }
.nl-nav-menu li { position: relative; }

.nl-nav-link {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    height: 2rem;
    padding: 0.5rem;
    overflow: hidden;
    border-radius: var(--radius);
    font-size: var(--text-base);
    line-height: 1.25rem;
    text-align: left;
    color: color-mix(in oklab, var(--sidebar-foreground) 55%, transparent);
    transition: width var(--transition-base), height var(--transition-base), padding var(--transition-base);
}

.nl-nav-link .nl-icon { width: 18px; height: 18px; }
.nl-nav-link span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-nav-link:hover,
.nl-nav-link.is-active { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-nav-link.is-active { font-weight: 500; }

.nl-sidebar__footer {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 0.75rem;
}

.nl-theme-toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding-inline: 0.25rem;
}

.nl-theme-toggle__label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--text-xs);
    line-height: 1rem;
    color: var(--muted-foreground);
}

.nl-theme-toggle__label .nl-icon { width: 0.875rem; height: 0.875rem; }
.nl-theme-toggle .is-dark-icon,
html.dark .nl-theme-toggle .is-light-icon { display: none; }
html.dark .nl-theme-toggle .is-dark-icon { display: inline-block; }

.nl-user-card {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem;
    border-radius: var(--radius);
    transition: background-color var(--transition-fast);
}

.nl-user-card:hover { background: var(--muted); }

.nl-user-card__text { min-width: 0; }
/* The sidebar's own dark green (--sidebar-accent-foreground doubles as "active link" text and
   "this is the signed-in user" text) — already the right shade for light and dark mode alike. */
.nl-user-card__name { font-size: var(--text-sm); line-height: 1.1rem; font-weight: 700; color: var(--sidebar-accent-foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-user-card__role { font-size: var(--text-2xs); color: var(--muted-foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Collapsed (icon) sidebar — desktop only; nelms.js sets the class on <html>. */
@media (min-width: 768px) {
    html.sidebar-collapsed .nl-sidebar-gap,
    html.sidebar-collapsed .nl-sidebar { width: var(--sidebar-width-icon); }
    html.sidebar-collapsed .nl-sidebar__header { padding-inline: 0.5rem; }
    html.sidebar-collapsed .nl-sidebar__brand-row { justify-content: center; gap: 0.25rem; padding-inline: 0; }
    html.sidebar-collapsed .nl-sidebar__brand span,
    html.sidebar-collapsed .nl-collapse-btn--docked,
    html.sidebar-collapsed .nl-nav-group__label .is-full,
    html.sidebar-collapsed .nl-nav-link span,
    html.sidebar-collapsed .nl-theme-toggle__label,
    html.sidebar-collapsed .nl-user-card__text,
    html.sidebar-collapsed .nl-logout span { display: none; }
    html.sidebar-collapsed .nl-collapse-btn--rail { display: flex; }
    html.sidebar-collapsed .nl-sidebar__content { overflow: hidden; }
    html.sidebar-collapsed .nl-nav-group__label { justify-content: center; padding-inline: 0; }
    html.sidebar-collapsed .nl-nav-group__label .is-short { display: inline; }
    html.sidebar-collapsed .nl-nav-menu li { display: flex; justify-content: center; }
    html.sidebar-collapsed .nl-nav-link { width: 2rem; padding: 0.5rem; }
    html.sidebar-collapsed .nl-theme-toggle { justify-content: center; padding-inline: 0; }
    html.sidebar-collapsed .nl-user-card { justify-content: center; padding: 0; border: 0; }
    html.sidebar-collapsed .nl-logout { justify-content: center; padding-inline: 0; }
    .nl-sidebar-backdrop { display: none; }
}

/* Mobile: the sidebar becomes an off-canvas sheet. */
@media (max-width: 767px) {
    .nl-sidebar-gap { display: none; }
    .nl-sidebar { z-index: 50; width: var(--sidebar-width-mobile); transform: translateX(-100%); }
    .nl-collapse-btn { display: none !important; }
    html.sidebar-open .nl-sidebar { transform: translateX(0); box-shadow: var(--shadow-lg); }
    .nl-sidebar-backdrop { position: fixed; inset: 0; z-index: 40; display: none; background: rgb(0 0 0 / 0.1); }
    html.sidebar-open .nl-sidebar-backdrop { display: block; }
}

.nl-inset {
    position: relative;
    display: flex;
    flex: 1;
    flex-direction: column;
    width: 100%;
    min-width: 0;
    height: 100svh;
    overflow: hidden;
    background: var(--background);
}

.nl-topbar {
    position: sticky;
    top: 0;
    z-index: 30;
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.5rem;
    height: 3.5rem;
    padding-inline: 1rem;
    border-bottom: 1px solid var(--border);
    background: var(--background);
}

.nl-topbar__title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-base); line-height: 1.25rem; color: var(--muted-foreground); }
.nl-topbar__center {
    flex-shrink: 0;
    padding: 0.125rem 0.625rem;
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--primary) 12%, transparent);
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--primary);
    text-transform: uppercase;
    letter-spacing: 0.02em;
    white-space: nowrap;
}
.nl-topbar__end { margin-left: auto; display: flex; align-items: center; gap: 0.75rem; }
.nl-separator-v { width: 1px; height: 1rem; flex-shrink: 0; background: var(--border); }
.nl-separator { height: 1px; width: 100%; flex-shrink: 0; background: var(--border); }

.nl-content {
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1.5rem;
    overflow-y: auto;
    background: color-mix(in oklab, var(--muted) 30%, transparent);
}

/* Breadcrumbs.razor: Dashboard / Group / Page [/ detail], above the page's own header. Pulled
   closer to the content below it than the surrounding .nl-content gap would otherwise leave. */
.nl-breadcrumbs { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375rem; margin-bottom: -0.75rem; font-size: var(--text-sm); }
.nl-breadcrumbs a { color: var(--muted-foreground); text-decoration: none; }
.nl-breadcrumbs a:hover { color: var(--foreground); text-decoration: underline; }
.nl-breadcrumbs span[aria-current] { color: var(--primary); font-weight: 700; }
.nl-breadcrumbs .nl-icon { width: 0.875rem; height: 0.875rem; color: var(--muted-foreground); flex-shrink: 0; }

/* Phone-width fallback for the full trail above: just a "back to parent" link, so wayfinding
   doesn't disappear entirely on narrow screens. */
.nl-breadcrumbs-back { display: none; align-items: center; gap: 0.25rem; margin-bottom: -0.75rem; font-size: var(--text-sm); color: var(--muted-foreground); text-decoration: none; }
.nl-breadcrumbs-back:hover { color: var(--foreground); text-decoration: underline; }
.nl-breadcrumbs-back .nl-icon { width: 0.875rem; height: 0.875rem; flex-shrink: 0; }
@media (max-width: 640px) {
    .nl-breadcrumbs { display: none; }
    .nl-breadcrumbs-back { display: flex; }
}

/* ---------------------------------------------------------------- Button */

.nl-btn {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    height: 2rem;
    padding-inline: 0.625rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background-clip: padding-box;
    font-size: var(--text-base);
    line-height: 1.25rem;
    font-weight: 500;
    white-space: nowrap;
    user-select: none;
    transition: all var(--transition-fast);
}

.nl-btn:active:not(:disabled) { transform: translateY(1px); }
.nl-btn:disabled, .nl-btn[aria-disabled="true"] { pointer-events: none; opacity: 0.5; }
.nl-btn:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

/* Loading: the trailing icon slot is reused for a spinner, so the button's width doesn't jump. */
.nl-btn .nl-spin { animation: nl-spin 0.8s linear infinite; }
@keyframes nl-spin { to { transform: rotate(360deg); } }

.nl-btn--default { background: var(--primary); color: var(--primary-foreground); }
.nl-btn--default:hover { background: color-mix(in oklab, var(--primary) 80%, transparent); }
.nl-btn--outline { border-color: var(--border); background: var(--background); }
.nl-btn--outline:hover { background: var(--muted); }
.nl-btn--secondary { background: var(--secondary); color: var(--secondary-foreground); }
.nl-btn--secondary:hover { background: color-mix(in oklch, var(--secondary), var(--foreground) 5%); }
.nl-btn--ghost:hover { background: var(--muted); color: var(--foreground); }
.nl-btn--destructive { background: var(--destructive); color: var(--destructive-foreground); }
.nl-btn--destructive:hover { background: color-mix(in oklab, var(--destructive) 85%, transparent); }
.nl-btn--success { background: var(--success); color: var(--success-foreground); }
.nl-btn--success:hover { background: color-mix(in oklab, var(--success) 85%, transparent); }
.nl-btn--link { color: var(--primary); text-underline-offset: 4px; }
.nl-btn--link:hover { text-decoration: underline; }

.nl-btn--xs { height: 1.5rem; gap: 0.25rem; padding-inline: 0.5rem; font-size: var(--text-xs); }
.nl-btn--xs .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-btn--sm { height: 1.75rem; gap: 0.25rem; padding-inline: 0.625rem; font-size: var(--text-sm); }
.nl-btn--sm .nl-icon { width: 0.875rem; height: 0.875rem; }
.nl-btn--lg { height: 2.25rem; }
.nl-btn--xl { height: 2.75rem; padding-inline: 1rem; }
.nl-btn--icon { width: 2rem; padding: 0; }
.nl-btn--icon-xs { width: 1.5rem; height: 1.5rem; padding: 0; }
.nl-btn--icon-sm { width: 1.75rem; height: 1.75rem; padding: 0; }
.nl-btn--icon-lg { width: 2.25rem; height: 2.25rem; padding: 0; }
.nl-btn--block { width: 100%; justify-content: flex-start; }

.nl-logout { width: 100%; justify-content: flex-start; gap: 0.5rem; padding-inline: 0.5rem; color: var(--muted-foreground); }

/* Icon button whose label stays hidden until hover/focus, with a persistent fill and no border —
   e.g. AssessmentDetails.razor's "Download" trigger, a single low-emphasis action that shouldn't
   compete with the page's real buttons at rest. Same highlight as the sidebar's active/hovered
   nav link (.nl-nav-link), so these read as the same "selected chip" pattern. */
.nl-btn--reveal { gap: 0; border-color: transparent; background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-btn--reveal:hover { background: color-mix(in oklab, var(--sidebar-accent), var(--foreground) 6%); }
.nl-btn--reveal .nl-btn__reveal-text {
    display: inline-block;
    max-width: 0;
    margin-inline-start: 0;
    overflow: hidden;
    opacity: 0;
    white-space: nowrap;
    transition: max-width var(--transition-fast), margin-inline-start var(--transition-fast), opacity var(--transition-fast);
}
.nl-btn--reveal:hover .nl-btn__reveal-text,
.nl-btn--reveal:focus-visible .nl-btn__reveal-text {
    max-width: 6rem;
    margin-inline-start: 0.375rem;
    opacity: 1;
}

/* ---------------------------------------------------------------- Badge */

.nl-badge {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    width: fit-content;
    height: 1.25rem;
    padding: 0.125rem 0.5rem;
    overflow: hidden;
    border: 1px solid transparent;
    border-radius: var(--radius);
    font-size: var(--text-xs);
    line-height: 1rem;
    font-weight: 500;
    white-space: nowrap;
}

.nl-badge .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-badge--default { background: var(--primary); color: var(--primary-foreground); }
.nl-badge--secondary { background: var(--secondary); color: var(--secondary-foreground); }
/* Deliberately a tint, not solid like Button's destructive: this badge is used as a repeated
   inline "flagged" chip across dense tables/cards (AssessmentRecord, Assessments, ChildDetail),
   where a loud solid red at every occurrence would overwhelm the row rather than just flag it. */
.nl-badge--destructive { background: color-mix(in oklab, var(--destructive) 10%, transparent); color: var(--destructive); }
.nl-badge--outline { border-color: var(--border); color: var(--foreground); }

/* Dot mode: a data-grid status chip reads as colored text with a small square swatch instead of
   a filled pill — quieter across a column of repeated rows, where a dozen solid pills compete for
   attention more than the row's own data does. */
.nl-badge--dot { height: auto; padding: 0; border: none; background: none; gap: 0.4rem; }
.nl-badge__dot { width: 0.5rem; height: 0.5rem; flex-shrink: 0; border-radius: 2px; background: currentColor; }
.nl-badge--dot.nl-badge--default { color: var(--primary); }
.nl-badge--dot.nl-badge--secondary { color: var(--muted-foreground); }
.nl-badge--dot.nl-badge--destructive { color: var(--destructive); }
.nl-badge--dot.nl-badge--outline { color: var(--foreground); }

/* ---------------------------------------------------------------- Card */

.nl-card {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    padding-block: 1rem;
    border: 1px solid color-mix(in oklab, var(--foreground) 10%, transparent);
    border-radius: var(--radius);
    background: var(--card);
    color: var(--card-foreground);
    font-size: var(--text-base);
    line-height: 1.25rem;
}

.nl-card__header { display: grid; gap: 0.25rem; padding-inline: 1rem; }
.nl-card__header--action { grid-template-columns: 1fr auto; align-items: start; }
.nl-card__title { font-size: var(--text-md); line-height: 1.375; font-weight: 500; }
.nl-card__description { font-size: var(--text-base); color: var(--muted-foreground); }
.nl-card__content { padding-inline: 1rem; }

.nl-stat-card { gap: 0.75rem; }
.nl-stat-card .nl-card__content { display: flex; align-items: center; gap: 0.75rem; }
.nl-stat-card__icon { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: 2.25rem; height: 2.25rem; border-radius: var(--radius); background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); }
.nl-stat-card__icon .nl-icon { width: 1.125rem; height: 1.125rem; }
.nl-stat-card__label { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-stat-card__value { font-size: var(--text-xl); line-height: 1.75rem; font-weight: 600; font-variant-numeric: tabular-nums; }

.nl-kpi { gap: 0.25rem; }
.nl-kpi__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.nl-kpi__label { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); }
.nl-kpi__icon { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: 1.75rem; height: 1.75rem; border-radius: var(--radius); background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); }
.nl-kpi__icon .nl-icon { width: 1rem; height: 1rem; }
.nl-kpi__value { font-size: var(--text-2xl); line-height: 2rem; font-weight: 600; }
.nl-kpi__value small { margin-left: 0.25rem; font-size: var(--text-md); font-weight: 400; color: var(--muted-foreground); }
.nl-kpi__hint { margin-top: 0.125rem; font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); }
/* Period-over-period trend pill: colour (good/bad, set by the caller per metric — an increase
   isn't always good, e.g. the red-flag rate) plus the arrow and the muted comparison label, so
   the meaning never rests on colour alone. */
.nl-kpi__trend { display: flex; align-items: center; gap: 0.25rem; margin-top: 0.125rem; font-size: var(--text-xs); line-height: 1rem; font-weight: 600; color: var(--muted-foreground); }
.nl-kpi__trend .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-kpi__trend.is-good { color: var(--tone-good); }
.nl-kpi__trend.is-bad { color: var(--tone-bad); }
.nl-kpi__trend-label { font-weight: 400; color: var(--muted-foreground); }

/* FamilyHome (Caregiver/Parent dashboard): one card per child, the whole card is a link. */
.nl-family-card { display: block; text-decoration: none; color: inherit; transition: box-shadow var(--transition-fast); }
.nl-family-card:hover, .nl-family-card:focus-visible { box-shadow: 0 0 0 2px var(--ring); outline: none; }
.nl-family-card .nl-card__content { display: flex; flex-direction: column; gap: 0.75rem; }
.nl-family-card__head { display: flex; align-items: center; gap: 0.75rem; }
.nl-family-card__name { font-weight: 600; }
.nl-family-card__age { font-size: var(--text-sm); color: var(--muted-foreground); }
.nl-kpi__hint.is-good { color: var(--tone-good); }
.nl-kpi__hint.is-bad { color: var(--tone-bad); }

.nl-empty { padding-block: 2rem; text-align: center; font-size: var(--text-base); color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Page header */

.nl-page-header { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; }
.nl-page-header__titles { display: flex; align-items: baseline; gap: 0.5rem; }
.nl-page-header__actions { display: flex; align-items: center; gap: 0.5rem; }
.nl-page-header h1 { font-size: var(--text-3xl); line-height: 2.25rem; font-weight: 700; letter-spacing: -0.025em; }
.nl-page-header__count { font-size: var(--text-xs); line-height: 1rem; font-weight: 500; color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Filter pills */

.nl-pills {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    width: fit-content;
    padding: 0.25rem;
    border-radius: var(--radius);
    background: var(--muted);
}

.nl-pills > * + * { border-left: 2px solid var(--border); }

.nl-pill {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    font-size: var(--text-base);
    line-height: 1.25rem;
    font-weight: 500;
    color: color-mix(in oklab, var(--foreground) 70%, transparent);
    transition: color var(--transition-fast), background-color var(--transition-fast);
}

.nl-pill:hover { color: var(--foreground); }
.nl-pill.is-active { border-radius: var(--radius); background: var(--primary); font-weight: 600; color: var(--primary-foreground); }
.nl-pill__count { padding: 0.125rem 0.5rem; border-radius: var(--radius); background: var(--background); font-size: var(--text-xs); line-height: 1rem; font-weight: 600; color: var(--muted-foreground); }
.nl-pill.is-active .nl-pill__count { background: color-mix(in oklab, var(--primary-foreground) 25%, transparent); color: var(--primary-foreground); }

/* FilterToggleGroup: discrete outlined chips (used inside filter panels), not a joined bar. */
.nl-toggle-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.nl-toggle {
    padding: 0.4375rem 0.875rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    background: var(--background);
    font-size: var(--text-sm);
    line-height: 1rem;
    font-weight: 500;
    color: var(--foreground);
    transition: background-color var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}
.nl-toggle:hover { background: var(--accent); border-color: color-mix(in oklab, var(--foreground) 25%, transparent); }
.nl-toggle.is-active { background: var(--primary); border-color: var(--primary); font-weight: 600; color: var(--primary-foreground); }
.nl-toggle:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

/* ---------------------------------------------------------------- Tabs */

.nl-tabs { display: flex; align-items: center; gap: 1.5rem; border-bottom: 1px solid var(--border); }

.nl-tab {
    padding: 0.625rem 0.125rem;
    border-bottom: 2px solid transparent;
    font-size: var(--text-base);
    line-height: 1.25rem;
    font-weight: 500;
    color: var(--muted-foreground);
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.nl-tab:hover { color: var(--foreground); }
.nl-tab.is-active { border-bottom-color: var(--primary); font-weight: 600; color: var(--foreground); }

/* ---------------------------------------------------------------- Table toolbar */

.nl-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1.25rem; }

.nl-search {
    display: flex;
    flex: 0 1 18rem;
    align-items: center;
    gap: 0.5rem;
    min-width: 10rem;
    padding-inline: 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--muted);
    transition: all var(--transition-fast);
}

.nl-search:focus-within { border-color: var(--ring); background: var(--background); box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 15%, transparent); }
.nl-search .nl-icon { color: var(--muted-foreground); }
.nl-search input { flex: 1; min-width: 0; height: 2.75rem; padding: 0; border: 0; outline: none; background: transparent; font-size: var(--text-base); }
.nl-search input::placeholder { color: var(--muted-foreground); }

.nl-filters-btn {
    display: none;
    flex-shrink: 0;
    align-items: center;
    gap: 0.75rem;
    min-width: 20rem;
    height: 2.75rem;
    padding-inline: 1.25rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--muted);
    font-size: 0.9375rem;
    font-weight: 500;
    transition: background-color var(--transition-fast);
}

.nl-filters-btn:hover { background: color-mix(in oklab, var(--muted), var(--foreground) 3%); }
.nl-filters-btn { cursor: pointer; }
.nl-filters-btn:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

/* Same treatment .nl-search gets on focus-within: while the panel is open, and — unlike the search
   box — persisting for as long as any filter is still active, not just while open/focused. */
.nl-dropdown[open] > .nl-filters-btn,
.nl-filters-btn.has-active-filters {
    border-color: var(--ring);
    background: var(--background);
    box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 15%, transparent);
}
.nl-filters-btn .nl-icon { color: var(--muted-foreground); width: 1.125rem; height: 1.125rem; }
.nl-filters-btn__divider { width: 1px; height: 1rem; flex-shrink: 0; background: var(--border); }
.nl-filters-btn__text { flex: 1; text-align: left; }
.nl-filters-btn__count { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; min-width: 1rem; height: 1rem; padding-inline: 0.25rem; border-radius: var(--radius-full); background: var(--primary); color: var(--primary-foreground); font-size: var(--text-2xs); font-weight: 600; font-variant-numeric: tabular-nums; }
.nl-filters-btn .nl-filters-btn__chevron { width: 0.875rem; height: 0.875rem; flex-shrink: 0; }
@media (min-width: 640px) { .nl-filters-btn { display: flex; } }

/* The chips live inside the Filters bar itself, between the divider and the count badge, not
   beside it — see FilterChip.razor. Single line, scrolling horizontally rather than wrapping, so
   the bar's height never grows past the search box's height no matter how many filters are active. */
.nl-filters-btn__chips { display: flex; flex: 1; flex-wrap: nowrap; align-items: center; gap: 0.375rem; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.nl-filters-btn__chips::-webkit-scrollbar { display: none; }

.nl-filter-panel { display: flex; flex-direction: column; gap: 1.25rem; min-width: 22rem; max-width: 28rem; }
/* .nl-menu (below) sets its own 0.25rem padding on this same element and comes later in the
   cascade, so it would otherwise win at equal specificity — the combined selector here outranks it
   regardless of source order. */
.nl-menu.nl-filter-panel { padding: 2rem; }
.nl-filter-panel .nl-field-grid { gap: 0.875rem; }
.nl-filter-panel__row { display: flex; align-items: center; gap: 0.75rem; }
.nl-filter-panel__row > * { flex: 1; min-width: 0; }
.nl-filter-panel__actions { display: flex; justify-content: flex-end; padding-top: 0.625rem; border-top: 1px solid var(--border); }

.nl-filter-chip {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.375rem;
    height: 2rem;
    padding-inline: 0.75rem 0.5rem;
    border-radius: var(--radius-full);
    background: color-mix(in oklab, var(--primary) 10%, transparent);
    color: var(--primary);
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
}
.nl-filter-chip__remove { display: inline-flex; align-items: center; justify-content: center; width: 1.125rem; height: 1.125rem; border-radius: var(--radius-full); color: inherit; }
.nl-filter-chip__remove:hover { background: color-mix(in oklab, var(--primary) 20%, transparent); }
.nl-filter-chip__remove:focus-visible { outline: none; box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 50%, transparent); }
.nl-filter-chip__remove .nl-icon { width: 0.75rem; height: 0.75rem; }

.nl-add-btn .nl-icon { width: 0.875rem; height: 0.875rem; }

/* ---------------------------------------------------------------- Data grid */

.nl-grid { overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius); background: var(--card); }
.nl-grid__scroll { overflow-x: auto; }

.nl-pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.75rem; padding: 0.625rem 1rem; border-top: 1px solid var(--border); font-size: var(--text-base); line-height: 1.25rem; }
.nl-pager__size { display: flex; align-items: center; gap: 1rem; color: var(--muted-foreground); }
.nl-pager__select-wrap { position: relative; display: inline-flex; align-items: center; }
.nl-pager__select { height: 2rem; min-width: 4.5rem; padding: 0 1.75rem 0 0.625rem; border: 1px solid var(--input); border-radius: var(--radius); background: var(--background); color: var(--foreground); font-variant-numeric: tabular-nums; cursor: pointer; appearance: none; -webkit-appearance: none; }
.nl-pager__select-wrap .nl-icon { position: absolute; right: 0.5rem; width: 0.75rem; height: 0.75rem; color: var(--muted-foreground); pointer-events: none; }
.nl-pager__select:focus-visible, .nl-pager__input:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }
.nl-pager__controls { display: flex; align-items: center; gap: 0.25rem; color: var(--muted-foreground); }
.nl-pager__label { padding-inline: 0.25rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
.nl-pager__input { width: 4rem; height: 2rem; padding: 0 0.5rem; border: 1px solid var(--input); border-radius: var(--radius); background: var(--background); color: var(--foreground); font-variant-numeric: tabular-nums; -moz-appearance: textfield; }
.nl-pager__input::-webkit-outer-spin-button, .nl-pager__input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.nl-table { width: 100%; border-collapse: collapse; caption-side: bottom; font-size: var(--text-base); line-height: 1.25rem; }
.nl-table thead tr { border-bottom: 1px solid var(--border); }
.nl-table tbody tr { border-bottom: 1px solid var(--border); transition: background-color var(--transition-fast); }
.nl-table tbody tr:last-child { border-bottom: 0; }
.nl-table tbody tr:hover { background: color-mix(in oklab, var(--muted) 50%, transparent); }
.nl-table tbody tr.is-clickable { cursor: pointer; }
.nl-table tbody tr.is-selected { background: var(--muted); }

.nl-th { height: 2.75rem; padding-inline: 1rem; text-align: left; vertical-align: middle; font-weight: 500; white-space: nowrap; color: var(--muted-foreground); }
.nl-td { padding: 0.75rem 1rem; vertical-align: middle; white-space: nowrap; color: var(--table-row); }
.nl-th--check, .nl-td--check { width: 2.5rem; padding-right: 0; }
.nl-td--muted { color: var(--muted-foreground); }
.nl-td--empty { height: 6rem; text-align: center; color: var(--muted-foreground); }

.nl-tr--skeleton { pointer-events: none; }
.nl-skeleton {
    display: block;
    width: 80%;
    height: 0.875rem;
    border-radius: var(--radius);
    background: var(--muted);
    animation: nl-pulse 1.5s ease-in-out infinite;
}
.nl-skeleton--check { width: 1rem; height: 1rem; }
@keyframes nl-pulse { 50% { opacity: 0.4; } }

/* DetailSkeleton.razor: the same pulsing-bar skeleton as above, shaped like a detail page's own
   PageHeader + Card + field-grid instead of a table's rows. */
.nl-detail-skeleton { display: flex; flex-direction: column; gap: 1.5rem; }
.nl-detail-skeleton__title { width: 10rem; height: 1.75rem; }
.nl-detail-skeleton__action { width: 5.5rem; height: 2rem; margin-left: auto; }
.nl-detail-skeleton__field { display: flex; flex-direction: column; gap: 0.4rem; }
.nl-detail-skeleton__label { width: 35%; height: 0.75rem; }
.nl-detail-skeleton__value { width: 65%; height: 1.1rem; }

/* Below phone width, each row becomes its own card (label : value rows) instead of a row that
   needs horizontal scrolling. Every <td> already carries data-label="<column title>" from
   DataGrid.razor. Interactions (row click, checkboxes, sort) are untouched — this is CSS-only. */
@media (max-width: 640px) {
    .nl-grid { overflow: visible; border: 0; background: transparent; }
    .nl-grid__scroll { overflow-x: visible; }
    .nl-table { border-collapse: collapse; display: block; }
    .nl-table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .nl-table tbody { display: block; }
    .nl-table tbody tr {
        display: block;
        border-radius: var(--radius);
        background: var(--card);
        box-shadow: var(--shadow-ring);
    }
    .nl-table tbody tr + tr { margin-top: 0.75rem; }
    .nl-table tbody tr:hover { background: var(--card); }
    .nl-table td, .nl-table .nl-td--check { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; width: auto; white-space: normal; min-width: 0; border-bottom: 1px solid var(--border); }
    .nl-table tbody tr > td:last-child { border-bottom: 0; }
    .nl-td[data-label]::before { content: attr(data-label); flex-shrink: 0; font-weight: 500; color: var(--muted-foreground); }
    .nl-table td.nl-td--empty { display: block; text-align: center; border: 0; box-shadow: none; background: transparent; }
    .nl-td--empty::before { content: none; }
    .nl-pager { margin-top: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); }
}

.nl-sort { display: flex; align-items: center; gap: 0.25rem; white-space: nowrap; font-weight: inherit; }
.nl-sort:hover, .nl-sort.is-active { color: var(--table-row); }
.nl-sort.is-active { font-weight: 600; }
.nl-sort .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-sort .nl-sort__idle { color: color-mix(in oklab, var(--muted-foreground) 60%, transparent); }

/* ---------------------------------------------------------------- Checkbox & switch */

.nl-checkbox {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border: 1px solid var(--input);
    border-radius: var(--radius);
    background: transparent;
    color: var(--primary-foreground);
    vertical-align: middle;
    transition: box-shadow var(--transition-fast);
}

.nl-checkbox[aria-checked="true"] { border-color: var(--primary); background: var(--primary); }
.nl-checkbox .nl-icon { width: 0.875rem; height: 0.875rem; }
.nl-checkbox:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

.nl-switch {
    position: relative;
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    width: 32px;
    height: 18.4px;
    border: 1px solid transparent;
    border-radius: var(--radius-full);
    background: var(--input);
    transition: background-color var(--transition-fast);
}

.nl-switch:disabled { pointer-events: none; opacity: 0.5; }
.nl-switch:focus-visible { outline: none; border-color: var(--ring); box-shadow: 0 0 0 3px color-mix(in oklab, var(--ring) 50%, transparent); }

.nl-switch__thumb {
    display: block;
    width: 1rem;
    height: 1rem;
    border-radius: var(--radius-full);
    background: var(--background);
    transform: translateX(0);
    transition: transform var(--transition-fast);
    pointer-events: none;
}

.nl-switch[aria-checked="true"] { background: var(--primary); }
.nl-switch[aria-checked="true"] .nl-switch__thumb { transform: translateX(calc(100% - 2px)); }
html.dark .nl-switch__thumb { background: var(--foreground); }
html.dark .nl-switch[aria-checked="true"] .nl-switch__thumb { background: var(--primary-foreground); }

/* The sidebar's theme toggle: a little larger than other switches, and sized so its thumb lands
   exactly flush against both edges (content-box = 2 × thumb width) — a plain translateX(100%)
   reaches it with no fudge factor, unlike .nl-switch above (its track isn't an exact multiple of
   its thumb's width, hence the "- 2px"). Thumb at the left end in light mode, right end in dark —
   driven by html.dark the same way the rest of this toggle already is, not by aria-checked. */
.nl-switch--theme { width: 38px; height: 20.4px; }
.nl-switch--theme .nl-switch__thumb { width: 1.125rem; height: 1.125rem; }
html.dark .nl-switch--theme { background: var(--primary); }
html.dark .nl-switch--theme .nl-switch__thumb { transform: translateX(100%); background: var(--primary-foreground); }

/* ---------------------------------------------------------------- Avatar */

.nl-avatar { display: flex; flex-shrink: 0; align-items: center; justify-content: center; width: 2rem; height: 2rem; border-radius: var(--radius-full); background: var(--sidebar-accent); font-size: var(--text-xs); text-transform: uppercase; color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Dropdown (language switcher) */

.nl-dropdown { position: relative; }
.nl-dropdown > summary { list-style: none; }
.nl-dropdown > summary::-webkit-details-marker { display: none; }

.nl-lang-trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    height: 1.75rem;
    padding-inline: 0.5rem;
    border-radius: var(--radius);
    background: var(--background);
    font-size: var(--text-xs);
    font-weight: 500;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
}

.nl-lang-trigger .nl-icon { width: 0.75rem; height: 0.75rem; color: var(--muted-foreground); }

.nl-menu {
    position: absolute;
    right: 0;
    z-index: 50;
    min-width: 9rem;
    margin-top: 0.25rem;
    padding: 0.25rem;
    border-radius: var(--radius);
    background: var(--popover);
    color: var(--popover-foreground);
    box-shadow: var(--shadow-md);
}

.nl-menu__item { display: flex; align-items: center; gap: 0.5rem; padding: 0.25rem 0.375rem; border-radius: var(--radius); font-size: var(--text-base); line-height: 1.25rem; }
.nl-menu__item:hover { background: var(--accent); color: var(--accent-foreground); }
.nl-menu__code { width: 1.5rem; font-weight: 500; text-transform: uppercase; }
.nl-menu__name { color: var(--muted-foreground); }
.nl-menu__check { margin-left: auto; width: 1rem; height: 1rem; }

/* NotificationsBell.razor: a bell trigger (same shape as .nl-lang-trigger) with a red dot while
   any of the signed-in caregiver/parent's children has an assessment due within 5 days or overdue. */
.nl-bell-trigger {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.75rem;
    height: 1.75rem;
    border-radius: var(--radius);
    background: var(--background);
    cursor: pointer;
    box-shadow: var(--shadow-sm);
}
.nl-bell-trigger .nl-icon { width: 1rem; height: 1rem; color: var(--muted-foreground); }
.nl-bell-dot { position: absolute; top: 0.25rem; right: 0.25rem; width: 0.5rem; height: 0.5rem; border-radius: var(--radius-full); background: var(--destructive); box-shadow: 0 0 0 2px var(--background); }

.nl-notifications { min-width: 18rem; max-width: 22rem; padding: 0.5rem; }
.nl-notifications__heading { padding: 0.25rem 0.375rem; font-size: var(--text-xs); font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; color: var(--muted-foreground); }
.nl-notifications__empty { padding: 0.5rem 0.375rem; font-size: var(--text-base); color: var(--muted-foreground); }
.nl-notifications__item { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.125rem 0.5rem; padding: 0.5rem 0.375rem; border-radius: var(--radius); text-decoration: none; color: inherit; }
.nl-notifications__item:hover { background: var(--accent); color: var(--accent-foreground); }
.nl-notifications__item + .nl-notifications__item { border-top: 1px solid var(--border); }
.nl-notifications__child { flex-basis: 100%; font-weight: 600; font-size: var(--text-base); }
.nl-notifications__label { font-size: var(--text-sm); color: var(--muted-foreground); }
.nl-notifications__label.is-overdue { color: var(--destructive); font-weight: 500; }
.nl-notifications__date { margin-left: auto; font-size: var(--text-xs); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

.nl-export-btn {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.5rem;
    height: 2.75rem;
    padding-inline: 1rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--primary);
    color: var(--primary-foreground);
    font-size: var(--text-base);
    font-weight: 500;
    cursor: pointer;
    transition: background-color var(--transition-fast);
}

.nl-export-btn:hover { background: color-mix(in oklab, var(--primary) 80%, transparent); }
.nl-export-btn .nl-icon { width: 0.875rem; height: 0.875rem; color: var(--primary-foreground); }
.nl-export-btn__chevron { width: 0.75rem; height: 0.75rem; }

.nl-export-menu { width: max-content; min-width: 9rem; padding: 0.25rem 0; overflow: hidden; }
.nl-export-menu .nl-menu__item {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 0;
    border-radius: 0;
    background: none;
    font: inherit;
    font-size: var(--text-sm);
    font-weight: 500;
    color: inherit;
    text-align: left;
    white-space: nowrap;
    cursor: pointer;
}
.nl-export-menu .nl-menu__item + .nl-menu__item { border-top: 1px solid var(--border); }
/* Same highlight the sidebar uses for its active/hovered link, so the two colored file-type icons
   are the only thing that still stands out once an item is highlighted. */
.nl-export-menu .nl-menu__item:hover { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-export-menu .nl-file-icon { width: 1rem; height: 1rem; flex-shrink: 0; }

/* Row actions menu (the "⋯" button in a grid row). */
.nl-row-menu > summary { cursor: pointer; }
.nl-row-menu .nl-menu { text-align: left; }
button.nl-menu__item { width: 100%; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.nl-menu__item .nl-icon { width: 1rem; height: 1rem; color: var(--muted-foreground); }
.nl-menu__item--destructive, .nl-menu__item--destructive .nl-icon { color: var(--destructive); }
/* The grid clips its overflow; let an open row menu show past the table's edge. */
.nl-grid:has(.nl-row-menu[open]),
.nl-grid:has(.nl-row-menu[open]) .nl-grid__scroll { overflow: visible; }

/* ---------------------------------------------------------------- Sheet & dialog */

.nl-overlay {
    position: fixed;
    inset: 0;
    z-index: 50;
    background: rgb(0 0 0 / 0.1);
    backdrop-filter: blur(4px);
    animation: nl-fade-in var(--transition-fast) ease-out;
}

.nl-sheet {
    position: fixed;
    inset-block: 0;
    right: 0;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    width: 75%;
    height: 100%;
    overflow-y: auto;
    border-left: 1px solid var(--border);
    background: var(--background);
    font-size: var(--text-base);
    box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
    animation: nl-slide-in var(--transition-base) ease-out;
}

@media (min-width: 640px) {
    .nl-sheet { max-width: 24rem; }
    .nl-sheet--xl { width: calc(100% - 4rem); max-width: 72rem; }
}

.nl-sheet__close { position: absolute; top: 0.75rem; right: 0.75rem; }
.nl-sheet__heading { display: flex; align-items: flex-start; justify-content: space-between; gap: 0.5rem; }
.nl-sheet__actions { display: flex; flex-shrink: 0; gap: 0.25rem; }
.nl-sheet__header { display: flex; flex-direction: column; gap: 0.125rem; padding: 1rem; padding-right: 3rem; }
.nl-sheet__title { font-size: var(--text-md); font-weight: 500; color: var(--foreground); }
.nl-sheet__description { font-size: var(--text-base); color: var(--muted-foreground); }
.nl-sheet__body { display: flex; flex-direction: column; gap: 1rem; padding: 0 1rem 1rem; }

.nl-dialog {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 50;
    display: grid;
    gap: 1rem;
    width: calc(100% - 2rem);
    max-width: 24rem;
    padding: 1rem;
    overflow: hidden;
    border-radius: var(--radius);
    background: var(--background);
    font-size: var(--text-base);
    transform: translate(-50%, -50%);
    box-shadow: var(--shadow-ring);
    animation: nl-zoom-in var(--transition-fast) ease-out;
}

.nl-dialog__title { font-size: var(--text-md); font-weight: 500; }
.nl-dialog__description { margin-top: 0.375rem; color: var(--muted-foreground); }
.nl-dialog__footer { display: flex; justify-content: flex-end; gap: 0.5rem; margin: 0 -1rem -1rem; padding: 1rem; border-top: 1px solid var(--border); background: color-mix(in oklab, var(--muted) 50%, transparent); }

/* Completion dialog shown when an assessment is finished (AssessmentNew.razor), above the modal
   layer (z-index: 50). Its fireworks canvas (nelms.fireworks in nelms.js) fills the overlay behind
   the card and keeps going until the dialog is closed. */
.nl-fireworks {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.nl-complete-overlay {
    position: fixed;
    inset: 0;
    z-index: 71;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgb(0 0 0 / 0.55);
    animation: nl-fade-in var(--transition-fast) ease-out;
    outline: none;
}

.nl-complete-card {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    max-width: 24rem;
    padding: 2rem;
    border-radius: var(--radius);
    background: var(--background);
    text-align: center;
    box-shadow: var(--shadow-ring);
    animation: nl-zoom-in var(--transition-fast) ease-out;
}

.nl-complete-card .nl-icon { width: 2.5rem; height: 2.5rem; color: var(--primary); }
.nl-complete-card__title { font-size: var(--text-lg); font-weight: 600; }
.nl-complete-card__due { color: var(--muted-foreground); }
.nl-complete-card .nl-complete-card__close { position: absolute; top: 0.5rem; right: 0.5rem; }

/* Overall score block in the completion card. */
.nl-complete-score {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    width: 100%;
    padding: 0.75rem 1rem;
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--primary) 8%, transparent);
}
.nl-complete-score__label { font-size: var(--text-xs); font-weight: 500; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-foreground); }
.nl-complete-score__value { font-size: 2.25rem; line-height: 1.1; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; animation: nl-score-pop 600ms 250ms cubic-bezier(0.34, 1.56, 0.64, 1) both; }
.nl-complete-score__value small { font-size: var(--text-base); font-weight: 500; color: var(--muted-foreground); }
.nl-complete-score__meter { width: 100%; height: 0.5rem; border-radius: 999px; background: color-mix(in oklab, var(--primary) 18%, transparent); overflow: hidden; }
.nl-complete-score__meter > span { display: block; height: 100%; width: var(--score); border-radius: inherit; background: var(--primary); animation: nl-score-fill 900ms 300ms ease-out both; }
.nl-complete-score__total { font-size: var(--text-sm); color: var(--muted-foreground); }
.nl-complete-score__total strong { color: var(--foreground); }

@keyframes nl-score-pop { from { opacity: 0; transform: scale(0.4); } }
@keyframes nl-score-fill { from { width: 0; } }

/* CelebrationMascot: white cartoon with a green outline on a white badge; zooms in and out on its
   own, and jumps with a bigger zoom + speech bubble when tapped. */
.nl-mascot {
    --mascot-green: oklch(0.596 0.145 163);
    position: relative;
    display: grid;
    place-items: center;
    width: 8.5rem;
    height: 8.5rem;
    padding: 0.5rem;
    border: 3px solid var(--mascot-green);
    border-radius: 50%;
    background: #fff;
    cursor: pointer;
    box-shadow: 0 0 0 6px color-mix(in oklab, var(--mascot-green) 15%, transparent);
    animation: nl-mascot-enter 600ms cubic-bezier(0.34, 1.56, 0.64, 1) both,
               nl-mascot-zoom 2.4s 600ms ease-in-out infinite;
    -webkit-tap-highlight-color: transparent;
}
.nl-mascot:focus-visible { outline: 3px solid var(--ring, var(--mascot-green)); outline-offset: 4px; }
.nl-mascot.is-cheer-a { animation: nl-mascot-cheer-a 700ms cubic-bezier(0.34, 1.56, 0.64, 1), nl-mascot-zoom 2.4s 700ms ease-in-out infinite; }
.nl-mascot.is-cheer-b { animation: nl-mascot-cheer-b 700ms cubic-bezier(0.34, 1.56, 0.64, 1), nl-mascot-zoom 2.4s 700ms ease-in-out infinite; }

.nl-mascot__art { width: 100%; height: 100%; overflow: visible; }
.nl-mascot__line { fill: #fff; stroke: var(--mascot-green); stroke-width: 4; stroke-linecap: round; stroke-linejoin: round; }
.nl-mascot__line[fill="none"] { fill: none; }
.nl-mascot__pupil { fill: var(--mascot-green); transition: cx 120ms ease-out, cy 120ms ease-out; }
.nl-mascot__cheek { fill: #fda4af; opacity: 0.7; }
.nl-mascot__shadow { fill: color-mix(in oklab, var(--mascot-green) 20%, transparent); }
.nl-mascot__star { stroke-width: 3.5; }
.nl-mascot__mouth-open { display: none; fill: color-mix(in oklab, var(--mascot-green) 25%, #fff); }

.nl-mascot__arm { transform-box: fill-box; }
.nl-mascot__arm--wave { transform-origin: 100% 100%; animation: nl-mascot-wave 1.2s ease-in-out infinite; }
.nl-mascot__arm--star { transform-origin: 0% 100%; animation: nl-mascot-lift 2.4s ease-in-out infinite; }
.nl-mascot:hover .nl-mascot__arm--wave { animation-duration: 0.5s; }
.nl-mascot__eyes { transform-box: fill-box; transform-origin: center; animation: nl-mascot-blink 4s infinite; }
.nl-mascot__sparkles { transform-box: fill-box; transform-origin: center; animation: nl-mascot-twinkle 1.6s ease-in-out infinite; }

/* Cheering: open mouth, faster wave, jump. */
.nl-mascot:is(.is-cheer-a, .is-cheer-b) .nl-mascot__smile { display: none; }
.nl-mascot:is(.is-cheer-a, .is-cheer-b) .nl-mascot__mouth-open { display: inline; }
.nl-mascot:is(.is-cheer-a, .is-cheer-b) .nl-mascot__body { animation: nl-mascot-jump 700ms ease-out; }

.nl-mascot__bubble {
    position: absolute;
    bottom: calc(100% - 0.25rem);
    left: 60%;
    z-index: 1;
    padding: 0.25rem 0.625rem;
    border: 2px solid var(--mascot-green);
    border-radius: 999px 999px 999px 0.25rem;
    background: #fff;
    color: var(--mascot-green);
    font-size: var(--text-sm);
    font-weight: 700;
    white-space: nowrap;
    animation: nl-mascot-bubble 1.8s ease-out both;
    pointer-events: none;
}

@keyframes nl-mascot-enter { from { opacity: 0; transform: scale(0.2) rotate(-12deg); } }
@keyframes nl-mascot-zoom { 0%, 100% { transform: scale(0.94); } 50% { transform: scale(1.08); } }
@keyframes nl-mascot-cheer-a { 0% { transform: scale(1); } 35% { transform: scale(1.28) rotate(-6deg); } 65% { transform: scale(0.9) rotate(4deg); } 100% { transform: scale(0.94); } }
@keyframes nl-mascot-cheer-b { 0% { transform: scale(1); } 35% { transform: scale(1.28) rotate(6deg); } 65% { transform: scale(0.9) rotate(-4deg); } 100% { transform: scale(0.94); } }
@keyframes nl-mascot-jump { 40% { transform: translateY(-14px); } 70% { transform: translateY(2px); } }
@keyframes nl-mascot-wave { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(-22deg); } }
@keyframes nl-mascot-lift { 0%, 100% { transform: rotate(0deg); } 50% { transform: rotate(8deg); } }
@keyframes nl-mascot-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(0.1); } }
@keyframes nl-mascot-twinkle { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.4; transform: scale(0.85); } }
@keyframes nl-mascot-bubble { 0% { opacity: 0; transform: scale(0.3); } 15% { opacity: 1; transform: scale(1.1); } 25% { transform: scale(1); } 80% { opacity: 1; } 100% { opacity: 0; transform: translateY(-6px); } }

@media (prefers-reduced-motion: reduce) {
    .nl-mascot, .nl-mascot *, .nl-complete-score__value, .nl-complete-score__meter > span { animation-duration: 1ms !important; animation-iteration-count: 1 !important; }
}
.nl-complete-card .nl-complete-card__close .nl-icon { width: 1rem; height: 1rem; color: inherit; }

.nl-field__label { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); }
.nl-field__value { font-size: var(--text-base); line-height: 1.25rem; font-weight: 500; }
.nl-field-grid { display: grid; grid-template-columns: 1fr; gap: 0.75rem; }
@media (min-width: 640px) { .nl-field-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.nl-primary-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    height: 2.5rem;
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--primary) 10%, transparent);
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--primary);
}

.nl-info-note {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.75rem;
    border-radius: var(--radius);
    background: color-mix(in oklab, var(--primary) 10%, transparent);
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--primary);
}

.nl-primary-link:hover { background: color-mix(in oklab, var(--primary) 20%, transparent); }

.nl-list-row { display: flex; align-items: center; justify-content: space-between; padding: 0.5rem 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); font-size: var(--text-base); }

@keyframes nl-fade-in { from { opacity: 0; } }
@keyframes nl-slide-in { from { transform: translateX(100%); } }
@keyframes nl-zoom-in { from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); } }

/* ---------------------------------------------------------------- Layout helpers */

.nl-stack { display: flex; flex-direction: column; gap: 1.5rem; }
.nl-stack--sm { gap: 1rem; }
.nl-stack--xs { gap: 0.5rem; }
.nl-grid-2, .nl-grid-kpi { display: grid; gap: 1rem; }
@media (min-width: 640px) { .nl-grid-kpi { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) {
    .nl-grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .nl-grid-kpi { grid-template-columns: repeat(5, minmax(0, 1fr)); }
}

/* ---------------------------------------------------------------- Charts */

.nl-chart { position: relative; width: 100%; font-size: var(--text-2xs); color: var(--viz-muted); }

.nl-legend { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.25rem 1rem; margin-top: 0.75rem; font-size: var(--text-xs); color: var(--foreground); }
.nl-legend__item { display: flex; align-items: center; gap: 0.375rem; }
.nl-legend__swatch { width: 0.625rem; height: 0.625rem; flex-shrink: 0; border-radius: 2px; }

/* Shared plot frame: y-axis labels on the left, gridlines across the plot. */
.nl-plot { position: relative; display: grid; grid-template-columns: auto 1fr; }
.nl-plot__y { position: relative; width: 2rem; }
.nl-plot__y span { position: absolute; right: 0.375rem; transform: translateY(-50%); font-variant-numeric: tabular-nums; }
.nl-plot__area { position: relative; }
.nl-plot__grid { position: absolute; left: 0; right: 0; height: 1px; background: var(--viz-grid); }
.nl-plot__x { display: flex; margin-top: 0.375rem; grid-column: 2; }
.nl-plot__x span { flex: 1; min-width: 0; overflow: hidden; text-align: center; text-overflow: ellipsis; white-space: nowrap; }
.nl-plot__x--positioned { position: relative; height: 1rem; }
.nl-plot__x--positioned span { position: absolute; flex: none; overflow: visible; transform: translateX(-50%); }

.nl-columns { position: absolute; inset: 0; display: flex; align-items: flex-end; }
.nl-columns__group { position: relative; display: flex; flex: 1; align-items: flex-end; justify-content: center; gap: 2px; height: 100%; }
.nl-column { position: relative; width: 100%; max-width: 22px; border-radius: 4px 4px 0 0; }
.nl-column:hover { filter: brightness(1.08); }

.nl-tooltip {
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    z-index: 5;
    display: none;
    min-width: 8rem;
    padding: 0.375rem 0.625rem;
    border-radius: var(--radius);
    background: var(--popover);
    color: var(--popover-foreground);
    font-size: var(--text-xs);
    line-height: 1rem;
    white-space: nowrap;
    transform: translateX(-50%);
    pointer-events: none;
    box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent);
}

.nl-tooltip__title { margin-bottom: 0.25rem; font-weight: 500; }
.nl-tooltip__row { display: flex; align-items: center; gap: 0.5rem; }
.nl-tooltip__row b { margin-left: auto; padding-left: 0.75rem; font-weight: 500; font-variant-numeric: tabular-nums; }
.nl-hover:hover > .nl-tooltip { display: block; }
/* Inside a full-height column group, anchor the tooltip to the top of the plot so the card never clips it. */
.nl-tooltip--inside { top: 0; bottom: auto; }
.nl-columns__group.nl-hover:hover { background: color-mix(in oklab, var(--muted) 40%, transparent); }

/* Horizontal bars */
.nl-hbars { display: grid; gap: 0.25rem 0.75rem; align-items: center; }
.nl-hbars__label { overflow: hidden; text-align: right; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-xs); color: var(--foreground); }
.nl-hbars__track { position: relative; height: 1.875rem; display: flex; align-items: center; }
.nl-hbars__bar { position: relative; height: 18px; border-radius: 0 4px 4px 0; }
.nl-hbars__value { margin-left: 0.375rem; font-size: var(--text-xs); color: var(--foreground); font-variant-numeric: tabular-nums; white-space: nowrap; }
.nl-hbars__threshold { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px dashed var(--viz-critical); }
.nl-hbars__gridline { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--viz-grid); }
.nl-hbars__axis { position: relative; height: 1rem; }
.nl-hbars__axis span { position: absolute; transform: translateX(-50%); font-variant-numeric: tabular-nums; }
/* HorizontalBarChart.razor sets its own label-column width inline (LabelWidth, default 150-170px
   on the Dashboard) so a long domain name doesn't wrap — on a phone that alone can eat most of the
   available width, squeezing the bar itself down to a sliver. The label already ellipsis-truncates
   (and keeps the full name in `title`), so narrowing the column here only affects that: the bar
   gets its width back. Only `!important` can win against an inline style. */
@media (max-width: 640px) {
    .nl-hbars { grid-template-columns: 90px 1fr !important; }
}

/* Line chart */
.nl-line svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.nl-line__point { position: absolute; width: 22px; height: 22px; transform: translate(-50%, -50%); }
.nl-line__dot { position: absolute; top: 50%; left: 50%; width: 9px; height: 9px; border-radius: var(--radius-full); box-shadow: 0 0 0 2px var(--card); transform: translate(-50%, -50%); transition: width 100ms, height 100ms; }
.nl-line__point:hover .nl-line__dot { width: 12px; height: 12px; }
.nl-line__threshold { position: absolute; left: 0; right: 0; height: 0; border-top: 1px dashed var(--viz-critical); }
.nl-line__threshold span { position: absolute; right: 0; bottom: 2px; font-size: var(--text-2xs); }

/* TrendCompareChart: a callout pinned open above the current period's latest point (not a
   hover-only .nl-tooltip) showing its value and % change against the previous period. */
.nl-trend-chart__callout {
    position: absolute;
    top: -0.25rem;
    z-index: 5;
    min-width: 7rem;
    padding: 0.375rem 0.625rem;
    border-radius: var(--radius);
    background: var(--popover);
    color: var(--popover-foreground);
    font-size: var(--text-xs);
    line-height: 1.1rem;
    white-space: nowrap;
    pointer-events: none;
    transform: translate(-100%, -100%);
    box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 0 0 1px color-mix(in oklab, var(--foreground) 10%, transparent);
}
.nl-trend-chart__callout-value { font-size: var(--text-md); font-weight: 600; font-variant-numeric: tabular-nums; }
.nl-trend-chart__callout-delta { font-weight: 500; color: var(--muted-foreground); }
.nl-trend-chart__callout-delta.is-good { color: var(--tone-good); }
.nl-trend-chart__callout-delta.is-bad { color: var(--tone-bad); }

/* Growth chart (WHO Child Growth Standards reference band) */
.nl-growth__area { position: relative; grid-column: 2; background: var(--viz-growth-bg); border-radius: 2px; }
.nl-growth__area svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.nl-growth__band { opacity: 0.55; }
.nl-growth__band--severe { fill: var(--viz-critical); }
.nl-growth__band--moderate { fill: var(--viz-growth-bg); }
.nl-growth__band--normal { fill: var(--viz-good); }
.nl-growth__gridline--year { stroke: var(--viz-grid); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
.nl-growth__gridline--month { stroke: var(--viz-grid); stroke-width: 0.5; opacity: 0.6; vector-effect: non-scaling-stroke; }
.nl-plot__y--right span { right: auto; left: 0.375rem; }
.nl-growth__months { height: 0.75rem; margin-top: 0.125rem; }
.nl-growth__months span { font-size: var(--text-2xs); color: var(--viz-muted); }
.nl-growth__x span { font-size: var(--text-2xs); font-weight: 600; }
.nl-growth__legend { display: flex; flex-wrap: wrap; gap: 0.25rem 1rem; margin-top: 0.75rem; font-size: var(--text-xs); color: var(--viz-muted); }
.nl-growth__legend span { display: inline-flex; align-items: center; gap: 0.375rem; }
.nl-growth__swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; }
.nl-growth__swatch--normal { background: var(--viz-good); }
.nl-growth__swatch--moderate { background: var(--viz-growth-bg); }
.nl-growth__swatch--severe { background: var(--viz-critical); }

/* Share bar & ranked list */
.nl-sharebar { display: flex; gap: 2px; width: 100%; height: 1rem; overflow: hidden; border-radius: var(--radius); }
.nl-sharebar > div { height: 100%; }
.nl-share-legend, .nl-ranked { display: flex; flex-direction: column; gap: 0.375rem; margin: 0.75rem 0 0; padding: 0; list-style: none; font-size: var(--text-base); }
.nl-ranked { gap: 0.75rem; margin: 0; }
.nl-share-legend li, .nl-ranked li { display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
.nl-share-legend__name, .nl-ranked__name { display: flex; min-width: 0; align-items: center; gap: 0.5rem; }
.nl-ranked__name span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-share-legend__swatch { width: 0.625rem; height: 0.625rem; flex-shrink: 0; border-radius: 2px; }
.nl-ranked__dot { width: 0.5rem; height: 0.5rem; flex-shrink: 0; border-radius: var(--radius-full); }
.nl-share-legend__value, .nl-ranked__value { flex-shrink: 0; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }

/* Heatmap */
.nl-heatmap { overflow-x: auto; }
.nl-heatmap table { width: 100%; min-width: 640px; border-collapse: separate; border-spacing: 2px; font-size: var(--text-xs); }
.nl-heatmap th { padding: 0.25rem; text-align: center; font-weight: 500; color: var(--muted-foreground); }
.nl-heatmap th:first-child { width: 10rem; padding-inline: 0.5rem; text-align: left; }
.nl-heatmap td:first-child { max-width: 10rem; padding: 0.25rem 0.5rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: var(--text-base); }
.nl-heatmap__cell { padding: 0.375rem 0.25rem; border-radius: var(--radius); text-align: center; font-weight: 500; font-variant-numeric: tabular-nums; }
.nl-heatmap__cell.is-empty { background: color-mix(in oklab, var(--muted) 40%, transparent); color: var(--muted-foreground); }
.nl-heatmap__cell.is-flagged { outline: 2px solid var(--viz-critical); outline-offset: -2px; }
.nl-heatmap__cell span { display: inline-flex; align-items: center; justify-content: center; gap: 0.125rem; }
.nl-heatmap__cell .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-heatmap__legend { margin-top: 0.5rem; font-size: var(--text-xs); color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Blazor framework UI */

#blazor-error-ui {
    position: fixed;
    bottom: 0;
    left: 0;
    z-index: 1000;
    display: none;
    width: 100%;
    padding: 0.6rem 1.25rem 0.7rem;
    background: var(--card);
    color: var(--foreground);
    box-shadow: 0 -1px 2px rgb(0 0 0 / 0.2);
}

#blazor-error-ui .dismiss { position: absolute; top: 0.5rem; right: 0.75rem; cursor: pointer; }
.blazor-error-boundary { padding: 1rem; border-radius: var(--radius); background: color-mix(in oklab, var(--destructive) 10%, transparent); color: var(--destructive); }
.blazor-error-boundary::after { content: "An error has occurred."; }

/* ---------------------------------------------------------------- Dialog (create/edit forms) */

.nl-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    z-index: 50;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    gap: 1rem;
    width: 100%;
    max-width: calc(100% - 2rem);
    max-height: calc(100svh - 2rem);
    padding: 1rem;
    border-radius: var(--radius);
    background: var(--popover);
    color: var(--popover-foreground);
    font-size: var(--text-base);
    line-height: 1.25rem;
    outline: none;
    overflow: hidden;
    transform: translate(-50%, -50%);
    box-shadow: var(--shadow-ring);
    animation: nl-zoom-in 100ms ease-out;
}

@media (min-width: 640px) {
    .nl-modal { max-width: 24rem; }
    .nl-modal--lg { max-width: 32rem; }
    .nl-modal--xl { max-width: 36rem; }
    .nl-modal--2xl { max-width: 42rem; }
    .nl-modal--3xl { max-width: 48rem; }
}

.nl-modal__close { position: absolute; top: 0.5rem; right: 0.5rem; }
.nl-modal__header { flex-shrink: 0; display: flex; flex-direction: column; gap: 0.5rem; padding-right: 2rem; }
.nl-modal__title { font-size: var(--text-md); line-height: 1; font-weight: 500; }
.nl-modal__description { color: var(--muted-foreground); }
.nl-modal__body { display: flex; flex-direction: column; gap: 1rem; min-height: 0; overflow-x: hidden; overflow-y: auto; scrollbar-width: none; }
.nl-modal__body::-webkit-scrollbar { display: none; }

.nl-modal__footer {
    flex-shrink: 0;
    display: flex;
    flex-direction: column-reverse;
    gap: 0.5rem;
    margin: 0 -1rem -1rem;
    padding: 1rem;
    border-top: 1px solid var(--border);
    border-radius: 0 0 var(--radius) var(--radius);
}

@media (min-width: 640px) {
    .nl-modal__footer { flex-direction: row; justify-content: flex-end; padding-right: 1.5rem; }
}

/* DocumentPreviewDialog.razor: a printable document shown in an <iframe>, so it needs real
   height to be worth looking at instead of a cramped scroll box — .nl-modal__body is already the
   grid's minmax(0, 1fr) row, this just has the iframe fill that row rather than its own content size. */
.nl-preview-frame { width: 100%; flex: 1; min-height: 60vh; border: 0; border-radius: var(--radius); background: var(--muted); }

/* ---------------------------------------------------------------- Form controls */

.nl-form-field { display: flex; flex-direction: column; gap: 0.375rem; }
.nl-label { display: flex; align-items: center; gap: 0.25rem; font-size: var(--text-base); line-height: 1; font-weight: 500; user-select: none; }
.nl-required { color: var(--destructive); }
.nl-field-error { font-size: var(--text-xs); line-height: 1rem; color: var(--destructive); }
.nl-field-hint { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); text-align: right; }
.nl-switch-row { display: flex; align-items: center; gap: 0.5rem; }

.nl-input,
.nl-select {
    width: 100%;
    min-width: 0;
    height: 2.5rem;
    padding: 0.25rem 0.625rem;
    border: 1px solid transparent;
    border-radius: var(--radius);
    background: var(--muted);
    color: var(--foreground);
    font-size: var(--text-base);
    outline: none;
    transition: background-color var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.nl-input::placeholder { color: var(--muted-foreground); }
.nl-input:focus-visible,
.nl-select:focus-visible { border-color: var(--ring); background: var(--background); box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 15%, transparent); }
.nl-input[aria-invalid="true"],
.nl-select[aria-invalid="true"] { border-color: var(--destructive); box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }
.nl-input:disabled,
.nl-select:disabled { cursor: not-allowed; opacity: 0.5; }

/* SelectInput.razor: a <details>/<summary> listbox, not a native <select> — its popup can then be
   themed like every other .nl-menu dropdown (ExportMenu, row-action menus), including a hover
   that matches the sidebar's own accent instead of an unthemeable OS popup. */
.nl-select-wrap { position: relative; width: 100%; }
.nl-select-wrap[aria-disabled="true"] { pointer-events: none; opacity: 0.5; }
.nl-select { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; cursor: pointer; }
.nl-select:hover:not(:focus-visible) { background: color-mix(in oklab, var(--muted), var(--foreground) 3%); }
.nl-select.is-placeholder { color: var(--muted-foreground); }
.nl-select__label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nl-select .nl-icon { flex-shrink: 0; color: var(--muted-foreground); }
.nl-select-menu { left: 0; right: 0; width: auto; min-width: 0; max-height: 16rem; overflow-y: auto; }
.nl-select-menu .nl-menu__item { cursor: pointer; }
.nl-select-menu .nl-menu__item.is-selected { font-weight: 600; }
.nl-select-menu .nl-menu__item:hover { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-password { position: relative; display: flex; align-items: center; width: 100%; }
.nl-password .nl-input { padding-right: 2.5rem; }
.nl-password__toggle { position: absolute; right: 0.25rem; display: inline-flex; align-items: center; justify-content: center; width: 2rem; height: 2rem; padding: 0; border: 0; border-radius: calc(var(--radius) - 2px); background: transparent; color: var(--muted-foreground); cursor: pointer; }
.nl-password__toggle:hover { color: var(--foreground); }
.nl-password__toggle:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.nl-password__toggle .nl-icon { width: 1rem; height: 1rem; }
.nl-password__toggle[aria-pressed="false"] .nl-password__hide,
.nl-password__toggle[aria-pressed="true"] .nl-password__show { display: none; }


/* ---- Sign-in pages (Login, SetPassword, Logout) ---- */
.nl-auth { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 1.5rem; background: var(--muted); }
.nl-auth__card { width: 100%; max-width: 24rem; display: flex; flex-direction: column; gap: 1rem; padding: 2rem; background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); border-radius: calc(var(--radius) * 2); }
.nl-auth__brand { display: flex; align-items: center; gap: 0.75rem; font-size: var(--text-sm); font-weight: 600; color: inherit; text-decoration: none; }
.nl-auth__title { font-size: var(--text-xl); line-height: 1.75rem; font-weight: 600; }
.nl-auth__desc { font-size: var(--text-base); color: var(--muted-foreground); }
.nl-auth__form { display: flex; flex-direction: column; gap: 1rem; }
.nl-auth__submit { width: 100%; justify-content: center; }

/* Login landing page: a pure-white card with a thin edge on a very light page. */
.nl-auth--login { background: oklch(0.985 0 0); }
.nl-login { width: 100%; max-width: 30rem; display: flex; flex-direction: column; gap: 1rem; padding: 2rem; background: #fff; color: #0a0a0a; border: 1px solid var(--border); border-radius: calc(var(--radius) * 2); box-shadow: 0 1px 3px rgb(0 0 0 / 6%); }
.nl-login__logo { display: block; width: 100%; max-width: 20rem; height: auto; margin: 0 auto; }
.nl-login__theme { position: absolute; top: 1rem; right: 1rem; }
.nl-login__title { margin-top: 0.5rem; text-align: center; font-size: var(--text-2xl); line-height: 2rem; font-weight: 700; }
.nl-login__subtitle { margin-bottom: 0.75rem; text-align: center; font-size: var(--text-lg); color: var(--muted-foreground); }
.nl-login .nl-input { border-color: var(--primary); background: #fff; }
.nl-login .nl-input:focus-visible { background: #fff; box-shadow: 0 0 0 3px color-mix(in oklab, var(--primary) 25%, transparent); }

/* Dark mode: a black page and a black card; the logo sits on a white plate so its dark-blue lettering stays readable. */
.dark .nl-auth--login { background: #000; }
.dark .nl-login { background: #0a0a0a; color: #fafafa; border-color: oklch(1 0 0 / 15%); box-shadow: none; }
.dark .nl-login .nl-input,
.dark .nl-login .nl-input:focus-visible { background: #0a0a0a; }
.dark .nl-login__logo { max-width: 21rem; padding: 0.75rem 1rem; border-radius: calc(var(--radius) * 2); background: #fff; }

/* ---- User pages ---- */
.nl-field-hint { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); }
.nl-actions { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.nl-actions--row { flex-wrap: nowrap; gap: 0.25rem; }
a.nl-user-card { color: inherit; text-decoration: none; }

.nl-auth__card--wide { max-width: 40rem; }
.nl-auth__section { font-size: 0.9375rem; font-weight: 600; margin-top: 0.5rem; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.nl-auth__alt { font-size: var(--text-base); text-align: center; color: var(--muted-foreground); }
.nl-auth__alt a { color: var(--primary); font-weight: 500; text-decoration: none; }
.nl-auth__alt a:hover { text-decoration: underline; }
@media (max-width: 40rem) { .nl-auth__card--wide .nl-field-grid { grid-template-columns: minmax(0, 1fr); } }
/* ---------------------------------------------------------------- Stepper (multi-step dialogs) */

.nl-stepper { display: flex; align-items: flex-start; list-style: none; margin: 0; padding: 0; }

.nl-stepper__step { display: flex; flex-shrink: 0; flex-direction: column; align-items: center; gap: 0.5rem; }

.nl-stepper__circle {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    border-radius: var(--radius-full);
    background: var(--muted);
    color: var(--muted-foreground);
    font-size: var(--text-base);
    font-weight: 600;
    transition: background-color var(--transition-fast), color var(--transition-fast);
}

.nl-stepper__step.is-active .nl-stepper__circle,
.nl-stepper__step.is-done .nl-stepper__circle { background: var(--primary); color: var(--primary-foreground); }

.nl-stepper__label { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); white-space: nowrap; }
.nl-stepper__step.is-active .nl-stepper__label { color: var(--foreground); font-weight: 600; }

.nl-stepper__connector { flex: 1; height: 1px; min-width: 1rem; margin-top: 1rem; background: var(--border); transition: background-color var(--transition-fast); }
.nl-stepper__connector.is-done { background: var(--primary); }

@media (max-width: 480px) {
    .nl-stepper__label { white-space: normal; max-width: 4rem; text-align: center; font-size: var(--text-2xs); line-height: 0.875rem; }
    .nl-stepper__circle { width: 1.75rem; height: 1.75rem; font-size: var(--text-xs); }
    .nl-stepper__connector { min-width: 0.375rem; margin-top: 0.875rem; }
}

/* Wizards with many steps (e.g. one per domain): steps share the width and long labels wrap, so nothing scrolls sideways. */
.nl-stepper--compact { flex-shrink: 0; padding-bottom: 0.25rem; }
.nl-stepper--compact .nl-stepper__step { flex: 1 1 0; min-width: 0; gap: 0.25rem; padding: 0; border: 0; background: none; font: inherit; color: inherit; text-align: center; }
.nl-stepper--compact button.nl-stepper__step:not(:disabled) { cursor: pointer; }
.nl-stepper--compact .nl-stepper__label { font-size: var(--text-2xs); white-space: normal; text-align: center; line-height: 1.25; overflow-wrap: break-word; }
.nl-stepper--compact .nl-stepper__connector { flex: 0 1 0.5rem; min-width: 0.25rem; margin-top: 0.875rem; }
.nl-stepper--compact .nl-stepper__circle { width: 1.75rem; height: 1.75rem; border: 1px solid var(--border); font-size: var(--text-xs); }
.nl-stepper--compact .nl-stepper__step.is-active .nl-stepper__circle { border-color: var(--primary); }
.nl-stepper--compact .nl-stepper__step.is-red:not(.is-active):not(.is-done) .nl-stepper__circle { border-color: var(--destructive); background: color-mix(in oklab, var(--destructive) 10%, transparent); color: var(--destructive); }
@media (max-width: 767px) {
    .nl-stepper--compact { flex-wrap: wrap; row-gap: 0.5rem; }
    .nl-stepper--compact .nl-stepper__step { flex: 0 0 4.5rem; }
}

/* Too many steps for every label: only the current one is spelled out, the rest keep their title tooltip. */
.nl-stepper--dense .nl-stepper__step:not(.is-active) .nl-stepper__label { display: none; }
.nl-stepper--dense .nl-stepper__step.is-active { flex: 0 0 9rem; }

/* ---------------------------------------------------------------- Assessment tool */

.nl-group-row__title { display: inline-flex; align-items: center; gap: 0.5rem; }
.nl-group-row__title .nl-icon { width: 1rem; height: 1rem; color: var(--muted-foreground); }
.nl-td--accent { font-weight: 500; color: color-mix(in oklab, var(--primary), var(--foreground) 45%); }
.nl-td--wrap { min-width: 18rem; white-space: normal; }
.nl-table tbody tr.nl-sub-row { background: color-mix(in oklab, var(--muted) 30%, transparent); }
.nl-table tbody tr.nl-sub-row:hover { background: color-mix(in oklab, var(--muted) 60%, transparent); }

@media (min-width: 640px) { .nl-field-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 640px) { .nl-field-grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 640px) { .nl-field-grid--5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }

/* ---------------------------------------------------------------- Combobox */

.nl-combobox { position: relative; width: 100%; }
.nl-combobox__list {
    position: absolute;
    z-index: 60;
    top: calc(100% + 0.25rem);
    left: 0;
    right: 0;
    max-height: 16rem;
    overflow-y: auto;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--popover);
    box-shadow: var(--shadow-lg);
}
.nl-combobox__option { padding: 0.5rem 0.625rem; border-radius: calc(var(--radius) - 2px); font-size: var(--text-base); cursor: pointer; }
.nl-combobox__option:hover,
.nl-combobox__option.is-highlighted { background: var(--muted); }
.nl-combobox__option[aria-selected="true"] { font-weight: 600; color: var(--primary); }
.nl-combobox__empty { padding: 0.5rem 0.625rem; font-size: var(--text-base); color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Assessment wizard */

.nl-wizard-child { display: flex; flex-direction: column; gap: 0.375rem; padding-block: 0.25rem; }
.nl-wizard-child h3 { font-size: var(--text-lg); line-height: 1.25; font-weight: 600; }
.nl-draft-banner { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.75rem; padding: 0.625rem 0.875rem; border-radius: var(--radius); background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); font-size: var(--text-base); }
.nl-draft-banner .nl-icon { width: 1rem; height: 1rem; flex-shrink: 0; }
.nl-draft-banner span { color: var(--foreground); }
.nl-draft-banner > .nl-btn { margin-left: auto; }
.nl-wizard-scroll { display: flex; flex: 1 1 auto; flex-direction: column; gap: 1rem; min-height: 0; overflow-y: auto; scrollbar-width: none; }
.nl-wizard-scroll::-webkit-scrollbar { display: none; }
.nl-assessment-wizard .nl-modal__body { overflow: hidden; }
.nl-assessment-wizard .nl-field-hint { text-align: left; }
.nl-wizard-questions { display: flex; flex-direction: column; gap: 0.75rem; }
.nl-wizard-questions h3 { font-size: var(--text-base); line-height: 1.25rem; font-weight: 600; }

.nl-score { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }
.nl-score.is-flagged { color: var(--destructive); }
.nl-red-flag { display: flex; align-items: center; gap: 0.5rem; padding: 0.5rem 0.75rem; border-radius: var(--radius); background: color-mix(in oklab, var(--destructive) 10%, transparent); font-size: var(--text-base); color: var(--destructive); }
.nl-red-flag .nl-icon { width: 1rem; height: 1rem; flex-shrink: 0; }

.nl-indicator { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); }
.nl-indicator.is-invalid { border-color: var(--destructive); }
.nl-indicator__text { padding: 0; font-size: var(--text-base); line-height: 1.25rem; }

.nl-segmented { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.nl-segmented__option { padding: 0.375rem 0.75rem; border: 0; border-radius: var(--radius); background: var(--muted); font-size: var(--text-xs); line-height: 1rem; font-weight: 500; color: color-mix(in oklab, var(--foreground) 80%, transparent); cursor: pointer; transition: background-color var(--transition-fast), color var(--transition-fast); }
.nl-segmented__option:hover { background: color-mix(in oklab, var(--primary) 10%, transparent); }
.nl-segmented__option:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; }
.nl-segmented__option.is-active { background: var(--primary); color: var(--primary-foreground); }

.nl-list-row--wrap { align-items: flex-start; gap: 1rem; }
.nl-list-row--wrap > :last-child { flex-shrink: 0; }
.nl-list-row--total { font-weight: 600; background: var(--muted); }

/* Assessment details: a domain score row that expands to its responses */
.nl-domain-toggle { width: 100%; background: transparent; color: inherit; font: inherit; font-size: var(--text-base); text-align: left; cursor: pointer; }
/* Same highlight as the sidebar's active/hovered nav link (.nl-nav-link). */
.nl-domain-toggle:hover,
.nl-domain-toggle[aria-expanded="true"] { background: var(--sidebar-accent); color: var(--sidebar-accent-foreground); }
.nl-domain-toggle:hover .nl-group-row__title .nl-icon,
.nl-domain-toggle[aria-expanded="true"] .nl-group-row__title .nl-icon { color: inherit; }
.nl-domain-toggle__alert { display: inline-flex; color: var(--destructive); }
.nl-domain-toggle__alert .nl-icon { color: inherit; }
.nl-domain-panel { display: flex; flex-direction: column; gap: 0.5rem; margin-left: 1.5rem; padding-bottom: 0.5rem; }
.nl-domain-panel h4 { margin: 0.25rem 0 0; font-size: var(--text-xs); font-weight: 600; color: var(--muted-foreground); text-transform: uppercase; letter-spacing: 0.03em; }

/* ---------------------------------------------------------------- Assessment wizard: red flags */

.nl-child-strip { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25rem 0; font-size: var(--text-xs); line-height: 1rem; color: color-mix(in oklab, var(--foreground) 80%, transparent); }
.nl-child-strip > * { padding-inline: 0.75rem; border-left: 2px solid color-mix(in oklab, var(--primary) 60%, transparent); }
.nl-child-strip > :first-child { padding-left: 0; border-left: 0; }
.nl-child-strip strong { font-weight: 500; color: var(--foreground); }

.nl-stepper__circle .nl-icon { width: 1rem; height: 1rem; }
.nl-stepper--compact .nl-stepper__step.is-done .nl-stepper__circle { background: color-mix(in oklab, var(--primary) 10%, transparent); border: 1px solid var(--primary); color: var(--primary); }
.nl-stepper__meta { display: inline-flex; align-items: center; gap: 0.25rem; font-size: var(--text-xs); line-height: 1rem; font-weight: 500; color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.nl-stepper__meta.is-flagged { color: var(--destructive); }
.nl-stepper__meta .nl-icon { width: 0.75rem; height: 0.75rem; }

.nl-wizard-questions h3.nl-red-heading { display: flex; align-items: center; gap: 0.375rem; color: var(--destructive); }
.nl-red-heading .nl-icon { width: 1rem; height: 1rem; }
.nl-red-item__domain { display: block; font-size: var(--text-xs); line-height: 1rem; font-weight: 500; color: var(--muted-foreground); }
.nl-red-item__bullets { margin: 0; padding-left: 1.125rem; list-style: disc; font-size: var(--text-base); line-height: 1.375rem; }
.nl-red-item__meta { font-size: var(--text-xs); line-height: 1rem; color: var(--muted-foreground); }
.nl-segmented--danger .nl-segmented__option.is-active { background: var(--destructive); color: var(--primary-foreground); }
/* Always/Sometimes/Never read as a condition scale, not three interchangeable buttons: Never (the
   behaviour is absent) is the good outcome, Sometimes is midway, Always (every ELDS checklist's
   worst answer) is the bad outcome — same --viz-good/--viz-warning/--destructive tones the charts
   already use elsewhere, just applied here instead of new colors. */
.nl-segmented--danger .nl-segmented__option--never.is-active { background: var(--viz-good); color: var(--primary-foreground); }
.nl-segmented--danger .nl-segmented__option--sometimes.is-active { background: var(--viz-warning); color: oklch(0.145 0 0); }
.nl-segmented--danger .nl-segmented__option--always.is-active { background: var(--destructive); color: var(--primary-foreground); }

.nl-standards__toggle { flex-shrink: 0; align-self: flex-start; height: 2.25rem; padding-inline: 0.75rem; font-size: var(--text-sm); color: var(--primary); background: color-mix(in oklab, var(--primary) 10%, transparent); }
.nl-standard-card { display: flex; flex-direction: column; gap: 0.5rem; padding: 0.75rem; border: 1px solid var(--border); border-radius: var(--radius); }
.nl-standard-card__facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; font-size: var(--text-xs); line-height: 1rem; }
.nl-standard-card__facts span { display: block; color: var(--muted-foreground); }
.nl-standard-card__facts strong { font-weight: 500; }
.nl-standard-card h4 { font-size: var(--text-xs); line-height: 1rem; font-weight: 600; color: var(--muted-foreground); }
.nl-standard-card p { font-size: var(--text-base); }

/* Step-level validation message in a dialog footer: above the buttons on phones, left of them on wider screens. */
.nl-modal__footer-error { order: 99; align-self: center; text-align: center; }
@media (min-width: 640px) { .nl-modal__footer-error { order: 0; margin-right: auto; text-align: left; } }
.nl-indicator:focus { outline: none; }
.nl-indicator:focus-visible, .nl-indicator.is-invalid:focus { box-shadow: 0 0 0 3px color-mix(in oklab, var(--destructive) 20%, transparent); }

.nl-focus-target:focus { outline: none; }

/* AssessmentNew.razor's vertical step list: a full page, not a dialog. Steps 1.._maxStep are all
   rendered at once, so any step ever reached stays visible as a collapsed summary card (.is-done)
   even while an earlier one is reopened for editing; only the active step (.is-active) has its
   editable body open. The next card appears in the DOM the moment Next() clears validation and
   advances _maxStep. The numbered circle and connecting line sit in a rail to the left of the
   cards, outside them, instead of inside each card's own header. */
.nl-vsteps { display: flex; flex-direction: column; gap: 1rem; }
.nl-vstep-row { display: flex; align-items: stretch; gap: 0.75rem; }
.nl-vstep-rail { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; width: 2rem; }
.nl-vstep-connector { flex: 1 1 auto; width: 2px; margin-top: 0.25rem; margin-bottom: -1rem; background: var(--border); }
.nl-vstep-row.is-done .nl-vstep-connector { background: var(--primary); }
.nl-vstep-card {
    flex: 1 1 auto;
    min-width: 0;
    border-radius: var(--radius);
    background: var(--card);
    box-shadow: var(--shadow-ring);
}
.nl-vstep__head { display: flex; align-items: center; gap: 0.75rem; padding: 1rem 1.25rem; }
.nl-vstep__head:focus { outline: none; }
.nl-vstep__circle {
    display: flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 2rem; height: 2rem; border-radius: 999px; border: 1px solid var(--border);
    font-size: var(--text-sm); font-weight: 600; color: var(--muted-foreground); background: var(--muted);
}
.nl-vstep__circle .nl-icon { width: 1rem; height: 1rem; }
.nl-vstep-row.is-active .nl-vstep__circle { border-color: var(--primary); background: var(--primary); color: var(--primary-foreground); }
.nl-vstep-row.is-done .nl-vstep__circle { border-color: var(--primary); background: color-mix(in oklab, var(--primary) 10%, transparent); color: var(--primary); }
/* Red-flag steps: title and circle/icon are destructive-toned in every state, not just while active. */
.nl-vstep-row.is-red .nl-vstep__title { color: var(--destructive); }
.nl-vstep-row.is-red .nl-vstep__circle { border-color: var(--destructive); color: var(--destructive); background: color-mix(in oklab, var(--destructive) 10%, transparent); }
.nl-vstep-row.is-red.is-active .nl-vstep__circle { background: var(--destructive); color: var(--primary-foreground); }
.nl-vstep__title-group { display: flex; flex: 1 1 auto; flex-wrap: wrap; align-items: baseline; gap: 0.25rem 0.75rem; min-width: 0; }
.nl-vstep__title { font-weight: 600; }
.nl-vstep__meta { display: inline-flex; align-items: center; gap: 0.25rem; font-size: var(--text-sm); color: var(--muted-foreground); font-variant-numeric: tabular-nums; }
.nl-vstep__meta .nl-icon { width: 0.75rem; height: 0.75rem; }
.nl-vstep__meta.is-flagged { color: var(--destructive); }
.nl-vstep__body { display: flex; flex-direction: column; gap: 1rem; padding: 0 1.25rem 1.25rem; border-top: 1px solid var(--border); padding-top: 1rem; }
.nl-vstep__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 0.75rem; }
@media (max-width: 640px) {
    .nl-vstep__actions { justify-content: stretch; }
    .nl-vstep__actions .nl-btn { flex: 1 1 auto; }
}

/* ---------------------------------------------------------------- Lists, textareas and grouped rows */

.nl-textarea { height: auto; min-height: 5rem; padding-block: 0.5rem; line-height: 1.25rem; resize: vertical; }

.nl-list-input {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--background);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
.nl-list-input:focus-within { border-color: var(--ring); box-shadow: 0 0 0 2px color-mix(in oklab, var(--ring) 15%, transparent); }
.nl-list-input__row { display: flex; align-items: flex-start; gap: 0.5rem; border-bottom: 1px solid var(--border); }
.nl-list-input__row:last-of-type { border-bottom: none; }
.nl-list-input__fields { display: flex; flex: 1; flex-direction: column; min-width: 0; }
.nl-list-input__fields .nl-input { border: none; border-radius: 0; background: transparent; box-shadow: none !important; }
.nl-list-input__fields .nl-input:not(:first-child) { border-top: 1px solid var(--border); }
.nl-list-input__remove { flex-shrink: 0; margin: 0.25rem; }
.nl-list-input__add { width: 100%; justify-content: center; border-radius: 0; background: color-mix(in oklab, var(--primary) 12%, transparent); color: var(--primary); }
.nl-list-input__row + .nl-list-input__add { border-top: 1px solid var(--border); }
.nl-list-input--single .nl-list-input__row { position: relative; align-items: center; }
.nl-list-input--single .nl-list-input__fields .nl-input { padding-right: 2.5rem; }
.nl-list-input--single .nl-list-input__remove { position: absolute; right: 0.25rem; top: 50%; transform: translateY(-50%); margin: 0; }

.nl-cell-list { margin: 0; padding-left: 1rem; list-style: disc; }

.nl-group-toggle { display: inline-flex; align-items: center; gap: 0.5rem; font-weight: 600; color: var(--foreground); }
.nl-group-toggle .nl-icon { width: 0.875rem; height: 0.875rem; color: var(--muted-foreground); }

/* ---------------------------------------------------------------- Printable documents */
/* Shared by every page rendered through PrintLayout (see that component): the on-screen
   toolbar, the A4 page frame, and the PrintHeader masthead. Document-specific content below
   the masthead can still use the regular nl-field-grid / nl-list-row / nl-score classes. */

.nl-print-toolbar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.75rem 1.5rem;
    background: var(--muted);
    border-bottom: 1px solid var(--border);
}

.nl-print-page {
    /* A printed page is always on white paper, so it pins the light-mode token values here —
       overriding them locally keeps every var(--...) below (and DetailField's own classes,
       reused for the field grid) correct even when the app is in dark mode. */
    color-scheme: light;
    --background: oklch(1 0 0);
    --foreground: oklch(0.145 0 0);
    --muted-foreground: oklch(0.556 0 0);
    --primary: oklch(0.596 0.145 163);
    --primary-foreground: oklch(0.985 0 0);
    --secondary: oklch(0.97 0 0);
    --secondary-foreground: oklch(0.205 0 0);
    --border: oklch(0.922 0 0);
    --destructive: oklch(0.577 0.245 27.325);
    --muted: oklch(0.97 0 0);
    /* Growth charts (ChildReport.razor) read these directly, not through --background/--foreground
       above, so they need their own light-mode pin too. */
    --viz-1: #2a78d6;
    --viz-critical: #d03b3b;
    --viz-good: #0ca30c;
    --viz-grid: #e1e0d9;
    --viz-muted: #898781;
    --viz-growth-bg: #f7f1c3;

    max-width: 210mm;
    margin: 1.5rem auto;
    padding: 16mm;
    background: var(--background);
    color: var(--foreground);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
    /* A wide, nowrap table (see .nl-print-table) can need more than 210mm — scrolls here on
       screen instead of spilling past the page's edge. print.js captures the full width
       regardless when it decides a document like that needs a landscape PDF. */
    overflow-x: auto;
}

.nl-print-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 1.5rem; }
.nl-print-header__gov { display: flex; align-items: center; gap: 0.6rem; }
.nl-print-header__emblem { width: 56px; height: 56px; object-fit: contain; flex-shrink: 0; }
.nl-print-header__gov-text { display: flex; flex-direction: column; line-height: 1.3; }
.nl-print-header__country { font-weight: 500; color: var(--foreground); font-size: 0.65rem; padding-bottom: 0.15rem; border-bottom: 1px solid var(--foreground); }
.nl-print-header__ministry { font-weight: 700; color: var(--foreground); font-size: 0.65rem; padding-top: 0.15rem; }
.nl-print-header__ncda { height: 56px; object-fit: contain; }

/* A heavy rule with a hairline under it, closing the header — "two rules read as printed". */
.nl-print-header__rule { height: 2px; background: var(--foreground); margin-top: 0.75rem; }
.nl-print-header__hairline { height: 1px; background: var(--border); margin: 0.2rem 0 1.5rem; }

/* Reference/Generated, right-aligned under the NCDA logo: a small muted label over a bold value. */
.nl-print-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 0.3rem; }
.nl-print-meta__entry { display: flex; flex-direction: column; align-items: flex-end; }
.nl-print-meta__label { font-size: var(--text-2xs); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted-foreground); }
.nl-print-meta__value { font-size: var(--text-sm); font-weight: 700; color: var(--foreground); }
/* In the footer the meta block sits beside the QR, not pinned to the page's right edge, so its
   entries read left-aligned like everything else around them instead of right-aligned. */
.nl-print-meta--left, .nl-print-meta--left .nl-print-meta__entry { align-items: flex-start; }

.nl-print-title { text-align: center; display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 1.5rem; }
.nl-print-title__en { font-size: 1.1rem; font-weight: 800; color: var(--primary); text-transform: uppercase; }

/* A section heading as a filled band, not a bare <h3> — the same uppercase/muted/letter-spaced
   treatment .nl-print-table th already uses, as a full-width strip instead of a table cell. */
.nl-print-band { margin: 1.5rem 0 0.75rem; padding: 0.4rem 0.6rem; background: var(--muted); color: var(--muted-foreground); font-size: var(--text-xs); font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; }

.nl-print-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem 2rem; margin-bottom: 1.5rem; }
.nl-print-fields--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

.nl-print-table { width: 100%; border-collapse: collapse; font-size: 0.75rem; }
.nl-print-table th, .nl-print-table td { border: 0.5px solid var(--border); padding: 0.4rem 0.5rem; text-align: left; vertical-align: middle; white-space: nowrap; }
.nl-print-table tr { break-inside: avoid; page-break-inside: avoid; }
.nl-print-table thead { display: table-header-group; }
.nl-print-table th { background: var(--muted); color: var(--muted-foreground); font-size: 0.65rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.02em; }
.nl-print-table__mark { text-align: center; color: var(--primary); font-weight: 700; }
.nl-print-table__mark.is-low { color: var(--destructive); }

/* One table per domain, indicators running down as rows and the three response levels as
   columns (checkmark at the matching indicator × response cell). */
.nl-print-domain { margin-bottom: 1.5rem; break-inside: avoid; page-break-inside: avoid; }

/* A section heading (.nl-print-band) and the one chart/block that belongs to it — print.js
   treats this as a single unbreakable unit too, the same way .nl-print-domain already is, so the
   heading can never get left behind alone on the page before it. */
.nl-print-section { margin-bottom: 1.5rem; }
.nl-print-section .nl-print-band { margin-top: 0; }
.nl-print-domain__header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.4rem; }
.nl-print-domain__name { font-weight: 700; }
.nl-print-domain__score { font-weight: 700; white-space: nowrap; }
.nl-print-domain__score.is-flagged { color: var(--destructive); }
.nl-print-table--domain th { font-size: 0.65rem; text-align: center; white-space: normal; }
.nl-print-table--domain th:first-child { text-align: left; }
.nl-print-table--domain .nl-print-table__rowlabel { font-size: var(--text-xs); color: var(--muted-foreground); white-space: normal; }

/* Every printed document closes the same way: a rule, then a note (PrintFooter.razor) — never
   just trailing whitespace. */
.nl-print-footer { margin-top: 2.5rem; padding-top: 1rem; border-top: 1px solid var(--border); display: flex; justify-content: space-between; align-items: flex-end; gap: 2.5rem; }
.nl-print-footer__note { font-size: 0.75rem; color: var(--muted-foreground); }

.nl-print-qr { display: flex; flex-direction: column; align-items: flex-start; gap: 0.35rem; }
.nl-print-qr__caption { font-size: 0.7rem; color: var(--muted-foreground); }

@media print {
    .nl-print-toolbar { display: none !important; }
    .nl-print-page { box-shadow: none; margin: 0; max-width: none; width: 100%; padding: 10mm; }
    @page { size: A4; margin: 5mm; }
}
