/* --------------------------------------------------------------------------
   Caenode — application styles

   Hand-written rather than Bootstrap. First-load size is the one real risk of
   a WASM app, and the framework CSS would be a larger download than everything
   this file needs.

   LIGHT ONLY, on purpose. There is deliberately no `prefers-color-scheme: dark`
   block: an engineer reading a pressure table wants the same paper-like page
   whatever their operating system is set to, and a dark variant that nobody
   reviewed is worse than none. `color-scheme: light` below also stops the
   browser from darkening form controls on a dark-mode machine — without it the
   inputs go black even though the page does not.

   Accent colours are sampled from the logo; the greys are warm rather than
   blue-grey, which keeps large light surfaces from looking clinical.
   -------------------------------------------------------------------------- */

:root {
    color-scheme: light;

    /* Brand, from the logo */
    --teal: #0e9ea8;
    --green: #6ed162;
    --purple: #7d5fee;
    --indigo: #2f2eb7;

    /* Softened for text and fills: the raw logo indigo is too heavy at body size */
    --brand-ink: #1d6f8b;
    --brand-gradient: linear-gradient(100deg, var(--teal), var(--green));
    --brand-wash: #eefaf8;

    /* Surfaces — warm, high-key */
    --bg: #fbfcfd;
    --surface: #ffffff;
    --surface-2: #f4f7f9;
    --surface-3: #eef3f6;
    --border: #e4eaee;
    --border-strong: #cfd9e0;

    /* Text — dark slate, never true black */
    --text: #263241;
    --text-muted: #5d6b7a;
    --text-faint: #8b98a5;

    /* Status — muted, not alarming */
    --danger: #b4453c;
    --danger-bg: #fdf0ee;
    --danger-border: #f2ccc6;
    --warn: #8a6212;
    --warn-bg: #fdf6e6;
    --warn-border: #efdfb8;
    --info-bg: #f0f6fb;
    --info-border: #d6e6f2;

    --radius: 12px;
    --radius-sm: 8px;
    --shadow-sm: 0 1px 2px rgba(38, 50, 65, .04);
    --shadow: 0 1px 2px rgba(38, 50, 65, .04), 0 6px 20px rgba(38, 50, 65, .05);

    --sidebar-w: 250px;

    --mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, monospace;
    --sans: system-ui, -apple-system, "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    font-family: var(--sans);
    background: var(--bg);
    color: var(--text);
    font-size: 15px;
    line-height: 1.55;
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { line-height: 1.28; margin: 0 0 .5rem; font-weight: 640; letter-spacing: -.01em; }
h1 { font-size: 1.65rem; }
h2 { font-size: 1.2rem; }
h3 { font-size: 1rem; }
p { margin: 0 0 1rem; }
a { color: var(--brand-ink); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---------------------------------------------------------------- layout -- */

.shell { display: flex; min-height: 100vh; }

.shell-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.content {
    flex: 1;
    padding: 1.75rem 2rem 3rem;
    max-width: 1180px;
    width: 100%;
    margin-inline: auto;
}

.topbar {
    display: flex;
    align-items: center;
    gap: .75rem;
    padding: .6rem 2rem;
    border-bottom: 1px solid var(--border);
    background: rgba(255, 255, 255, .88);
    backdrop-filter: saturate(1.4) blur(6px);
    position: sticky;
    top: 0;
    z-index: 20;
}

.topbar-spacer { flex: 1; }

.account { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.account-name { font-size: .86rem; color: var(--text-muted); }
.account-link { display: flex; align-items: center; gap: .5rem; color: inherit; }
.account-link:hover { text-decoration: none; opacity: .8; }

.plan-chip {
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .02em;
    padding: .12rem .55rem;
    border-radius: 999px;
    background: var(--brand-gradient);
    color: #fff;
}

.footer {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    padding: 1rem 2rem;
    border-top: 1px solid var(--border);
    font-size: .78rem;
    color: var(--text-faint);
}

.footer-warning { font-style: italic; }

/* --------------------------------------------------------------- sidebar -- */

.sidebar {
    width: var(--sidebar-w);
    flex-shrink: 0;
    background: var(--surface);
    border-right: 1px solid var(--border);
    display: flex;
    flex-direction: column;
    padding: 1.1rem .75rem;
    gap: 1.4rem;
    position: sticky;
    top: 0;
    height: 100vh;
    overflow-y: auto;
}

.brand { display: block; padding: .2rem .5rem 0; }
.brand:hover { text-decoration: none; }
.brand-logo { width: 100%; max-width: 168px; height: auto; display: block; }

.nav-group { display: flex; flex-direction: column; gap: .12rem; }

.nav-group-title {
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .07em;
    color: var(--text-faint);
    padding: 0 .65rem .35rem;
}

.nav-item {
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .48rem .65rem;
    border-radius: var(--radius-sm);
    color: var(--text-muted);
    font-size: .9rem;
    font-weight: 500;
}

.nav-item:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }

.nav-item.active {
    background: var(--brand-wash);
    color: var(--brand-ink);
    font-weight: 600;
}

.nav-item.disabled { color: var(--text-faint); cursor: default; }
.nav-item.disabled:hover { background: none; color: var(--text-faint); }

.nav-icon { width: 1.1rem; text-align: center; opacity: .75; font-size: .95rem; }

.badge {
    margin-left: auto;
    font-size: .64rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    padding: .1rem .42rem;
    border-radius: 999px;
    background: var(--surface-2);
    border: 1px solid var(--border);
    color: var(--text-faint);
}

.nav-footer { margin-top: auto; padding: .65rem; }
.nav-note { font-size: .74rem; color: var(--text-faint); line-height: 1.5; }

.nav-toggle { display: none; }

/* --------------------------------------------------------------- buttons -- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    padding: .5rem .95rem;
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    font: inherit;
    font-weight: 600;
    font-size: .88rem;
    cursor: pointer;
    transition: filter .12s ease, background .12s ease, border-color .12s ease;
    white-space: nowrap;
}

.btn:hover { text-decoration: none; }
.btn:disabled { opacity: .5; cursor: not-allowed; filter: none; }

.btn-sm { padding: .36rem .75rem; font-size: .82rem; }

.btn-primary { background: var(--brand-gradient); color: #fff; box-shadow: var(--shadow-sm); }
.btn-primary:hover { filter: brightness(1.05); }

.btn-outline { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.btn-outline:hover { background: var(--surface-2); }

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

.icon-btn { background: none; border: none; cursor: pointer; padding: .4rem; color: var(--text); }

/* ----------------------------------------------------------------- cards -- */

.card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.2rem 1.3rem;
    box-shadow: var(--shadow);
}

.card + .card { margin-top: 1.25rem; }

.card-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: .9rem;
}

