/* =====================================================================
   SOLVA DESIGN FOUNDATION  —  canonical path: /styles/solva.css
   Single source of truth for the whole product: brand tokens, the spacing
   scale, the shared 1200px page frame, a reusable 12-column grid, and the
   shared components (header band, signal blocks, controls, table, status
   markers, pager). Both the admin hub AND the public marketing/intake site
   link this one file — no page redefines these values.

   Public static asset served from the site root, so any page can
   <link rel="stylesheet" href="/styles/solva.css">, including pages served
   by a function (the launch tracker, whose absolute href resolves in the
   browser after the admin-tracker loader document.writes the page).

   Linked today by: admin.html (Jobs), admin/notes.html (Considerations),
   netlify/functions/lib/tracker.html (Launch tracker). The public pages
   (index.html, start.html, solva-brief.html) adopt it in later PRs.
   ===================================================================== */

/* ---------------------------------------------------------------------
   TOKENS — this block is the spec.
   --------------------------------------------------------------------- */
:root{
  /* Brand — Solva Brand Guidelines (exact tokens) */
  --green:        #2A5C3F;   /* Forest Green — structural, primary */
  --green-deep:   #1E3D2A;   /* depth / hover */
  --green-tint:   #E4EDE6;   /* derived: quiet fills on cream */
  --ink:          #1A1A1A;   /* anchor text */
  --graphite:     #4A4A46;   /* muted text */
  --ink-soft:     var(--graphite); /* alias — existing rules reference --ink-soft */
  --cream:        #F4F1EA;   /* working ground */
  --paper:        #FAF9F5;   /* lighter panel */
  --cream-panel:  var(--paper);    /* alias — existing rules reference --cream-panel */
  --cream-line:   #E4DFD4;   /* the only rule colour, used sparingly */
  --white:        #FFFFFF;
  --on-green:     #F4F1EA;   /* cream text on green */
  --on-green-dim: rgba(244,241,234,.78); /* transparency of text, never grey-on-colour */

  /* Type — Playfair Display (display) + Archivo (text/UI) */
  --serif: 'Playfair Display', Georgia, serif;
  --sans:  'Archivo', system-ui, -apple-system, sans-serif;
  --mono:  'SF Mono', ui-monospace, Menlo, Consolas, monospace;

  /* Spacing scale — nothing off-scale */
  --s1:8px; --s2:16px; --s3:24px; --s4:40px; --s5:64px; --s6:96px;

  /* Grid */
  --maxw:1200px;
  --gutter:24px;

  /* Motion */
  --ease:cubic-bezier(.22,1,.36,1);

  /* z-index scale — semantic, never arbitrary */
  --z-sticky:10; --z-toast:40;
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
body{
  font-family:var(--sans);
  font-size:14px;
  color:var(--ink);
  background:var(--cream);
  -webkit-font-smoothing:antialiased;
  min-height:100vh;
}

/* small letterspaced caps eyebrow — already on-brand */
.eyebrow{
  font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ink-soft);
}

/* ============================ HEADER BAND ============================
   Colour as structure: the header is a solid green plane, not a bar
   with a green accent. Shared verbatim across every admin page. */
.band{
  background:var(--green);
  color:var(--on-green);
  position:sticky;top:0;z-index:var(--z-sticky);
}
/* .band-inner shares the exact frame of .page-container (same max-width, same
   horizontal padding) so the SOLVA. wordmark's left edge lines up with the
   page content's left edge on every admin page. */
.band-inner{
  max-width:var(--maxw);margin:0 auto;
  padding:0 var(--s5);
  height:60px;
  display:flex;align-items:center;justify-content:space-between;gap:var(--s4);
}
/* Wordmark — Playfair Display Bold, tracking -1.5%. The dot is part of the
   wordmark and flips to cream here because it sits on the green header band
   (its default state is green #2A5C3F on a light ground). Never re-spaced. */
.wordmark{
  font-family:var(--serif);font-weight:700;font-size:22px;letter-spacing:-.015em;
  color:var(--on-green);line-height:1;user-select:none;
}
.nav{display:flex;align-items:center;gap:var(--s4);height:100%}
/* Nav items are usually <a>; admin.html's Jobs item is a <button> (SPA,
   no navigation) — both style identically here. */
.nav a,.nav button{
  position:relative;height:100%;display:flex;align-items:center;
  color:var(--on-green-dim);text-decoration:none;
  font-family:var(--sans);font-size:13px;font-weight:500;letter-spacing:.01em;
  background:none;border:none;cursor:pointer;
  transition:color .18s var(--ease);
}
.nav a:hover,.nav button:hover{color:var(--on-green)}
/* Active nav item — one canonical class ("active"), applied by the shared
   header renderer in /admin/header.js. */
