/* AS1 admin. Tokens live in tokens.css, which must load first.

   Type ladder: a display face on headings so hierarchy exists at all, body at
   14px, table cells at 13px, and mono reserved for one meaning throughout -
   machine-produced or categorical metadata, never prose. */

* { box-sizing: border-box; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font: 400 14px/1.55 var(--font-body);
    -webkit-font-smoothing: antialiased;
}

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

/* Readable secondary copy. Deliberately NOT --text-tertiary: this class
   carries roughly half the visible text in the app, including on screens that
   get shown over a video call. */
.muted { color: var(--text-secondary); font-weight: 400; }
.small { font-size: 12px; }

/* Keyboard focus, visible everywhere. */
:focus-visible {
    outline: 2px solid var(--focus-edge);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* ---------------------------------------------------------------- Shell -- */

.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
/* Load-bearing. Without it a wide table blows the grid track out and the
   sidebar gets pushed off screen. */
.app > * { min-width: 0; }

.sidebar {
    background: var(--bg-sunk); border-right: 1px solid var(--border);
    display: flex; flex-direction: column;
    position: sticky; top: 0; height: 100vh;
}
.sidebar__brand {
    display: flex; align-items: center; flex: 0 0 auto;
    height: var(--topbar-h); padding: 0 var(--sp-md);
    border-bottom: 1px solid var(--border);
    font-family: var(--font-display); font-weight: 600; font-size: 17px;
    letter-spacing: -.01em; color: var(--text);
}
.sidebar__brand:hover { text-decoration: none; }
.sidebar__brand .muted { margin-left: 5px; }

.sidebar__nav { flex: 1 1 auto; overflow-y: auto; padding: var(--sp-md) var(--sp-sm); }
.nav-group + .nav-group { margin-top: var(--sp-lg); }
.nav-group__label {
    font-family: var(--font-mono); font-size: 10px; font-weight: 500;
    text-transform: uppercase; letter-spacing: .10em;
    color: var(--text-tertiary); padding: 0 var(--sp-sm) var(--sp-sm);
}
.nav-item {
    position: relative; display: block;
    padding: 8px var(--sp-sm) 8px 14px; margin-bottom: 2px;
    border-radius: var(--radius-sm);
    color: var(--text-secondary); font-size: 13px;
    transition: background var(--transition), color var(--transition);
}
.nav-item:hover { background: var(--bg-hover); color: var(--text); text-decoration: none; }
.nav-item.is-active { background: var(--bg-hover); color: var(--text); font-weight: 600; }
.nav-item.is-active::before {
    content: ''; position: absolute; left: 0; top: 6px; bottom: 6px;
    width: 3px; border-radius: 0 2px 2px 0; background: var(--accent);
}

.sidebar__foot {
    flex: 0 0 auto; border-top: 1px solid var(--border);
    padding: var(--sp-md); font-size: 12px;
}
.sidebar__user {
    display: block; color: var(--text); margin-bottom: 2px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.sidebar__foot a { color: var(--text-secondary); }

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

.topbar {
    position: sticky; top: 0; z-index: 10;
    height: var(--topbar-h);
    background: var(--bg-card); border-bottom: 1px solid var(--border);
}
/* Same measure as .content, so the page title stays aligned with the heading
   it labels once the content column starts centring in its track. */
.topbar__inner {
    display: flex; align-items: center; gap: var(--sp-md); height: 100%;
    width: 100%; max-width: var(--content-max); margin-inline: auto;
    padding: 0 var(--sp-lg);
}
.topbar__title {
    font-family: var(--font-display); font-weight: 600; font-size: 16px;
    letter-spacing: -.01em; margin: 0; color: var(--text);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.topbar__spacer { flex: 1; }

/* margin-inline is the half cf1 forgot: without it the whole app hugs the left
   edge above the max width, with a growing dead gutter on the right. */
.content {
    width: 100%; max-width: var(--content-max); margin-inline: auto;
    padding: var(--sp-lg) var(--sp-lg) var(--sp-3xl);
}

.backlink { display: inline-block; font-size: 13px; color: var(--text-secondary); margin-bottom: var(--sp-sm); }
.backlink:hover { color: var(--text); }

/* Out of scope below 900px, but it should degrade rather than break: the
   sidebar becomes a scrolling strip above the content. */
@media (max-width: 900px) {
    .app { grid-template-columns: 1fr; }
    .sidebar { position: static; height: auto; }
    .sidebar__nav { display: flex; gap: var(--sp-sm); overflow-x: auto; padding: var(--sp-sm); }
    .nav-group { display: flex; gap: var(--sp-xs); margin: 0 !important; }
    .nav-group__label { display: none; }
    .nav-item { white-space: nowrap; }
    .nav-item.is-active::before { display: none; }
}

/* ------------------------------------------------------------- Headings -- */

h1 {
    font-family: var(--font-display); font-weight: 600; font-size: 26px;
    letter-spacing: -.01em; line-height: 1.2; margin: 0 0 var(--sp-lg);
}
/* Was a 16px uppercase muted form label, which flattened every page to a
   single level of hierarchy. It is a heading again. */
h2 {
    font-family: var(--font-display); font-weight: 600; font-size: 20px;
    letter-spacing: -.01em; line-height: 1.3; margin: 0 0 var(--sp-md);
    color: var(--text);
}
h3 {
    font-family: var(--font-display); font-weight: 600; font-size: 16px;
    margin: 0 0 var(--sp-sm); color: var(--text);
}

/* Cards */
.cards {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--sp-md); margin-bottom: var(--sp-lg);
}
.cards > * { min-width: 0; }
.cards--metrics { grid-template-columns: repeat(6, minmax(0, 1fr)); }
@media (max-width: 1560px) { .cards--metrics { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 820px)  { .cards--metrics { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius-lg); padding: var(--sp-md) 18px;
    color: var(--text-secondary); font-size: 12px;
}
.card__label { display: block; }
/* Provenance belongs beside the figure, not in a shared paragraph below the
   row, which on a wide screen became a narrow ragged column against
   full-width tiles. */
.card__note {
    display: block; margin-top: var(--sp-sm); padding-top: var(--sp-sm);
    border-top: 1px solid var(--border);
    font-size: 11px; line-height: 1.5; color: var(--text-secondary);
}
.card .num {
    display: block; font-family: var(--font-display); font-weight: 600;
    font-size: 28px; letter-spacing: -.02em; color: var(--text);
    font-variant-numeric: tabular-nums; margin-bottom: 2px;
}

.grid2 {
    display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-lg);
    margin-bottom: var(--sp-lg); align-items: start;
}
.grid2 > * { min-width: 0; }
@media (max-width: 1100px) { .grid2 { grid-template-columns: 1fr; } }

section {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius-lg); padding: 18px; overflow-x: auto;
}

/* Tables */
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--border); }
td { font-size: 13px; }
/* Mono uppercase micro-label. --text-secondary rather than --text-tertiary: a
   header a viewer has to read is not decoration, and 3.7:1 does not survive
   video-call compression. */