.card-title h2 { margin: 0; }
.card-subtitle { font-size: .8rem; color: var(--text-faint); }

/* ----------------------------------------------------------------- forms -- */

.field-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: .9rem 1.1rem;
}

.field { display: flex; flex-direction: column; gap: .3rem; }

.field label { font-size: .8rem; font-weight: 600; color: var(--text-muted); }

.field .hint, .hint { font-size: .74rem; color: var(--text-faint); }

.field input,
.field select {
    font: inherit;
    font-size: .9rem;
    padding: .48rem .6rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    width: 100%;
}

.field input:hover,
.field select:hover { border-color: #b9c7d1; }

.field input:focus,
.field select:focus {
    outline: 3px solid rgba(14, 158, 168, .18);
    outline-offset: 0;
    border-color: var(--teal);
}

.symbol { font-family: var(--mono); font-size: .95em; }

/* ---------------------------------------------------------------- tables -- */

.table-wrap { overflow-x: auto; }

table.data {
    width: 100%;
    border-collapse: collapse;
    font-size: .85rem;
    font-variant-numeric: tabular-nums;
}

table.data th,
table.data td {
    padding: .48rem .6rem;
    text-align: right;
    border-bottom: 1px solid var(--border);
    white-space: nowrap;
}

table.data th {
    font-size: .71rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--text-faint);
    font-weight: 700;
    border-bottom: 1px solid var(--border-strong);
    background: var(--surface-2);
}

