/* ─────────────────────────────────────────────────────────────────────────
   Marketing OS — operator console
   Design language: premium utilitarian minimalism (document-style).
   Warm monochrome canvas, 1px hairline borders, editorial type contrast,
   muted pastel semantics, ink-black primary actions, quiet 200ms motion.
   ───────────────────────────────────────────────────────────────────────── */

:root {
  /* Indizilla brand: paper + ink, one acid-lime action colour.
     Light is the default; the dark block below mirrors indizilla.com. */

  /* canvas + surfaces */
  /* indizilla.com: paper, the card on it, and the hairline between them. */
  /* The ground is toned, the way indizilla.com's is: a white card on near
     white paper is the same plane, and on a toned atmospheric field it
     floats. That one change is most of the language. */
  --canvas: #C6CFD4;
  --surface: #FFFFFF;
  --surface-2: #DDE3E7;
  --hover: #D2DADF;
  --line: #AFB8BD;
  --line-strong: #93A0A7;
  --grid: rgba(20, 22, 26, .055);
  --canvas-mesh:
    radial-gradient(78% 60% at 6% -8%, rgba(236, 208, 172, .92) 0%, rgba(236, 208, 172, 0) 60%),
    radial-gradient(64% 54% at 102% 14%, rgba(158, 184, 212, .88) 0%, rgba(158, 184, 212, 0) 58%),
    radial-gradient(86% 64% at 42% 114%, rgba(186, 198, 190, .90) 0%, rgba(186, 198, 190, 0) 62%),
    radial-gradient(50% 44% at 74% 64%, rgba(214, 198, 206, .55) 0%, rgba(214, 198, 206, 0) 60%);

  /* text */
  /* Measured against the tone, not against white. On this ground the old
     --muted read 3.4 to 1 and --faint 2.0, which is not a quiet colour but
     one nobody can read. The ramp is 11.4, 6.8, 5.7 and 5.0 to 1 on the
     paper, and higher again on a card. */
  --ink: #16181C;
  --body: #3A3E45;
  --muted: #44484F;
  --faint: #4E525A;

  /* Base actions stay ink: a console has dozens of buttons per screen and
     they cannot all shout. Lime is the brand colour, reserved for primary. */
  --action: #14161A;
  --action-hover: #2A2D31;
  --on-action: #FAFAF8;
  --brand: #DAFE31;
  --brand-hover: #CDF11F;
  --on-brand: #14161A;
  /* The accent as a word. The accent itself is 1.05:1 on paper, so it is
     never text on a light ground; this is the form that is, at 5.36:1. */
  --brand-ink: #5C6B00;

  /* semantic pastels, retuned to sit on paper rather than warm cream */
  --ok-bg: #EDF6E8;   --ok-fg: #3F6B22;
  --bad-bg: #FDECEC;  --bad-fg: #9F2F2D;
  --warn-bg: #FBF3DB; --warn-fg: #8A5D00;
  --info-bg: #E7F1FB; --info-fg: #1F5F9F;

  /* Short aliases. The page scripts write these inline; without the
     definitions the whole declaration is invalid and the element silently
     keeps its default colour, which is why a red banner was not red. */
  --ok: var(--ok-fg);     --ok-soft: var(--ok-bg);
  --bad: var(--bad-fg);   --bad-soft: var(--bad-bg);
  --warn: var(--warn-fg); --warn-soft: var(--warn-bg);
  --info: var(--info-fg); --info-soft: var(--info-bg);

  /* The site's --r. */
  --r-card: 12px;
  --r-btn: 8px;     /* the site's button radius; it does not use pills */
  --r-field: 8px;   /* inputs: a pill clips multi-line text at the corners */
  --ease: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);

  --font-sans: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-disp: "Archivo", system-ui, sans-serif;
  /* The site has one family. What was called serif here is the same face at
     its heavier weights, set tight — which is how indizilla.com sets a heading. */
  --font-serif: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* Dark, mirroring indizilla.com. Toggled by data-theme on <html>. */
[data-theme="dark"] {
  /* The site's dark sections: --black on the ground, --black-2 raised, and
     its three levels of text on them. Dark here is the same material the
     site uses for a dark band, not a separately invented palette. */
  --canvas: #0B0E12;
  --surface: #1C2027;
  --surface-2: #24282F;
  --hover: #2B3038;
  --line: #2F343B;
  --line-strong: #434952;
  --grid: rgba(255, 255, 255, .035);
  --ink: #EDEFF2;
  --body: #CBD0D6;
  --muted: #AEB4BD;
  --faint: #868D96;
  /* The ground keeps its weather and loses its brightness: the same four
     lights, at a fifth of the strength, over a near black. */
  --canvas-mesh:
    radial-gradient(78% 60% at 6% -8%, rgba(236, 208, 172, .15) 0%, rgba(236, 208, 172, 0) 60%),
    radial-gradient(64% 54% at 102% 14%, rgba(158, 184, 212, .17) 0%, rgba(158, 184, 212, 0) 58%),
    radial-gradient(86% 64% at 42% 114%, rgba(186, 198, 190, .13) 0%, rgba(186, 198, 190, 0) 62%),
    radial-gradient(50% 44% at 74% 64%, rgba(214, 198, 206, .09) 0%, rgba(214, 198, 206, 0) 60%);
  --action: #E9EAEC;
  --action-hover: #FFFFFF;
  --on-action: #14161A;
  --brand: #DAFE31;
  --brand-hover: #E4FF57;
  --on-brand: #14161A;
  /* Accent text. Light uses a darkened lime so it passes on white; on dark the
     full lime is the readable one. Defined in both so var(--brand-ink) is the
     one name for "accent, as text" whichever scheme is on. */
  --brand-ink: #DAFE31;
  --ok-bg: #17250F;   --ok-fg: #A8DE7A;
  --bad-bg: #2A1414;  --bad-fg: #F09A98;
  --warn-bg: #2A2210; --warn-fg: #E8C25F;
  --info-bg: #12212E; --info-fg: #8FC4F0;
  --shadow-card: 0 1px 2px rgba(0, 0, 0, 0.5), 0 8px 24px -12px rgba(0, 0, 0, 0.6);
  --shadow-pop: 0 18px 50px -12px rgba(0, 0, 0, 0.75);
  --focus: rgba(218, 254, 49, 0.28);
}

/* One scale, so a label is a label everywhere and a number reads as a number.
   The old file had every size within two points of 13, which is why the
   screens had no hierarchy to read. */
:root {
  /* The site's own display step, which is far larger than a console's habit. */
  --t-display: clamp(30px, 3.2vw, 44px);
  --t-h1: 21px;
  --t-h2: 15.5px;
  --t-h3: 13.5px;
  --t-body: 13.5px;
  --t-small: 12.5px;
  --t-micro: 10.5px;
  --shadow-card: 0 1px 2px rgba(20, 22, 26, 0.04), 0 8px 20px -14px rgba(20, 22, 26, 0.18);
  --shadow-pop: 0 18px 44px -14px rgba(20, 22, 26, 0.24);
  --focus: rgba(20, 22, 26, 0.12);
}

* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; }

/* The grain that keeps a wide gradient from banding. */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 200;
  pointer-events: none;
  opacity: .24;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.86' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}
[data-theme="dark"] body::after { opacity: .18; }
body {
  font: 400 14px/1.6 var(--font-sans);
  /* The ground is a material, not a colour: a toned field with four lights in
     it, fixed so it does not travel with the scroll, and a grain over the top
     that keeps a wide gradient from banding. The same ground as the site and
     the same as the console. */
  background-color: var(--canvas);
  background-image: var(--canvas-mesh);
  background-attachment: fixed;
  color: var(--body);
  display: grid;
  grid-template-columns: 232px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas: "side top" "side main";
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--brand); color: var(--on-brand); }

i.ph { font-size: 17px; line-height: 1; vertical-align: -2.5px; }

/* ── Sidebar ─────────────────────────────────────────────────────────── */
#side {
  grid-area: side;
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 20px 12px 16px;
}
#side .logo {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  padding: 0 12px 20px;
}
#side .logo span { color: var(--faint); }
#side a {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--muted);
  text-decoration: none;
  padding: 8px 12px;
  border-radius: 7px;
  margin-bottom: 1px;
  font-size: 13.5px;
  font-weight: 500;
  transition: background 150ms var(--ease), color 150ms var(--ease);
}
#side a i.ph { font-size: 17px; color: var(--faint); transition: color 150ms; }
#side a:hover { background: var(--surface-2); color: var(--ink); }
#side a:hover i.ph { color: var(--muted); }
#side a.active {
  background: var(--hover); color: var(--ink);
  box-shadow: inset 2px 0 0 var(--brand);
}
#side a.active i.ph { color: var(--ink); }
#side a .n {
  margin-left: auto;
  background: var(--bad-bg);
  color: var(--bad-fg);
  border-radius: 99px;
  font-size: 11px;
  font-weight: 600;
  padding: 0 7px;
  line-height: 18px;
}
#side .foot {
  margin-top: auto;
  font-size: 11.5px;
  line-height: 1.5;
  color: var(--faint);
  padding: 12px 12px 0;
  border-top: 1px solid var(--line);
}

/* ── Topbar ──────────────────────────────────────────────────────────── */
#top {
  grid-area: top;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 20px;
  min-width: 0;
  overflow: visible;
}
/* The pickers read as fields, not floating words: the chevron from the base
   select rule needs a ground to sit on or the control has no edge at all. */
#top select {
  width: auto;
  min-width: 160px;
  min-height: 32px;
  border: 1px solid var(--line);
  background-color: var(--surface-2);
  font-weight: 500;
  color: var(--ink);
  padding: 4px 30px 4px 11px;
}
#top select:hover { border-color: var(--line-strong); background-color: var(--hover); }
#new-project {
  padding: 5px 9px;
  font-size: 14px;
  line-height: 1;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: var(--t-small);
  font-weight: 500;
  padding: 5px 11px;
  border-radius: 99px;
  border: 1px solid var(--line);
  color: var(--muted);
  background: var(--surface);
}
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--faint); }
.chip.ok .dot { background: var(--ok-fg); }
.chip.warn .dot { background: var(--warn-fg); }
.chip.bad .dot { background: var(--bad-fg); }
/* The queue badge. Empty means not asked yet, and an empty chip is a stray
   outline on the bar, so it collapses rather than sitting there blank. */
.chip.sched:empty { display: none; }
.chip.sched.warn { color: var(--warn-fg); }
.chip.sched.bad { color: var(--bad-fg); }
/* Status reads left to right and gives way first; the controls that must be
   reachable at any width are pinned and never shrink. The bar used to scroll
   inside itself, which meant the emergency control sat half off the right
   edge of a 1440 screen on every page. */
#top .statuses {
  display: flex; align-items: center; gap: 8px;
  min-width: 0; overflow-x: auto; flex: 1 1 auto;
  scrollbar-width: none;
}
#top .statuses::-webkit-scrollbar { display: none; }
#top .statuses .chip { flex: 0 0 auto; }
#top .pinned { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; margin-left: 8px; }
#top .pinned button.icon { min-width: 34px; padding: 0 10px; }
#kill {
  border: 1px solid var(--line-strong);
  color: var(--bad-fg);
  background: var(--surface);
  font-weight: 600;
  font-size: 12.5px;
  border-radius: var(--r-btn);
  padding: 0 13px;
  min-height: 32px;
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
  transition: all 180ms var(--ease);
}
#kill:hover { border-color: var(--bad-fg); background: var(--bad-bg); }
#kill.on { background: var(--bad-fg); border-color: var(--bad-fg); color: var(--surface); }

/* ── Main / page scaffolding ─────────────────────────────────────────── */
/* A measure, so a card on a wide monitor is a card and not a banner, and a
   line of text stays readable. Everything inside it is laid out against this
   width rather than the window's. */