th {
    font-family: var(--font-mono); font-weight: 500; font-size: 10.5px;
    text-transform: uppercase; letter-spacing: .06em;
    color: var(--text-secondary); background: var(--bg-elevated);
    border-bottom: 1px solid var(--border-light); white-space: nowrap;
}
td.r, th.r { text-align: right; font-variant-numeric: tabular-nums; }
tr:last-child td { border-bottom: none; }

/* Auth and error */
.auth-page { display: flex; min-height: 100vh; align-items: center; justify-content: center; padding: var(--sp-lg); }
.auth-card {
    background: var(--bg-card); border: 1px solid var(--border);
    border-radius: var(--radius-lg); padding: 34px 38px; width: 380px;
    box-shadow: var(--shadow);
}
.auth-card h1 { margin: 0 0 var(--sp-xs); font-size: 22px; }
.auth-card p { margin: 0 0 var(--sp-lg); color: var(--text-secondary); }
.error-code {
    font-family: var(--font-mono); font-size: 10.5px; font-weight: 500;
    text-transform: uppercase; letter-spacing: .10em;
    color: var(--text-tertiary); margin: 0 0 var(--sp-sm) !important;
}

label { display: block; margin-bottom: 14px; color: var(--text-secondary); font-size: 12px; }
input[type=email], input[type=password], input[type=text], select {
    width: 100%; margin-top: 5px; padding: 10px 12px;
    background: var(--bg-sunk); color: var(--text);
    border: 1px solid var(--border-light); border-radius: var(--radius);
    font-family: var(--font-body); font-size: 14px;
}
input::placeholder { color: var(--text-dim); }
input:focus, select:focus {
    outline: none; border-color: var(--focus-edge); box-shadow: var(--focus-ring);
}

button {
    width: 100%; padding: 11px; margin-top: var(--sp-xs);
    background: var(--accent); color: #fff;
    font-family: var(--font-body); font-weight: 600; font-size: 13px;
    border: none; border-radius: var(--radius); cursor: pointer;
    transition: background var(--transition);
}
button:hover { background: var(--accent-hover); }
button:active { background: var(--accent-press); }