table.data th:first-child,
table.data td:first-child { text-align: left; }

table.data tbody tr:hover { background: var(--surface-2); }

.zone-tag {
    display: inline-block;
    min-width: 1.5rem;
    text-align: center;
    font-family: var(--mono);
    font-weight: 700;
    padding: .05rem .38rem;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    color: var(--text-muted);
}

/* A is the suction peak and D the pressure peak — the two rows an engineer
   looks for first, so they get a tint. The rest stay neutral. */
.zone-A { background: #fdefec; border-color: #f3d2cb; color: #a2493f; }
.zone-D { background: #ecf8f0; border-color: #c9e6d3; color: #2c7048; }

.num-negative { color: var(--danger); }

/* -------------------------------------------------------------- messages -- */

.messages { display: flex; flex-direction: column; gap: .45rem; margin-top: .9rem; }

.message {
    display: flex;
    gap: .55rem;
    padding: .58rem .8rem;
    border-radius: var(--radius-sm);
    font-size: .83rem;
    border: 1px solid transparent;
}

.message-error { background: var(--danger-bg); border-color: var(--danger-border); color: var(--danger); }
.message-warning { background: var(--warn-bg); border-color: var(--warn-border); color: var(--warn); }
.message-info { background: var(--info-bg); border-color: var(--info-border); color: var(--text-muted); }

.message .clause { font-family: var(--mono); font-size: .76rem; opacity: .8; }

/* ----------------------------------------------------------------- trace -- */

details.trace { margin-top: 1rem; }

details.trace > summary {
    cursor: pointer;
    font-size: .85rem;
    font-weight: 600;
    color: var(--text-muted);
    padding: .4rem .6rem;
    border-radius: var(--radius-sm);
    background: var(--surface-2);
    list-style-position: inside;
}

details.trace > summary:hover { background: var(--surface-3); color: var(--text); }

table.trace-table {
    width: 100%;
    border-collapse: collapse;
    font-family: var(--mono);
    font-size: .78rem;
    margin-top: .6rem;
}

table.trace-table td {
    padding: .32rem .5rem;
    border-bottom: 1px solid var(--border);
    vertical-align: top;
}

table.trace-table tr:nth-child(odd) td { background: var(--surface-2); }

table.trace-table .t-symbol { font-weight: 700; white-space: nowrap; color: var(--brand-ink); }
table.trace-table .t-expr { color: var(--text-muted); word-break: break-word; }
table.trace-table .t-value { text-align: right; white-space: nowrap; }
table.trace-table .t-clause { color: var(--text-faint); white-space: nowrap; font-size: .72rem; }

/* ------------------------------------------------------- language picker -- */

.lang { position: relative; }

.lang-button {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .3rem .55rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: .82rem;
    font-weight: 600;
    cursor: pointer;
}

.lang-button:hover { background: var(--surface-2); }

.flag {
    width: 20px;
    height: 14px;
    object-fit: cover;
    border-radius: 2px;
    display: block;
    border: 1px solid rgba(38, 50, 65, .12);
}

.lang-code { letter-spacing: .02em; }
.caret { font-size: .6rem; opacity: .55; }

/* Catches the click that closes the menu, without any JS document listener. */
.lang-backdrop { position: fixed; inset: 0; z-index: 30; }

.lang-menu {
    position: absolute;
    top: calc(100% + .35rem);
    right: 0;
    z-index: 31;
    margin: 0;
    padding: .25rem;
    list-style: none;
    min-width: 168px;
    background: var(--surface);
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow);
}

.lang-option {
    display: flex;
    align-items: center;
    gap: .55rem;
    width: 100%;
    padding: .4rem .5rem;
    border: none;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font: inherit;
    font-size: .85rem;
    cursor: pointer;
    text-align: left;
}

.lang-option:hover { background: var(--surface-2); }
.lang-option.selected { font-weight: 650; background: var(--brand-wash); color: var(--brand-ink); }

/* ------------------------------------------------------------- home page -- */

.hero {
    display: grid;
    grid-template-columns: 1.25fr 1fr;
    gap: 2.5rem;
    align-items: center;
    padding: 1rem 0 2.5rem;
}

.hero h1 { font-size: 2.1rem; letter-spacing: -.02em; }

.hero-lead { font-size: 1rem; color: var(--text-muted); max-width: 48ch; }

.hero-actions { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.2rem; }

.hero-art { display: flex; justify-content: center; }
.hero-art img { width: 100%; max-width: 300px; height: auto; }

.gradient-text {
    background: var(--brand-gradient);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.tile-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1rem;
}

.tile {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 1.15rem;
    box-shadow: var(--shadow-sm);
}

.tile h3 { margin-bottom: .35rem; }
.tile p { font-size: .87rem; color: var(--text-muted); margin: 0; }

a.tile-link { color: inherit; display: block; transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease; }
a.tile-link:hover { text-decoration: none; border-color: var(--teal); transform: translateY(-1px); box-shadow: var(--shadow); }

.tile-status {
    display: inline-block;
    font-size: .68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .05em;
    padding: .14rem .5rem;
    border-radius: 999px;
    margin-bottom: .6rem;
}

.status-ready { background: var(--brand-gradient); color: #fff; }

.section { margin-top: 2.5rem; }
.section > h2 { margin-bottom: 1rem; }

/* ------------------------------------------------------------ empty state -- */

.empty-state { text-align: center; padding: 3.5rem 1rem; color: var(--text-muted); }
.empty-state h1 { margin-bottom: .5rem; color: var(--text); }
.empty-state p { max-width: 46ch; margin-inline: auto; }
.empty-state .btn { margin-top: 1rem; }

.summary-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: .9rem;
    margin-bottom: 1.1rem;
}

.stat {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: .75rem .9rem;
    box-shadow: var(--shadow-sm);
}

.stat-label { font-size: .71rem; text-transform: uppercase; letter-spacing: .04em; color: var(--text-faint); font-weight: 700; }
.stat-value { font-size: 1.3rem; font-weight: 640; font-variant-numeric: tabular-nums; margin-top: .15rem; }
.stat-unit { font-size: .8rem; color: var(--text-faint); font-weight: 400; margin-left: .2rem; }

/* ------------------------------------------------------------ login page -- */

.login-wrap {
    display: flex;
    justify-content: center;
    align-items: center;
    /* Fills the space left between the sticky top bar and the footer, so the card sits
       in the optical centre of the page rather than clinging to the top of it. */
    min-height: calc(100vh - 180px);
    padding: 2rem 1rem 3rem;
}

.login-card {
    width: 100%;
    max-width: 430px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 2rem 1.9rem 1.6rem;
    text-align: center;
}

.login-logo { width: 176px; max-width: 70%; height: auto; margin-bottom: 1.4rem; }
.login-card h1 { font-size: 1.3rem; }
.login-body { color: var(--text-muted); font-size: .9rem; }

.login-actions { display: flex; flex-direction: column; gap: .6rem; margin: 1.4rem 0 1.1rem; }

.btn-provider {
    background: var(--surface);
    border: 1px solid var(--border-strong);
    color: var(--text);
    padding: .68rem 1rem;
    font-size: .92rem;
    justify-content: flex-start;
    gap: .7rem;
}

.btn-provider:hover { background: var(--surface-2); }

.provider-mark {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    display: inline-grid;
    place-items: center;
    border-radius: 50%;
    background: var(--surface-2);
    border: 1px solid var(--border-strong);
    font-size: .78rem;
    font-weight: 700;
    color: var(--text-muted);
    line-height: 1;
}

/*
   A neutral monogram, not the providers' own marks. Both are trademarks with
   published usage rules, and a hand-drawn look-alike is the wrong thing to ship.
   Download the official assets, save them as wwwroot/img/google.svg and
   wwwroot/img/microsoft.svg, and uncomment the two rules below — nothing else
   needs to change.

.provider-mark {
    background: none;
    border: none;
    text-indent: -9999px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
}
.provider-mark.google { background-image: url("../img/google.svg"); }
.provider-mark.microsoft { background-image: url("../img/microsoft.svg"); }
*/

.login-note { font-size: .76rem; color: var(--text-faint); margin: 0 0 1.1rem; }
.login-skip { font-size: .84rem; color: var(--text-muted); }

/* ----------------------------------------------------------- responsive -- */

@media (max-width: 900px) {
    .hero { grid-template-columns: 1fr; gap: 1.5rem; }
    .hero-art { order: -1; justify-content: flex-start; }

    .sidebar {
        position: fixed;
        inset: 0 auto 0 0;
        z-index: 40;
        transform: translateX(-100%);
        transition: transform .18s ease;
        box-shadow: var(--shadow);
    }

    .shell.nav-open .sidebar { transform: none; }

    .nav-toggle { display: block; }
    .nav-toggle span {
        display: block;
        width: 20px;
        height: 2px;
        margin: 4px 0;
        background: var(--text-muted);
        border-radius: 2px;
    }

    .content { padding: 1.25rem 1rem 2.5rem; }
    .topbar { padding: .6rem 1rem; }
    .footer { padding: 1rem; }
}

/* ------------------------------------------------------------- start-up -- */

.loading-splash {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1.1rem;
    min-height: 100vh;
    padding: 2rem;
    background: var(--bg);
}

.loading-splash img { width: 210px; max-width: 60vw; height: auto; }

.loading-bar {
    width: 210px;
    max-width: 60vw;
    height: 3px;
    border-radius: 3px;
    background: var(--surface-3);
    overflow: hidden;
}

.loading-bar::after {
    content: "";
    display: block;
    width: 40%;
    height: 100%;
    background: var(--brand-gradient);
    animation: slide 1.1s ease-in-out infinite;
}

@keyframes slide {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(250%); }
}

