/* ─── THOR Pure — Material Design 3 ─────────────────────────────── */

:root {
    /* MD2 Primary (matches THOR1 Angular Material primary) */
    --primary: #1976d2;
    --primary-container: #e3f2fd;
    --on-primary: #FFFFFF;
    --on-primary-container: #0d47a1;

    /* Secondary */
    --secondary: #535F70;
    --secondary-container: #D7E3F7;
    --on-secondary: #FFFFFF;
    --on-secondary-container: #101C2B;

    /* Tertiary (accent) */
    --tertiary: #6B5778;
    --tertiary-container: #F2DAFF;

    /* Error */
    --error: #BA1A1A;
    --error-container: #FFDAD6;
    --on-error: #FFFFFF;

    /* Success (custom) */
    --success: #2E7D32;
    --success-container: #C8E6C9;
    --warning: #E65100;
    --warning-container: #FFE0B2;

    /* Neutral surfaces — MD3 tonal elevation */
    --surface: #FAFCFF;
    --surface-dim: #D8DAE0;
    --surface-bright: #FAFCFF;
    --surface-container-lowest: #FFFFFF;
    --surface-container-low: #F2F4F9;
    --surface-container: #ECEEF4;
    --surface-container-high: #E6E8EE;
    --surface-container-highest: #E0E2E8;
    --on-surface: #191C20;
    --on-surface-variant: #43474E;
    --outline: #73777F;
    --outline-variant: #C3C7CF;
    --inverse-surface: #2E3036;
    --inverse-on-surface: #F0F0F7;
    --scrim: #000000;

    /* Brand (Nordzucker red accent) */
    --brand: #E30613;

    /* Elevation shadows — MD3 */
    --elevation-0: none;
    --elevation-1: 0 2px 1px -1px rgba(0,0,0,0.2), 0 1px 1px 0 rgba(0,0,0,0.14), 0 1px 3px 0 rgba(0,0,0,0.12);
    --elevation-2: 0 3px 1px -2px rgba(0,0,0,0.2), 0 2px 2px 0 rgba(0,0,0,0.14), 0 1px 5px 0 rgba(0,0,0,0.12);
    --elevation-3: 0 3px 3px -2px rgba(0,0,0,0.2), 0 3px 4px 0 rgba(0,0,0,0.14), 0 1px 8px 0 rgba(0,0,0,0.12);
    --elevation-4: 0 2px 4px -1px rgba(0,0,0,0.2), 0 4px 5px 0 rgba(0,0,0,0.14), 0 1px 10px 0 rgba(0,0,0,0.12);
    --elevation-5: 0 3px 5px -1px rgba(0,0,0,0.2), 0 5px 8px 0 rgba(0,0,0,0.14), 0 1px 14px 0 rgba(0,0,0,0.12);

    /* Layout */
    --appbar-h: 64px;
    --drawer-w: 280px;

    /* Shape — Material Design 2 rounding */
    --shape-xs: 4px;
    --shape-sm: 4px;
    --shape-md: 4px;
    --shape-lg: 8px;
    --shape-xl: 8px;
    --shape-full: 4px;

    /* Motion — MD3 standard easing */
    --motion-standard: cubic-bezier(0.2, 0, 0, 1);
    --motion-emphasized: cubic-bezier(0.2, 0, 0, 1);
    --motion-duration-short: 80ms;
    --motion-duration-medium: 0ms;
    --motion-duration-long: 0ms;
}

/* ─── Dark Mode ──────────────────────────────────────────────────── */

[data-theme="dark"] {
    --surface: #1E1E1E;
    --surface-dim: #141414;
    --surface-bright: #2C2C2C;
    --surface-container-lowest: #252525;
    --surface-container-low: #1A1A1A;
    --surface-container: #222222;
    --surface-container-high: #2A2A2A;
    --surface-container-highest: #333333;
    --on-surface: #E2E2E2;
    --on-surface-variant: #A0A0A0;
    --outline: #555555;
    --outline-variant: #383838;
    --inverse-surface: #E2E2E2;
    --inverse-on-surface: #1A1A1A;
    --scrim: rgba(0,0,0,0.8);
    --error: #F28B82;
    --error-container: #601410;
    --on-error: #000;
    --success: #81C784;
    --success-container: #1B3A1C;
    --warning: #FFB74D;
    --warning-container: #3E1800;
    --secondary-container: #2B3545;
    --on-secondary-container: #D7E3F7;
    /* Primary: blue in dark */
    --primary: #90BBFF;
    --primary-container: #003D8E;
    --on-primary: #001C4A;
    --on-primary-container: #D4E2FF;
    /* Elevations lighter in dark */
    --elevation-1: 0 1px 3px rgba(0,0,0,0.6);
    --elevation-2: 0 2px 6px rgba(0,0,0,0.5);
    --elevation-3: 0 4px 8px rgba(0,0,0,0.5);
}

/* Cards in dark: elevated via border, no shadow */
[data-theme="dark"] .card {
    box-shadow: none;
    border: 1px solid var(--outline-variant);
}

/* ─── Accent Colors (light mode) ─────────────────────────────────── */