#view { grid-area: main; overflow-y: auto; padding: 36px 40px 80px; }
#view > * { max-width: 1240px; margin-left: auto; margin-right: auto; }
.page-head {
  position: relative;
  margin: 0 0 26px;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
  display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap;
}
/* A hairline that starts at the brand colour and fades, so the top of every
   screen is the one place the brand is allowed to show. */
.page-head::after {
  content: ""; position: absolute; left: 0; bottom: -1px; height: 1px; width: 120px;
  background: linear-gradient(90deg, var(--brand), transparent);
}
.page-head > div:first-child { max-width: 720px; }
.page-head h1 {
  margin: 0 0 9px;
  font-family: var(--font-sans);
  font-size: var(--t-display);
  font-weight: 700;
  letter-spacing: -0.035em;
  line-height: 0.98;
  color: var(--ink);
  text-wrap: balance;
}
.page-head p { margin: 0; color: var(--muted); font-size: var(--t-body); line-height: 1.55; }
.page-head .eyebrow {
  display: block; margin-bottom: 10px;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); font-weight: 400;
}
.page-head .head-act { display: flex; gap: 8px; flex-wrap: wrap; padding-bottom: 2px; }

.grid { display: grid; gap: 16px; }
.cols-2 { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }
.cols-3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }

/* The site's card: white on paper, one hairline, and room. No gradient and
   no shadow — indizilla.com does not use either, and the lit surface I had
   built belonged to a darker, glossier product than this one. */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 24px 26px 26px;
  animation: rise 450ms var(--ease) both;
}
/* In dark the surfaces are the site's raised black; a hairline alone is not
   enough separation there, so they take the smallest possible shadow. */
[data-theme="dark"] .card { box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35); }
/* A card that can be acted on lifts under the pointer; one that only reports
   does not, because a hover that promises nothing is noise. */
.card.act:hover { border-color: var(--line-strong); }
.card:nth-child(2) { animation-delay: 40ms; }
.card:nth-child(3) { animation-delay: 80ms; }
.card:nth-child(4) { animation-delay: 120ms; }
.card:nth-child(5) { animation-delay: 160ms; }
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .card, #view > * { animation: none !important; transition: none !important; }
}
.card h2 {
  margin: 0 0 5px;
  font-family: var(--font-sans);
  font-size: var(--t-h2);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.018em;
  line-height: 1.25;
}
.card h3 {
  margin: 18px 0 8px;
  font-size: var(--t-h3);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.003em;
}
.card h2 .badge { margin-left: 6px; vertical-align: 1px; }
.card > p.sub { margin: 0 0 16px; color: var(--muted); font-size: var(--t-small); line-height: 1.55; max-width: 62ch; }
.big {
  font-size: var(--t-display);
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
}
/* A statistic is a label, a figure and the sentence that makes it mean
   something. Without the third it is a number floating in a box, which is
   what the money screen looked like. */
.stat { display: flex; flex-direction: column; gap: 6px; }
.stat .lab {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--muted); font-weight: 400;
}
.stat .fig { font-size: var(--t-display); font-weight: 600; letter-spacing: -0.025em; color: var(--ink); font-variant-numeric: tabular-nums; line-height: 1.05; }
.stat .fig.up { color: var(--ok-fg); }
.stat .fig.down { color: var(--bad-fg); }
.stat .note { font-size: var(--t-small); color: var(--muted); line-height: 1.5; }
.muted { color: var(--muted); font-size: 12.5px; }
.spacer { height: 16px; }

/* ── Buttons ─────────────────────────────────────────────────────────── */
button, .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: var(--action);
  color: var(--on-action);
  border: 1px solid var(--action);
  border-radius: var(--r-btn);
  min-height: 34px;
  padding: 0 15px;
  font: 600 13px/1 var(--font-sans);
  cursor: pointer;
  transition: background 160ms var(--ease), transform 120ms var(--ease), border-color 160ms, box-shadow 160ms;
  white-space: nowrap;
}
button i.ph, .btn i.ph { font-size: 15px; }
/* The one action a screen exists for. Exactly one per screen, or it stops
   meaning anything. */
button.primary, .btn.primary {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand);
  font-weight: 700;
}
button.primary:hover, .btn.primary:hover { filter: brightness(0.97); }
button.primary:hover, .btn.primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }
button:focus-visible, .btn:focus-visible, a:focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--focus);
}
button:hover { background: var(--action-hover); border-color: var(--action-hover); }
button:active { transform: scale(0.98); }
button:disabled { opacity: 0.4; cursor: default; transform: none; }
button.ghost, .btn.ghost {
  background: var(--surface);
  color: var(--ink);
  border: 1px solid var(--line-strong);
  font-weight: 500;
}
button.ghost:hover, .btn.ghost:hover { background: var(--surface-2); border-color: var(--faint); }
/* The site has no green button. Approving is the affirmative action on a
   draft, so it wears the brand colour, which is what lime is for. */
button.good { background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 700; }
button.good:hover { filter: brightness(0.97); background: var(--brand); border-color: var(--brand); }
button.danger { background: var(--surface); border-color: var(--line-strong); color: var(--bad-fg); }
button.danger:hover { background: var(--bad-bg); border-color: var(--bad-fg); }
button.small, .btn.small { min-height: 28px; padding: 0 11px; font-size: 12px; gap: 5px; }
button.small i.ph, .btn.small i.ph { font-size: 13px; }

/* ── Forms ───────────────────────────────────────────────────────────── */
input, textarea, select {
  font: 400 var(--t-body)/1.5 var(--font-sans);
  color: var(--ink);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-field);
  min-height: 36px;
  padding: 7px 12px;
  width: 100%;
  transition: border-color 150ms, box-shadow 150ms, background 150ms;
}
/* 84px was five lines at this line-height, with its own scrollbar inside it.
   A brand bible section is paragraphs, so every one of them was read through
   a slit — and the same box is used for every long answer in the tool. They
   open at a readable size and grow to their content (grabTextareas() in
   app.js), with the drag handle left on for anything taller. */
textarea { min-height: 168px; line-height: 1.6; padding: 10px 12px; resize: vertical; }
/* The native arrow is the one part of a select a browser will not let you
   style, so it goes and the chevron is drawn. */
select {
  appearance: none; -webkit-appearance: none;
  padding-right: 34px;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 17px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--ink);
  cursor: pointer;
}
select:disabled, input:disabled, textarea:disabled { opacity: 0.5; cursor: not-allowed; }
input[type="checkbox"], input[type="radio"] { width: auto; min-height: 0; accent-color: var(--brand); }
input::placeholder, textarea::placeholder { color: var(--faint); }
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--ink);
  box-shadow: 0 0 0 3px var(--focus);
}
label.f { display: block; margin-bottom: 12px; }
label.f span {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
  font-weight: 400;
}
/* A hint belongs under the field, in sentence case, not inside the label. */
label.f span.hint {
  margin: 5px 0 0; text-transform: none; letter-spacing: 0;
  font-size: var(--t-small); font-weight: 400; color: var(--muted);
}
form.stack { max-width: 520px; }
.row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
/* A field that shares a line with another one.
   This was an inline `style="flex:1"` in 176 places, which no stylesheet can
   override, so two fields side by side stayed side by side at every width.
   On a 375px screen that left the Networks select 153px wide rendering
   "Google Business Profile" — its own content cut off by 25px inside its own
   box. As a class it can simply take the line when there is no room. */
.f.grow { flex: 1 1 0; min-width: 0; }
@media (max-width: 560px) {
  .f.grow, #view .row > label.f { flex: 1 1 100%; }
}

/* ── Tables ──────────────────────────────────────────────────────────── */
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
td { font-size: var(--t-small); color: var(--body); }
th {
  color: var(--faint);
  font-weight: 700;
  font-size: var(--t-micro);
  text-transform: uppercase;
  letter-spacing: 0.07em;
  border-bottom: 1px solid var(--line-strong);
  background: var(--surface-2);
  white-space: nowrap;
}
th:first-child { border-top-left-radius: 8px; }
th:last-child { border-top-right-radius: 8px; }
tbody tr:last-child td { border-bottom: 0; }
/* A column of money or counts lines up on the decimal, always. */
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
tbody tr, table tr { transition: background 120ms; }
table tr:hover td { background: var(--surface-2); }
tr:last-child td { border-bottom: 0; }
td b { color: var(--ink); font-weight: 600; }

/* ── Badges (muted pastel, pill, small) ──────────────────────────────── */
.badge {
  display: inline-block;
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  border-radius: 5px;
  padding: 3px 7px;
  line-height: 1.35;
  background: var(--info-bg);
  color: var(--info-fg);
  white-space: nowrap;
}
.badge.ok { background: var(--ok-bg); color: var(--ok-fg); }
.badge.warn { background: var(--warn-bg); color: var(--warn-fg); }
.badge.bad { background: var(--bad-bg); color: var(--bad-fg); }
.badge.dim { background: var(--hover); color: var(--muted); }

/* ── Checklist ───────────────────────────────────────────────────────── */
.checklist { list-style: none; margin: 0; padding: 0; }
.checklist li {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
.checklist li:last-child { border-bottom: 0; }
.checklist .tick {
  width: 21px; height: 21px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--line-strong);
  color: transparent; font-size: 12px; flex: none;
  margin-top: 2px;
  transition: all 200ms var(--ease);
}
.checklist li.done .tick { background: var(--ok-fg); border-color: var(--ok-fg); color: var(--surface); }
.checklist li.done .t { color: var(--faint); text-decoration: line-through; text-decoration-color: var(--line-strong); }
.checklist .t { font-weight: 600; color: var(--ink); font-size: 13.5px; }
.checklist .h { color: var(--muted); font-size: 12.5px; }
.checklist li a { margin-left: auto; flex: none; }

/* ── Approval cards ──────────────────────────────────────────────────── */
.approval {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 16px 18px;
  margin-bottom: 12px;
  background: var(--surface);
  transition: border-color 150ms, box-shadow 200ms var(--ease);
}
.approval:hover { border-color: var(--line-strong); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04); }
.approval h3 { margin: 0 0 5px; font-size: 13.5px; font-weight: 600; color: var(--ink); }
.approval .why { color: var(--muted); font-size: 13px; margin-bottom: 10px; }
.approval .facts {
  display: flex; gap: 6px; flex-wrap: wrap; align-items: center;
  margin-bottom: 14px;
}
/* A brand-fit score: the dot carries the verdict so the number does not have
   to be read to know whether it is fine. */
.approval .facts .score {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--t-small); font-weight: 600; color: var(--body);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 6px; padding: 3px 9px;
  font-variant-numeric: tabular-nums;
}
.approval .facts .score i { width: 6px; height: 6px; border-radius: 50%; background: var(--faint); }
.approval .facts .score.good i { background: var(--ok-fg); }
.approval .facts .score.fair i { background: var(--warn-fg); }
.approval .facts .score.poor i { background: var(--bad-fg); }
.approval .facts .tag {
  display: inline-flex; align-items: center; gap: 4px;
  font-size: var(--t-small); color: var(--muted);
  border: 1px solid var(--line); border-radius: 6px; padding: 3px 9px;
}
.approval .facts .tag.done { color: var(--ok-fg); border-color: var(--ok-bg); background: var(--ok-bg); }
.approval .facts .tag i.ph { font-size: 12px; }
.approval.risk-high, .approval.risk-critical { border-left: 3px solid var(--bad-fg); }
.approval.risk-medium { border-left: 3px solid var(--warn-fg); }

/* The bible is what this screen is for, so it gets the room; the things you
   touch once a month are folds beside it. */
.brandcols { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 20px; align-items: start; }
.brandside .deck:first-child { border-top: 0; }
@media (max-width: 1000px) { .brandcols { grid-template-columns: 1fr; } }