.loading-text { font-size: .82rem; color: var(--text-faint); }

/* Blazor's own error strip */
#blazor-error-ui {
    background: var(--warn-bg);
    border-top: 1px solid var(--warn-border);
    color: var(--warn);
    bottom: 0;
    display: none;
    left: 0;
    padding: .7rem 1.25rem;
    position: fixed;
    width: 100%;
    z-index: 1000;
    font-size: .85rem;
}

#blazor-error-ui .dismiss { cursor: pointer; position: absolute; right: 1rem; top: .6rem; font-size: 1.1rem; }

/* ============================================================================
   PRINT — the report sheet
   ============================================================================

   The PDF is produced by the browser's own print pipeline rather than by a
   JavaScript PDF library. Three reasons, in order of weight:

   1. Turkish. The base-14 PDF fonts use WinAnsi encoding, which has no ş, ğ, ı
      or İ. Getting them into a hand-built PDF means embedding and subsetting a
      TrueType font; getting them out of the browser means doing nothing at all.
   2. Weight. pdfmake plus its bundled font file is roughly 2 MB — on an app
      whose one real risk is first-load size, for a feature most sessions never
      use.
   3. Fidelity. What is printed is the same document that was reviewed on
      screen, laid out by the same engine. No second renderer to disagree with
      the first.

   The cost is that the user passes through the print dialog and picks
   "Save as PDF". If a one-click download is wanted later, this stylesheet stays
   as the fallback and the library goes alongside it.
   ============================================================================ */

