/* ============================================================================
   T-PROMO UPM — design system
   Hand-written, no build step. Layers keep specificity predictable so nothing
   here needs !important.
   ========================================================================= */

@layer reset, tokens, base, layout, components, utilities;

/* ---------------------------------------------------------------- reset -- */
@layer reset {
    *, *::before, *::after { box-sizing: border-box; }

    body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ol, ul {
        margin: 0;
    }

    ul[class], ol[class] { list-style: none; padding: 0; }

    input, button, textarea, select { font: inherit; color: inherit; }

    img, svg { display: block; max-width: 100%; }

    table { border-collapse: collapse; }
}

/* --------------------------------------------------------------- tokens -- */
@layer tokens {
    :root {
        /* Surfaces — neutral chrome. Colour is reserved for meaning. */
        --surface:        #ffffff;
        --surface-sunk:   #fafafa;
        --surface-mute:   #f4f4f5;
        --surface-hover:  #f4f4f5;

        /* Text */
        --text:           #18181b;
        --text-secondary: #3f3f46;
        --text-muted:     #71717a;
        --text-subtle:    #a1a1aa;
        --text-on-accent: #ffffff;

        /* Borders */
        --border:         #e4e4e7;
        --border-strong:  #d4d4d8;

        /* Accent ramp, derived from the original brand green #1c5e55 */
        --accent-50:      #ecf5f3;
        --accent-100:     #d3e8e3;
        --accent-200:     #a8d1c8;
        --accent-300:     #74b3a6;
        --accent-400:     #48907f;
        --accent-500:     #2a7365;
        --accent-600:     #1c5e55;
        --accent-700:     #15524a;
        --accent-800:     #114139;
        --accent-900:     #0d332d;
        --accent:         var(--accent-600);
        --accent-hover:   var(--accent-700);

        /* Status */
        --ok:             #15803d;
        --ok-bg:          #f0fdf4;
        --ok-border:      #bbf7d0;
        --warn:           #a16207;
        --warn-bg:        #fefce8;
        --warn-border:    #fde68a;
        --danger:         #b91c1c;
        --danger-bg:      #fef2f2;
        --danger-border:  #fecaca;
        --info:           #1d4ed8;
        --info-bg:        #eff6ff;
        --info-border:    #bfdbfe;

        /* Categorical series for charts */
        --series-1: #1c5e55;
        --series-2: #2a7365;
        --series-3: #48907f;
        --series-4: #74b3a6;

        /* Spacing — 4px base */
        --space-1:  0.25rem;
        --space-2:  0.5rem;
        --space-3:  0.75rem;
        --space-4:  1rem;
        --space-5:  1.25rem;
        --space-6:  1.5rem;
        --space-8:  2rem;
        --space-10: 2.5rem;
        --space-12: 3rem;
        --space-16: 4rem;

        /* Type scale */
        --text-2xs: 0.6875rem; /* 11 */
        --text-xs:  0.75rem;   /* 12 */
        --text-sm:  0.8125rem; /* 13 */
        --text-md:  0.875rem;  /* 14 */
        --text-base:0.9375rem; /* 15 */
        --text-lg:  1.0625rem; /* 17 */
        --text-xl:  1.25rem;   /* 20 */
        --text-2xl: 1.5rem;    /* 24 */
        --text-3xl: 1.875rem;  /* 30 */

        --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto,
                     "Helvetica Neue", Arial, sans-serif;
        --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
                     "Liberation Mono", monospace;

        /* Radii */
        --radius-sm: 4px;
        --radius:    6px;
        --radius-md: 8px;
        --radius-lg: 12px;

        /* Elevation */
        --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
        --shadow:    0 1px 3px rgb(0 0 0 / 0.08), 0 1px 2px rgb(0 0 0 / 0.04);
        --shadow-md: 0 4px 12px rgb(0 0 0 / 0.08), 0 2px 4px rgb(0 0 0 / 0.04);
        --shadow-lg: 0 12px 32px rgb(0 0 0 / 0.12), 0 4px 8px rgb(0 0 0 / 0.06);

        /* Motion */
        --ease: cubic-bezier(0.4, 0, 0.2, 1);
        --duration: 150ms;

        /* Layout metrics */
        --topbar-h: 56px;
        --sidebar-w: 244px;
        --sidebar-w-collapsed: 60px;

        /* Table density, switched by [data-density] */
        --row-py: var(--space-3);
    }

    [data-density="compact"] { --row-py: var(--space-1); }
}