[data-accent="teal"]   { --primary: #00796B; --primary-container: #B2DFDB; --on-primary: #fff; --on-primary-container: #002018; }
[data-accent="purple"] { --primary: #7B1FA2; --primary-container: #E1BEE7; --on-primary: #fff; --on-primary-container: #1A0029; }
[data-accent="orange"] { --primary: #E65100; --primary-container: #FFE0B2; --on-primary: #fff; --on-primary-container: #2D1600; }
[data-accent="red"]    { --primary: #C62828; --primary-container: #FFCDD2; --on-primary: #fff; --on-primary-container: #2D0000; }
[data-accent="green"]  { --primary: #2E7D32; --primary-container: #C8E6C9; --on-primary: #fff; --on-primary-container: #002108; }

/* ─── Accent Colors (dark mode) ─────────────────────────────────── */

[data-theme="dark"][data-accent="teal"]   { --primary: #80CBC4; --primary-container: #004039; --on-primary: #001F1B; --on-primary-container: #B2DFDB; }
[data-theme="dark"][data-accent="purple"] { --primary: #CE93D8; --primary-container: #4A0072; --on-primary: #3A0061; --on-primary-container: #E1BEE7; }
[data-theme="dark"][data-accent="orange"] { --primary: #FFCC80; --primary-container: #7F3800; --on-primary: #4D2000; --on-primary-container: #FFE0B2; }
[data-theme="dark"][data-accent="red"]    { --primary: #EF9A9A; --primary-container: #7F0000; --on-primary: #560000; --on-primary-container: #FFCDD2; }
[data-theme="dark"][data-accent="green"]  { --primary: #A5D6A7; --primary-container: #1B5E20; --on-primary: #003A00; --on-primary-container: #C8E6C9; }

/* ─── Reset ──────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

button { border: none; background: none; cursor: pointer; font: inherit; color: inherit; }

html { height: 100%; -webkit-font-smoothing: antialiased; }

body {
    height: 100%;
    font-family: 'Roboto', system-ui, -apple-system, sans-serif;
    font-size: 15px;
    line-height: 1.43;
    color: var(--on-surface);
    background: var(--surface-container-low);
}

a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ─── MD3 Typography ─────────────────────────────────────────────── */

.display-large   { font-size: 3.5625rem;  font-weight: 400; line-height: 4rem;     letter-spacing: -0.25px; }
.display-medium  { font-size: 2.8125rem;  font-weight: 400; line-height: 3.25rem;  }
.display-small   { font-size: 2.25rem;    font-weight: 400; line-height: 2.75rem;  }
.headline-large  { font-size: 2rem;       font-weight: 400; line-height: 2.5rem;   }
.headline-medium { font-size: 1.75rem;    font-weight: 400; line-height: 2.25rem;  }
.headline-small  { font-size: 1.5rem;     font-weight: 400; line-height: 2rem;     }

h1 { font-size: 1.5rem;   font-weight: 400; line-height: 2rem;   }
h2 { font-size: 1.25rem;  font-weight: 500; line-height: 1.75rem; }
h3 { font-size: 1rem;     font-weight: 500; line-height: 1.5rem;  letter-spacing: 0.15px; }
h4 { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: 0.1px; }

.title-large  { font-size: 1.375rem; font-weight: 400; line-height: 1.75rem; }
.title-medium { font-size: 1rem;     font-weight: 500; line-height: 1.5rem;  letter-spacing: 0.15px; }
.title-small  { font-size: 0.875rem; font-weight: 500; line-height: 1.25rem; letter-spacing: 0.1px; }
.body-large   { font-size: 1rem;     font-weight: 400; line-height: 1.5rem;  letter-spacing: 0.5px; }
.body-medium  { font-size: 0.875rem; font-weight: 400; line-height: 1.25rem; letter-spacing: 0.25px; }
.body-small   { font-size: 0.75rem;  font-weight: 400; line-height: 1rem;    letter-spacing: 0.4px; }
.label-medium { font-size: 0.75rem;  font-weight: 500; line-height: 1rem;    letter-spacing: 0.5px; }
.label-small  { font-size: 0.6875rem;font-weight: 500; line-height: 1rem;    letter-spacing: 0.5px; }

.caption { font-size: 0.75rem; color: var(--on-surface-variant); letter-spacing: 0.4px; }
.overline { font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.5px; text-transform: uppercase; color: var(--on-surface-variant); }

/* ─── Shell Layout (animated grid) ───────────────────────────────── */

.shell {
    display: grid;
    grid-template-rows: var(--appbar-h) 1fr;
    grid-template-columns: var(--drawer-w) 1fr;
    grid-template-areas:
        "appbar appbar"
        "drawer main";
    height: 100vh;
    overflow: hidden;
    transition: grid-template-columns var(--motion-duration-medium) var(--motion-emphasized);
}

.shell.drawer-closed {
    grid-template-columns: 0px 1fr;
}

/* ─── AppBar — MD3 Top App Bar (Small) ───────────────────────────── */

.appbar {
    grid-area: appbar;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 0 8px 0 4px;
    background: var(--primary);
    color: var(--on-primary);
    z-index: 100;
    min-height: var(--appbar-h);
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
}

.appbar .logo {
    font-size: 1.375rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    color: var(--on-primary);
    margin-left: 4px;
}

.appbar .version {
    font-size: 0.625rem;
    color: rgba(255,255,255,0.7);
    margin-top: 6px;
}

.appbar .spacer { flex: 1; }

/* ─── Drawer — MD3 Navigation Drawer ─────────────────────────────── */

.drawer {
    grid-area: drawer;
    background: var(--surface-container-lowest);
    border-right: 1px solid var(--outline-variant);
    overflow: hidden;
    min-width: 0;
    z-index: 90;
}

.drawer-inner {
    width: var(--drawer-w);
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
}

.drawer .brand {
    padding: 20px 16px 12px;
    display: flex;
    align-items: center;
    gap: 12px;
}

.drawer .brand img { max-width: 140px; }

/* ─── Nav — MD3 Navigation Items ─────────────────────────────────── */

.nav { padding: 8px 0; }

.nav a, .nav-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0 16px;
    height: 48px;
    color: var(--on-surface-variant);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.1px;
    text-decoration: none;
    border-radius: 0;
    transition: background 80ms, color 80ms;
    cursor: pointer;
    position: relative;
    overflow: hidden;
}

.nav a:hover, .nav-item:hover {
    background: color-mix(in srgb, var(--on-surface) 7%, transparent);
    text-decoration: none;
}

.nav a.active {
    background: color-mix(in srgb, var(--primary) 12%, transparent);
    color: var(--primary);
    font-weight: 600;
}

.nav a .material-symbols-outlined,
.nav-item .material-symbols-outlined {
    font-size: 24px;
    color: var(--on-surface-variant);
}

/* "Shared with me" unopened badge */
.nav-badge {
    margin-left: auto;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    border-radius: 10px;
    background: var(--primary);
    color: var(--on-primary, #fff);
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transform-origin: center;
}
/* Flash a few times when a new share arrives (overflow:hidden on the row clips a ring, so use scale+colour). */
.nav-badge-pulse { animation: nav-badge-pulse 0.55s ease-in-out 0s 3; }
@keyframes nav-badge-pulse {
    0%, 100% { transform: scale(1); background: var(--primary); }
    50% { transform: scale(1.35); background: var(--error); }
}

.nav a.active .material-symbols-outlined {
    color: var(--primary);
    font-variation-settings: 'FILL' 1;
}

.nav-divider {
    height: 1px;
    background: var(--outline-variant);
    margin: 8px 0;
}

.nav-section-label {
    padding: 8px 16px 4px;
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--on-surface-variant);
}

/* Collapsible custom-menu group header (Factory Links / User Links) */
.nav-group-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 16px 4px;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    color: var(--on-surface-variant);
    text-align: left;
}
.nav-group-toggle:hover { color: var(--on-surface); }
.nav-group-toggle .material-symbols-outlined { font-size: 18px; color: inherit; }

/* Compact custom-menu link — overrides the tall default .nav a so the lists
   stay dense like THOR1 (smaller height, font and icon, indented). */
.nav .nav-custom-link {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 30px;
    padding: 0 16px 0 30px;
    font-size: 0.8125rem;
    font-weight: 400;
    color: var(--on-surface-variant);
    text-decoration: none;
}
.nav .nav-custom-link:hover { background: color-mix(in srgb, var(--on-surface) 7%, transparent); }
.nav .nav-custom-link.active { background: color-mix(in srgb, var(--primary) 12%, transparent); color: var(--primary); }
.nav .nav-custom-link .material-symbols-outlined { font-size: 16px; color: var(--on-surface-variant); }

/* ─── Main Content ───────────────────────────────────────────────── */

.main {
    grid-area: main;
    overflow-y: auto;
    padding: 24px;
    background: var(--surface);
}

/* ─── MD3 Buttons ────────────────────────────────────────────────── */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 0 16px;
    height: 36px;
    border: none;
    border-radius: 4px;
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.1px;
    cursor: pointer;
    transition: box-shadow var(--motion-duration-short) var(--motion-standard),
                background var(--motion-duration-short) var(--motion-standard);
    text-decoration: none;
    line-height: 1;
    position: relative;
    overflow: hidden;
    white-space: nowrap;
}

/* Filled */
.btn-filled, .btn-primary {
    background: var(--primary);
    color: var(--on-primary);
}
.btn-filled:hover, .btn-primary:hover {
    box-shadow: var(--elevation-1);
    background: color-mix(in srgb, var(--on-primary) 8%, var(--primary));
}

/* Filled Tonal */
.btn-tonal {
    background: var(--secondary-container);
    color: var(--on-secondary-container);
}
.btn-tonal:hover {
    box-shadow: var(--elevation-1);
    background: color-mix(in srgb, var(--on-secondary-container) 8%, var(--secondary-container));
}

/* Outlined */
.btn-outlined, .btn-outline {
    background: transparent;
    color: var(--primary);
    border: 1px solid color-mix(in srgb, var(--primary) 50%, transparent);
}
.btn-outlined:hover, .btn-outline:hover {
    background: color-mix(in srgb, var(--primary) 4%, transparent);
    border-color: var(--primary);
}

/* Text */
.btn-text, .btn-ghost {
    background: transparent;
    color: var(--primary);
    padding: 0 12px;
}
.btn-text:hover, .btn-ghost:hover {
    background: color-mix(in srgb, var(--primary) 8%, transparent);
}

/* Danger */
.btn-danger {
    background: var(--error);
    color: var(--on-error);
}
.btn-danger:hover {
    box-shadow: var(--elevation-1);
    background: color-mix(in srgb, var(--on-error) 8%, var(--error));
}

.btn-sm { height: 32px; padding: 0 16px; font-size: 0.8125rem; }

.btn .material-symbols-outlined { font-size: 18px; }

/* FAB */
.fab {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    border: none;
    border-radius: var(--shape-lg);
    background: var(--primary-container);
    color: var(--on-primary-container);
    box-shadow: var(--elevation-3);
    cursor: pointer;
    transition: box-shadow var(--motion-duration-short) var(--motion-standard);
}
.fab:hover { box-shadow: var(--elevation-4); }

/* Icon buttons — MD3 Standard */
.icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--on-surface-variant);
    cursor: pointer;
    transition: background var(--motion-duration-short) var(--motion-standard);
}
.icon-btn:hover { background: color-mix(in srgb, var(--on-surface-variant) 8%, transparent); }
.icon-btn:active { background: color-mix(in srgb, var(--on-surface-variant) 12%, transparent); }

/* Icon button on colored surfaces (appbar) */
.icon-btn.on-surface { color: var(--on-primary); }
.icon-btn.on-surface:hover { background: rgba(255,255,255,0.15); }
.icon-btn.on-surface:active { background: rgba(255,255,255,0.25); }
/* Active/toggled icon button (e.g. decimals on, settings open) */
.icon-btn.active-icon { color: var(--primary); }

/* ─── Report Menu Cards (matches THOR1 mat-card layout) ─────────── */

.report-section {
    margin-bottom: 40px;
}
.report-section h2 {
    margin-bottom: 0;
}
.report-section .section-desc {
    color: var(--on-surface-variant);
    margin-bottom: 18px;
    font-size: 15px;
}
.card-row {
    display: flex;
    gap: 32px;
    flex-wrap: wrap;
}
.report-card {
    flex: 1 1 260px;
    min-width: 260px;
    max-width: 340px;
    margin-bottom: 24px;
    border: 1px solid var(--outline-variant);
    border-radius: 4px;
    box-shadow: none;
    background: var(--surface-container-lowest);
    transition: box-shadow 0.2s;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    min-height: 160px;
    padding: 32px 16px;
}
.report-card:hover {
    box-shadow: 0 2px 12px rgba(0,0,0,0.08);
}
.report-card .icon-box {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    margin: 0 auto 12px auto;
    font-size: 40px;
    background: none;
}
.report-card .icon-box .material-symbols-outlined {
    font-size: 40px;
}
.report-card .card-title {
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 6px;
    text-align: center;
    color: var(--on-surface);
}
.report-card .card-desc {
    color: var(--on-surface-variant);
    font-size: 14px;
    text-align: center;
}

/* ─── MD3 Cards ──────────────────────────────────────────────────── */

.card {
    background: var(--surface-container-lowest);
    border-radius: var(--shape-md);
    box-shadow: var(--elevation-1);
    overflow: hidden;
    transition: box-shadow var(--motion-duration-short) var(--motion-standard);
}

.card.elevated {
    background: var(--surface-container-low);
    box-shadow: var(--elevation-1);
}
.card.elevated:hover { box-shadow: var(--elevation-2); }

.card.filled {
    background: var(--surface-container-highest);
    box-shadow: none;
}

.card.outlined {
    background: var(--surface);
    box-shadow: none;
    border: 1px solid var(--outline-variant);
}

.card.clickable {
    cursor: pointer;
    user-select: none;
}
.card.clickable:hover { box-shadow: var(--elevation-2); }
.card.clickable:active { box-shadow: var(--elevation-1); }

.card-body { padding: 16px; }

/* ─── MD3 Dropdown / Menu ────────────────────────────────────────── */

.dropdown {
    position: relative;
    display: inline-block;
}

.dropdown-trigger {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    background: none;
    border: none;
    color: inherit;
    font: inherit;
    padding: 8px 12px;
    border-radius: var(--shape-sm);
    transition: background var(--motion-duration-short) var(--motion-standard);
}
.dropdown-trigger:hover { background: color-mix(in srgb, var(--on-surface) 8%, transparent); }

.dropdown-panel {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 200px;
    /* Seventeen factories do not fit under the app bar, and without a bound the panel simply ran off the
       bottom of the screen with no way to reach the last entries — Säkylä and Schladen were unreachable
       on a laptop. Scroll the list instead of shrinking the rows: the eye/pencil rights icons stay
       readable, and it holds however many sites Nordzucker ends up with. */
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--surface-container);
    border-radius: var(--shape-xs);
    box-shadow: var(--elevation-2);
    z-index: 200;
    padding: 8px 0;
    opacity: 0;
    transform: scaleY(0.8);
    transform-origin: top right;
    pointer-events: none;
    transition: opacity var(--motion-duration-short) var(--motion-standard),
                transform var(--motion-duration-short) var(--motion-standard);
}

.dropdown.open .dropdown-panel {
    opacity: 1;
    transform: scaleY(1);
    pointer-events: auto;
}

.dropdown-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    font-size: 0.875rem;
    letter-spacing: 0.25px;
    color: var(--on-surface);
    cursor: pointer;
    transition: background var(--motion-duration-short) var(--motion-standard);
    border: none;
    background: none;
    width: 100%;
    text-align: left;
    border-radius: 0;
    min-height: 48px;
}
.dropdown-item:hover { background: color-mix(in srgb, var(--on-surface) 8%, transparent); }
.dropdown-item.active {
    background: var(--secondary-container);
    color: var(--on-secondary-container);
    font-weight: 500;
}

.dropdown-divider {
    height: 1px;
    background: var(--outline-variant);
    margin: 4px 0;
}

.dropdown-header {
    padding: 8px 12px;
    font-size: 0.6875rem;
    color: var(--on-surface-variant);
    font-weight: 500;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

/* ─── MD3 Text Fields ────────────────────────────────────────────── */

.input {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--outline);
    border-radius: 4px;
    font-size: 1rem;
    font-family: inherit;
    color: var(--on-surface);
    background: var(--surface-container-lowest);
    outline: none;
    transition: border-color 150ms ease;
    line-height: 1.5;
    box-sizing: border-box;
}

.input:focus {
    border-color: var(--primary);
    border-width: 2px;
    padding: 7px 11px;
}
.input::placeholder { color: var(--on-surface-variant); }

.input-group {
    display: flex;
    align-items: stretch;
}
.input-group .input {
    border-radius: 0;
    flex: 1;
}
.input-group > :first-child { border-radius: var(--shape-xs) 0 0 var(--shape-xs); }
.input-group > :last-child { border-radius: 0 var(--shape-xs) var(--shape-xs) 0; }

.input-icon {
    display: flex;
    align-items: center;
    padding: 0 12px;
    background: var(--surface-container);
    border: 1px solid var(--outline);
    color: var(--on-surface-variant);
}

/* Search field — Material outline style (matches THOR1 mat-form-field appearance="outline") */
.search-field {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    height: 48px;
    background: var(--surface-container-lowest);
    border-radius: 4px;
    border: 1px solid var(--outline);
    color: var(--on-surface);
    min-width: 240px;
    transition: border-color 150ms ease;
}
.search-field:focus-within {
    border: 2px solid var(--primary);
    padding: 0 11px;
}
.search-field .material-symbols-outlined {
    color: var(--on-surface-variant);
    font-size: 20px;
    flex-shrink: 0;
}
.search-field input {
    flex: 1;
    border: none;
    background: transparent;
    outline: none;
    font-size: 1rem;
    font-family: inherit;
    color: var(--on-surface);
}
.search-field input::placeholder { color: var(--on-surface-variant); }

/* ─── Data Table — Material Design 2 style (matches THOR1 mat-table) ─ */

table.data-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface-container-lowest);
}

table.data-table th {
    padding: 0 16px;
    text-align: left;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--on-surface-variant);
    border-bottom: 1px solid var(--outline-variant);
    white-space: nowrap;
    user-select: none;
    height: 48px;
    vertical-align: middle;
    background: var(--surface-container-high);
}