.print-only { display: none; }

@media print {
    @page {
        size: A4 portrait;
        margin: 16mm 14mm;
    }

    /* Everything that exists to be clicked has no business on paper. */
    .sidebar,
    .topbar,
    .footer,
    .no-print,
    #blazor-error-ui { display: none !important; }

    html, body {
        background: #fff;
        color: #000;
        font-size: 9.5pt;
        line-height: 1.35;
    }

    .shell { display: block; }
    .shell-main { display: block; }

    .content {
        display: block;
        padding: 0;
        margin: 0;
        max-width: none;
    }

    .print-only { display: block !important; }

    /* ---- report head ---- */

    .report-head {
        display: flex;
        align-items: center;
        gap: 10mm;
        border-bottom: 1.2pt solid #000;
        padding-bottom: 3mm;
        margin-bottom: 4mm;
    }

    .report-logo { width: 38mm; height: auto; }

    .report-head-text h1 {
        font-size: 15pt;
        margin: 0 0 1mm;
        letter-spacing: -.01em;
    }

    .report-standard { font-size: 8.5pt; color: #444; }

    /* ---- meta block ---- */

    .report-meta {
        width: 100%;
        border-collapse: collapse;
        font-size: 8.5pt;
        margin-bottom: 6mm;
    }

    .report-meta th,
    .report-meta td {
        border: .4pt solid #999;
        padding: 1.4mm 2mm;
        text-align: left;
        vertical-align: top;
    }

    .report-meta th {
        background: #f0f0f0;
        font-weight: 700;
        width: 22mm;
        white-space: nowrap;
    }

    /* ---- section headings ---- */

    .report h2 {
        font-size: 10.5pt;
        margin: 6mm 0 2mm;
        padding-bottom: 1mm;
        border-bottom: .6pt solid #666;
        break-after: avoid;
        page-break-after: avoid;
    }

    /* ---- tables ---- */

    .report-table {
        width: 100%;
        border-collapse: collapse;
        font-size: 8.5pt;
        margin-bottom: 2mm;
    }

    .report-table th,
    .report-table td {
        border: .4pt solid #999;
        padding: 1.1mm 1.8mm;
        text-align: left;
        vertical-align: top;
    }

    .report-table thead th {
        background: #ececec;
        font-weight: 700;
        white-space: nowrap;
    }

    .report-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
    .report-table .sym { font-family: var(--mono); font-size: 8pt; white-space: nowrap; }
    .report-table .expr { white-space: normal; word-break: break-word; }

    .report-table.two-col th { background: #f5f5f5; width: 26mm; font-weight: 700; }

    .report-table.trace { font-size: 7.8pt; }

    /* A header row repeated on every page is the difference between a report and
       a pile of numbers. Rows must not be sliced in half across a page break. */
    .report-table thead { display: table-header-group; }
    .report-table tfoot { display: table-footer-group; }
    .report-table tr { break-inside: avoid; page-break-inside: avoid; }

    .report-note {
        font-size: 8pt;
        color: #333;
        margin: 1mm 0 0;
    }

    /* ---- foot ---- */

    .report-foot {
        margin-top: 8mm;
        padding-top: 2.5mm;
        border-top: .6pt solid #666;
        font-size: 7.5pt;
        color: #333;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .report-foot p { margin: 0 0 1mm; }
    .report-foot-meta { color: #666; }

    a { color: inherit; text-decoration: none; }
}

/* ------------------------------------------------------- project actions -- */

.card-actions { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; }

.save-status { font-size: .8rem; color: var(--text-muted); }

.row-actions { display: flex; gap: .35rem; justify-content: flex-end; white-space: nowrap; }

.btn-danger {
    background: var(--danger-bg);
    border-color: var(--danger-border);
    color: var(--danger);
}

.btn-danger:hover { background: #fbe3df; }

.login-local-note {
    font-size: .8rem;
    color: var(--text-muted);
    background: var(--brand-wash);
    border: 1px solid #cdeceb;
    border-radius: var(--radius-sm);
    padding: .6rem .75rem;
    margin: 0 0 1rem;
    text-align: left;
}


/* ============================================================================
   ICONS AND RICHER SURFACES

   The first pass used text glyphs for icons and one flat card for everything,
   which read as unfinished. What follows adds a real icon system and gives cards
   a hierarchy: an accent rail for sections that matter, a tinted medallion for
   the thing a card is about, and a lift on the ones you can click.

   Restraint still applies — this is a tool an engineer stares at for an hour,
   not a landing page. Nothing here animates on load, and nothing carries colour
   that does not mean something.
   ============================================================================ */

.icon { flex-shrink: 0; display: block; }

/* A tinted circle behind an icon. Size and hue say what kind of thing it marks. */
.icon-badge {
    display: inline-grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 11px;
    background: var(--brand-wash);
    color: var(--brand-ink);
    flex-shrink: 0;
}

.icon-badge.lg { width: 46px; height: 46px; border-radius: 13px; }
.icon-badge.sm { width: 30px; height: 30px; border-radius: 9px; }

.icon-badge.accent { background: var(--brand-gradient); color: #fff; }
.icon-badge.muted { background: var(--surface-2); color: var(--text-faint); border: 1px solid var(--border); }
.icon-badge.violet { background: #efeefc; color: #4b49c9; }
.icon-badge.warm { background: #fdf0ee; color: var(--danger); }
.icon-badge.amber { background: #fbf1de; color: #8a5a12; }

/* ---- cards with more structure ---- */

.card-head {
    display: flex;
    align-items: flex-start;
    gap: .85rem;
    margin-bottom: 1rem;
}

.card-head .card-head-text { flex: 1; min-width: 0; }
.card-head h2 { margin: 0 0 .1rem; }
.card-head p { margin: 0; font-size: .82rem; color: var(--text-faint); }

/* An accent rail marks the card that carries the result, not the inputs. */
.card-accent {
    position: relative;
    overflow: hidden;
}

.card-accent::before {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 3px;
    background: var(--brand-gradient);
}

.card-accent.warn::before { background: var(--warn); }
.card-accent.danger::before { background: var(--danger); }

/* ---- tiles ---- */

.tile {
    display: flex;
    flex-direction: column;
    gap: .1rem;
}

.tile-icon { margin-bottom: .75rem; }

.tile-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .35rem;
}

.tile-head h3 { margin: 0; }

a.tile-link { position: relative; }

a.tile-link .tile-go {
    position: absolute;
    top: 1.1rem;
    right: 1.1rem;
    color: var(--text-faint);
    opacity: 0;
    transform: translateX(-3px);
    transition: opacity .12s ease, transform .12s ease;
}

a.tile-link:hover .tile-go { opacity: 1; transform: none; }

/* ---- stat tiles ---- */

.stat {
    display: flex;
    align-items: center;
    gap: .8rem;
}

.stat-body { min-width: 0; }

.stat.is-good .icon-badge { background: #ecf8f0; color: #2c7048; }
.stat.is-warn .icon-badge { background: var(--warn-bg); color: var(--warn); }
.stat.is-bad .icon-badge { background: var(--danger-bg); color: var(--danger); }

/* ---- nav ---- */

.nav-item .icon { opacity: .7; }
.nav-item.active .icon { opacity: 1; }
.nav-item.disabled .icon { opacity: .45; }

/* ---- buttons carrying an icon ---- */

.btn .icon { margin-right: -.1rem; }

/* ---- inline message icons ---- */

.message { align-items: flex-start; }
.message .icon { margin-top: .1rem; }

/* ---- section heading with an icon ---- */

.section-head {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: 1rem;
}

.section-head h2 { margin: 0; }

/* ============================================================================
   CHARTS
   ============================================================================

   Palette validated with the dataviz colour checks against the card surface:
   lightness band, chroma floor, colour-vision separation (worst adjacent pair
   ΔE 18.2 deutan), normal-vision floor and contrast all pass. The logo indigo
   #2f2eb7 failed the lightness band and was lifted to #5a58e0 to pass.
   ============================================================================ */

:root {
    --series-1: #0e9ea8;   /* measured quantity — vapour pressure, temperature */
    --series-2: #5a58e0;   /* the limit it is judged against — saturation */
    --series-critical: #b4453c;
}

.chart { margin: 0 0 1.5rem; }

.chart figcaption {
    font-size: .8rem;
    font-weight: 650;
    color: var(--text-muted);
    margin-bottom: .4rem;
}

.chart-svg {
    width: 100%;
    height: auto;
    display: block;
    overflow: visible;
}

.chart-svg .axis { stroke: var(--border-strong); stroke-width: 1; }
.chart-svg .grid { stroke: var(--border); stroke-width: 1; }
.chart-svg .grid-zero { stroke: var(--text-faint); stroke-width: 1; stroke-dasharray: 3 3; }

.chart-svg .tick {
    font-family: var(--sans);
    font-size: 10px;
    fill: var(--text-faint);
    text-anchor: end;
}

.chart-svg .tick-zero { text-anchor: start; }
.chart-svg .axis-title { text-anchor: start; font-size: 10px; }
.chart-svg .axis-title.end { text-anchor: end; }

.chart-svg .series { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart-svg .series-1 { stroke: var(--series-1); }
.chart-svg .series-2 { stroke: var(--series-2); }
.chart-svg .series-critical { stroke: var(--series-critical); }
.chart-svg .dashed { stroke-dasharray: 6 4; }

/* The allowable value a diagram is judged against: present, but never competing with
   the data for attention. Dashed so it reads as a rule rather than as a measurement. */
.chart-svg .grid-limit {
    stroke: var(--series-critical);
    stroke-width: 1;
    stroke-dasharray: 5 4;
    opacity: .7;
}

/* A surface-coloured ring keeps overlapping markers readable where the two
   lines meet — which on a Glaser diagram is exactly the interesting place. */
.chart-svg .marker { stroke: var(--surface); stroke-width: 2; }
.chart-svg .marker-1 { fill: var(--series-1); }
.chart-svg .marker-2 { fill: var(--series-2); }
.chart-svg .marker-critical { fill: var(--series-critical); }

.chart-svg .marker-condensation {
    fill: none;
    stroke: var(--series-critical);
    stroke-width: 2;
}

.chart-svg .direct-label {
    font-family: var(--sans);
    font-size: 11px;
    font-weight: 650;
    text-anchor: start;
}

.chart-svg .direct-label.end { text-anchor: end; }
.chart-svg .label-1 { fill: var(--series-1); }
.chart-svg .label-2 { fill: var(--series-2); }

.chart-legend {
    display: flex;
    gap: 1.1rem;
    flex-wrap: wrap;
    font-size: .78rem;
    color: var(--text-muted);
    margin-top: .3rem;
}

.legend-item { display: inline-flex; align-items: center; gap: .4rem; }

.swatch {
    width: 14px;
    height: 3px;
    border-radius: 2px;
    display: inline-block;
}

.swatch-1 { background: var(--series-1); }

/* The dashes are the point: identity must survive greyscale and colour blindness. */
.swatch-2 {
    background: repeating-linear-gradient(
        to right, var(--series-2) 0 5px, transparent 5px 8px);
}

.swatch-condensation {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: none;
    border: 2px solid var(--series-critical);
}

/* ---------------------------------------------------------- layer editor -- */

table.layer-table input {
    font: inherit;
    font-size: .82rem;
    padding: .28rem .4rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--surface);
    color: var(--text);
    width: 100%;
    min-width: 68px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

table.layer-table input:focus {
    outline: 3px solid rgba(14, 158, 168, .18);
    border-color: var(--teal);
}

table.layer-table .cell-name { min-width: 190px; }
table.layer-table .cell-name input { text-align: left; }

/* Values the engine derives, not values you type — flat, so the difference is obvious. */
table.layer-table .cell-derived { color: var(--text-faint); font-variant-numeric: tabular-nums; }

.layer-add {
    display: flex;
    gap: .6rem;
    flex-wrap: wrap;
    align-items: center;
    margin: 1rem 0 .6rem;
}

.layer-add select {
    font: inherit;
    font-size: .86rem;
    padding: .38rem .55rem;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    min-width: 220px;
}

/* A row where the profile has been pulled onto the saturation curve. */
tr.row-alert td { background: var(--danger-bg); }
tr.row-alert:hover td { background: #fbe3df; }