/* ── The brand's colours, shown rather than described ─────────────────── */
.palette { margin: 4px 0 14px; }
.palette-h { font-size: var(--t-small); font-weight: 500; margin-bottom: 8px; }
.palette-h .muted { font-weight: 400; }
.swatches { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.swatch {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 5px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 11.5px; background: var(--surface);
}
.swatch i {
  width: 16px; height: 16px; border-radius: 50%; flex: none;
  border: 1px solid rgba(0, 0, 0, 0.12); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.25);
}
.swatch b { font-weight: 600; color: var(--ink); }
.swatch code { font-family: var(--font-mono); color: var(--muted); font-size: 10.5px; }
.card-preview {
  border-radius: var(--r-card); padding: 14px 16px; font-size: 13px;
  border: 1px solid var(--line);
}
.logoslots { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 620px) { .logoslots { grid-template-columns: 1fr; } }
.logoslot-k { font-size: 12px; font-weight: 600; margin-bottom: 6px; }
.logoslot-k .muted { font-weight: 400; }
/* The image's height is in pixels, not a percentage, and that is the whole
   point. The box is a grid whose row is auto-sized, so a percentage height
   on the image resolves against nothing and falls back to auto: the mark
   took the full width, grew to 209px tall inside a 68px box, and was clipped
   to its top third. It looked for all the world like a broken logo file. */
.logoslot-box {
  height: 96px; padding: 14px; box-sizing: border-box;
  border: 1px solid var(--line); border-radius: var(--r-card);
  display: grid; place-items: center; margin-bottom: 8px; overflow: hidden;
}
.logoslot-box img { max-width: 100%; height: 68px; object-fit: contain; display: block; }
.logoslot input[type="file"] { font-size: 11.5px; max-width: 170px; }

/* ── The rail: forty destinations, eight icons ────────────────────────────
   A strip of icons against the edge and the window given to the content, the
   way a browser does it. The three screens you press every day have their
   own icon; each group opens beside the rail with its screens in words. The
   old labelled sidebar is still in the document — the counts and ticks are
   written into it by id — it is simply not on screen any more.           */
body.rail-on { grid-template-columns: 56px 1fr; }
/* The sidebar is not removed and not rebuilt — five other modules write into
   it by selector. It becomes the flyout: off screen until a group is asked
   for, then beside the rail showing that group alone. */
body.rail-on #side {
  position: fixed; left: 56px; top: 0; bottom: 0; z-index: 45;
  width: 238px; overflow-y: auto; padding: 14px 10px 20px;
  background: var(--surface); border-right: 1px solid var(--line);
  box-shadow: 12px 0 32px rgba(0, 0, 0, 0.10);
  transform: translateX(-104%); visibility: hidden;
  transition: transform 160ms var(--ease), visibility 160ms;
}
body.rail-on.rail-fly #side { transform: none; visibility: visible; }
body.rail-on #side .logo, body.rail-on #side #next-up, body.rail-on #side .foot { display: none; }
/* One group at a time: everything not belonging to the open one is out. */
body.rail-on #side .nav > [data-group] { display: none; }
body.rail-on #side[data-show="Foundations"] .nav > [data-group="Foundations"],
body.rail-on #side[data-show="Create"] .nav > [data-group="Create"],
body.rail-on #side[data-show="Grow"] .nav > [data-group="Grow"],
body.rail-on #side[data-show="Control"] .nav > [data-group="Control"] { display: flex; }
body.rail-on #side .nav > .group[data-group] {
  display: none; font-family: var(--font-mono); font-size: 11px;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
  padding: 4px 10px 10px;
}
body.rail-on #side[data-show="Foundations"] .nav > .group[data-group="Foundations"],
body.rail-on #side[data-show="Create"] .nav > .group[data-group="Create"],
body.rail-on #side[data-show="Grow"] .nav > .group[data-group="Grow"],
body.rail-on #side[data-show="Control"] .nav > .group[data-group="Control"] { display: block; }

#rail {
  grid-column: 1; grid-row: 1 / -1;
  position: sticky; top: 0; height: 100vh; z-index: 40;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 0; background: var(--surface-2); border-right: 1px solid var(--line);
}
/* The mark is 1.087:1 and not square, per the bible, so the box is too and
   the artwork is never stretched to fit a tidier number. 14px is the floor
   it gives for screen; this is 28. */
.rail-mark {
  width: 30px; height: 27.6px; margin: 2px 0 12px; flex: none;
  display: grid; place-items: center;
}
.rail-mark img { width: 100%; height: 100%; object-fit: contain; display: block; }
.rail-mark .on-dark { display: none; }
[data-theme="dark"] .rail-mark .on-light { display: none; }
[data-theme="dark"] .rail-mark .on-dark { display: block; }
.rail-b {
  position: relative; width: 40px; height: 40px; flex: none; padding: 0;
  display: grid; place-items: center; border: 0; border-radius: 10px;
  background: none; color: var(--muted); cursor: pointer;
}
.rail-b i.ph { font-size: 20px; }
.rail-b:hover { background: var(--hover); color: var(--ink); }
.rail-b.active { background: var(--surface); color: var(--ink); box-shadow: inset 2px 0 0 var(--brand); }
.rail-b.open { background: var(--surface); color: var(--ink); }
/* Something inside a closed group is waiting. Losing that signal would be
   the whole cost of folding the list away. */
.rail-b.has-n::after {
  content: ""; position: absolute; top: 7px; right: 7px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--brand); border: 1.5px solid var(--surface-2);
}
.rail-tip {
  position: absolute; left: calc(100% + 8px); top: 50%; transform: translateY(-50%);
  white-space: nowrap; padding: 5px 9px; border-radius: 7px;
  background: var(--ink); color: var(--canvas); font-size: 12px;
  opacity: 0; pointer-events: none; transition: opacity 120ms var(--ease); z-index: 1;
}
.rail-b:hover .rail-tip { opacity: 1; }
.rail-b.open .rail-tip { opacity: 0; }

/* On a phone the rail runs along the bottom, where a thumb is, and the
   flyout covers the screen above it. */
@media (max-width: 860px) {
  body.rail-on { grid-template-columns: 1fr; }
  #rail {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto; height: auto;
    flex-direction: row; justify-content: space-around; gap: 0;
    border-right: 0; border-top: 1px solid var(--line); padding: 6px 4px;
  }
  .rail-mark, .rail-tip { display: none; }
  body.rail-on #side { left: 0; width: min(290px, 86vw); bottom: 56px; }
  body.rail-on #view { padding-bottom: 70px; }
}

/* ── Home: one thing, then the numbers, then everything folded ────────────
   Eight cards of equal weight read as one wall. Nothing below is deleted,
   only ranked: the ask is large and first, the month is a line of figures
   rather than three cards of prose, and the references fold away with their
   counts on the fold.                                                     */
.onething { border: 1px solid var(--line-strong); max-width: 720px; }
.onething h2 { font-size: var(--t-h1); line-height: 1.15; margin: 6px 0 4px; }
.onething .sub { margin-bottom: 14px; }
.onething .row { margin-top: 2px; }

.numline {
  display: flex; flex-wrap: wrap; gap: 4px 28px;
  margin: 18px 0 20px; padding: 0 2px;
}
.numline a {
  display: flex; align-items: baseline; gap: 7px;
  text-decoration: none; color: var(--muted); padding: 4px 0;
}
.numline a b { font-family: var(--font-disp); font-size: 20px; color: var(--ink); font-weight: 700; }
.numline a span { font-size: var(--t-small); }
.numline a:hover b { color: var(--brand-ink); }
.numline a.bad b { color: var(--bad-fg); }
.numline a.warn b { color: var(--warn-fg); }

.deck { border-top: 1px solid var(--line); }
.deck:last-of-type { border-bottom: 1px solid var(--line); }
.deck > summary {
  display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap;
  padding: 13px 2px; cursor: pointer; list-style: none;
  font-size: 14px; color: var(--ink);
}
.deck > summary::-webkit-details-marker { display: none; }
.deck > summary::before { content: "▸"; font-size: 10px; color: var(--muted); }
.deck[open] > summary::before { content: "▾"; }
.deck > summary .muted { font-size: var(--t-small); }
.deck > summary:hover b { color: var(--brand-ink); }
.deck-body { padding: 0 0 8px; }
/* The folded cards keep their own markup and lose the second frame. */
.deck-body > .card { border: 0; padding: 0; margin: 0; background: none; }
.deck-body > .card > h2 { display: none; }

/* ── A draft, shown as the post it is about to become ─────────────────────
   The approval card used to describe a post: a topic, a hook, six chips of
   metadata. Approving fifty of those meant reading fifty summaries and
   trusting them, because what actually publishes was behind a modal. So the
   post is the card now, at the width a post is read at, and the reasoning
   folds away underneath it.                                               */
.approval.post { max-width: 460px; padding: 0; overflow: hidden; }
.approval.post .post-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.approval.post .post-head b { font-size: 13.5px; color: var(--ink); }
.approval.post .pfp {
  width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  background: var(--brand); color: var(--on-brand);
  font-weight: 700; font-size: 13px;
}
.approval.post .banner { margin: 10px 12px 0; }
.approval.post .post-media {
  aspect-ratio: 4 / 5; background: var(--surface-2);
  display: grid; place-items: center; overflow: hidden;
}
.approval.post .post-media.tall { aspect-ratio: 9 / 16; }
/* The shape is worth holding for a real picture and not for the absence of
   one: a 9:16 box with two lines of camera direction in it is half a screen
   of grey, which is how ten drafts became a page nobody scrolls. */
.approval.post .post-media.empty { aspect-ratio: auto; min-height: 112px; }
.approval.post .post-media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.approval.post .post-shoot { width: 100%; box-sizing: border-box; padding: 24px 20px; text-align: center; color: var(--muted); }
.approval.post .post-shoot i.ph { font-size: 26px; color: var(--faint); display: block; margin-bottom: 8px; }
.approval.post .post-shoot p {
  margin: 0; font-size: 12.5px; line-height: 1.5; overflow-wrap: anywhere;
  /* max-height rather than -webkit-box: a clamped box reports a scrollWidth
     wider than itself, which the screen audit reads, correctly, as a word cut
     off sideways. Four lines of direction, folded the plain way. */
  max-height: calc(1.5em * 4); overflow: hidden;
}
.approval.post .post-shoot .tag { margin-top: 10px; display: inline-flex; }
/* Inert on purpose: the shape of a post, not a pretend one you can press. */
.approval.post .post-bar {
  display: flex; gap: 14px; padding: 9px 12px 2px;
  color: var(--faint); font-size: 18px;
}
.approval.post .post-caption { padding: 2px 12px 12px; }
.approval.post .post-caption .text {
  font-size: 13.5px; line-height: 1.55; color: var(--ink); white-space: pre-wrap;
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}
.approval.post .post-caption.all .text { -webkit-line-clamp: unset; display: block; }
.approval.post .post-caption .text b { font-weight: 600; margin-right: 4px; }
.approval.post .post-caption .tags { margin-top: 6px; font-size: 13px; color: var(--brand-ink); word-break: break-word; }
.approval.post .post-caption .more {
  background: none; border: 0; padding: 4px 0 0; margin: 0;
  color: var(--muted); font-size: 12.5px; cursor: pointer;
  /* A thumb needs 36px even when the word is small. */
  min-height: 36px; display: inline-flex; align-items: center;
}
.approval.post .post-caption .more:hover { color: var(--ink); }
.approval.post .post-why { border-top: 1px solid var(--line); }
.approval.post .post-why > summary {
  padding: 10px 12px; cursor: pointer; font-size: 12.5px; color: var(--muted);
  list-style: none; display: flex; align-items: center; gap: 6px;
}
.approval.post .post-why > summary::-webkit-details-marker { display: none; }
.approval.post .post-why > summary::before { content: "▸"; font-size: 10px; }
.approval.post .post-why[open] > summary::before { content: "▾"; }
.approval.post .post-why > summary:hover { color: var(--ink); }
.approval.post .post-why-body { padding: 0 12px 12px; }
.approval.post .post-why-body p { margin: 0 0 8px; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.approval.post .post-why-body p b { color: var(--ink); }
.approval.post .post-why-body .facts { margin: 10px 0; }
.approval.post .post-do {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 12px; border-top: 1px solid var(--line); background: var(--surface-2);
}
.approval.post .post-do .go {
  font-weight: 600; background: var(--action); color: var(--on-action);
  border: 0; border-radius: var(--r-btn); padding: 10px 16px; cursor: pointer;
}
.approval.post .post-do .go:hover { background: var(--action-hover); }
.approval.post .post-do input[type="datetime-local"] { max-width: 196px; }
/* The queue's own report: one line until it is asked for. */
.mixfold > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 13.5px; color: var(--ink);
}
.mixfold > summary::-webkit-details-marker { display: none; }
.mixfold > summary::before { content: "▸"; font-size: 10px; color: var(--muted); }
.mixfold[open] > summary::before { content: "▾"; }
.mixfold > summary .muted { font-size: var(--t-small); }
.mixfold > summary:hover b { color: var(--brand-ink); }
.mixfold .box { margin-top: 8px; }