table.data-table th.sortable { cursor: pointer; }
table.data-table th.sortable:hover { color: var(--on-surface); }

table.data-table td {
    padding: 0 16px;
    border-bottom: 1px solid var(--outline-variant);
    font-size: 0.875rem;
    color: var(--on-surface);
    height: 48px;
    vertical-align: middle;
}

table.data-table tbody tr {
    transition: background 80ms;
}
table.data-table tbody tr:hover {
    background: var(--surface-container);
}
table.data-table tbody tr.clickable { cursor: pointer; }

/* AddSamples grid: highlight the cell under the cursor (not the whole row), so the
   highlight follows the pointer instead of always lighting up the limits column.
   !important so it also overrides cells that carry an inline status background. */
table.data-table.samples-grid tbody tr:hover { background: transparent; }
table.data-table.samples-grid tbody td.sample-cell:hover,
table.data-table.samples-grid tbody td.comment-cell:hover {
    background: color-mix(in srgb, var(--primary) 16%, transparent) !important;
}
/* Subtle outline on the editable value/comment cells so they stand out from the
   read-only label columns and read as clickable inputs within the row. */
table.data-table.samples-grid tbody td.sample-cell,
table.data-table.samples-grid tbody td.comment-cell {
    border: 1px solid var(--outline-variant);
    border-radius: var(--shape-xs);
}