.alert {
    background: var(--danger-dim); border: 1px solid var(--danger);
    color: var(--danger); border-radius: var(--radius);
    padding: 10px 12px; margin-bottom: var(--sp-md); font-size: 13px;
}
.notice {
    background: var(--success-dim); border: 1px solid var(--success);
    color: var(--success); border-radius: var(--radius);
    padding: 10px 12px; margin-bottom: var(--sp-md); font-size: 13px;
}

/* Filters bar */
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 18px; }
.filters input[type=text], .filters select {
    width: auto; margin: 0; padding: 8px 10px; font-size: 13px;
}
.filters button { width: auto; margin: 0; padding: 8px 16px; }
/* Controls sized to their content, for forms that sit in a full width
   panel rather than a narrow column. */
.form-inline { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--sp-md); }
.form-inline label { margin-bottom: 0; }
.form-inline select, .form-inline input[type=text] { width: auto; min-width: 280px; }
.form-inline button { width: auto; margin-top: 0; padding: 10px 20px; }
.form-inline > p { flex: 1 0 100%; margin: 0; }
label.check { display: flex; align-items: center; gap: var(--sp-sm); margin-bottom: 0; }
label.check input { width: auto; }

/* Progress. The bar is driven by app.js writing style.width directly, and the
   width transition is what makes that animate rather than jump. Do not
   reimplement with transform or a custom property. */
.progress {
    height: 10px; background: var(--bg-sunk); border: 1px solid var(--border);
    border-radius: var(--radius-sm); overflow: hidden; margin: 12px 0 6px;
}
.progress-bar {
    height: 100%; background: linear-gradient(90deg, var(--accent), var(--accent-hover));
    transition: width .6s ease;
}

/* ------------------------------------------------------- Phase 3: chips -- */

/* One chip primitive for every enum in the product: research_status, task
   status, run status. Colour is never the only signal, the label is always
   present. Status colours are reserved and never reused decoratively. */
.badge {
    display: inline-block; vertical-align: baseline;
    font-family: var(--font-mono); font-weight: 500; font-size: 10.5px;
    text-transform: uppercase; letter-spacing: .06em;
    padding: 2px 7px; border-radius: var(--radius-sm);
    background: var(--bg-elevated); border: 1px solid var(--border-light);
    color: var(--text-secondary); white-space: nowrap;
}
.badge--green { color: var(--success); border-color: var(--success); background: var(--success-dim); }
.badge--blue  { color: var(--accent-hover); border-color: var(--accent-line); background: var(--accent-dim); }
.badge--amber { color: var(--warning); border-color: var(--warning); background: var(--warning-dim); }
.badge--red   { color: var(--danger); border-color: var(--danger); background: var(--danger-dim); }
.badge--gray  { color: var(--text-tertiary); }

/* ------------------------------------------------------ Phase 3: tables -- */

tbody tr:hover td, table tr:hover td { background: var(--bg-hover); }
th { position: relative; }

/* A key/value table: the th is a ROW label, not a column header, so it must
   not get the elevated uppercase header treatment. lead.php's Profile panel
   is the one that matters. */
.kv th {
    background: transparent; border-bottom: 1px solid var(--border);
    font-family: var(--font-body); font-weight: 400; font-size: 12px;
    text-transform: none; letter-spacing: 0;
    color: var(--text-secondary); vertical-align: top; white-space: normal;
}
.kv tr:hover td, .kv tr:hover th { background: transparent; }