.approval.post .chanpick { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.approval.post .chanmore > summary {
  cursor: pointer; font-size: 12px; color: var(--muted);
  list-style: none; white-space: nowrap;
}
.approval.post .chanmore > summary::-webkit-details-marker { display: none; }
.approval.post .chanmore > summary::after { content: " ▸"; font-size: 9px; }
.approval.post .chanmore[open] > summary::after { content: " ▾"; }
.approval.post .chanmore > summary:hover { color: var(--ink); }
.approval.post .chanmore[open] { flex: 1 1 100%; }
@media (max-width: 520px) {
  .approval.post { max-width: none; }
  .approval.post .post-do .go { flex: 1 1 100%; }
}

/* strategic-reason strip on content cards */
.reason {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 8px 12px;
  font-size: 12.5px;
  color: var(--body);
  margin-bottom: 10px;
}
.reason b { color: var(--ink); }

/* hook option rows */
.hook-opt {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 9px 2px; border-bottom: 1px solid var(--line);
  font-size: 13px;
}
.hook-opt:last-child { border-bottom: 0; }
.hook-opt input[type="radio"] { width: auto; margin-top: 3px; accent-color: var(--ink); }
.hook-opt .rank {
  font-family: var(--font-mono); font-size: 11px; color: var(--faint);
  flex: none; margin-top: 2px;
}
.hook-opt .rat { color: var(--muted); font-size: 12px; }

/* ── Misc components ─────────────────────────────────────────────────── */
details.box {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 12px 18px;
  margin-bottom: 10px;
  background: var(--surface);
}
details.box summary { cursor: pointer; font-weight: 600; font-size: 13px; color: var(--ink); }
details.box summary::marker { color: var(--faint); }

pre.json {
  white-space: pre-wrap;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 7px;
  padding: 14px;
  font: 12px/1.6 var(--font-mono);
  color: var(--body);
  max-height: 380px;
  overflow: auto;
}
kbd {
  border: 1px solid var(--line-strong);
  border-radius: 4px;
  background: var(--canvas);
  font: 11px var(--font-mono);
  padding: 1px 6px;
}

.empty {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  text-align: left;
  padding: 18px 20px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-card);
  background: var(--surface-2);
  color: var(--muted);
  font-size: var(--t-small);
  line-height: 1.55;
}
.empty .e-icon { margin: 0 0 2px; }
.empty .e-icon i.ph { font-size: 20px; color: var(--faint); }
.empty b { display: block; color: var(--ink); font-size: var(--t-h3); font-weight: 600; }
.empty button, .empty .btn { margin-top: 8px; }
/* An empty state inside a card that already carries the form is a note, not
   an event: it says what is missing and gets out of the way. */
.card > .empty:first-of-type { margin-bottom: 16px; }

.steps { display: flex; gap: 6px; margin-bottom: 20px; flex-wrap: wrap; }
.steps .s {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 500; color: var(--faint);
  padding: 5px 13px; border-radius: 99px;
  border: 1px solid var(--line); background: var(--surface);
}
.steps .s.here { border-color: var(--brand); color: var(--ink); background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--brand); }
.steps .s.past { color: var(--ok-fg); border-color: var(--ok-bg); background: var(--ok-bg); }

#toast {
  position: fixed; bottom: 20px; right: 20px; z-index: 60;
  background: var(--ink); color: var(--canvas);
  border-radius: 8px;
  padding: 12px 18px; max-width: 420px; display: none;
  font-size: 13px;
  box-shadow: 0 8px 24px rgba(31, 30, 27, 0.18);
  animation: rise 300ms var(--ease);
}
#modal-wrap {
  position: fixed; inset: 0; z-index: 50;
  background: rgba(31, 30, 27, 0.35);
  display: none; align-items: center; justify-content: center; padding: 24px;
}
#modal {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 26px 28px;
  width: min(720px, 100%); max-height: 88vh; overflow-y: auto;
  animation: rise 250ms var(--ease);
}
/* A button that reads as a word inside a sentence, for the "or do it the other
   way" offer that should not look like a second thing to press. */
.link {
  background: none; border: 0; padding: 0;
  font: inherit; color: var(--brand-ink);
  text-decoration: underline; text-underline-offset: 2px;
  cursor: pointer;
}
.link:hover { color: var(--ink); }

/* The way out, which does not scroll away.
   #modal is the scrolling box, so an absolutely positioned corner button
   scrolls off with the content. Sticky keeps it against the top of the
   scrollport, and the float holds it in the corner while text flows past it. */
.modal-x {
  position: sticky; top: 0; float: right;
  margin: -10px -12px 0 10px;
  width: 32px; height: 32px; padding: 0;
  display: grid; place-items: center;
  font-size: 15px; line-height: 1;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: 9px;
  cursor: pointer;
}
.modal-x:hover { color: var(--ink); border-color: var(--brand); }

#modal h2 {
  margin: 0 0 8px;
  font-family: var(--font-serif);
  font-size: 21px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
}
#modal h3 { font-size: 13px; font-weight: 600; color: var(--ink); }

.help {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 10px 14px;
  color: var(--muted);
  font-size: 12.5px;
  margin-bottom: 14px;
}
.help.warn { background: var(--warn-bg); border-color: transparent; color: var(--warn-fg); }
.help.bad { background: var(--bad-bg); border-color: transparent; color: var(--bad-fg); }

.kv { display: grid; grid-template-columns: auto 1fr; gap: 6px 18px; font-size: 13px; }
.kv .k { color: var(--muted); }
.kv b { color: var(--ink); }

/* ── Discovery wizard ────────────────────────────────────────────────── */
.wiz-progress { display: flex; gap: 5px; margin: 4px 0 20px; }
.wiz-progress .p {
  height: 3px; flex: 1; border-radius: 2px;
  background: var(--line);
  transition: background 250ms var(--ease);
}
.wiz-progress .p.done { background: var(--ink); }
.wiz-q {
  font-family: var(--font-serif);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 4px;
}
.wiz-hint { color: var(--muted); font-size: 12.5px; margin: 0 0 14px; }
.chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; }
.chips button {
  background: var(--surface); color: var(--body);
  border: 1px solid var(--line-strong); font-weight: 500;
  border-radius: 99px; padding: 6px 14px; font-size: 12.5px;
  /* An audience is named in a sentence, not a word: "Warm — people who have
     watched half a video". On a small phone that label is wider than the
     screen, and a chip that cannot wrap simply hangs off the edge. */
  max-width: 100%; white-space: normal; text-align: left; border-radius: 16px;
}
.chips button:hover { border-color: var(--ink); color: var(--ink); background: var(--surface); }
/* The filter that is in force (Inbox). */
.chips button.on { background: var(--ink); color: var(--surface); border-color: var(--ink); }

/* ── Sidebar grouping ────────────────────────────────────────────────── */
#side .group {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--faint);
  padding: 14px 12px 5px;
}
#side .nav { overflow-y: auto; flex: 1; margin: 0 -4px; padding: 0 4px; }
#side .nav::-webkit-scrollbar { width: 4px; }
#side .nav::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 2px; }

/* ── Login gate ──────────────────────────────────────────────────────── */
#login-wrap {
  position: fixed; inset: 0; z-index: 90;
  background: var(--canvas);
  display: none; align-items: center; justify-content: center; padding: 24px;
}
#login-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 14px; padding: 32px; width: min(400px, 100%);
}
#login-card h1 {
  font-family: var(--font-serif); font-size: 24px; font-weight: 500;
  margin: 0 0 6px; color: var(--ink); letter-spacing: -0.01em;
}
#login-card p { color: var(--muted); font-size: 13px; margin: 0 0 20px; }

/* ── Chat command center ─────────────────────────────────────────────── */
.chat-wrap { display: flex; flex-direction: column; height: calc(100vh - 190px); min-height: 380px; }
.chat-log {
  flex: 1; overflow-y: auto; padding: 4px 2px 16px;
  display: flex; flex-direction: column; gap: 14px;
}
.msg { max-width: 80%; }
.msg.user { align-self: flex-end; }
.msg .bubble {
  padding: 11px 15px; border-radius: 12px; font-size: 13.5px; line-height: 1.6;
  white-space: pre-wrap; word-break: break-word;
}
.msg.user .bubble { background: var(--ink); color: var(--canvas); border-bottom-right-radius: 4px; }
.msg.assistant .bubble {
  background: var(--surface); border: 1px solid var(--line);
  color: var(--body); border-bottom-left-radius: 4px;
}
.msg .tools {
  font-family: var(--font-mono); font-size: 10.5px; color: var(--faint);
  margin-top: 5px; padding-left: 4px;
}
/* An answer that changed something should not look like one that only read.
   Faint grey is right for "I checked six things" and wrong for "three drafts
   exist now". `pending` comes second so that when an answer both changed
   something and left a card, the card wins: that is the half with something
   for the operator to do. */
.msg .tools.acted { color: var(--body); }
.msg .tools.pending { color: var(--warn-fg); }
.chat-input { display: flex; gap: 8px; padding-top: 12px; border-top: 1px solid var(--line); }
/* The microphone has to look different while it is listening, or nobody
   believes it is. Lime is the accent both schemes already use. */
.chat-input #mic-btn.listening {
  color: var(--brand-ink); border-color: var(--brand-ink);
  animation: mic-live 1.4s ease-in-out infinite;
}
@keyframes mic-live { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }
@media (prefers-reduced-motion: reduce) {
  .chat-input #mic-btn.listening { animation: none; }
}
/* The language select is a control, not a sentence: it should not grow. */
.chat-input #mic-lang { width: auto; min-width: 7.5rem; }
.chat-input textarea { resize: none; min-height: 44px; max-height: 140px; }

/* ── Inbox rows ──────────────────────────────────────────────────────── */
.inbox-row {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 16px; margin-bottom: 10px; background: var(--surface);
}
.inbox-row.lead { border-left: 3px solid var(--ok-fg); }
.inbox-row.negative { border-left: 3px solid var(--bad-fg); }
.inbox-row.question { border-left: 3px solid var(--info-fg); }
.inbox-row .who { font-weight: 600; color: var(--ink); font-size: 13px; }
.inbox-row .said { margin: 4px 0 10px; font-size: 13.5px; }
.inbox-row textarea { min-height: 60px; margin-bottom: 8px; }

/* ── Stat strip ──────────────────────────────────────────────────────── */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--r-card); overflow: hidden; }
.stats > div { background: var(--surface); padding: 14px 16px; }
.stats .n { font-size: 21px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
.stats .l { font-size: 11.5px; color: var(--muted); margin-top: 2px; }

/* ── Bars (simple inline charts) ─────────────────────────────────────── */
.bar-row { display: grid; grid-template-columns: minmax(90px, 150px) 1fr auto; gap: 10px; align-items: center; padding: 5px 0; font-size: 12.5px; }
.bar-track { background: var(--hover); border-radius: 3px; height: 7px; overflow: hidden; }
.bar-fill { background: var(--ink); height: 100%; border-radius: 3px; }
.bar-row .v { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); min-width: 48px; text-align: right; }

