/*
 * LP Central — the whole design system. No framework, no CDN, no build step.
 *
 * Colour roles come from the house data-viz palette. Two decisions worth
 * knowing about, both forced by measurement rather than taste:
 *
 * 1. STATUS IS NEVER COLOUR ALONE. The status green and red measure ΔE 4.1
 *    apart under deuteranopia — effectively identical for a red-green
 *    colourblind reader. So every badge carries a distinct GLYPH and a TEXT
 *    LABEL, and the colour merely reinforces them. Removing the colour must
 *    lose no information; check that before changing a badge.
 *
 * 2. CHARTS USE ONE HUE. Every chart here plots a single series (leads per
 *    day, conversion rate per variant), so it gets one sequential blue and no
 *    legend — the heading names what is plotted. Categorical hues would imply
 *    an identity distinction that does not exist in this data.
 */

:root {
    color-scheme: light;

    --surface-1:      #fcfcfb;  /* cards, chart surface */
    --plane:          #f9f9f7;  /* page background */
    --text-primary:   #0b0b0b;
    --text-secondary: #52514e;
    --text-muted:     #898781;
    --gridline:       #e1e0d9;
    --baseline:       #c3c2b7;
    --border:         rgba(11, 11, 11, 0.10);

    --status-good:     #0ca30c;
    --status-warning:  #fab219;
    --status-critical: #d03b3b;
    --status-neutral:  #898781;

    --series-1:        #2a78d6;  /* sequential blue, mid step */
    --series-1-wash:   rgba(42, 120, 214, 0.10);

    --radius: 8px;
    --font: system-ui, -apple-system, "Segoe UI", sans-serif;
}

@media (prefers-color-scheme: dark) {
    :root:where(:not([data-theme="light"])) {
        color-scheme: dark;
        --surface-1:      #1a1a19;
        --plane:          #0d0d0d;
        --text-primary:   #ffffff;
        --text-secondary: #c3c2b7;
        --text-muted:     #898781;
        --gridline:       #2c2c2a;
        --baseline:       #383835;
        --border:         rgba(255, 255, 255, 0.10);
        --series-1:       #3987e5;
        --series-1-wash:  rgba(57, 135, 229, 0.14);
    }
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font);
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-primary);
    background: var(--plane);
}

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

/* --- Chrome ------------------------------------------------------------- */

.topbar {
    display: flex;
    align-items: center;
    gap: 24px;
    padding: 12px 24px;
    background: var(--surface-1);
    border-bottom: 1px solid var(--border);
}
.topbar .brand { font-weight: 650; color: var(--text-primary); font-size: 15px; }
.topbar nav { display: flex; gap: 16px; }
.topbar nav a { color: var(--text-secondary); }
.topbar .user-chip { margin-left: auto; color: var(--text-muted); font-size: 13px; }

main { padding: 24px; max-width: 1400px; margin: 0 auto; }
.foot { padding: 16px 24px; color: var(--text-muted); font-size: 12px; text-align: center; }

h1 { font-size: 20px; margin: 0 0 4px; }
h2 { font-size: 15px; margin: 28px 0 10px; }
.sub { color: var(--text-secondary); margin: 0 0 20px; }

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