/* Truncated cells get a real ellipsis and keep the full value on hover. */
.trunc { display: inline-block; max-width: 100%; overflow: hidden;
         text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

/* An empty result set should say so rather than leaving a header hanging over
   nothing. leads.php was the only one of seven tables without this. */
.empty {
    padding: var(--sp-xl) var(--sp-md); text-align: center; color: var(--text-secondary);
}
.empty strong { display: block; color: var(--text); font-family: var(--font-display);
                font-size: 16px; font-weight: 600; margin-bottom: var(--sp-xs); }

/* Placeholder for a value that genuinely is not there. The house content
   policy forbids em dashes, including as table placeholders. */
.na { color: var(--text-dim); font-variant-numeric: normal; }

/* ----------------------------------------------------- Phase 3: buttons -- */

/* The CSV link must stay an <a>: it sits INSIDE the filter form, so a <button>
   would submit the filter and silently stop exporting. It is styled as a
   secondary button instead, because it produces the actual deliverable and was
   reading as a lesser action than "Filter" beside it. */
.btn-secondary {
    display: inline-block; padding: 8px 16px;
    background: var(--bg-elevated); color: var(--text);
    border: 1px solid var(--border-strong); border-radius: var(--radius);
    font-family: var(--font-body); font-weight: 600; font-size: 13px;
    cursor: pointer; transition: background var(--transition), border-color var(--transition);
}
.btn-sm { padding: 6px 12px; font-size: 12px; }

/* Withheld rather than removed. A demo account should be able to see that
   export exists and read why it is off, so this keeps the button's footprint
   and drops only its affordances: no pointer, no hover, no href behind it. The
   text stays above the readable floor (--text-secondary) because the tooltip
   is not the only place the reason has to survive. */
.btn-secondary.is-disabled {
    background: var(--bg-card); color: var(--text-secondary);
    border-color: var(--border); cursor: not-allowed; opacity: .72;
}
.btn-secondary.is-disabled:hover {
    background: var(--bg-card); border-color: var(--border); color: var(--text-secondary);
}
.btn-secondary:hover {
    background: var(--bg-hover); border-color: var(--text-tertiary);
    text-decoration: none; color: var(--text);
}

/* A row of actions under a heading, rather than links floating in a <p>. */
.actions { display: flex; flex-wrap: wrap; gap: var(--sp-sm); align-items: center; margin-bottom: var(--sp-lg); }

/* -------------------------------------------------- Phase 4: source notes -- */

/* One line per panel naming where its numbers came from. On a screen showing
   657,641 rows this is the cheapest credibility available, and it is most of
   what separates research from a scrape. */
.src-note {
    /* --text-secondary, not --text-dim: these notes carry the denominators and
       caveats that make every figure on the page defensible, so they are
       readable copy and fall under the same contrast floor as body text.
       Size, not colour, is what separates them. */
    font-size: 11.5px; line-height: 1.55; color: var(--text-secondary);
    margin: var(--sp-sm) 0 0; max-width: 96ch;
}
.page-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: var(--sp-xl); flex-wrap: wrap; margin-bottom: var(--sp-lg);
}
.page-head__text { min-width: 0; flex: 1 1 auto; }
.page-head__text .src-note { max-width: 120ch; }
.page-head__text h1 { margin-bottom: 6px; }
.page-head__text .src-note { margin-top: 0; }
.page-head__action {
    display: flex; align-items: center; gap: var(--sp-sm);
    flex: 0 0 auto; margin-top: 6px;
}
.page-head__action .src-note { margin: 0; white-space: nowrap; }
/* Sits directly under the block it explains. */
.src-note--tight { margin-top: calc(var(--sp-lg) * -1 + 6px); margin-bottom: var(--sp-lg); }

/* ----------------------------------------------------- Phase 4: overview -- */

.funnel { display: flex; flex-direction: column; gap: var(--sp-lg); }
.funnel__row { border-left: 2px solid var(--border-light); padding-left: var(--sp-md); }
.funnel__head { display: flex; align-items: baseline; gap: var(--sp-sm); flex-wrap: wrap; }
.funnel__step {
    font-family: var(--font-mono); font-size: 10px; font-weight: 500;
    color: var(--text-tertiary); border: 1px solid var(--border-light);
    border-radius: var(--radius-sm); padding: 1px 5px;
}
.funnel__label { font-family: var(--font-display); font-weight: 600; font-size: 15px; color: var(--text); }
.funnel__value {
    margin-left: auto; padding-left: var(--sp-md); font-family: var(--font-display); font-weight: 600; font-size: 22px;
    letter-spacing: -.02em; font-variant-numeric: tabular-nums; color: var(--text);
}
/* No percentage appears without its denominator beside it. */
.funnel__pct {
    font-family: var(--font-mono); font-size: 10.5px; text-transform: uppercase;
    letter-spacing: .06em; color: var(--text-secondary); white-space: nowrap;
}
.funnel__bar {
    height: 3px; background: var(--bg-elevated); border-radius: 2px;
    margin: 10px 0 0; overflow: hidden;
}
.funnel__bar span {
    display: block; height: 100%; border-radius: 2px;
    background: linear-gradient(90deg, var(--accent), var(--accent-hover));
}
.funnel__row .src-note { margin-top: 6px; max-width: none; }

/* A submit control that reads as a link, for the snapshot refresh sitting
   inside a source note. The element rule makes buttons full-width blocks. */
.btn-link {
    width: auto; margin: 0; padding: 0; background: none; border: none;
    color: var(--accent-hover); font: inherit; font-size: 11.5px;
    cursor: pointer; text-decoration: underline;
}
.btn-link:hover { background: none; color: var(--text); }