/* ── Banner ──────────────────────────────────────────────────────────── */
.banner {
  border-radius: 10px; padding: 12px 16px; margin-bottom: 18px;
  font-size: 13px; display: flex; gap: 10px; align-items: flex-start;
  background: var(--warn-bg); color: var(--warn-fg);
}
.banner i.ph { flex: none; margin-top: 2px; }
.banner b { display: block; margin-bottom: 2px; }

/* ── Responsive ──────────────────────────────────────────────────────── */
#menu-btn { display: none; }
@media (max-width: 900px) {
  body {
    grid-template-columns: 1fr;
    grid-template-areas: "top" "main";
  }
  #side {
    position: fixed; inset: 0 auto 0 0; width: 250px; z-index: 80;
    transform: translateX(-100%); transition: transform 220ms var(--ease);
    box-shadow: 0 0 40px rgba(16, 24, 40, 0.16);
  }
  body.nav-open #side { transform: none; }
  body.nav-open::after {
    content: ""; position: fixed; inset: 0; background: rgba(31, 30, 27, 0.3); z-index: 79;
  }
  #menu-btn { display: inline-flex; }
  #top { padding: 0 14px; gap: 8px; overflow-x: auto; }
  #top select { min-width: 120px; font-size: 13px; }
  #kill { font-size: 11.5px; padding: 7px 10px; }
  #view { padding: 20px 16px 60px; }
  .page-head h1 { font-size: 24px; }
  .cols-2, .cols-3 { grid-template-columns: 1fr; }
  .card { padding: 16px; }
  .msg { max-width: 92%; }
  table { font-size: 12.5px; }
  th, td { padding: 7px 6px; }
  .row { gap: 8px; }
}
@media (max-width: 560px) {
  .approval .facts { font-size: 10.5px; }
  #modal { padding: 18px; border-radius: 10px; }
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv .k { margin-top: 8px; font-weight: 600; }
}

/* Tables that must scroll rather than break the page */
.scroll-x { overflow-x: auto; }
.scroll-x table { min-width: 520px; }

/* ── Knowledge: source list, drop target, inline boxes ───────────────── */
.list { border-top: 1px solid var(--line); }
.li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 12px 2px;
  border-bottom: 1px solid var(--line);
}
.li > .row { flex-shrink: 0; }
.li b { font-size: 13.5px; color: var(--ink); }

div.box {
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: 12px 16px;
  margin-bottom: 10px;
  background: var(--surface-2);
}
div.box > *:first-child { margin-top: 0; }
div.box > *:last-child { margin-bottom: 0; }

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  text-align: center;
  min-height: 150px;
  padding: 20px;
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-card);
  background: var(--surface-2);
  cursor: pointer;
  transition: background 0.15s var(--ease), border-color 0.15s var(--ease);
}
.dropzone:hover, .dropzone.over { background: var(--hover); border-color: var(--faint); }
.dropzone i { font-size: 22px; color: var(--faint); }
.dropzone b { font-size: 13.5px; color: var(--ink); }

label.check {
  display: flex;
  gap: 9px;
  align-items: flex-start;
  font-size: 12.5px;
  color: var(--body);
  cursor: pointer;
  margin-bottom: 12px;
}
label.check input[type="checkbox"] { width: auto; flex: 0 0 auto; margin: 2px 0 0; }

a.button {
  display: inline-block;
  text-decoration: none;
  border-radius: var(--r-btn);
  padding: 8px 14px;
  font-size: 13px;
  font-weight: 500;
  border: 1px solid var(--line-strong);
  color: var(--ink);
  background: var(--surface);
}
a.button:hover { background: var(--hover); }

/* ---- Indizilla brand layer ----
   Display face on headings, lime primary actions with ink text, and the
   press feedback the main site now has. Layout and structure untouched. */
h1, h2, h3, h4, .page-title { font-family: var(--font-disp); letter-spacing: -0.02em; }
h1, .page-title { font-weight: 900; letter-spacing: -0.03em; }

button.primary, .btn-primary, button[type="submit"].primary {
  background: var(--brand); border-color: var(--brand); color: var(--on-brand); font-weight: 700;
}
button.primary:hover, .btn-primary:hover { background: var(--brand-hover); border-color: var(--brand-hover); }

button, .btn, .tab, .chip { transition: transform 160ms var(--ease-out), background .15s ease, border-color .15s ease, color .15s ease; }
button:active, .btn:active, .tab:active, .chip:active { transform: scale(.97); }

/* Gentler, not zero — matches the main site. */
@media (prefers-reduced-motion: reduce) {
  *:not(.spinner), *::before, *::after {
    animation-duration: .15s !important; animation-iteration-count: 1 !important;
    transition-duration: .15s !important;
  }
}

/* the theme switch is a utility control, quieter than any real action */
#themetoggle {
  background: transparent; color: var(--muted);
  border: 1px solid var(--line-strong); font-weight: 600;
}
#themetoggle:hover { color: var(--ink); border-color: var(--muted); background: var(--hover); }

/* ---- where the brand colour actually lands ----
   This console has no .primary buttons yet, so lime would otherwise never
   appear. It marks the current location and focus — identity without
   turning nineteen buttons per screen into nineteen shouts. */
#side a.active { box-shadow: inset 2px 0 0 var(--brand); }
.logo span { color: var(--brand); }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── Guided mode — every screen in plain words (guide.js) ─────────────── */
#guide-toggle { cursor: pointer; font-family: inherit; white-space: nowrap; }
.chip { white-space: nowrap; }
/* Between the phone layout and a wide desk, the bar is one chip too full:
   the status chips give way before the pickers and the stop button do. */
/* These used to sit in the bar, where width mattered. They live in a menu
   now, so hiding them by width empties the menu that exists to hold them. */
#guide-toggle:hover { background: var(--hover); border-color: var(--line); color: var(--muted); transform: none; }
.guide {
  max-width: 720px; margin: -10px 0 26px;
  padding: 16px 18px 14px; border-radius: 12px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-left: 3px solid var(--ok-fg);
  font-size: 14px; line-height: 1.55;
}
.guide-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.guide-tag { font-size: 12px; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; color: var(--ok-fg); display: inline-flex; gap: 6px; align-items: center; }
.guide-plain { margin: 0 0 6px; font-size: 15px; }
.guide-why { margin: 0 0 12px; color: var(--muted); }
.guide-row { display: grid; grid-template-columns: 120px 1fr; gap: 10px; padding: 7px 0; border-top: 1px solid var(--line); }
.guide-row b { font-size: 12.5px; color: var(--muted); font-weight: 600; padding-top: 2px; }
.guide-row ol { margin: 0; padding-left: 18px; }
.guide-row ol li { margin: 2px 0; }
.guide-row.cost b { color: var(--warn-fg); }
.guide-words { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--line); }
.guide-words summary { cursor: pointer; font-size: 12.5px; color: var(--muted); font-weight: 600; }
.guide-words dl { display: grid; grid-template-columns: 140px 1fr; gap: 4px 12px; margin: 10px 0 0; }
.guide-words dt { font-weight: 600; }
.guide-words dd { margin: 0; color: var(--muted); }
@media (max-width: 600px) {
  .guide-row, .guide-words dl { grid-template-columns: 1fr; gap: 2px; }
}
.guide-steps { padding: 7px 0; border-top: 1px solid var(--line); }
.guide-steps summary { cursor: pointer; font-size: 12.5px; color: var(--muted); font-weight: 600; }
.guide-steps ol { margin: 8px 0 0; padding-left: 18px; }
.guide-steps ol li { margin: 6px 0; }
.guide-ask { font-size: 12.5px; font-weight: 600; color: var(--ok-fg); text-decoration: none; }
.guide-ask:hover { text-decoration: underline; }

/* ── The helper (helper.js) ─────────────────────────────────────────── */
/* Anchored in the top bar rather than fixed over the page: a disc welded to
   the bottom-right corner hides whatever is under it, and the only way to
   read that was to scroll the words out from beneath it. */
#hp { position: relative; display: inline-flex; }
#hp-btn { width: 34px; height: 34px; border-radius: 50%; padding: 0; display: inline-flex; align-items: center; justify-content: center; font-size: 18px; }
#hp-panel { display: none; position: absolute; right: 0; top: calc(100% + 8px); z-index: 70; width: min(380px, calc(100vw - 36px)); max-height: min(72vh, 640px); overflow: auto; background: var(--surface); border: 1px solid var(--line-strong); border-radius: 14px; box-shadow: 0 16px 48px rgba(0,0,0,0.22); font-size: 13.5px; }
#hp.open #hp-panel { display: block; }
.hp-head { display: flex; align-items: center; justify-content: space-between; padding: 12px 14px; border-bottom: 1px solid var(--line); font-family: var(--font-disp); font-weight: 700; position: sticky; top: 0; background: var(--surface); }
.hp-head i.ph { vertical-align: -2px; margin-right: 4px; color: var(--ok-fg); }
.hp-section { padding: 12px 14px; border-bottom: 1px solid var(--line); }
.hp-section:last-child { border-bottom: 0; }
.hp-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.hp-pointer { display: flex; gap: 10px; align-items: flex-start; padding: 8px 10px; border-radius: 8px; text-decoration: none; color: var(--ink); border-left: 3px solid var(--line-strong); background: var(--surface-2); margin-bottom: 6px; }
.hp-pointer:hover { background: var(--hover); }
.hp-pointer i.ph { flex: none; margin-top: 2px; color: var(--muted); }
.hp-pointer span { display: block; line-height: 1.45; }
.hp-pointer b { display: block; font-size: 12px; color: var(--ok-fg); margin-top: 2px; }
.hp-pointer.hp-stop { border-left-color: var(--bad-fg); } .hp-pointer.hp-stop i.ph { color: var(--bad-fg); }
.hp-pointer.hp-fix { border-left-color: var(--warn-fg); } .hp-pointer.hp-fix i.ph { color: var(--warn-fg); }
.hp-pointer.hp-decide { border-left-color: var(--ink); }
.hp-pointer.hp-next, .hp-pointer.hp-tip { border-left-color: var(--ok-fg); }
#hp-trouble { background: var(--warn-bg); }
.hp-trouble-text { display: flex; gap: 8px; align-items: flex-start; color: var(--warn-fg); margin-bottom: 8px; font-size: 12.5px; word-break: break-word; }
#hp-thread { display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow: auto; margin-bottom: 8px; }
.hp-msg { padding: 8px 11px; border-radius: 10px; line-height: 1.5; max-width: 92%; }
.hp-you { align-self: flex-end; background: var(--ink); color: var(--canvas); }
.hp-them { align-self: flex-start; background: var(--surface-2); }
.hp-declined { border: 1px dashed var(--line-strong); color: var(--muted); }
.hp-msg ol { margin: 6px 0 0; padding-left: 18px; }
.hp-go { display: inline-block; margin-top: 6px; font-weight: 600; color: var(--ok-fg); text-decoration: none; }
.hp-form { display: flex; gap: 6px; }
.hp-form input { flex: 1; min-width: 0; }
.hp-foot { font-size: 11.5px; margin-top: 6px; }
@media (max-width: 600px) { #hp { right: 10px; bottom: 10px; } }
@media (prefers-reduced-motion: no-preference) { #hp-panel { animation: hp-in 120ms ease-out; } @keyframes hp-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } } }

/* ── Market repository and library rows ─────────────────────────────── */
.mk-row { padding: 8px 0; border-top: 1px solid var(--line); font-size: 13.5px; line-height: 1.5; }
.mk-row:first-of-type { border-top: 0; }
a.btn { display: inline-flex; align-items: center; text-decoration: none; }

/* ── Calendar grid (P9) ────────────────────────────────────────────────── */
.cal-head { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-top: 6px; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em; }
.cal-head div { padding: 4px 6px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
.cal-grid.week .cal-cell { min-height: 220px; }
.cal-cell { min-height: 92px; border: 1px solid var(--line); border-radius: 8px; padding: 4px 5px; background: var(--surface); transition: border-color 120ms; }
.cal-cell.faded { opacity: 0.45; }
.cal-cell.today { border-color: var(--ink); }
.cal-cell.over { border-color: var(--ok-fg); background: var(--ok-bg); }
.cal-date { font-size: 11.5px; color: var(--muted); margin-bottom: 3px; }
.cal-item { font-size: 11.5px; line-height: 1.35; border-radius: 6px; padding: 3px 6px; margin-bottom: 3px; cursor: grab; background: var(--surface-2); border-left: 3px solid var(--line-strong); }
.cal-item[draggable="false"] { cursor: pointer; }
.cal-item.warn { border-left-color: var(--warn-fg); }
.cal-item.ok { border-left-color: var(--ok-fg); }
.cal-item.bad { border-left-color: var(--bad-fg); background: var(--bad-bg); }
.cal-item.dim { border-left-color: var(--line); color: var(--muted); }
.cal-time { font-family: var(--font-mono); font-size: 10.5px; margin-right: 4px; }
.cal-net { font-weight: 600; }
.cal-grp { margin-left: 4px; color: var(--muted); font-size: 10.5px; }
.cal-topic { color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
li.bad { color: var(--bad-fg); }
@media (max-width: 900px) { .cal-grid { grid-template-columns: repeat(2, 1fr); } .cal-head { display: none; } .cal-cell.faded { display: none; } }

/* ── Where you are: state on every link, a ring on every group ──────────
   The sidebar used to be forty links with nothing to say which had anything
   in them. The marks are quiet on purpose: a tick is enough, and an empty
   screen simply says nothing rather than nagging. */
#side .nav .group {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
#side .nav .group .gring {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-mono);
  color: var(--muted); font-weight: 400; letter-spacing: 0;
  text-transform: none; font-size: 10.5px;
}
#side .nav .group .gring b { font-weight: 600; font-variant-numeric: tabular-nums; }
#side a .pg {
  margin-left: auto; font-size: 11px; line-height: 1;
  color: var(--faint); font-weight: 700;
}
#side a .pg.pg-done { color: var(--ok-fg); }
#side a .pg.pg-started { color: var(--warn-fg); }
#side a.pg-blocked { opacity: 0.55; }
#side a.pg-blocked:hover { opacity: 1; }
#side a .n + .pg { margin-left: 6px; }

/* The next step, above the list. One card, one verb, and the reason. */
#next-up { padding: 0 4px 12px; }
#next-up .nx {
  display: block; text-decoration: none;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface-2); padding: 10px 12px;
  transition: border-color 150ms var(--ease), background 150ms var(--ease);
}
#next-up a.nx:hover { border-color: var(--line-strong); background: var(--hover); }
#next-up .nx .k {
  display: block; font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin-bottom: 3px;
}
#next-up .nx b { display: block; color: var(--ink); font-size: 13.5px; margin-bottom: 3px; }
#next-up .nx span:not(.k) { display: block; color: var(--muted); font-size: 11.5px; line-height: 1.45; }
#next-up .nx.done { background: var(--ok-bg); border-color: transparent; }
#next-up .nx.done b { color: var(--ok-fg); }