/* AddSamples (#Sample App): freeze Product/Location/Alias/Analysis/Unit while the time columns scroll —
   same pattern as the Laborbuch report (offsets measured at runtime via table-scroll.js:thorLabLayout,
   reusing the --lab-l1..5 vars since each table's vars are scoped to its own element). */
table.data-table.samples-grid th, table.data-table.samples-grid td { white-space: nowrap; }
table.data-table.samples-grid th.sg-sticky-1, table.data-table.samples-grid td.sg-sticky-1,
table.data-table.samples-grid th.sg-sticky-2, table.data-table.samples-grid td.sg-sticky-2,
table.data-table.samples-grid th.sg-sticky-3, table.data-table.samples-grid td.sg-sticky-3,
table.data-table.samples-grid th.sg-sticky-4, table.data-table.samples-grid td.sg-sticky-4,
table.data-table.samples-grid th.sg-sticky-5, table.data-table.samples-grid td.sg-sticky-5,
table.data-table.samples-grid th.sg-sticky-6, table.data-table.samples-grid td.sg-sticky-6,
table.data-table.samples-grid th.sg-sticky-7, table.data-table.samples-grid td.sg-sticky-7,
table.data-table.samples-grid th.sg-sticky-8, table.data-table.samples-grid td.sg-sticky-8 {
    position: sticky; z-index: 3; background: var(--surface-container-lowest);
}
table.data-table.samples-grid th.sg-sticky-1, table.data-table.samples-grid th.sg-sticky-2,
table.data-table.samples-grid th.sg-sticky-3, table.data-table.samples-grid th.sg-sticky-4,
table.data-table.samples-grid th.sg-sticky-5, table.data-table.samples-grid th.sg-sticky-6,
table.data-table.samples-grid th.sg-sticky-7, table.data-table.samples-grid th.sg-sticky-8 { z-index: 5; }
table.data-table.samples-grid .sg-sticky-1 { left: var(--lab-l1, 0px); }
table.data-table.samples-grid .sg-sticky-2 { left: var(--lab-l2, 0px); }
table.data-table.samples-grid .sg-sticky-3 { left: var(--lab-l3, 0px); }
table.data-table.samples-grid .sg-sticky-4 { left: var(--lab-l4, 0px); }
table.data-table.samples-grid .sg-sticky-5 { left: var(--lab-l5, 0px); }
table.data-table.samples-grid .sg-sticky-6 { left: var(--lab-l6, 0px); }
table.data-table.samples-grid .sg-sticky-7 { left: var(--lab-l7, 0px); }
table.data-table.samples-grid .sg-sticky-8 { left: var(--lab-l8, 0px); }
table.data-table.samples-grid th.sg-sticky-end, table.data-table.samples-grid td.sg-sticky-end {
    border-right: 1px solid var(--outline-variant);
}
/* Group-header row already sets an opaque background inline; regular rows need an opaque fallback so
   scrolled time columns don't show through the frozen cells. */
table.data-table.samples-grid tbody tr td[class*="sg-sticky-"] { background: var(--surface-container-lowest); }
table.data-table.samples-grid tbody tr.group-row td[class*="sg-sticky-"] { background: var(--surface-container-high); }

/* AddSamples column-visibility popover */
.column-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 1001;
    min-width: 200px;
    background: var(--surface-container, #fff);
    border: 1px solid var(--outline-variant, #e0e0e0);
    border-radius: var(--shape-xs, 6px);
    box-shadow: var(--elevation-2, 0 4px 12px rgba(0,0,0,0.15));
    padding: 6px;
}
.column-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--shape-xs, 6px);
    font-size: 0.875rem;
    cursor: pointer;
    user-select: none;
}
.column-menu-item:hover { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.column-menu-item input { width: 16px; height: 16px; cursor: pointer; }

/* ─── MD3 Chips ──────────────────────────────────────────────────── */

.chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 0 12px;
    height: 32px;
    border-radius: 16px;
    font-size: 0.8125rem;
    font-weight: 500;
    border: 1px solid rgba(0,0,0,0.12);
    background: var(--surface-container-high);
    color: var(--on-surface);
}

.chip-sm { height: 24px; padding: 0 8px; font-size: 0.6875rem; border-radius: 12px; }

/* Report-list flags: denser than .chip-sm and squared off (house style is 4px, not pill). */
.chip-flag { height: 18px; padding: 0 6px; font-size: 0.625rem; border-radius: 4px; }

.chip-primary {
    background: var(--primary-container);
    color: var(--on-primary-container);
    border-color: transparent;
}
.chip-success {
    background: #4caf50;
    color: #fff;
    border-color: transparent;
}
.chip-warning {
    background: #ff9800;
    color: #fff;
    border-color: transparent;
}
.chip-error {
    background: #f44336;
    color: #fff;
    border-color: transparent;
}

.chip-filter {
    cursor: pointer;
    transition: background var(--motion-duration-short) var(--motion-standard);
}
.chip-filter:hover {
    background: color-mix(in srgb, var(--on-surface) 8%, transparent);
}
.chip-filter.selected {
    /* #1: a picked batch was near-invisible (two low-contrast neutral tints). Use the primary accent + a solid
       border + bold so the selection reads clearly ("underlined/coloured"). */
    background: var(--primary-container);
    color: var(--on-primary-container);
    border-color: var(--primary);
    font-weight: 600;
}