.nav a.active,.nav button.active{color:var(--on-green)}
.nav a.active::after,.nav button.active::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--on-green);
}
.nav a.soon{color:rgba(244,241,234,.45);pointer-events:none}
.nav a.soon .pill{
  margin-left:6px;font-size:9px;letter-spacing:.1em;text-transform:uppercase;
  border:1px solid rgba(244,241,234,.3);border-radius:2px;padding:1px 5px;
}
.band-right{display:flex;align-items:center;gap:var(--s3)}
.band-right .who{font-size:12px;color:var(--on-green-dim)}
.logout{
  background:transparent;border:1px solid rgba(244,241,234,.35);color:var(--on-green);
  font-family:var(--sans);font-size:12px;padding:6px 14px;border-radius:3px;cursor:pointer;
  transition:background .18s var(--ease);
}
.logout:hover{background:rgba(244,241,234,.12)}

/* ===================== SHARED PAGE FRAME =====================
   One canonical centered content frame (1200px via --maxw) for every page.
   Same max-width and horizontal padding as .band-inner, so the wordmark and
   the content share one outer frame and header alignment. Jobs uses the full
   frame width (its table needs it); the text-heavy pages wrap their content
   in .measure to keep a readable line length, centered within this frame. */
.page-container{
  max-width:var(--maxw);
  margin-inline:auto;
  padding:var(--s5) var(--s5) var(--s6);
}
/* Readable text column — centered within the shared frame (margin-inline:auto),
   so it reads balanced while the outer frame and header still align with Jobs.
   Used by Considerations and the tracker. */
.measure{max-width:72ch;margin-inline:auto}

/* ===================== 12-COLUMN GRID =====================
   Reusable layout grid for composing sections across the hub and the public
   site. Content spans whole columns; the gutter is the shared --gutter token
   (24px). Put .grid-12 on a container, then .col-N (N = 1..12) on children —
   e.g. a 5/7 split is .col-5 + .col-7, a four-up row is four .col-3. Fully
   token-driven; no bare pixel widths. */
.grid-12{
  display:grid;
  grid-template-columns:repeat(12,minmax(0,1fr));
  gap:var(--gutter);
}
.col-1 {grid-column:span 1}
.col-2 {grid-column:span 2}
.col-3 {grid-column:span 3}
.col-4 {grid-column:span 4}
.col-5 {grid-column:span 5}
.col-6 {grid-column:span 6}
.col-7 {grid-column:span 7}
.col-8 {grid-column:span 8}
.col-9 {grid-column:span 9}
.col-10{grid-column:span 10}
.col-11{grid-column:span 11}
.col-12{grid-column:span 12}
/* On narrow viewports the grid collapses to a single stacked column and every
   span becomes full width. Matches the frame's 820px breakpoint below. */
@media (max-width:820px){
  .grid-12{grid-template-columns:1fr}
  .col-1,.col-2,.col-3,.col-4,.col-5,.col-6,
  .col-7,.col-8,.col-9,.col-10,.col-11,.col-12{grid-column:1 / -1}
}

.page-head{display:flex;align-items:baseline;gap:var(--s2);margin-bottom:var(--s4)}
.page-head h1{
  font-family:var(--serif);font-weight:600;font-size:34px;letter-spacing:-.01em;
  color:var(--ink);line-height:1;text-wrap:balance;
}
.page-head .count{font-size:13px;color:var(--ink-soft)}

/* ---- Signal blocks: weight maps to priority (green = act, dark = alarm) ---- */
.signals{
  display:grid;grid-template-columns:repeat(4,1fr);
  gap:1px;background:var(--cream-line);
  border:1px solid var(--cream-line);
  margin-bottom:var(--s5);
}
.sig{padding:var(--s3) var(--s3) var(--s3);background:var(--cream-panel);display:flex;flex-direction:column;gap:var(--s2)}
.sig .n{font-family:var(--serif);font-weight:600;font-size:40px;line-height:.9;letter-spacing:-.01em}
.sig .l{font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft)}
.sig.accent{background:var(--green);color:var(--on-green)}
.sig.accent .n{color:var(--on-green)}
.sig.accent .l{color:var(--on-green-dim)}
.sig.dark{background:var(--ink);color:var(--cream)}
.sig.dark .n{color:var(--cream)}
.sig.dark .l{color:rgba(244,241,234,.6)}

/* ---- Filter / search row ---- */
.controls{display:flex;gap:var(--s2);align-items:center;margin-bottom:var(--s3);flex-wrap:wrap}
.filters{display:flex;gap:6px;flex-wrap:wrap}
.fbtn{
  font:inherit;font-size:12.5px;background:transparent;color:var(--ink-soft);
  border:1px solid var(--cream-line);padding:6px 13px;border-radius:99px;cursor:pointer;
  transition:all .16s var(--ease);
}
.fbtn:hover{border-color:var(--green);color:var(--green)}
.fbtn.on{background:var(--green);border-color:var(--green);color:var(--on-green)}
.search{flex:1;min-width:220px}
.search input{
  width:100%;font:inherit;font-size:14px;padding:9px 14px;
  background:var(--cream-panel);border:1px solid var(--cream-line);border-radius:4px;color:var(--ink);
  transition:border-color .16s var(--ease);
}
.search input::placeholder{color:var(--ink-soft)}
.search input:focus{outline:none;border-color:var(--green)}
/* Native <select> filter (admin.html keeps its select-based filter logic) —
   styled to sit in the controls row like the mockup's controls. */