/* ── What is running ────────────────────────────────────────────────────
   A four-minute generation used to sit behind a toast that said "stay on
   this page". This says what it is making, how long it has taken, and that
   leaving the screen is safe. */
#runs {
  position: fixed; right: 20px; bottom: 20px; z-index: 55;
  display: flex; flex-direction: column; gap: 10px; width: min(360px, calc(100vw - 40px));
}
#runs .run {
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: 12px; padding: 12px 14px;
  box-shadow: 0 10px 30px rgba(20, 22, 26, 0.12);
  animation: rise 200ms var(--ease);
}
#runs .run.ok { border-color: var(--ok-fg); }
#runs .run.bad { border-color: var(--bad-fg); }
#runs .run-h { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--ink); }
#runs .run-h b { font-weight: 600; flex: 1; }
#runs .run-h .t { color: var(--muted); font-size: 11.5px; font-variant-numeric: tabular-nums; }
#runs .run-h i.ph { font-size: 16px; color: var(--muted); }
#runs .run.ok .run-h i.ph { color: var(--ok-fg); }
#runs .run.bad .run-h i.ph { color: var(--bad-fg); }
#runs .run-m { margin-top: 6px; font-size: 12px; color: var(--body); }
#runs .run-f { margin-top: 6px; font-size: 11.5px; color: var(--muted); line-height: 1.45; }
#runs .run-a { margin-top: 10px; display: flex; gap: 6px; }
#runs .run-a a.small {
  display: inline-flex; align-items: center; text-decoration: none;
  border: 1px solid var(--line-strong); border-radius: 7px;
  padding: 4px 10px; font-size: 12px; color: var(--ink); background: var(--surface);
}
.spin { animation: spin 1.1s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ── A generated document, read as one ──────────────────────────────────
   The strategy was four fields and a JSON dump. It is the thing a client
   waited four minutes for, so it reads like a document: one section per
   section the model wrote, and the decision at the bottom. */
#modal .sdoc { max-width: 68ch; }
#modal .sdoc-h { margin-bottom: 18px; }
#modal .sdoc-h h2 { margin-bottom: 4px; }
#modal .sdoc-s { margin: 0 0 22px; }
#modal .sdoc-s h3 {
  font-family: var(--font-serif); font-size: 15.5px; font-weight: 500;
  color: var(--ink); margin: 0 0 8px; letter-spacing: -0.005em;
}
#modal .sdoc-s p { margin: 0 0 10px; font-size: 13.5px; line-height: 1.62; color: var(--body); }
#modal .sdoc-s ul { margin: 0 0 10px; padding-left: 18px; }
#modal .sdoc-s li { font-size: 13.5px; line-height: 1.6; color: var(--body); margin-bottom: 5px; }
#modal .sblock {
  border-left: 2px solid var(--line-strong); padding: 2px 0 2px 12px; margin: 0 0 14px;
}
#modal .sblock > b { display: block; font-size: 13.5px; color: var(--ink); margin-bottom: 5px; font-weight: 600; }
#modal .sline { margin-bottom: 6px; }
#modal .sline > span {
  display: block; font-size: 10.5px; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin-bottom: 2px;
}
#modal .sline p { margin: 0 0 4px; }
#modal .sdoc-a {
  position: sticky; bottom: -26px; margin-top: 8px;
  background: var(--surface); border-top: 1px solid var(--line);
  padding: 14px 0 2px; display: flex; gap: 8px; flex-wrap: wrap;
}

/* One initiative, with the state of its strategy on the screen rather than
   behind a button. */
.initiative { border-bottom: 1px solid var(--line); padding: 14px 0; }
.initiative:last-child { border-bottom: 0; padding-bottom: 2px; }
.initiative > b { font-size: 14px; color: var(--ink); }
.initiative .stat-line {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-top: 8px; font-size: 12.5px; color: var(--muted);
}
.initiative .quote {
  margin-top: 8px; font-size: 12.5px; line-height: 1.55;
  border-left: 2px solid var(--line-strong); padding-left: 10px;
}
.initiative button[disabled] { opacity: 0.45; cursor: not-allowed; }

/* ── Before the data, and when it does not come ─────────────────────────
   A skeleton in the shape of the screen that is coming: the layout arrives
   first, the eye settles, and the swap is invisible. The console used to
   show the word "Loading" centred in a blank page, which is what an unbuilt
   page looks like. */
.sk {
  display: block;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--surface-2) 0%, var(--hover) 40%, var(--surface-2) 80%);
  background-size: 220% 100%;
  animation: skwipe 1.5s var(--ease) infinite;
  margin-bottom: 9px;
}
@keyframes skwipe { from { background-position: 140% 0; } to { background-position: -40% 0; } }
@media (prefers-reduced-motion: reduce) { .sk { animation: none; } }
.sk-head { opacity: 0.85; }
.sk-head .sk:first-child { border-radius: 8px; margin-bottom: 12px; }
.sk-card { animation: none; }
.sk-card .sk-body { margin-top: 14px; }
.sk-row {
  display: flex; gap: 14px; align-items: center;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.sk-row .sk { margin: 0; }
.sk-steps { display: flex; gap: 6px; margin-bottom: 20px; }
.sk-steps .sk { border-radius: 99px; margin: 0; }
.sk-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 8px; margin-top: 14px; }
.sk-grid .sk { margin: 0; border-radius: 8px; }

/* A screen that failed says what failed and offers the action that fixes it. */
.errcard { border-color: var(--bad-fg); max-width: 640px; }
.errcard .err-h { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; }
.errcard .err-h i.ph { font-size: 20px; color: var(--bad-fg); }
.errcard .err-h b { font-family: var(--font-serif); font-size: var(--t-h2); font-weight: 500; color: var(--ink); }
.errcard code { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); }

/* ── Copy, read as copy ─────────────────────────────────────────────────
   The words being approved are what a customer will read on a phone, so
   they are set as prose. They used to be in a monospace block, which made
   the most-opened screen in the console look like a log file. */
.copy {
  border-left: 2px solid var(--line-strong);
  padding: 2px 0 2px 14px;
  margin: 0 0 14px;
}
.copy p {
  margin: 0 0 9px;
  font-size: var(--t-body);
  line-height: 1.68;
  color: var(--ink);
  white-space: pre-wrap;
}
.copy p:last-child { margin-bottom: 0; }
.copy.final {
  border-left-color: var(--brand);
  background: var(--surface-2);
  border-radius: 0 8px 8px 0;
  padding: 12px 14px;
}
.copy.quiet p { color: var(--body); font-size: var(--t-small); line-height: 1.6; }
.copy .tags { color: var(--muted); font-size: var(--t-small); margin-top: 10px; }
#modal h3 { font-size: var(--t-h3); font-weight: 600; color: var(--ink); margin: 18px 0 8px; }


/* ── Picking networks ───────────────────────────────────────────────────
   A native multiple-select hides its own interaction behind a modifier key
   and a scroll. These are toggles: on is obviously on. */
.chanpick { display: flex; flex-direction: column; gap: 8px; }
.chanpick .chanset { display: flex; flex-direction: column; gap: 5px; }
.chanpick .chanset .k {
  font-size: var(--t-micro); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--faint); font-weight: 700;
}
.chanpick .chips-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chanchip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line-strong); border-radius: 7px;
  padding: 4px 10px; cursor: pointer;
  font-size: var(--t-small); color: var(--muted);
  background: var(--surface);
  transition: border-color 140ms var(--ease), background 140ms var(--ease), color 140ms var(--ease);
  user-select: none;
}
.chanchip:hover { border-color: var(--faint); color: var(--body); }
.chanchip input { position: absolute; opacity: 0; pointer-events: none; }
.chanchip.on {
  border-color: var(--brand); background: var(--surface-2); color: var(--ink); font-weight: 600;
}
.chanchip.on::before { content: "✓"; font-size: 11px; color: var(--brand); }

/* ── Simple mode ────────────────────────────────────────────────────────
   One screen for someone who does not want a console. The sidebar keeps
   only the handful of places a person in this mode has any reason to open;
   everything else is still reachable by link, because hiding a screen is
   not the same as removing it. */
body.simple #side .nav .group,
body.simple #side .nav a:not([data-route="home"]):not([data-route="content"]):not([data-route="calendar"]):not([data-route="money"]):not([data-route="ask"]):not([data-route="plans"]):not([data-route="setup"]) {
  display: none;
}
body.simple #next-up { display: none; }
body.simple #side .nav { padding-top: 6px; }