/* ─── MD3 Dialog ─────────────────────────────────────────────────── */

dialog {
    border: none;
    border-radius: var(--shape-xl);
    box-shadow: var(--elevation-3);
    padding: 0;
    max-width: 560px;
    width: 90vw;
    /* Explicit centering — don't rely on the UA margin:auto, which can be reset elsewhere
       and left the dialog pinned to the top-left corner. */
    position: fixed;
    inset: 0;
    margin: auto;
    height: fit-content;
    background: var(--surface-container-high);
    color: var(--on-surface);
    animation: dialog-in var(--motion-duration-medium) var(--motion-emphasized);
}

dialog::backdrop {
    background: color-mix(in srgb, var(--scrim) 32%, transparent);
    animation: backdrop-in var(--motion-duration-medium) var(--motion-standard);
}

@keyframes dialog-in {
    from { opacity: 0; transform: scale(0.9); }
    to   { opacity: 1; transform: scale(1); }
}
@keyframes backdrop-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.dialog-header {
    padding: 24px 24px 16px;
}
.dialog-header h3 { margin: 0; font-size: 1.5rem; font-weight: 400; }

.dialog-body {
    padding: 0 24px 24px;
    font-size: 0.875rem;
    color: var(--on-surface-variant);
    letter-spacing: 0.25px;
    line-height: 1.43;
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 16px 24px 24px;
}

/* ─── MD3 Toast / Snackbar ───────────────────────────────────────── */

.toast-container {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 999;
    display: flex;
    flex-direction: column-reverse;
    gap: 8px;
    align-items: center;
}

.toast {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-radius: var(--shape-xs);
    background: var(--inverse-surface);
    color: var(--inverse-on-surface);
    font-size: 0.875rem;
    letter-spacing: 0.25px;
    box-shadow: var(--elevation-3);
    min-width: 344px;
    max-width: 560px;
    animation: toast-in var(--motion-duration-medium) var(--motion-emphasized);
}

.toast.success { background: var(--success); color: white; }
.toast.info { background: var(--inverse-surface); color: var(--inverse-on-surface); }
.toast.warning { background: var(--warning); color: white; }
.toast.error { background: var(--error); color: white; }

.toast .close-btn {
    margin-left: auto;
    cursor: pointer;
    opacity: 0.7;
    background: none;
    border: none;
    color: inherit;
    font-size: 1.2rem;
    padding: 4px;
    border-radius: var(--shape-full);
    transition: opacity var(--motion-duration-short);
}
.toast .close-btn:hover { opacity: 1; }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(16px) scale(0.95); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* ─── Progress — MD3 Linear ──────────────────────────────────────── */

.progress-bar {
    height: 4px;
    background: var(--surface-container-highest);
    overflow: hidden;
    border-radius: 2px;
}

.progress-bar.indeterminate::after {
    content: '';
    display: block;
    width: 40%;
    height: 100%;
    background: var(--primary);
    border-radius: 2px;
    animation: indeterminate 1.5s infinite var(--motion-standard);
}

@keyframes indeterminate {
    0%   { transform: translateX(-100%); }
    100% { transform: translateX(350%); }
}

/* ─── Alert ──────────────────────────────────────────────────────── */

.alert {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 16px;
    border-radius: var(--shape-md);
    font-size: 0.875rem;
    letter-spacing: 0.25px;
    line-height: 1.43;
}

.alert .material-symbols-outlined { font-size: 20px; margin-top: 1px; }

.alert-info    { background: var(--primary-container); color: var(--on-primary-container); }
.alert-success { background: var(--success-container); color: var(--success); }
.alert-warning { background: var(--warning-container); color: var(--warning); }
.alert-error   { background: var(--error-container);   color: var(--error); }

/* ─── Avatar ─────────────────────────────────────────────────────── */

.avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: var(--primary);
    color: var(--on-primary);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.1px;
}

.avatar-sm { width: 28px; height: 28px; font-size: 0.6875rem; }
.avatar-lg { width: 56px; height: 56px; font-size: 1.5rem; }

img.avatar { object-fit: cover; background: transparent; }

/* ─── Status dot ─────────────────────────────────────────────────── */

.status-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--outline);
}
.status-dot.online { background: var(--success); }
.status-dot.offline { background: var(--outline); }

/* ─── Divider ────────────────────────────────────────────────────── */

.divider {
    height: 1px;
    background: var(--outline-variant);
    margin: 0;
}

/* ─── Utility ────────────────────────────────────────────────────── */

.flex      { display: flex; }
.flex-col  { display: flex; flex-direction: column; }
.flex-1    { flex: 1; }
.items-center { align-items: center; }
.items-start  { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.justify-center { justify-content: center; }
.flex-wrap { flex-wrap: wrap; }
.gap-1  { gap: 4px; }
.gap-2  { gap: 8px; }
.gap-3  { gap: 12px; }
.gap-4  { gap: 16px; }
.gap-6  { gap: 24px; }
.p-2    { padding: 8px; }
.p-3    { padding: 12px; }
.p-4    { padding: 16px; }
.p-6    { padding: 24px; }
.px-4   { padding-left: 16px; padding-right: 16px; }
.px-6   { padding-left: 24px; padding-right: 24px; }
.py-2   { padding-top: 8px; padding-bottom: 8px; }
.py-3   { padding-top: 12px; padding-bottom: 12px; }
.mt-1   { margin-top: 4px; }
.mt-2   { margin-top: 8px; }
.mt-3   { margin-top: 12px; }
.mt-4   { margin-top: 16px; }
.mb-1   { margin-bottom: 4px; }
.mb-2   { margin-bottom: 8px; }
.mb-3   { margin-bottom: 12px; }
.mb-4   { margin-bottom: 16px; }
.mb-6   { margin-bottom: 24px; }
.ml-2   { margin-left: 8px; }
.mr-2   { margin-right: 8px; }
.w-full { width: 100%; }
.text-center { text-align: center; }
.font-medium { font-weight: 500; }
.font-bold { font-weight: 600; }
.opacity-60 { opacity: 0.6; }
.cursor-pointer { cursor: pointer; }
.hidden { display: none !important; }
.no-wrap { white-space: nowrap; }

/* Grid layout */
.grid { display: grid; gap: 16px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

/* ─── Report Virtual-Scroll Table — Azure Portal flat style ─────── */

/* A real <table>, styled to match .report-table above so the two do not look like different products.
   The user-management page was written against .table, .row-selected and .chip-accent, none of which
   existed — so it rendered with the browser's default table styling and looked nothing like THOR. Added
   here rather than rewriting that page onto the grid-based .report-table markup: a table is the right
   element for tabular data, and the next page that needs one now has a style to use. */
.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.875rem;
}

.table thead th {
    height: 48px;
    padding: 0 16px;
    text-align: left;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--on-surface-variant);
    background: var(--surface-container-high);
    border-bottom: 1px solid var(--outline-variant);
    position: sticky;
    top: 0;
    z-index: 1;
}

.table tbody td {
    padding: 10px 16px;
    border-bottom: 1px solid var(--outline-variant);
    vertical-align: middle;
}

/* Not inside a dialog. .modal-body is the scroll container and carries 20px of padding, so a header
   stuck to its top leaves a transparent band above itself and the rows scroll visibly through the gap —
   the header appears to float in the middle of the list. A dialog's table is short enough not to need it. */
.modal-body .table thead th { position: static; }

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: color-mix(in srgb, var(--on-surface) 4%, transparent); }

