/* BlackOS — Admin brand kit */
:root{
  /* SavvyFaire design system — cream canvas · red commit · purple ✦ AI · teal Aby · amber passport. */
  --ink:#080706; --ink-soft:#3F3A35; --paper:#ffffff;
  --cream:#F9F2EB; --cream-2:#F3EEE8; --cream-3:#E1DCD7;
  /* FIELD CONTRAST — look B (Asa, 16 Sep 2026: "white on white … the background is darker and the entry fields are
     lighter, so it's easier on the eye" → chose B, "consistently", from site/admin/mockups/field-contrast.mockup.html).
     The page is a shade darker than the cream it was, cards stay white, and every entry field is the palest cream
     with a stronger border and a soft inner shadow, with a dark ring on focus. Read-only values are text, not boxes. */
  --page:#EFE8DF; --field:#FCFAF7; --field-line:#BDB3A6;
  --field-shadow:inset 0 1px 2px rgba(42,35,32,.08); --field-ring:0 0 0 3px rgba(63,58,53,.14);
  --stone:#675E54; --stone-soft:#504B47; --line:#E1DCD7;
  /* CHROME — the app's ordinary furniture: buttons, links, selected tabs, focus rings.
     It is deliberately NOT red. .btn takes its fill from --plum, so making this red would put
     ten red buttons on a single screen and spend the one colour that is supposed to mean
     "a human is committing something". Warm espresso instead: it sits on the cream canvas as a
     considered choice rather than the cold #1A1A1A placeholder that used to overwrite it. */
  --plum:#3F3A35; --plum-deep:#2A2622; --plum-tint:#F1EAE2;
  --accent-rgb:63,58,53; --accent-deep-rgb:42,38,34;
  /* COMMIT — red, and only ever red for this. One per screen, applied explicitly so it can never
     leak into chrome by inheriting a token. */
  --commit:#BD2424; --commit-deep:#8E1B1B; --commit-tint:#F6E0E0;
  --purple:#7F77DD; --purple-bg:#EEEDFE;                       /* AI ✦ */
  --teal:#1D9E75; --teal-bg:#E1F5EE;                           /* Aby (staff) */
  --amber:#BA7517; --amber-bg:#F7EEDD;                         /* Passport / personal */
  --good:#1D9E75; --good-bg:#E1F5EE; --warn:#BA7517; --warn-bg:#F7EEDD; --bad:#BD2424; --bad-bg:#F6E0E0;
  --disp:'Plus Jakarta Sans',system-ui,sans-serif; --body:'Inter',system-ui,sans-serif;
  --shadow:0 18px 44px rgba(42,35,32,.10); --shadow-sm:0 6px 18px rgba(42,35,32,.06);
  --r-chip:999px; --r-card:14px; --r-panel:16px;
  /* ── THE SCALES ────────────────────────────────────────────────────────────────────────────
     Measured across site/ on 8 Sep 2026: 35 distinct font sizes (7.5px to 26px, including
     8.5, 9.5, 10.5, 11.5, 12.5, 13.5, 14.5 and 15.5) and 20 distinct border radii (2, 3, 4, 5,
     6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 99, 999). Nobody chose 20 radii; each
     was chosen once, alone, and never compared with the other nineteen.

     These are the ramps everything NEW is built from. They are deliberately short: a scale you
     can hold in your head is a scale people actually use. The existing off-ramp values are not
     rewritten here — that is a visual change to screens already approved, and it is a separate,
     deliberate pass. What stops the drift getting worse is the design gate, which now counts
     off-ramp values and fails when the number goes up. */
  --t-micro:9px;    /* source tags, stamps — the smallest thing that may carry meaning */
  --t-label:10px;   /* THE EYEBROW. Small caps, .07em, 700. */
  --t-xs:11px;      /* secondary metadata under a line */
  --t-sm:12.5px;    /* table cells, chips, dense body */
  --t-md:13.5px;    /* body, a row's own name */
  --t-lg:15px;      /* a sub-head */
  --t-xl:19px;      /* a tile's figure */
  --t-fig:22px;     /* a counter's figure and a sheet's title — Asa, 16 Sep 2026, "strictly follow"
                       the approved booking mockup, which sets both at 22-23px */
  --t-2xl:26px;     /* a page or record title */

  --r-xs:4px; --r-sm:8px; --r-md:12px;   /* with --r-card 14, --r-panel 16, --r-chip 999 above */
}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:var(--body);background:var(--page);color:var(--ink);line-height:1.55;-webkit-font-smoothing:antialiased}
.serif{font-family:var(--disp)}
a{color:var(--plum);text-decoration:none}
h1,h2{font-family:var(--disp);font-weight:700;line-height:1.12;letter-spacing:-.01em}
h3{font-family:var(--body);font-weight:700;line-height:1.2;letter-spacing:-.005em}
.muted{color:var(--stone-soft)}
.small{font-size:12.5px}
button,input,select,textarea{font-family:inherit}
input,select,textarea{width:100%;padding:11px 13px;border:1px solid var(--field-line);border-radius:12px;font-size:13.5px;background:var(--field);color:var(--ink);box-shadow:var(--field-shadow)}
/* The old line read "input:focus,select,textarea:focus" — the bare "select" gave every dropdown the focus border all
   the time. Each control is focused on its own now, with the ring. */