/* The line across the top: how much of the setup is standing up. */
.ap-bar {
  position: relative;
  height: 34px; border-radius: 99px;
  background: var(--surface-2); border: 1px solid var(--line);
  display: flex; align-items: center; padding: 0 14px;
  margin-bottom: 18px; overflow: hidden;
}
.ap-bar-fill {
  position: absolute; inset: 0 auto 0 0;
  background: linear-gradient(90deg, color-mix(in srgb, var(--brand) 35%, transparent), color-mix(in srgb, var(--brand) 12%, transparent));
  border-right: 1px solid color-mix(in srgb, var(--brand) 55%, transparent);
  transition: width 600ms var(--ease);
}
.ap-bar span {
  position: relative; font-size: var(--t-small); font-weight: 600; color: var(--ink);
  letter-spacing: 0.01em;
}

.ap-grid { align-items: start; }
.ap-k {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--t-micro); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin-bottom: 12px;
}
.ap-k i.ph { font-size: 15px; }
.card.ap-need { border-color: var(--warn-fg); }
.card.ap-need .ap-k { color: var(--warn-fg); }
.card.ap-clear .ap-k { color: var(--ok-fg); }
.ap-need-row {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.ap-need-row:first-of-type { border-top: 0; padding-top: 0; }
.ap-need-row b { font-size: 22px; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.card.ap-next h2 { font-size: 22px; margin-bottom: 6px; }
.card.ap-next .ap-why {
  margin: 10px 0 14px; padding-left: 11px;
  border-left: 2px solid var(--line-strong);
  font-size: var(--t-small); line-height: 1.55;
}

.ap-feed { list-style: none; margin: 0; padding: 0; }
.ap-feed li {
  display: flex; gap: 14px; align-items: baseline;
  padding: 8px 0; border-top: 1px solid var(--line);
  font-size: var(--t-small); color: var(--body);
}
.ap-feed li:first-child { border-top: 0; }
.ap-feed .w { color: var(--faint); min-width: 72px; font-variant-numeric: tabular-nums; }

.ap-feed .who {
  font-size: var(--t-micro); letter-spacing: 0.07em; text-transform: uppercase;
  font-weight: 700; color: var(--faint); min-width: 26px;
}
.ap-feed li.mine .who { color: var(--brand); }
.ap-feed li.mine { color: var(--ink); }


/* ── The top bar's menus ────────────────────────────────────────────────
   Where you are, how things are, what you prefer: three menus and the stop
   button, instead of eleven controls in a row. */
/* The workspace switcher is the only thing in the bar that may give way.
   Without this it refused to shrink, so below 360 the row grew past the
   viewport and pushed the stop button off the right edge. It truncates
   instead, and the name it keeps is the brand. */
.popwrap { position: relative; flex: 0 0 auto; min-width: 0; }
#wswrap { flex: 0 1 auto; }
.wsbtn { min-width: 0; }
.wsbtn .ws-p, .wsbtn .ws-b { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.wsbtn .ws-p { flex: 0 1 auto; }
.wsbtn .ws-b { flex: 1 1 auto; }
.wsbtn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-btn); min-height: 32px; padding: 0 11px;
  color: var(--ink); font: 500 13px/1 var(--font-sans); cursor: pointer;
  max-width: 340px;
}
.wsbtn:hover, .wsbtn.open { border-color: var(--line-strong); background: var(--hover); }
.wsbtn .ws-p { font-weight: 600; }
.wsbtn .ws-b { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wsbtn .ws-b.none { font-style: italic; }
.wsbtn i.ph { font-size: 12px; color: var(--faint); }
.wsbtn i.caret { margin-left: 3px; }

/* A menu floats over the page, so it has to read as lifted off it. In dark
   the surface sits eight points from the canvas and a soft shadow does
   nothing against a dark ground, so it takes the raised surface and a ring
   that is visible in both themes. Without this it looked transparent. */
.pop {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 70;
  min-width: 268px; padding: 14px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-pop), 0 0 0 1px rgba(0, 0, 0, 0.06);
  animation: rise 160ms var(--ease) both;
}
[data-theme="dark"] .pop {
  background: var(--hover);
  box-shadow: 0 24px 60px -16px rgba(0, 0, 0, 0.9), 0 0 0 1px rgba(255, 255, 255, 0.06);
}
.pop.pop-right { left: auto; right: 0; }
.pop .pop-k {
  font-size: var(--t-micro); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--faint); font-weight: 700; margin-bottom: 10px;
}
.pop .statuses { display: flex; flex-direction: column; align-items: stretch; gap: 6px; overflow: visible; }
/* A chip inside the menu sits on the menu, so it needs the surface above it
   or it disappears into its own container. */
.pop .statuses .chip {
  justify-content: flex-start; width: 100%;
  background: var(--surface); border-color: var(--line);
}
.pop .pop-more {
  display: block; margin-top: 12px; padding-top: 10px;
  border-top: 1px solid var(--line);
  font-size: var(--t-small); color: var(--muted); text-decoration: none;
}
.pop .pop-more:hover { color: var(--ink); }
.pop .f { margin-bottom: 10px; }
.pop .f:last-of-type { margin-bottom: 12px; }
.pop select { width: 100%; }

.pop-row {
  /* It is a button, and the base button rule centres its content. A row in
     a menu reads left, like every other row. */
  display: flex; align-items: flex-start; justify-content: flex-start; gap: 9px; width: 100%;
  background: transparent; border: 1px solid transparent; border-radius: 9px;
  padding: 9px 10px; margin-bottom: 2px; text-align: left; cursor: pointer;
  color: var(--body); font: 500 13px/1.35 var(--font-sans); min-height: 0;
}
.pop-row:hover { background: var(--surface-2); border-color: var(--line); }
.pop-row .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--faint); margin-top: 4px; flex: 0 0 auto; }
.pop-row.on .dot { background: var(--brand); }
.pop-row b { display: block; color: var(--ink); font-weight: 600; }
.pop-row em { display: block; font-style: normal; color: var(--muted); font-size: var(--t-small); margin-top: 2px; }


/* ── The label voice ────────────────────────────────────────────────────
   The site's own: mono, eleven pixels, wide, uppercase. Everything that
   names a thing rather than says it wears this, so a column head and a
   section label are visibly the same kind of object. */
.ap-k,
.pop .pop-k,
.chanpick .chanset .k,
#next-up .nx .k,
#modal .sline > span,
#side .nav .group,
.cal-head,
.ap-feed .who,
.approval .facts .score,
th {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 400;
}
/* The score keeps its figures aligned and does not shout its digits. */
.approval .facts .score { letter-spacing: 0.06em; font-size: 11px; }
th { color: var(--muted); }
#side .nav .group { letter-spacing: 0.12em; }
.badge {
  font-family: var(--font-mono);
  font-weight: 400;
  letter-spacing: 0.08em;
}
.guide-tag { font-family: var(--font-mono); letter-spacing: 0.1em; font-weight: 400; }

/* ── The grid, as the site draws it ─────────────────────────────────────
   indizilla.com puts a faint rule grid behind its paper sections. One line
   of it here, behind the whole console, is what makes the surfaces sit on
   something rather than float on a flat fill. */
body::before {
  content: "";
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(to right, var(--grid, rgba(20, 22, 26, .045)) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid, rgba(20, 22, 26, .045)) 1px, transparent 1px);
  background-size: 40px 40px;  /* the site draws it at forty */
  opacity: 1;
}
[data-theme="dark"] body::before { opacity: 0.35; }
/* The grid is painted on the body, so everything above it needs a layer.
   The order matters: the bar carries menus that hang over the page, and it
   comes before the page in the document — same layer meant the page painted
   over its own menu, which is exactly what it did. */
/* These three are grid items, so they take a layer without being positioned.
   Saying "position: relative" here once broke the phone: this block sits
   after the media query, so it overrode the drawer's "transform" and
   the sidebar rendered half off the left edge at every width below 900.

   The same word then broke the other two, in the other direction. #runs and
   #modal-wrap are already "position: fixed" where they are defined, and this
   block was overriding that with "relative" purely to carry a z-index they
   did not need it for: a fixed element honours z-index on its own.

   What "relative" did instead was put them back in normal flow, and since
   both are children of body, and body is a grid of "232px 1fr", each was
   auto-placed into the grid as if it were the sidebar. The modal opened as a
   232px column of one word per line, and the run tray did the same thing
   every time a long job started, which is what "the screens freeze" was. */
#view { z-index: 1; }
#side { z-index: 20; }
#top { z-index: 30; }
#runs { z-index: 55; }
#modal-wrap { z-index: 60; }
#toast { z-index: 70; }


/* ── Tablet ─────────────────────────────────────────────────────────────
   The sidebar is already a drawer below 900. These are the pieces added
   since, which had no rules at all. */
@media (max-width: 900px) {
  /* A menu anchored to a button near the right edge must not hang off it. */
  .pop { min-width: min(300px, calc(100vw - 28px)); max-width: calc(100vw - 28px); }
  .pop.pop-right { right: 0; left: auto; }
  #wswrap .pop { left: 0; right: auto; }

  .wsbtn { max-width: 210px; }
  #top .pinned { gap: 6px; }

  /* The header's action stays; it is the point of the screen. It goes full
     width rather than squeezing beside a wrapped title. */
  .page-head { align-items: flex-start; gap: 12px; }
  /* On a tablet it sits under the title at its own width; a button the
     width of the page reads as a banner, not an action. */
  .page-head .head-act { width: auto; }

  #next-up .nx { padding: 9px 11px; }
  #runs { right: 12px; bottom: 12px; width: calc(100vw - 24px); }
  .ap-grid { gap: 12px; }
  .ap-need-row { flex-direction: column; align-items: flex-start; gap: 8px; }
  .ap-need-row .btn { width: 100%; }
}

/* ── Phone ──────────────────────────────────────────────────────────────
   Below 560 the bar keeps four things and drops the words from two of them.
   Everything in the bar is still reachable; only its labels are gone. */
@media (max-width: 560px) {
  #top { padding: 0 10px; gap: 6px; }
  /* The workspace switcher keeps the brand, which is the half that changes
     while you work; the workspace is in the menu it opens. */
  .wsbtn { max-width: 132px; padding: 0 8px; gap: 5px; }
  .wsbtn .ws-p, .wsbtn > i.ph:not(.caret) { display: none; }
  .wsbtn .ws-b { font-weight: 600; color: var(--ink); }
  /* The status keeps its dot and loses its sentence; the sentence is inside. */
  #status-summary { padding: 5px 9px; gap: 0; }
  #status-summary { font-size: 0; }
  #status-summary .dot { width: 9px; height: 9px; }
  /* The stop button never gives way, but it can be its icon. */
  #kill span { display: none; }
  #kill { padding: 0 10px; }
  #kill i.ph { font-size: 17px; }

  .page-head h1 { font-size: 26px; }
  .card { padding: 16px 14px 18px; }
  /* Long unbroken strings — a URL, a slug, a quoted line — must wrap rather
     than push the card past the screen. */
  .card, .copy p, .initiative .quote, .approval .why, .approval .reason, td, .li b {
    overflow-wrap: anywhere;
  }
  .steps { gap: 5px; }
  .steps .s { padding: 4px 10px; font-size: var(--t-micro); }
  .chanpick .chips-row { gap: 5px; }
  .chanchip { padding: 4px 9px; }
  .stat .fig, .big { font-size: 26px; }
  .initiative .row button, .approval .row button { flex: 1 1 auto; }
  #runs { left: 12px; right: 12px; width: auto; }
  /* A modal on a phone is the screen, not a card floating on one. */
  #modal-wrap { padding: 0; align-items: flex-end; }
  #modal { max-height: 92vh; border-radius: 14px 14px 0 0; padding: 20px 16px; width: 100%; }
  #modal .sdoc-a { bottom: -20px; }
  /* On a phone the thumb wants the whole width. */
  .page-head .head-act, .page-head .head-act button, .page-head .head-act .btn { width: 100%; }
  /* A menu anchored to a button cannot fit beside it on a phone: right-aligned
     to a button near the middle of a 375px bar, a 300px panel starts at minus
     a hundred. Below this width they stop being anchored and become a sheet
     under the bar, the width of the screen. */
  .popwrap { position: static; }
  .pop, .pop.pop-right {
    position: fixed; left: 10px; right: 10px; top: 58px;
    min-width: 0; max-width: none; width: auto;
  }
  .head-act.auto { margin-top: 2px; }
}