.table .row-selected,
.row-selected {
    background: var(--secondary-container);
    color: var(--on-secondary-container);
}

/* Distinct from a plain .chip so "Administrator" reads as a status, not a tag. */
.chip-accent {
    background: var(--secondary-container);
    color: var(--on-secondary-container);
    border-color: transparent;
    font-weight: 600;
}

/* Tighter chips inside table cells: a user with fifteen factories should not stretch the row. */
.table td .chip {
    height: 24px;
    padding: 0 8px;
    font-size: 0.75rem;
    margin: 2px 4px 2px 0;
}

.report-table {
    width: 100%;
    background: var(--surface-container-lowest);
    box-shadow: 0 3px 4px -1px rgba(0,0,0,.15), 0 4px 5px 0 rgba(0,0,0,.1), 0 1px 10px 0 rgba(0,0,0,.07);
    border-radius: 4px;
    overflow: hidden;
}

.report-table-header {
    display: grid;
    grid-template-columns: 1fr 100px 130px;
    padding: 0 12px;
    height: 48px;
    align-items: center;
    border-bottom: 1px solid var(--outline-variant);
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--on-surface-variant);
    background: var(--surface-container-high);
    position: sticky;
    top: 0;
    z-index: 1;
}

.report-table-body {
    height: calc(100vh - 260px);
    overflow-y: auto;
}

.report-row {
    display: grid;
    grid-template-columns: 1fr 100px 130px;
    padding: 0 12px;
    align-items: center;
    border-bottom: 1px solid var(--outline-variant);
    min-height: 40px;
    background: var(--surface-container-lowest);
    transition: background 80ms;
}
.report-row:hover {
    background: var(--surface-container);
}

.report-row .col-name { padding: 6px 0; }
.report-row .col-date { font-size: 0.8125rem; color: var(--on-surface-variant); }
.report-row .col-actions { display: flex; justify-content: flex-end; gap: 0; }
.report-table-header .col-date { text-align: left; }
.report-table-header .col-actions { text-align: right; }

/* ─── Page Header ────────────────────────────────────────────────── */

/* Blazor router programmatically focuses h1 after navigation (for screen readers).
   Suppress the visual outline — it's not triggered by keyboard navigation. */
[tabindex="-1"]:focus { outline: none; }

.page-header {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-bottom: 24px;
}
.page-header h1 { flex: 1; }

/* ─── Toolbar ────────────────────────────────────────────────────── */

.toolbar {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
}
.toolbar .spacer { flex: 1; }

/* ─── Empty state ────────────────────────────────────────────────── */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 48px 24px;
    text-align: center;
    color: var(--on-surface-variant);
}
.empty-state .material-symbols-outlined {
    font-size: 48px;
    color: var(--outline);
    margin-bottom: 16px;
}

/* ─── Responsive ─────────────────────────────────────────────────── */

@media (max-width: 840px) {
    .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 600px) {
    .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
    .shell { grid-template-columns: 0px 1fr; }
    .drawer {
        position: fixed;
        top: var(--appbar-h);
        bottom: 0;
        left: 0;
        width: var(--drawer-w);
        z-index: 95;
        box-shadow: var(--elevation-3);
        transform: translateX(-100%);
        transition: transform var(--motion-duration-medium) var(--motion-emphasized);
    }
    .shell:not(.drawer-closed) .drawer { transform: translateX(0); }
    .main { padding: 16px; }
}

/* ─── Appearance Settings — theme & accent controls ─────────────── */

.theme-btn {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 20px;
    border: 1px solid var(--outline-variant);
    background: transparent;
    color: var(--on-surface-variant);
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: 500;
    transition: background 80ms, border-color 80ms, color 80ms;
}
.theme-btn:hover {
    background: color-mix(in srgb, var(--on-surface) 8%, transparent);
    color: var(--on-surface);
}
.theme-btn.active {
    background: var(--primary-container);
    color: var(--on-primary-container);
    border-color: var(--primary);
}
.theme-btn .material-symbols-outlined { font-size: 18px; }

.color-swatch {
    width: 36px;
    height: 36px;
    border: 2px solid transparent;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 80ms;
    flex-shrink: 0;
}
.color-swatch:hover { transform: scale(1.12); }
.color-swatch.selected {
    outline: 3px solid var(--on-surface);
    outline-offset: 2px;
}

/* ─── Report Viewer — Data Table ──────────────────────────────────── */

.report-data-table-wrap {
    overflow-x: auto;
    overflow-y: auto;
    max-height: calc(100vh - 320px);
    border: 1px solid rgb(218, 218, 218);
    background: var(--surface-container-lowest);
}
/* Browser-native lazy rendering: inside the scrollable wrap, skip layout/paint of rows scrolled out of
   view so very tall/wide reports (many factory×tile columns) stay responsive. contain-intrinsic-size gives
   off-screen rows a placeholder height (per size class) so the scrollbar stays stable and rows don't jump. */
.report-data-table tbody tr { content-visibility: auto; contain-intrinsic-size: auto 33px; }
.report-size-compact .report-data-table tbody tr { contain-intrinsic-size: auto 24px; }
.report-size-large .report-data-table tbody tr { contain-intrinsic-size: auto 40px; }
.report-data-table {
    border-collapse: collapse;
    /* Size to content (#14/#19): columns are as wide as the longest parameter name / value (th/td are
       nowrap), and the table no longer stretches to fill the container -- so a single-column report stays
       narrow instead of one giant column. Wider-than-container tables still scroll via .report-data-table-wrap. */
    width: max-content;
    font-size: 0.875rem;
    background: var(--surface-container-lowest);
}
.report-size-compact .report-data-table { font-size: 0.75rem; }
.report-size-compact .report-data-table td { padding: 2px 8px; }
.report-size-compact .report-data-table th { padding: 4px 8px; }
.report-size-large .report-data-table { font-size: 1rem; }
.report-size-large .report-data-table td { padding: 8px 12px; }
.report-size-large .report-data-table th { padding: 8px 12px; }
.report-data-table th {
    position: sticky;
    background: var(--surface-container-high);
    border: 1px solid rgb(218, 218, 218);
    padding: 6px 10px;
    font-weight: 600;
    white-space: nowrap;
    z-index: 2;
    color: var(--on-surface);
}
.report-data-table th.site-header { top: 0; z-index: 3; text-align: center; }
/* Parameter names wrap instead of stretching the column to the width of the longest caption (NYK: THOR1
   showed them as a narrow multi-line block, so all columns fitted on one screen). Body cells and the site
   band stay nowrap — only this header row wraps. */
.report-data-table th.col-header {
    top: 32px;
    white-space: normal;
    overflow-wrap: break-word;
    max-width: 170px;
    vertical-align: bottom;
}
.report-size-compact .report-data-table th.col-header { max-width: 140px; }
.report-size-large .report-data-table th.col-header { max-width: 210px; }
/* low|high over llow|hhigh, THOR1 style. Only rendered for columns that actually have limits configured. */
.report-data-table th.col-header .col-header-limits {
    margin-top: 2px;
    padding-top: 2px;
    border-top: 1px solid var(--outline-variant);
    font-size: 0.8125rem;
    font-weight: 400;
    line-height: 1.25;
    white-space: nowrap;
    color: var(--on-surface-variant);
}
.report-data-table th.first-col { left: 0; z-index: 4; text-align: left; }
.report-data-table th.col-header.first-col { top: 32px; z-index: 5; }
.report-data-table td {
    border: 1px solid rgb(218, 218, 218);
    padding: 4px 10px;
    text-align: right;
    white-space: nowrap;
    color: var(--on-surface);
}
.report-data-table tbody tr:nth-child(odd) td:not(.key-col) { background: var(--surface-container-lowest); }
.report-data-table tbody tr:nth-child(even) td:not(.key-col) { background: var(--surface-container-low); }
.report-data-table td.key-col {
    position: sticky;
    left: 0;
    background: var(--surface-container-high);
    text-align: left;
    font-weight: 500;
    z-index: 1;
}
.report-data-table tr.summary-row td {
    background: var(--surface-container-high);
    font-weight: 600;
}
.report-data-table tr.summary-row td.key-col {
    background: var(--surface-container-high);
}
.report-data-table tr:hover td { background: color-mix(in srgb, var(--primary) 22%, var(--surface-container-lowest)) !important; }
.report-data-table tr.summary-row:hover td { background: color-mix(in srgb, var(--primary) 22%, var(--surface-container-lowest)) !important; }