/* ----------------------------------------------------------------- base -- */
@layer base {
    html { -webkit-text-size-adjust: 100%; }

    body {
        font-family: var(--font-sans);
        font-size: var(--text-base);
        line-height: 1.55;
        color: var(--text);
        background: var(--surface-sunk);
        -webkit-font-smoothing: antialiased;
    }

    h1, h2, h3 { line-height: 1.3; font-weight: 600; letter-spacing: -0.011em; }
    h1 { font-size: var(--text-2xl); }
    h2 { font-size: var(--text-lg); }
    h3 { font-size: var(--text-base); }

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

    code {
        font-family: var(--font-mono);
        font-size: 0.9em;
        background: var(--surface-mute);
        padding: 0.1em 0.35em;
        border-radius: var(--radius-sm);
    }

    /* One consistent focus treatment everywhere. */
    :focus-visible {
        outline: 2px solid var(--accent);
        outline-offset: 2px;
        border-radius: var(--radius-sm);
    }
    :focus:not(:focus-visible) { outline: none; }

    @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after {
            animation-duration: 0.01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: 0.01ms !important;
            scroll-behavior: auto !important;
        }
    }
}

/* --------------------------------------------------------------- layout -- */
@layer layout {
    .skip-link {
        position: absolute;
        left: var(--space-2);
        top: -100px;
        z-index: 100;
        background: var(--accent);
        color: var(--text-on-accent);
        padding: var(--space-2) var(--space-4);
        border-radius: var(--radius);
        transition: top var(--duration) var(--ease);
    }
    .skip-link:focus { top: var(--space-2); text-decoration: none; }

    /* --- top bar --- */
    .topbar {
        position: sticky;
        top: 0;
        z-index: 30;
        height: var(--topbar-h);
        display: flex;
        align-items: center;
        gap: var(--space-4);
        padding-inline: var(--space-4);
        background: var(--surface);
        border-bottom: 1px solid var(--border);
    }

    .brand {
        display: flex;
        align-items: center;
        gap: var(--space-2);
        font-size: var(--text-lg);
        font-weight: 650;
        letter-spacing: -0.02em;
        color: var(--text);
    }
    .brand:hover { text-decoration: none; }
    .brand-mark {
        width: 26px; height: 26px;
        display: grid; place-items: center;
        background: var(--accent);
        color: var(--text-on-accent);
        border-radius: var(--radius);
        font-size: var(--text-xs);
        font-weight: 700;
        letter-spacing: 0;
    }
    .brand-sub { color: var(--text-subtle); font-weight: 400; }

    .topbar-spacer { flex: 1; }

    .icon-btn {
        display: grid; place-items: center;
        width: 34px; height: 34px;
        background: none;
        border: 1px solid transparent;
        border-radius: var(--radius);
        color: var(--text-muted);
        cursor: pointer;
        transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
    }
    .icon-btn:hover { background: var(--surface-hover); color: var(--text); }

    .user-chip {
        display: flex; align-items: center; gap: var(--space-2);
        font-size: var(--text-md); color: var(--text-secondary);
    }
    .avatar {
        width: 26px; height: 26px; border-radius: 50%;
        display: grid; place-items: center;
        background: var(--accent-100); color: var(--accent-700);
        font-size: var(--text-xs); font-weight: 650;
        text-transform: uppercase;
    }

    /* --- shell --- */
    .shell { display: flex; align-items: stretch; min-height: calc(100dvh - var(--topbar-h)); }

    .sidebar {
        flex: 0 0 var(--sidebar-w);
        width: var(--sidebar-w);
        background: var(--surface);
        border-right: 1px solid var(--border);
        padding: var(--space-3) 0 var(--space-8);
        position: sticky;
        top: var(--topbar-h);
        height: calc(100dvh - var(--topbar-h));
        overflow-y: auto;
        transition: flex-basis var(--duration) var(--ease), width var(--duration) var(--ease);
    }

    .nav-group {
        padding: var(--space-4) var(--space-4) var(--space-1);
        font-size: var(--text-2xs);
        font-weight: 650;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: var(--text-subtle);
        white-space: nowrap;
    }

    .nav-link {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        margin-inline: var(--space-2);
        padding: var(--space-2) var(--space-3);
        border-radius: var(--radius);
        color: var(--text-secondary);
        font-size: var(--text-md);
        white-space: nowrap;
        transition: background var(--duration) var(--ease), color var(--duration) var(--ease);
    }
    .nav-link:hover { background: var(--surface-hover); color: var(--text); text-decoration: none; }
    .nav-link svg { flex: 0 0 17px; width: 17px; height: 17px; opacity: 0.75; }

    /* The legacy app gave no indication of the current page at all. */
    .nav-link[aria-current="page"] {
        background: var(--accent-50);
        color: var(--accent-700);
        font-weight: 600;
    }
    .nav-link[aria-current="page"] svg { opacity: 1; }

    .content {
        flex: 1;
        min-width: 0;
        padding: var(--space-6) var(--space-8) var(--space-16);
    }
    .content-inner { max-width: 1400px; }

    /* Collapsed sidebar — labels hide, icons remain. */
    body[data-sidebar="collapsed"] .sidebar {
        flex-basis: var(--sidebar-w-collapsed);
        width: var(--sidebar-w-collapsed);
    }
    body[data-sidebar="collapsed"] .nav-label,
    body[data-sidebar="collapsed"] .nav-group { display: none; }
    body[data-sidebar="collapsed"] .nav-link { justify-content: center; padding-inline: 0; }

    /* Narrow viewports: the sidebar becomes a horizontal strip rather than
       stealing width. Not a phone-optimised experience, but it does not break. */
    @media (max-width: 900px) {
        .shell { flex-direction: column; }
        .sidebar {
            position: static;
            width: 100%;
            flex-basis: auto;
            height: auto;
            display: flex;
            gap: var(--space-1);
            overflow-x: auto;
            padding: var(--space-2);
            border-right: none;
            border-bottom: 1px solid var(--border);
        }
        .nav-group { display: none; }
        .nav-link { margin: 0; }
        .content { padding: var(--space-5) var(--space-4) var(--space-12); }
    }

    /* --- primitives --- */
    .stack > * + * { margin-top: var(--flow, var(--space-5)); }
    .cluster { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
    .split { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); }
    .grid-auto {
        display: grid;
        gap: var(--space-4);
        grid-template-columns: repeat(auto-fit, minmax(var(--col-min, 180px), 1fr));
    }
}