.controls select{
  font:inherit;font-size:13px;padding:9px 12px;
  background:var(--cream-panel);border:1px solid var(--cream-line);border-radius:4px;color:var(--ink);
  cursor:pointer;transition:border-color .16s var(--ease);
}
.controls select:focus{outline:none;border-color:var(--green)}

/* ---- The table: a hard-aligned grid, not a card list ---- */
.table{border-top:1px solid var(--cream-line)}
.thead,.trow{
  display:grid;
  grid-template-columns:150px 200px 1fr 220px 90px;
  gap:var(--s3);align-items:center;
}
.thead{
  padding:var(--s2) var(--s2);
  font-size:10.5px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-soft);
  border-bottom:1px solid var(--cream-line);
}
.trow{
  padding:var(--s3) var(--s2);
  border-bottom:1px solid var(--cream-line);
  cursor:pointer;transition:background .14s var(--ease);
}
.trow:hover{background:var(--cream-panel)}

/* status marker: monochrome discipline, weight = priority.
   solid green = needs you · solid dark = failed · outline = in-flight/done.
   The mockup's short marker names plus the real render_jobs.status names
   (st-<status>) are mapped to the same treatments below. */
.st{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:500;letter-spacing:.01em}
.st .dot{width:8px;height:8px;border-radius:2px;flex:none}

/* solid green — needs your action */
.st.needs,.st.st-needs_review{color:var(--green);font-weight:600}
.st.needs .dot,.st.st-needs_review .dot{background:var(--green)}

/* hollow green — quote-gated / manual, awaiting a human decision */
.st.quote,.st.st-pending_quote,.st.st-awaiting_team{color:var(--green)}
.st.quote .dot,.st.st-pending_quote .dot,.st.st-awaiting_team .dot{
  background:transparent;border:1.5px solid var(--green)}

/* outline / muted — approved (done, hollow) */
.st.approved,.st.st-approved{color:var(--ink-soft)}
.st.approved .dot,.st.st-approved .dot{background:transparent;border:1.5px solid var(--ink-soft)}

/* muted — delivered (done, filled) */
.st.delivered,.st.st-delivered{color:var(--ink-soft)}
.st.delivered .dot,.st.st-delivered .dot{background:var(--ink-soft)}

/* muted — queued (waiting, faint outline) */
.st.queued,.st.st-queued{color:var(--ink-soft)}
.st.queued .dot,.st.st-queued .dot{background:transparent;border:1.5px solid var(--cream-line)}

/* in-flight — generating (pulsing green) */
.st.generating,.st.st-generating{color:var(--ink)}
.st.generating .dot,.st.st-generating .dot{background:var(--green);animation:pulse 1.4s var(--ease) infinite}

/* solid dark — failed / alarm */
.st.failed,.st.st-failed{color:var(--ink);font-weight:600}
.st.failed .dot,.st.st-failed .dot{background:var(--ink)}

@keyframes pulse{0%,100%{opacity:1}50%{opacity:.3}}

.pkg{font-size:13px;color:var(--ink)}
.contact .nm{font-size:14px;font-weight:500;color:var(--ink)}
.contact .em{font-size:12.5px;color:var(--ink-soft)}
.loc{font-size:13.5px;color:var(--ink)}
.age{font-size:13px;color:var(--ink-soft);text-align:right;font-variant-numeric:tabular-nums}

.trow.hide{display:none}

/* footer / pagination */
.pager{display:flex;align-items:center;justify-content:space-between;margin-top:var(--s3);
  font-size:13px;color:var(--ink-soft)}
.pager .btns{display:flex;gap:8px}
.pager button{
  font:inherit;font-size:13px;background:var(--cream-panel);border:1px solid var(--cream-line);
  color:var(--ink);padding:7px 14px;border-radius:4px;cursor:pointer;transition:all .16s var(--ease);
}
.pager button:hover:not(:disabled){border-color:var(--green);color:var(--green)}
.pager button:disabled{opacity:.4;cursor:default}

@media (max-width:820px){
  /* Tighten the shared frame on small screens — 64px side padding is too
     much. Header inner and page frame stay in lockstep so they keep aligning. */
  .band-inner,.page-container{padding-left:var(--gutter);padding-right:var(--gutter)}
  .signals{grid-template-columns:repeat(2,1fr)}
  .thead{display:none}
  .trow{grid-template-columns:1fr;gap:6px;padding:var(--s3) var(--s2)}
  .age{text-align:left}
}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}