/* Inventory in the REVERTED 3D view, where it is a column rather than a row, so tr.summary-row cannot
   reach it. Marks the header only — the campaign's stock-taking should be as easy to pick out here as
   the highlighted cell it had in THOR1. */
.report-data-table th.col-header.inventory-row {
    background: var(--surface-container-high);
    font-weight: 700;
}
.report-data-table .cell-icon { font-size: 14px; vertical-align: middle; margin-left: 4px; }

/* Laborbuch (#31): freeze the analysis + unit columns while the time-period / limit / AVG columns scroll. */
/* Laborbuch: columns size to content (auto layout) — the analysis column stretches to the longest name and
   the period headers fit the full "HH:MM - HH:MM". No wrapping/clipping; the frozen columns' left offsets
   are MEASURED at runtime and applied as --lab-l1..5 (table-scroll.js), so they always match actual widths
   (a hard-coded offset was what made Unit overlap the analysis name). */
.report-data-table.laborbuch th, .report-data-table.laborbuch td { white-space: nowrap; }
/* Sticky header row — the wrap scrolls vertically (max-height), so top:0 pins the header there.
   The frozen corner cells (lab-sticky-*) already carry z-index 5 so they stay above both axes. */
.report-data-table.laborbuch thead th { top: 0; }
/* Freeze the five info columns (analysis · unit · aspentech · low|high · llow|hhigh); periods + AVG scroll. */
.report-data-table.laborbuch th.lab-sticky-1, .report-data-table.laborbuch td.lab-sticky-1,
.report-data-table.laborbuch th.lab-sticky-2, .report-data-table.laborbuch td.lab-sticky-2,
.report-data-table.laborbuch th.lab-sticky-3, .report-data-table.laborbuch td.lab-sticky-3,
.report-data-table.laborbuch th.lab-sticky-4, .report-data-table.laborbuch td.lab-sticky-4,
.report-data-table.laborbuch th.lab-sticky-5, .report-data-table.laborbuch td.lab-sticky-5 {
    position: sticky; z-index: 3; background: var(--surface-container-lowest);
}
.report-data-table.laborbuch th.lab-sticky-1, .report-data-table.laborbuch th.lab-sticky-2,
.report-data-table.laborbuch th.lab-sticky-3, .report-data-table.laborbuch th.lab-sticky-4,
.report-data-table.laborbuch th.lab-sticky-5 { z-index: 5; }
/* Fallback offsets approximate the first paint; table-scroll.js replaces them with measured widths. */
.report-data-table.laborbuch .lab-sticky-1 { left: var(--lab-l1, 0px); }
.report-data-table.laborbuch .lab-sticky-2 { left: var(--lab-l2, 220px); }
.report-data-table.laborbuch .lab-sticky-3 { left: var(--lab-l3, 284px); }
.report-data-table.laborbuch .lab-sticky-4 { left: var(--lab-l4, 394px); }
.report-data-table.laborbuch .lab-sticky-5 { left: var(--lab-l5, 472px); }
/* A subtle right border on the last frozen column marks where the scrolling area begins. */
.report-data-table.laborbuch th.lab-sticky-5, .report-data-table.laborbuch td.lab-sticky-5 {
    border-right: 1px solid var(--outline-variant);
}
/* Striping for the frozen cells — must be opaque so scrolling period columns don't show through. */
.report-data-table.laborbuch tbody tr:nth-child(odd) td[class*="lab-sticky-"] { background: var(--surface-container-lowest); }
.report-data-table.laborbuch tbody tr:nth-child(even) td[class*="lab-sticky-"] { background: var(--surface-container-low); }

/* Product-group divider row — same surface family as the header/sticky columns (no odd/even striping),
   a subtle left accent marks it as a section start. td carries the bg too (it's sticky-left). */
.report-data-table.laborbuch tbody tr.lab-group-row td,
.report-data-table.laborbuch tbody tr.lab-group-row:hover td {
    background: var(--surface-container) !important;
    border-left: 3px solid var(--primary);
    color: var(--on-surface);
    text-align: left;   /* the table's default is right-align; keep the product label at the left */
}
/* The product name sticks to the left so it stays visible while the period columns scroll. */
.report-data-table.laborbuch tr.lab-group-row .lab-group-label {
    position: sticky;
    left: 0;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-weight: 600;
    background: var(--surface-container);
    padding-right: 12px;
}
/* Editor: readable data-source path shown under a tile's display name. */
.tile-source-path {
    display: flex; align-items: center; gap: 4px;
    margin-top: 3px; font-size: 0.75rem; line-height: 1.3;
    color: var(--on-surface-variant);
}

.report-data-table .cell-rejected { text-decoration: line-through; opacity: 0.7; }
.report-data-table .empty-cell { color: var(--on-surface-variant); }
.report-site-separator { border-left: 2px solid var(--outline) !important; }

/* ─── Divider tiles (#17) — a tile of type "Divider" renders as a visual separator between parameter groups.
   As a COLUMN (Table / 3D normal, tiles = columns) it's a narrow band with vertical text; as a ROW
   (3D reverted, tiles = rows) it's a labelled horizontal band. */
/* Vertical text is centred by giving the CELL a vertical writing-mode: text-align then centres it along the
   column height, vertical-align across the narrow width. This is reliable in a table cell of any height (no
   absolute-positioning / containing-block quirks) — fills the band top-to-bottom, no white gap. */
.report-divider-col {
    width: 30px; min-width: 30px; max-width: 30px;
    padding: 6px 2px !important;
    background: var(--surface-container-high);
    border-left: 2px solid var(--outline);
    border-right: 2px solid var(--outline);
    writing-mode: vertical-rl;
    text-align: center;
    vertical-align: middle;
}
/* The label lives in the merged body cell (rowspan). Pin it to the TOP so it reads down from just under the
   header, instead of being vertical-centred in the middle of the data. */
/* writing-mode: vertical-rl makes the INLINE axis vertical, so text-align (not vertical-align) controls the
   vertical position. start = top — put the label at the top of the merged cell, right under the header. */
.report-data-table td.report-divider-col { vertical-align: top; text-align: start; }
/* The band must be ONE solid colour across the header + every row. The merged body cell otherwise inherits
   its first row's background (odd/even stripe, :hover, or the green current-day highlight — which is why the
   band looked green and disconnected from the header). Force it, beating those higher-specificity rules. */
.report-data-table tbody td.report-divider-col,
.report-data-table th.report-divider-col {
    background: var(--surface-container-high) !important;
}
/* The divider header carries the .col-header class, which sticks the SECOND header row at top:32px. The other
   headers override this with an inline top:0; the divider didn't, so it stuck 32px too low — leaving a white
   gap above it and spilling into the first data row. Pin it to the top like every other header cell. */