.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
    margin-bottom: 24px;
}
.stat {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 14px 16px;
}
.stat .label {
    color: var(--text-secondary);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* Proportional figures for standalone numbers; tabular is for columns. */
.stat .value { font-size: 30px; font-weight: 600; line-height: 1.15; margin-top: 4px; }
.stat .note { color: var(--text-muted); font-size: 12px; }
.stat.is-alert .value { color: var(--status-critical); }

/* --- Cards and tables --------------------------------------------------- */

.table-card {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    overflow-x: auto;
}
table { width: 100%; border-collapse: collapse; }
th, td {
    text-align: left;
    padding: 10px 14px;
    border-bottom: 1px solid var(--gridline);
    white-space: nowrap;
}
th {
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
tr:last-child td { border-bottom: none; }
tbody tr:hover { background: var(--series-1-wash); }
.num { text-align: right; font-variant-numeric: tabular-nums; }
.muted { color: var(--text-muted); }
.wrap { white-space: normal; }
.mono { font-family: ui-monospace, "SF Mono", Menlo, monospace; font-size: 12px; }

/* --- Status badges -----------------------------------------------------
 * Glyph + label carry the meaning. Colour is reinforcement only, because
 * good and critical are indistinguishable under deuteranopia.
 */
.badge {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    font-size: 12px;
    font-weight: 600;
    padding: 2px 8px 2px 6px;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--text-primary);
}
.badge::before { font-size: 11px; line-height: 1; }
.badge.good     { background: rgba(12, 163, 12, 0.12); }
.badge.good::before     { content: "\25CF"; color: var(--status-good); }      /* filled circle */
.badge.warning  { background: rgba(250, 178, 25, 0.16); }
.badge.warning::before  { content: "\25B2"; color: #8a6000; }                 /* triangle */
.badge.critical { background: rgba(208, 59, 59, 0.12); }
.badge.critical::before { content: "\2715"; color: var(--status-critical); }   /* cross */
.badge.neutral  { background: rgba(137, 135, 129, 0.14); }
.badge.neutral::before  { content: "\2014"; color: var(--status-neutral); }    /* dash */

@media (prefers-color-scheme: dark) {
    :root:where(:not([data-theme="light"])) .badge.warning::before { color: var(--status-warning); }
}

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

.chart-card {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 16px;
    margin-bottom: 20px;
}
.chart-card h2 { margin-top: 0; }
svg.chart { display: block; width: 100%; height: auto; }
svg.chart .grid { stroke: var(--gridline); stroke-width: 1; }
svg.chart .axis { stroke: var(--baseline); stroke-width: 1; }
svg.chart .tick { fill: var(--text-muted); font-size: 10px; font-variant-numeric: tabular-nums; }
svg.chart .bar  { fill: var(--series-1); }
svg.chart .bar:hover { fill: var(--text-primary); }
svg.chart .peak { fill: var(--text-secondary); font-size: 10px; font-weight: 600; }
.empty { color: var(--text-muted); padding: 20px 0; text-align: center; }

/* --- Range picker, banners, forms -------------------------------------- */

/* Range filter.
 *
 * align-items is centre, so anything taller than a pill drags the pills off
 * the line with it. That is what broke when the custom-range form was a nested
 * .rangebar: the date inputs picked up width:100% from the generic form rule
 * below, could not sit side by side, stacked, and the presets floated against
 * the middle of the stack. Keep every child of this row pill-height.
 */
.rangebar { display: flex; gap: 8px; align-items: center; margin-bottom: 18px; flex-wrap: wrap; }

/* The custom from/to group. row-gap matches the parent so that when this wraps
 * under the presets on a narrow screen the spacing stays even.
 *
 * min-width: 0 is load-bearing, not tidying. This is itself a flex item of
 * .rangebar, and flex items default to min-width:auto, which refuses to shrink
 * below their content width. Without it the group stays as wide as From + To +
 * Apply, its own flex-wrap can never trigger, and it pushes the whole page
 * wider than the viewport -- which clips Apply AND stops body text wrapping,
 * because everything then sits in an over-wide containing block.
 */
.rangebar-custom {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin: 0;
    min-width: 0;
}

/* Divider between the presets and the custom range, so the row reads as two
 * groups rather than one undifferentiated strip of controls. Hidden once the
 * row wraps, where a stray vertical rule would just look like debris. */
.rangebar-sep {
    width: 1px;
    align-self: stretch;
    min-height: 20px;
    background: var(--border);
    margin: 0 4px;
}

/* Inline label for a control that sits in a row rather than above one. The
 * generic `label` rule is display:block with a bottom margin, which is right
 * for stacked card forms and wrong here. */
.inline-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 0;
    color: var(--text-secondary);
    font-size: 13px;
    white-space: nowrap;
}

/* Date fields inside the row: sized to content, not to the container, and
 * height-matched to the pills. Without the width and margin resets these
 * inherit width:100% and margin-top:4px from the generic input rule. */
.rangebar input[type=date],
.rangebar-custom input[type=date] {
    width: auto;
    min-width: 8.5em;
    margin-top: 0;
    padding: 4px 8px;
    font-size: 13px;
}

/* Apply sits in the row too, so it matches the pills rather than the taller
 * card buttons. */
.rangebar-custom .btn {
    padding: 5px 11px;
    font-size: 13px;
    border-radius: 999px;
}

@media (max-width: 720px) {
    /* Stack the two groups on small screens and drop the divider, which only
     * makes sense while they share a line. */
    .rangebar-sep { display: none; }
    .rangebar-custom { width: 100%; }

}

/* Only at genuinely narrow widths do the date fields need to share the line by
 * splitting it. Applying this across the whole tablet range stretched them to
 * ~230px each, which looked ungainly for a field holding eight characters. */
@media (max-width: 460px) {
    .rangebar-custom .inline-label { flex: 1 1 40%; min-width: 0; }
    .rangebar-custom .inline-label input[type=date] {
        min-width: 0;
        width: 100%;
    }
}
.rangebar a, .rangebar button {
    padding: 5px 11px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-1);
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}
.rangebar a.on { background: var(--series-1); border-color: var(--series-1); color: #fff; }

.banner {
    border-left: 3px solid var(--status-warning);
    background: rgba(250, 178, 25, 0.10);
    padding: 10px 14px;
    border-radius: 4px;
    margin-bottom: 16px;
}
.banner.critical { border-left-color: var(--status-critical); background: rgba(208, 59, 59, 0.10); }

form.card {
    background: var(--surface-1);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 20px;
    max-width: 620px;
}
label { display: block; margin-bottom: 12px; color: var(--text-secondary); font-size: 13px; }
input[type=text], input[type=email], input[type=password], input[type=url],
input[type=number], input[type=date], select, textarea {
    width: 100%;
    margin-top: 4px;
    padding: 8px 10px;
    font: inherit;
    color: var(--text-primary);
    background: var(--plane);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.btn {
    padding: 8px 16px;
    border: none;
    border-radius: 6px;
    background: var(--series-1);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.btn.secondary { background: transparent; color: var(--text-secondary); border: 1px solid var(--border); }
.error { color: var(--status-critical); margin-bottom: 12px; }
.login-wrap { max-width: 340px; margin: 80px auto; }
.inline-form { display: inline; }

/* --- Utility classes ----------------------------------------------------
 * These exist because the Content-Security-Policy omits 'unsafe-inline':
 * a style="..." attribute is silently dropped by the browser, so every
 * one-off adjustment has to live here. Add to this list rather than
 * reaching for an inline style.
 */
.cell-detail        { max-width: 300px; }
.stat .value.compact { font-size: 20px; padding-top: 8px; }
.stat .value.address { font-size: 15px; padding-top: 12px; }
.flush              { margin: 0; }
.flush-bottom       { margin-bottom: 0; }
.stack-top          { margin-top: 12px; }
.section-gap        { margin-top: 24px; }
.checkbox-row       { display: flex; gap: 8px; align-items: center; }
.checkbox-row input[type=checkbox] { width: auto; margin: 0; }
a.btn               { display: inline-block; text-decoration: none; }
a.btn:hover         { text-decoration: none; }

/* Copy-paste blocks for the reporter wiring steps. */
.snippet {
    margin: 0;
    padding: 14px 16px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 12px;
    line-height: 1.6;
    white-space: pre-wrap;
    word-break: break-all;
    color: var(--text-primary);
    background: var(--plane);
    border-radius: var(--radius);
    user-select: all;
}

/* Destructive action, e.g. turning the second factor off. Carries a text
 * label as well as the colour: the critical red and the good green sit only
 * ~4 ΔE apart under deuteranopia, so colour alone must never be the signal. */
.btn.danger {
    background: transparent;
    color: var(--status-critical);
    border: 1px solid var(--status-critical);
}

/* Recovery codes, shown once at enrolment. */
.code-list {
    list-style: none;
    margin: 12px 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 8px;
}
.code-list code {
    display: block;
    padding: 8px 10px;
    font-family: ui-monospace, "SF Mono", Menlo, monospace;
    font-size: 13px;
    letter-spacing: 0.04em;
    background: var(--plane);
    border-radius: var(--radius);
    user-select: all;
}

/* Stacked form inside a card that already contains prose. */
.stack { margin-top: 16px; }

/* Two-factor enrolment QR.
 *
 * The svg carries explicit black-on-white fills rather than theme variables:
 * a QR code is not decoration, and inverting or tinting it under a dark theme
 * can stop it scanning. The white plate below guarantees the quiet zone reads
 * as white even against a dark page background. */
.qr-wrap {
    display: inline-block;
    margin: 12px 0;
    padding: 0;
    background: #fff;
    border-radius: var(--radius);
    line-height: 0;
}
.qr { display: block; width: 232px; height: 232px; }