input:focus,select:focus,textarea:focus{outline:none;border-color:var(--plum);box-shadow:var(--field-shadow),var(--field-ring)}
input[type=checkbox],input[type=radio],input[type=range],input[type=color],input[type=file]{box-shadow:none;background:transparent}
/* Inputs that are deliberately borderless — the top search, the command bar, the big figure editors — stay flat. */
.tb-search input,.cmd input,.slc-dv input,.slc-dv select{box-shadow:none}
label{display:block;font-size:12.5px;font-weight:600;color:var(--ink-soft);margin:0 0 5px;letter-spacing:.01em}
.field{margin-bottom:14px}
.row{display:grid;gap:12px}
.row.c2{grid-template-columns:1fr 1fr}.row.c3{grid-template-columns:1fr 1fr 1fr}
@media(max-width:640px){.row.c2,.row.c3{grid-template-columns:1fr}}
.btn{display:inline-flex;align-items:center;gap:7px;padding:11px 18px;border:1px solid var(--plum);border-radius:var(--r-chip);background:var(--plum);color:#fff;font-weight:600;font-size:13.5px;cursor:pointer;transition:.15s}
.btn:hover{background:var(--plum-deep);border-color:var(--plum-deep)}
.btn.ghost{background:#fff;color:var(--plum)}.btn.ghost:hover{background:var(--plum-tint)}
/* COMMIT — the one action on a screen where a human takes responsibility for something.
   Red is spent here and nowhere else; if two of these appear on one screen, one of them is
   not really a commit and should be a ghost. */
.btn.commit{background:var(--commit);border-color:var(--commit)}
.btn.commit:hover{background:var(--commit-deep);border-color:var(--commit-deep)}
.btn.commit.ghost{background:#fff;color:var(--commit);border-color:var(--commit)}
.btn.commit.ghost:hover{background:var(--commit-tint)}
.btn.sm{padding:7px 13px;font-size:12.5px}
.btn.dark{background:var(--ink);border-color:var(--ink)}.btn.dark:hover{background:#000}
.chip{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:var(--r-chip);font-size:11px;font-weight:600;background:var(--cream-2);color:var(--ink-soft)}
.chip.good{background:var(--good-bg);color:var(--good)}.chip.warn{background:var(--warn-bg);color:var(--warn)}.chip.bad{background:var(--bad-bg);color:var(--bad)}
.card{background:var(--paper);border:1px solid var(--line);border-radius:16px;padding:22px;box-shadow:var(--shadow-sm)}

/* ══ THE PRIMITIVES ════════════════════════════════════════════════════════════════════════════
   Eight shapes the app actually has, each written ONCE, here, in the shared system.

   They were not invented — they were EXTRACTED. Measured on 8 Sep 2026, app.html carried 1,054
   lines of CSS in 25 per-page namespaces (jr- bi- pd- ppl- vk- tp- tb- katy- …), and those
   namespaces were re-deriving the same handful of shapes with slightly different numbers each
   time: the panel card existed three times at two radii, the small-caps eyebrow six times at
   three sizes and three weights, the status row twice as near-identical copies. Nothing was
   wrong with any one of them; the problem was that a fix to one silently missed the others,
   which is exactly how .ppl-p and .bi-pax drifted apart.

   The old class names are kept as ALIASES so no markup had to change. A page keeps calling its
   card .bi-card; it simply now gets the same card as everybody else. New work should use the
   unprefixed name.

   NOTE — .card above and .panel below are DIFFERENT SHAPES, deliberately:
     .card   is a single padded box. Content sits straight inside it.
     .panel  is a box with a header bar and a body, and clips its children (overflow:hidden), so
             a table or a list of rows can run edge to edge inside it.
   Merging them was tempting and would have been wrong — .card's 22px padding is load-bearing on
   dozens of screens.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* 1 · PANEL — header bar + body. Radius comes from the token, so it is one number, not three
      (it was 14px on .pd-card and 15px on .bi-card). */
.panel,.pd-card{
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-card);
  overflow:hidden;box-shadow:0 1px 2px rgba(28,29,31,.035);margin-bottom:14px}

/* 2 · PANEL HEADER — the bar with a bottom rule. THIS is what stops a panel reading flat; an
      eyebrow floating above content is not a header. Aligned flex-start rather than centre so a
      two-line title with a provenance note under it does not drag its right-hand chip down. */
.panel-h,.pd-card-h{
  display:flex;align-items:flex-start;justify-content:space-between;gap:18px;flex-wrap:wrap;
  padding:13px 18px 12px;border-bottom:1px solid var(--cream-2)}

/* 3 · PANEL BODY */
.panel-b,.pd-card-b{padding:14px 18px}
.panel-b.flush,.pd-card-b.flush{padding:0}

/* 4 · EYEBROW — the small-caps kick that says which domain a block belongs to. Six definitions
      became one at 10px/700/.07em, the modal value of the six. .tagpill and .bi-tab b are NOT in
      this group: they sit on the espresso band at weight 800 and are tags, not eyebrows. */
.kick,.eyebrow,.vk-tbl .h{
  font-size:10px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;color:var(--stone)}

/* 5 · PROVENANCE — which table this block binds to. The house signature: it makes a screen
      self-documenting and it is the thing that makes a block look considered rather than bare. */
.prov{font-size:11px;color:#9C9B97;margin-top:2px}

/* 6 · STATUS ROW — one person, one task, one segment. The 3px left edge IS the status system:
      teal ready, amber a gap, red blocking. It reads down a column of twelve without a pill. */
.rowitem{
  display:flex;align-items:flex-start;gap:13px;padding:13px 18px 13px 15px;
  border-bottom:1px solid var(--cream-3);border-left:3px solid transparent;position:relative}
.rowitem:last-of-type{border-bottom:0}
.rowitem.ok{border-left-color:var(--good)}
.rowitem.gap{border-left-color:var(--amber)}
.rowitem.stop{border-left-color:var(--bad)}

/* 7 · INITIALS — the round mark at the head of a status row, tinted by that row's state. */
.ini{
  flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;
  background:var(--cream);color:var(--stone);font-size:11px;font-weight:700;letter-spacing:.03em}
.rowitem.ok .ini{background:rgba(29,158,117,.12);color:var(--good)}
.rowitem.stop .ini{background:rgba(189,36,36,.10);color:var(--bad)}

/* 8 · METER — a bar is decoration until a sentence states the reading underneath it. */
.meter{height:8px;border-radius:99px;background:var(--sunk,#EFE9DF);overflow:hidden;display:flex}
.meter i{height:100%;display:block}
table{width:100%;border-collapse:collapse;font-size:13.5px}
th{text-align:left;font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--stone-soft);font-weight:700;padding:9px 10px;border-bottom:2px solid var(--cream-3)}
td{padding:10px;border-bottom:1px solid var(--cream-2);vertical-align:top}
tr:hover td{background:var(--cream)}
.num{text-align:right;font-variant-numeric:tabular-nums}
/* pipeline kanban — desktop = all columns, mobile = swipeable full-width columns that stay within the screen */
.board{display:grid;grid-template-columns:repeat(var(--ncol),minmax(180px,1fr));gap:12px;align-items:start;overflow-x:auto}
@media(max-width:760px){.board{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:86%;scroll-snap-type:x proximity;padding-bottom:8px}.board>*{scroll-snap-align:start}}
.kpi{background:#fff;border:1px solid var(--line);border-radius:12px;padding:13px 15px}
.kpi .v{font-family:var(--body);font-size:19px;font-weight:700;line-height:1.1;letter-spacing:-.015em;font-variant-numeric:tabular-nums;color:var(--ink,#1a1018)}
.kpi .l{font-size:11px;text-transform:uppercase;letter-spacing:.06em;color:var(--stone-soft);margin-top:5px;font-weight:600}
.empty{text-align:center;color:var(--stone-soft);padding:40px 20px;font-size:13.5px}

/* ── "boiling over" — generation-motion reveal (staggered shimmer → settle). Brand-tinted (plum + warm gold). ── */
@keyframes gen-shimmer{0%{background-position:-150% 0}100%{background-position:250% 0}}
@keyframes gen-pop{0%{opacity:0;transform:translateY(10px) scale(.985)}100%{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.gen,.gen::after,.gen--in{animation:none!important}.gen>*{opacity:1!important;filter:none!important}}
.gen{position:relative;border:1.5px dashed var(--line,#E2DDD4)!important;overflow:hidden}
.gen>*{opacity:.22;filter:blur(.5px);transition:opacity .4s ease,filter .4s ease}
.gen::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:3;background:linear-gradient(100deg,transparent 30%,rgba(var(--accent-rgb),.13) 46%,rgba(202,165,61,.14) 56%,transparent 72%);background-size:220% 100%;animation:gen-shimmer 1.05s linear infinite}
.gen--in{animation:gen-pop .42s cubic-bezier(.22,1,.36,1) both}