.report-data-table th.report-divider-col { top: 0 !important; }
.report-divider-col .divider-label {
    white-space: nowrap;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    color: var(--on-surface-variant);
}
/* #12 — live-updated cell: one-shot highlight so the user sees which value just changed. */
@keyframes cell-flash-kf {
    0%   { background: var(--tertiary-container); box-shadow: inset 0 0 0 2px var(--tertiary); }
    100% { background: transparent; box-shadow: none; }
}
.report-data-table td.cell-flash { animation: cell-flash-kf 3.5s ease-out; }
.live-updated-chip {
    display: inline-flex; align-items: center; gap: 3px;
    padding: 2px 9px; border-radius: 11px;
    background: var(--tertiary-container); color: var(--on-tertiary-container, var(--on-surface));
    font-size: 0.6875rem; font-weight: 600; white-space: nowrap;
    animation: cell-flash-kf 0.4s ease-out;
}

.report-divider-row td {
    background: var(--surface-container-high);
    border-top: 2px solid var(--outline);
    border-bottom: 2px solid var(--outline);
    padding: 4px 10px !important;
    text-align: left;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.5px;
    color: var(--on-surface-variant);
}
/* The divider-row spans the whole width; keep its label frozen at the left (like the parameter column) so it
   stays visible while scrolling horizontally. */
.report-divider-row .divider-row-label {
    position: sticky;
    left: 0;
    display: inline-block;
    background: var(--surface-container-high);
    padding-right: 10px;
}

/* ─── Report Viewer — Settings Panel ──────────────────────────────── */

.settings-panel {
    border: 1px solid var(--outline-variant);
    background: var(--surface-container-lowest);
    padding: 16px 20px;
    margin-bottom: 16px;
}
.settings-panel .settings-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px 24px;
    align-items: flex-start;
}
.settings-panel .settings-group { display: flex; flex-direction: column; gap: 4px; }
.settings-panel label {
    font-size: 0.6875rem;
    color: var(--on-surface-variant);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.settings-panel select.input,
.settings-panel input.input {
    padding: 6px 10px;
    font-size: 0.875rem;
    min-width: 160px;
    background: var(--surface-container-lowest);
    border-color: var(--outline);
    color: var(--on-surface);
}
.settings-panel .site-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.settings-panel .site-chips .chip {
    cursor: pointer;
    user-select: none;
    background: var(--surface-container);
    color: var(--on-surface-variant);
    border: 1px solid var(--outline-variant);
}
.settings-panel .site-chips .chip.selected {
    background: var(--primary-container);
    color: var(--on-primary-container);
    border-color: var(--primary);
}

/* ─── Report Viewer — View Mode Toggle ────────────────────────────── */

.view-mode-toggle {
    display: inline-flex;
    border: 1px solid rgba(0,0,0,0.12);
    border-radius: 8px;
    background: var(--surface-container-lowest);
    overflow: hidden;
}
.view-mode-toggle button {
    padding: 6px 14px;
    background: transparent;
    border: none;
    border-right: 1px solid rgba(0,0,0,0.12);
    color: var(--on-surface-variant);
    cursor: pointer;
    font-size: 0.8125rem;
    font-weight: 500;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 36px;
}
.view-mode-toggle button:last-child { border-right: none; }
.view-mode-toggle button:hover { background: color-mix(in srgb, var(--on-surface) 7%, transparent); }
.view-mode-toggle button.active {
    background: var(--primary);
    color: var(--on-primary);
}
.view-mode-toggle .material-symbols-outlined { font-size: 16px; }

/* ─── Report viewer toolbar (THOR1-style: clean title row + controls row) ─── */
.viewer-title { font-size: 1.0625rem; font-weight: 600; flex: 1; min-width: 120px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewer-controls-spacer { flex: 1 1 auto; min-width: 8px; }
/* Vertical separator between toolbar icon groups (view | export/share | actions). */
.toolbar-sep { align-self: stretch; width: 1px; background: var(--outline-variant); margin: 2px 4px; flex: 0 0 auto; }

/* While data loads, the whole controls block collapses (and is non-interactive) so no click can fire a
   second request mid-load; it slides back open when the data arrives. grid 1fr/0fr animates the real
   auto-height without a max-height guess. */
.viewer-controls-collapsible { display: grid; grid-template-rows: 1fr;
    transition: grid-template-rows .3s ease; }
.viewer-controls-collapsible.collapsed { grid-template-rows: 0fr; }
.viewer-controls-inner { overflow: visible; min-height: 0; transition: opacity .2s ease; }
.viewer-controls-collapsible.collapsed .viewer-controls-inner { overflow: hidden; opacity: 0; pointer-events: none; }

/* Slide switch for "hide empty columns" (replaces the bare checkbox) */
.switch-toggle { display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
    font-size: 0.8125rem; white-space: nowrap; user-select: none; }
.switch-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track { position: relative; width: 36px; height: 20px; border-radius: 10px;
    background: var(--outline); transition: background .15s ease; flex: 0 0 auto; }
.switch-thumb { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
    border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,0.3);
    transition: transform .15s ease; }
.switch-toggle input:checked + .switch-track { background: color-mix(in srgb, var(--primary) 55%, transparent); }
.switch-toggle input:checked + .switch-track .switch-thumb { transform: translateX(16px); background: var(--primary); }

/* Overflow (⋯) menu */
.overflow-menu { position: relative; display: inline-flex; }
.overflow-backdrop { position: fixed; inset: 0; z-index: 40; background: transparent; }
.overflow-menu-panel { position: absolute; top: calc(100% + 4px); right: 0; z-index: 41;
    min-width: 200px; background: var(--surface, #fff); border: 1px solid rgba(0,0,0,0.12);
    border-radius: 8px; box-shadow: var(--elevation-2, 0 4px 12px rgba(0,0,0,0.18)); padding: 4px; }
.overflow-item { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left;
    background: transparent; border: none; border-radius: 6px; padding: 8px 10px; cursor: pointer;
    font-size: 0.8125rem; color: inherit; }
.overflow-item:hover { background: color-mix(in srgb, var(--on-surface-variant) 8%, transparent); }
.overflow-item:disabled { opacity: .5; cursor: default; }
.overflow-item .material-symbols-outlined { font-size: 18px; }
.overflow-item-check { cursor: pointer; }
.shadow-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: 0 0 auto; }

/* ─── Modal ───────────────────────────────────────────────────────── */

.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}
.modal-dialog {
    background: var(--surface-container-lowest);
    border: 1px solid var(--outline-variant);
    width: 90vw;
    max-width: 960px;
    max-height: 85vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    box-shadow: var(--elevation-3);
}
.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    border-bottom: 1px solid var(--outline-variant);
    background: var(--surface-container);
    gap: 12px;
}
.modal-header h2 { margin: 0; font-size: 1.125rem; }
.modal-body { padding: 20px; overflow-y: auto; flex: 1; color: var(--on-surface); }
.modal-body .settings-row {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: flex-start;
}
.modal-body .settings-row fluent-select,
.modal-body .settings-row .settings-group {
    flex: 1;
    min-width: 180px;
}
.modal-footer {
    padding: 12px 20px;
    border-top: 1px solid var(--outline-variant);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}
.rotating { animation: spin 0.8s linear infinite; }

/* Power BI Presentation Mode: fill the screen with a white background so the report's
   aspect-ratio letterbox reads white, not the browser's black ::backdrop. */
#powerbi-container:fullscreen { width: 100vw; height: 100vh; background: #ffffff; }
#powerbi-container:fullscreen::backdrop { background: #ffffff; }