/* ----------------------------------------------------------- components -- */
@layer components {
    /* --- page header --- */
    .page-header {
        display: flex;
        justify-content: space-between;
        align-items: flex-start;
        gap: var(--space-4);
        flex-wrap: wrap;
        margin-bottom: var(--space-6);
    }
    .page-title { font-size: var(--text-2xl); margin-bottom: var(--space-1); }
    .page-description { color: var(--text-muted); font-size: var(--text-md); max-width: 68ch; }
    .page-actions { display: flex; gap: var(--space-2); flex-shrink: 0; }

    /* --- card --- */
    .card {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        box-shadow: var(--shadow-sm);
    }
    .card-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        gap: var(--space-4);
        padding: var(--space-4) var(--space-5);
        border-bottom: 1px solid var(--border);
    }
    .card-title { font-size: var(--text-base); font-weight: 600; }
    .card-subtitle { font-size: var(--text-sm); color: var(--text-muted); margin-top: 2px; }
    .card-body { padding: var(--space-5); }
    .card-body.is-flush { padding: 0; }
    .card-footer {
        padding: var(--space-4) var(--space-5);
        border-top: 1px solid var(--border);
        background: var(--surface-sunk);
        border-radius: 0 0 var(--radius-md) var(--radius-md);
    }

    /* --- stat --- */
    .stat {
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-md);
        padding: var(--space-4) var(--space-5);
        box-shadow: var(--shadow-sm);
    }
    .stat-label {
        font-size: var(--text-xs);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
        color: var(--text-muted);
        margin-bottom: var(--space-2);
    }
    .stat-value {
        font-size: var(--text-2xl);
        font-weight: 650;
        letter-spacing: -0.02em;
        font-variant-numeric: tabular-nums;
        line-height: 1.15;
    }
    .stat-hint { font-size: var(--text-xs); color: var(--text-subtle); margin-top: var(--space-1); }

    /* --- buttons --- */
    .btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--space-2);
        padding: var(--space-2) var(--space-4);
        min-height: 34px;
        border: 1px solid transparent;
        border-radius: var(--radius);
        font-size: var(--text-md);
        font-weight: 550;
        cursor: pointer;
        white-space: nowrap;
        transition: background var(--duration) var(--ease), border-color var(--duration) var(--ease);
    }
    .btn:hover { text-decoration: none; }
    .btn svg { width: 15px; height: 15px; }

    .btn-primary { background: var(--accent); color: var(--text-on-accent); }
    .btn-primary:hover { background: var(--accent-hover); }

    .btn-secondary {
        background: var(--surface);
        color: var(--text-secondary);
        border-color: var(--border-strong);
        box-shadow: var(--shadow-sm);
    }
    .btn-secondary:hover { background: var(--surface-hover); color: var(--text); }

    .btn-danger { background: var(--danger); color: #fff; }
    .btn-danger:hover { background: #991b1b; }

    .btn-ghost { background: none; color: var(--text-muted); }
    .btn-ghost:hover { background: var(--surface-hover); color: var(--text); }

    .btn:disabled { opacity: 0.5; cursor: not-allowed; }
    .btn-sm { min-height: 28px; padding: var(--space-1) var(--space-3); font-size: var(--text-sm); }

    /* --- forms --- */
    .field { display: flex; flex-direction: column; gap: var(--space-2); }
    .field-label { font-size: var(--text-md); font-weight: 550; color: var(--text-secondary); }
    .field-hint { font-size: var(--text-sm); color: var(--text-muted); }
    .field-error { font-size: var(--text-sm); color: var(--danger); }

    .input, input[type=text], input[type=password], input[type=number],
    input[type=email], select, textarea {
        width: 100%;
        padding: var(--space-2) var(--space-3);
        min-height: 34px;
        background: var(--surface);
        border: 1px solid var(--border-strong);
        border-radius: var(--radius);
        font-size: var(--text-md);
        transition: border-color var(--duration) var(--ease), box-shadow var(--duration) var(--ease);
    }
    .input:hover, input:hover, select:hover { border-color: var(--text-subtle); }
    .input:focus, input:focus, select:focus, textarea:focus {
        border-color: var(--accent);
        box-shadow: 0 0 0 3px var(--accent-50);
        outline: none;
    }
    textarea { min-height: 96px; resize: vertical; }
    select {
        appearance: none;
        padding-right: var(--space-8);
        background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath fill='%2371717a' d='M3 4.5 6 8l3-3.5z'/%3E%3C/svg%3E");
        background-repeat: no-repeat;
        background-position: right var(--space-3) center;
        background-size: 12px;
    }

    /* --- selectable option card, used by promo generation --- */
    .option-card {
        display: flex;
        gap: var(--space-3);
        padding: var(--space-4);
        border: 1px solid var(--border-strong);
        border-radius: var(--radius-md);
        background: var(--surface);
        cursor: pointer;
        transition: border-color var(--duration) var(--ease), background var(--duration) var(--ease);
    }
    .option-card:hover { border-color: var(--accent-300); background: var(--accent-50); }
    .option-card:has(input:checked) {
        border-color: var(--accent);
        background: var(--accent-50);
        box-shadow: 0 0 0 1px var(--accent);
    }
    .option-card input { margin-top: 3px; accent-color: var(--accent); flex: 0 0 auto; width: auto; min-height: 0; }
    .option-card-title { font-weight: 600; font-size: var(--text-md); }
    .option-card-desc { font-size: var(--text-sm); color: var(--text-muted); margin-top: 2px; }

    .check { display: flex; align-items: center; gap: var(--space-2); }
    .check input { width: auto; min-height: 0; accent-color: var(--accent); }

    /* --- messages --- */
    .msg {
        display: flex;
        gap: var(--space-3);
        padding: var(--space-3) var(--space-4);
        border: 1px solid;
        border-radius: var(--radius);
        font-size: var(--text-md);
    }
    .msg svg { flex: 0 0 17px; width: 17px; height: 17px; margin-top: 2px; }
    .msg ul { margin-top: var(--space-2); padding-left: var(--space-4); list-style: disc; }
    .msg-ok     { background: var(--ok-bg);     border-color: var(--ok-border);     color: var(--ok); }
    .msg-warn   { background: var(--warn-bg);   border-color: var(--warn-border);   color: var(--warn); }
    .msg-err    { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger); }
    .msg-info   { background: var(--info-bg);   border-color: var(--info-border);   color: var(--info); }

    /* --- empty state --- */
    .empty {
        display: grid;
        justify-items: center;
        text-align: center;
        gap: var(--space-3);
        padding: var(--space-12) var(--space-6);
        color: var(--text-muted);
    }
    .empty-icon {
        width: 40px; height: 40px;
        display: grid; place-items: center;
        background: var(--surface-mute);
        border-radius: 50%;
        color: var(--text-subtle);
    }
    .empty-title { font-size: var(--text-base); font-weight: 600; color: var(--text); }
    .empty-text { font-size: var(--text-md); max-width: 46ch; }

    /* --- toolbar --- */
    .toolbar {
        display: flex;
        flex-wrap: wrap;
        gap: var(--space-3);
        align-items: flex-end;
        padding: var(--space-4) var(--space-5);
        border-bottom: 1px solid var(--border);
    }
    .toolbar .field { min-width: 180px; }
    .toolbar-spacer { flex: 1; }

    /* --- table --- */
    .table-wrap {
        overflow-x: auto;
        /* Shadows at the edges reveal that content is scrolled out of view. */
        background:
            linear-gradient(to right, var(--surface) 30%, transparent) left / 40px 100% no-repeat,
            linear-gradient(to left,  var(--surface) 30%, transparent) right / 40px 100% no-repeat,
            radial-gradient(farthest-side at 0 50%, rgb(0 0 0 / 0.09), transparent) left / 14px 100% no-repeat,
            radial-gradient(farthest-side at 100% 50%, rgb(0 0 0 / 0.09), transparent) right / 14px 100% no-repeat;
        background-attachment: local, local, scroll, scroll;
    }

    .data-table { width: 100%; font-size: var(--text-md); }
    .data-table th {
        position: sticky;
        top: 0;
        z-index: 1;
        background: var(--surface-mute);
        text-align: left;
        font-size: var(--text-xs);
        font-weight: 650;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--text-muted);
        padding: var(--space-3) var(--space-4);
        border-bottom: 1px solid var(--border);
        white-space: nowrap;
    }
    .data-table td {
        padding: var(--row-py) var(--space-4);
        border-bottom: 1px solid var(--border);
        white-space: nowrap;
    }
    .data-table tbody tr:last-child td { border-bottom: none; }
    .data-table tbody tr { transition: background var(--duration) var(--ease); }
    .data-table tbody tr:hover { background: var(--accent-50); }
    .data-table .num { text-align: right; font-variant-numeric: tabular-nums; }
    .data-table .mono { font-family: var(--font-mono); font-size: var(--text-sm); }

    /* sortable headers */
    .th-sort { padding: 0; }
    .th-sort a {
        display: flex;
        align-items: center;
        gap: var(--space-1);
        padding: var(--space-3) var(--space-4);
        color: inherit;
        font: inherit;
    }
    .th-sort a:hover { color: var(--text); background: var(--border); text-decoration: none; }
    .th-sort.num a { justify-content: flex-end; }
    .sort-arrow { opacity: 0.35; width: 11px; height: 11px; }
    [aria-sort="ascending"] .sort-arrow,
    [aria-sort="descending"] .sort-arrow { opacity: 1; color: var(--accent); }
    [aria-sort="descending"] .sort-arrow { transform: rotate(180deg); }

    .badge {
        display: inline-flex;
        align-items: center;
        padding: 1px var(--space-2);
        border-radius: 999px;
        font-size: var(--text-xs);
        font-weight: 600;
        background: var(--surface-mute);
        color: var(--text-secondary);
    }
    .badge-accent { background: var(--accent-50); color: var(--accent-700); }
    .badge-code {
        font-family: var(--font-mono);
        background: var(--accent-50);
        color: var(--accent-700);
        letter-spacing: 0.02em;
    }

    /* --- pagination --- */
    .pagination {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: var(--space-3);
        padding: var(--space-3) var(--space-5);
        border-top: 1px solid var(--border);
        font-size: var(--text-md);
        color: var(--text-muted);
    }
    .pagination-pages { display: flex; gap: var(--space-1); align-items: center; }
    .page-link {
        display: grid; place-items: center;
        min-width: 30px; height: 30px;
        padding-inline: var(--space-2);
        border: 1px solid var(--border);
        border-radius: var(--radius-sm);
        background: var(--surface);
        color: var(--text-secondary);
        font-size: var(--text-sm);
        font-variant-numeric: tabular-nums;
    }
    .page-link:hover { background: var(--surface-hover); text-decoration: none; }
    .page-link[aria-current="page"] {
        background: var(--accent);
        border-color: var(--accent);
        color: var(--text-on-accent);
        font-weight: 600;
    }
    .page-gap { padding-inline: var(--space-1); color: var(--text-subtle); }
    .page-size { display: flex; align-items: center; gap: var(--space-2); }
    .page-size select { width: auto; min-height: 30px; padding-block: 0; font-size: var(--text-sm); }

    /* --- charts ---
       Bar widths come from a --pct custom property set in a nonced <style>
       block, so the strict CSP holds without 'unsafe-inline'. */
    .chart { display: flex; flex-direction: column; gap: var(--space-2); }
    .chart-row {
        display: grid;
        grid-template-columns: var(--label-w, 150px) 1fr auto;
        align-items: center;
        gap: var(--space-3);
        font-size: var(--text-md);
    }
    .chart-label {
        color: var(--text-secondary);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .chart-track {
        position: relative;
        background: var(--surface-mute);
        border-radius: var(--radius-sm);
        height: 22px;
        overflow: hidden;
    }
    .chart-bar {
        height: 100%;
        width: calc(var(--pct, 0) * 1%);
        background: var(--accent);
        border-radius: var(--radius-sm);
        transition: width 400ms var(--ease);
    }
    .chart-row:hover .chart-bar { background: var(--accent-700); }
    .chart-value {
        font-variant-numeric: tabular-nums;
        color: var(--text-secondary);
        font-size: var(--text-sm);
        min-width: 56px;
        text-align: right;
    }
    .chart-share { color: var(--text-subtle); font-size: var(--text-xs); min-width: 42px; text-align: right; }

    /* --- chart tooltip (positioned by app.js) --- */
    .chart-tip {
        position: fixed;
        z-index: 70;
        padding: var(--space-1) var(--space-3);
        background: var(--text);
        color: var(--surface);
        border-radius: var(--radius-sm);
        font-size: var(--text-sm);
        white-space: nowrap;
        pointer-events: none;
        opacity: 0;
        transition: opacity var(--duration) var(--ease);
    }
    .chart-tip[data-visible] { opacity: 1; }

    /* --- file drop zone --- */
    .file-zone {
        display: grid;
        justify-items: center;
        gap: var(--space-2);
        padding: var(--space-8);
        border: 1.5px dashed var(--border-strong);
        border-radius: var(--radius-md);
        background: var(--surface-sunk);
        text-align: center;
        cursor: pointer;
        transition: border-color var(--duration) var(--ease), background var(--duration) var(--ease);
    }
    .file-zone:hover { border-color: var(--accent-300); background: var(--accent-50); }
    .file-zone:focus-within { border-color: var(--accent); background: var(--accent-50); }
    .file-zone input[type=file] {
        position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
    }
    .file-name { font-size: var(--text-md); color: var(--text-muted); }
    .file-name[data-has-file] { color: var(--accent-700); font-weight: 600; }

    /* --- toast --- */
    .toast-region {
        position: fixed;
        bottom: var(--space-5);
        right: var(--space-5);
        z-index: 60;
        display: flex;
        flex-direction: column;
        gap: var(--space-2);
        pointer-events: none;
    }
    .toast {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        padding: var(--space-3) var(--space-4);
        background: var(--surface);
        border: 1px solid var(--border);
        border-left: 3px solid var(--accent);
        border-radius: var(--radius);
        box-shadow: var(--shadow-lg);
        font-size: var(--text-md);
        pointer-events: auto;
        animation: toast-in 200ms var(--ease);
    }
    .toast-ok { border-left-color: var(--ok); }
    .toast-err { border-left-color: var(--danger); }
    @keyframes toast-in {
        from { opacity: 0; transform: translateY(8px); }
        to   { opacity: 1; transform: none; }
    }

    /* --- login --- */
    .login-wrap {
        min-height: 100dvh;
        display: grid;
        place-items: center;
        padding: var(--space-6);
        background:
            radial-gradient(60rem 40rem at 50% -10%, var(--accent-50), transparent),
            var(--surface-sunk);
    }
    .login-card {
        width: 100%;
        max-width: 380px;
        background: var(--surface);
        border: 1px solid var(--border);
        border-radius: var(--radius-lg);
        box-shadow: var(--shadow-md);
        padding: var(--space-8);
    }
    .login-brand {
        display: flex; align-items: center; gap: var(--space-3);
        margin-bottom: var(--space-6);
    }

    /* --- workflow steps --- */
    .steps { display: flex; flex-direction: column; gap: 0; }
    .step {
        display: flex;
        gap: var(--space-4);
        padding: var(--space-3) 0;
        position: relative;
    }
    .step + .step { border-top: 1px solid var(--border); }
    .step-num {
        flex: 0 0 24px;
        width: 24px; height: 24px;
        display: grid; place-items: center;
        border-radius: 50%;
        background: var(--surface-mute);
        color: var(--text-muted);
        font-size: var(--text-xs);
        font-weight: 650;
    }
    .step.is-done .step-num { background: var(--ok); color: #fff; }
    .step.is-next .step-num { background: var(--accent); color: #fff; }
    .step-body { flex: 1; min-width: 0; }
    .step-title { font-weight: 550; font-size: var(--text-md); }
    .step-desc { font-size: var(--text-sm); color: var(--text-muted); }
}

/* ------------------------------------------------------------ utilities -- */
@layer utilities {
    /* The icon sprite must not occupy layout space. */
    .svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

    .muted { color: var(--text-muted); font-size: var(--text-md); }
    .subtle { color: var(--text-subtle); }
    .num { font-variant-numeric: tabular-nums; }
    .mono { font-family: var(--font-mono); }
    .text-sm { font-size: var(--text-sm); }
    .nowrap { white-space: nowrap; }
    .mw-form { max-width: 420px; }
    .mw-prose { max-width: 68ch; }
    .flow-sm { --flow: var(--space-3); }

    /* Available to screen readers, invisible on screen. Used for the chart
       data tables so the values are readable without the visual. */
    .visually-hidden {
        position: absolute !important;
        width: 1px; height: 1px;
        padding: 0; margin: -1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        white-space: nowrap;
        border: 0;
    }
}

/* ------------------------------------------------------------------ print */
@media print {
    .topbar, .sidebar, .page-actions, .pagination, .toolbar, .skip-link { display: none !important; }
    .content { padding: 0; }
    .card { border: 1px solid #ccc; box-shadow: none; break-inside: avoid; }
    .data-table th { background: #eee !important; color: #000 !important; }
}