/* A table below the phone breakpoint keeps its columns whole and scrolls
   inside its frame; see .tw. The table itself is no longer made a scroller,
   because a scroller inside a scroller is two scrollbars for one table. */
@media (max-width: 720px) {
  .tw th, .tw td { white-space: nowrap; }
}


/* ── Scrollbars ─────────────────────────────────────────────────────────
   Thin, no arrows, the theme's own hairline. Firefox takes the two-value
   form; the rest take the parts. A console scrolls in several places at
   once and the operating system's default bar is a grey trough with
   buttons on it — on a short window two of them stack and read as one
   scrollbar sitting above another. */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--line-strong);
  border-radius: 99px;
  border: 3px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--faint); background-clip: content-box; }
*::-webkit-scrollbar-corner { background: transparent; }
/* The arrow buttons are the loudest part of the default and the least used. */
*::-webkit-scrollbar-button { display: none; height: 0; width: 0; }

/* ── A short window ─────────────────────────────────────────────────────
   A laptop with a small window, a split screen, a phone in landscape: the
   bar was a fixed sixty pixels and the view took whatever was left, which
   at two hundred pixels of height was nothing worth having. */
@media (max-height: 560px) {
  body { grid-template-rows: 48px 1fr; }
  #top { padding: 0 12px; gap: 6px; }
  #top .wsbtn, #top .chip, #top .pinned button, #kill { min-height: 28px; }
  #view { padding: 16px 16px 40px; }
  .page-head { margin-bottom: 16px; padding-bottom: 14px; }
  .page-head h1 { font-size: 22px; }
  .card { padding: 14px 16px 16px; }
  #next-up { padding: 0 4px 8px; }
  #runs { bottom: 10px; }
  #modal { max-height: 94vh; padding: 16px; }
}
@media (max-height: 420px) {
  /* Below this the sidebar's own chrome is more than the screen can spare. */
  #next-up { display: none; }
  .page-head p { display: none; }
}

/* ── The menus float above the page, properly ───────────────────────────
   Absolutely positioned inside the bar, a menu lives in the bar's stacking
   context and cannot rise above anything outside it. Fixed, and placed from
   its button when it opens, it sits in the top layer under the modal. */
.pop {
  position: fixed;
  z-index: 200;
  /* It rises, it does not fade. A hundred and sixty milliseconds of opacity
     is long enough to be seen, and what it looks like in that moment is a
     menu behind the page — which is what it was reported as, twice. */
  animation: popin 120ms var(--ease) both;
}
@keyframes popin { from { transform: translateY(-6px); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .pop { animation: none; } }

/* ── Nothing wider than the screen ──────────────────────────────────────
   A grid or flex item is allowed to grow to its content's minimum width,
   and a twelve column table's minimum is twelve columns. One such table
   made a phone screen three and a half thousand pixels wide: the heading
   stretched with it, the paragraph stretched with it, and you scrolled the
   whole page sideways to read one cell. Saying the items may shrink is the
   whole fix; the table then scrolls inside its own frame. */
.grid > *, .stack > *, .row > *, .page-head > *, .cols-2 > *, .cols-3 > * { min-width: 0; }

.tw { overflow-x: auto; overscroll-behavior-x: contain; }
.tw > table { margin: 0; }

/* A field is as wide as the box it is in, never as wide as its cols attribute. */
#view textarea { width: 100%; }
#view input, #view select, #view textarea { max-width: 100%; }
#view pre, #view code { overflow-x: auto; overflow-wrap: anywhere; }

/* ── Made for a thumb ───────────────────────────────────────────────────
   Thirty-four pixels is a comfortable button for a mouse and a miss for a
   finger. Every control grows on a touch-sized screen; nothing moves on a
   desktop, where the smaller sizes are right. */
@media (max-width: 900px) {
  button, .btn { min-height: 40px; padding: 0 16px; }
  /* The small ones are the filters, the row actions, the segment pickers —
     the controls people press most and the ones that were hardest to hit.
     They keep their smaller type; they do not keep their smaller box. */
  button.small, .btn.small { min-height: 40px; padding: 0 13px; }
  #top button, #top .btn, .wsbtn, #kill { min-height: 38px; }
  #top .pinned button.icon, #menu-btn { min-width: 38px; }
  #side a { padding: 10px 12px; }
  .pop-row { min-height: 44px; }
  input, select, textarea { min-height: 40px; }
  .head-act .btn, .head-act button { min-height: 44px; }
}

/* ── The rail ───────────────────────────────────────────────────────────
   Forty links is the map of the whole tool: worth having open while you are
   learning it, worth folding away once you know the way. Folded it keeps
   the icons and the section rings, because a sidebar that vanishes entirely
   makes you open it again just to see where you are. */
#side .logo {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
#railbtn { flex: 0 0 auto; color: var(--faint); }
#railbtn:hover { color: var(--ink); }

/* Only after the first paint, so a folded sidebar does not fold again on
   every load: the preference is already true when the page arrives. */
body.ready { transition: grid-template-columns 200ms var(--ease); }
body.nav-rail { grid-template-columns: 64px 1fr; }
body.nav-rail #side { padding-left: 8px; padding-right: 8px; overflow: hidden; }
body.nav-rail #side .logo { font-size: 0; justify-content: center; padding: 0 0 16px; }
body.nav-rail #side #next-up, body.nav-rail #side .foot { display: none; }
body.nav-rail #side a {
  font-size: 0; gap: 0; justify-content: center; padding: 10px 0;
}
body.nav-rail #side a i.ph { font-size: 18px; }
/* The count becomes a dot: the number is unreadable at this width, but that
   something is waiting there is the part you need. */
body.nav-rail #side a .n {
  margin: -10px 0 0 -7px; min-width: 7px; width: 7px; height: 7px;
  padding: 0; font-size: 0; line-height: 0; border-radius: 99px; background: var(--bad-fg);
}
body.nav-rail #side .nav .group { font-size: 0; justify-content: center; padding: 12px 0 4px; }
body.nav-rail #side .nav .group svg { margin: 0; }
body.nav-rail #side a.active { box-shadow: inset 2px 0 0 var(--brand); }

/* On a phone the sidebar is already a drawer, so there is nothing to fold. */
@media (max-width: 900px) {
  #railbtn, #rail-toggle { display: none; }
  body.nav-rail { grid-template-columns: 1fr; }
  body.nav-rail #side { padding: 20px 12px 16px; }
  body.nav-rail #side .logo { font-size: 19px; justify-content: space-between; padding: 0 12px 20px; }
  body.nav-rail #side a { font-size: 13.5px; gap: 10px; justify-content: flex-start; padding: 10px 12px; }
  body.nav-rail #side .foot { display: block; }
}
@media (prefers-reduced-motion: reduce) { body { transition: none; } }

/* The calendar is a grid too, and it was left out of the rule that lets a grid
   item shrink below its content. Nothing showed while the calendar was empty:
   seven equal columns of nothing fit anywhere. With real entries in them, one
   long topic set the min-content width of its track and pushed the whole month
   past the right edge, at every width. Same fault as .grid, same fix. */
.cal-grid > *, .cal-cell > *, .cal-item > * { min-width: 0; }
.cal-item { overflow: hidden; }

/* ── What a screen is for, before the form on it ─────────────────────────
   Three short answers in a row: what it is for, how to come at it, what it
   gives back. The middle one is the one usually missing, and the one that
   decides whether the answer a person gives is worth anything. */
.fd-hint {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 18px;
  padding: 16px 18px; margin-bottom: 14px;
  border: 1px solid var(--line); border-left: 3px solid var(--brand);
  border-radius: var(--r-card); background: var(--surface);
}
.fd-hint > * { min-width: 0; }
.fd-hint p { margin: 5px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--body); }
@media (max-width: 900px) { .fd-hint { grid-template-columns: 1fr; gap: 12px; } }


/* ── Groundwork: what is missing ───────────────────────────────────────
   The list that replaces an empty form with an ordered answer. It reads as
   one block rather than a card, because it is the preface to the tab and not
   another thing on it. */
.fd-gaps {
  border-left: 3px solid var(--warn);
  margin-bottom: 14px;
}
.fd-gaps.done { border-left-color: var(--ok); }
.fd-gap-list {
  margin: 0; padding-left: 20px;
  display: grid; gap: 10px;
}
.fd-gap-list li { min-width: 0; }
.fd-gap-list li .badge { margin-right: 6px; }


/* ── Stakeholders: how a ranking got its number ────────────────────────
   The bars exist so a score can be argued with. Each one is a factor, its
   points, and the recorded fact the points came from. */
.tg-factors { display: grid; gap: 10px; margin-top: 8px; }
.tg-factor { min-width: 0; }
.tg-bar {
  height: 6px; border-radius: 3px;
  background: var(--line);
  margin: 4px 0 3px;
  overflow: hidden;
}
.tg-bar > span { display: block; height: 100%; background: var(--brand); }
.tg-row { margin-bottom: 10px; }


/* ── What is left, and who does it ─────────────────────────────────────
   Three columns because the point is the comparison: how little of the
   remaining work is actually the operator's. Stacks on a phone, where the
   comparison is read by scrolling instead. */
.wdw { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.wdw-col { min-width: 0; }
.wdw-h { margin-bottom: 2px; }
.wdw-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.wdw-list li { min-width: 0; padding-left: 10px; border-left: 2px solid var(--line); }
.wdw-list li:hover { border-left-color: var(--brand); }
/* A browser's own link colour is the one colour on this screen that belongs to
   nobody. The accent carries in both schemes; the bible asks for that. */
.wdw-list a { color: var(--brand-ink); text-decoration: none; }
.wdw-list a:hover { text-decoration: underline; text-underline-offset: 2px; }
@media (max-width: 900px) { .wdw { grid-template-columns: 1fr; gap: 14px; } }


/* ── A long job, while it runs ──────────────────────────────────────────
   Steps that have happened, with what each one found. Monospace marks so
   the column does not shift as a step completes. */
.cs-steps { display: grid; gap: 10px; margin-top: 4px; }
.cs-step { display: grid; grid-template-columns: 18px 1fr; gap: 10px; align-items: start; min-width: 0; }
.cs-mark { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--faint); line-height: 1.5; }
.cs-step.running .cs-mark { color: var(--brand-ink); }
.cs-step.done .cs-mark { color: var(--ok); }
.cs-step.failed .cs-mark { color: var(--bad); }
.cs-step.waiting { opacity: 0.55; }
.cs-found {
  list-style: none; margin: 4px 0 0; padding: 0 0 0 10px;
  border-left: 1px solid var(--line);
  display: grid; gap: 2px;
}
.cs-found li {
  font-size: var(--t-small); color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}


/* ── The shots ──────────────────────────────────────────────────────────
   A running order, read top to bottom while holding a phone. The timecode
   is a fixed column so the eye can run down it without re-finding itself. */
.shots { display: grid; gap: 12px; }
.shot {
  display: grid; grid-template-columns: 62px 1fr; gap: 12px;
  padding-left: 10px; border-left: 2px solid var(--line); min-width: 0;
}
.shot:hover { border-left-color: var(--brand); }
.shot-at {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--t-small); color: var(--ink);
  display: grid; gap: 1px;
}
.shot-at span { font-size: var(--t-micro); }
.shot-say {
  margin: 3px 0; padding-left: 9px;
  border-left: 2px solid var(--brand);
  font-style: italic;
}
.shot-screen {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: var(--t-small); color: var(--brand-ink);
  margin: 3px 0;
}
@media (max-width: 560px) { .shot { grid-template-columns: 54px 1fr; gap: 8px; } }
