/* Webfonts — joris design system.

   The @import that used to live here has moved to app/views/shared/_webfonts.html.erb
   as a <link> in the <head>. An @import is invisible to the browser's preload
   scanner, so the font request could not start until application.css had been
   fetched and parsed — a serialized chain that delayed first paint on every page.

   Nothing else belongs in this file today. For a fully self-hosted build,
   download Newsreader + Hanken Grotesk into app/assets/fonts and declare local
   @font-face rules here (then drop the <link> and the preconnects). */
/* ---------------------------------------------------------------
   joris — Color tokens
   Warm, calm, editorial. Paper surfaces on a warm canvas, deep warm
   ink for text, a muted forest green as the single primary, with
   terracotta and provider-purple as sparing accents.
   All base values are literal; semantic aliases reference the base.
   --------------------------------------------------------------- */
:root {
  /* --- Neutrals (warm) --- */
  --canvas:        #efece4;  /* app background */
  --canvas-hi:     #f5f2ec;  /* top of page gradient */
  --canvas-lo:     #eae6dd;  /* bottom of page gradient */
  --paper:         #ffffff;  /* card / sheet surface */
  --paper-warm:    #faf8f3;  /* subtle raised strip, table headers */

  --ink:           #26221b;  /* primary text */
  --ink-soft:      #6f6a5e;  /* secondary text */
  --ink-faint:     #9a9384;  /* tertiary / meta text */
  --ink-ghost:     #a49d8d;  /* placeholders, monospace hints */

  --border:        #e6e1d6;  /* default hairline */
  --border-soft:   #ece8df;  /* inner dividers */
  --border-strong: #d9d3c6;  /* hover border */

  /* --- Primary: forest green --- */
  --primary:        #2f6d5b;
  --primary-press:  #28604f;
  --primary-tint:   #eef4f1;  /* green wash background */
  --primary-tint-2: #f4f8f6;
  --primary-border: #cfe0d9;  /* green hairline */
  --primary-chip:   #dcebe5;  /* filled green chip bg */

  /* --- Accent: terracotta (used sparingly for links/callouts) --- */
  --accent:         #b45b3e;
  --accent-soft:    #b0623c;

  /* --- Danger: destructive actions (Danger Zone only — not the same as accent) --- */
  --danger:           #b0553a;
  --danger-press:     #8f3f28;
  --danger-tint:      #fdf6f2;
  --danger-border:    #e8d3ca;
  --danger-disabled:      #ecdcd4;
  --danger-disabled-text: #c4a99d;

  /* --- Provider: muted purple (AI model badges only) --- */
  --provider:       #6a4c86;
  --provider-tint:  #efe9f2;

  /* --- Placeholder hatch (image / chart / map slots) --- */
  --hatch-a:        #f6f3ec;
  --hatch-b:        #f1ede4;

  /* --- Focus ring --- */
  --ring:           rgba(47,109,91,.35);

  /* ============ Semantic aliases ============ */
  --surface-page:    var(--canvas);
  --surface-card:    var(--paper);
  --surface-raised:  var(--paper-warm);

  --text-body:       var(--ink);
  --text-muted:      var(--ink-soft);
  --text-faint:      var(--ink-faint);
  --text-placeholder:var(--ink-ghost);
  --text-link:       var(--accent);

  --border-default:  var(--border);
  --border-divider:  var(--border-soft);

  --action-primary:      var(--primary);
  --action-primary-press:var(--primary-press);
  --focus-ring:          var(--ring);

  --success:  var(--primary);
  --warning:  var(--accent);
}
/* ---------------------------------------------------------------
   joris — Typography tokens
   Two families: Newsreader (serif) carries editorial headlines and
   any "document" numerals; Hanken Grotesk (sans) carries all UI.
   Monospace only for placeholder / data hints.
   --------------------------------------------------------------- */
:root {
  --font-display: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-sans:    'Hanken Grotesk', system-ui, -apple-system, sans-serif;
  --font-mono:    ui-monospace, 'SF Mono', Menlo, monospace;

  /* Reading scale. Stays 1 outside the reading surface — see .reading-scope
     at the bottom of this file. */
  --reading-scale: 1;

  /* Type scale. Baselines are a notch up from the original 10–15px set: this
     is a reading app and 13px body was under the 16px web norm. */
  --text-2xs: 11px;
  --text-xs:  12px;
  --text-sm:  13px;
  --text-ui:  14px;   /* default control text */
  --text-md:  15px;   /* body */
  --text-lg:  17px;   /* long-form prose */
  --display-sm: 22px;
  --display-md: 25px;
  --display-lg: 28px;
  --display-xl: 31px;

  /* Weights */
  --weight-regular: 400;
  --weight-medium:  500;
  --weight-semibold:600;
  --weight-bold:    700;

  /* Line heights */
  --leading-tight:  1.15;
  --leading-snug:   1.3;
  --leading-normal: 1.5;
  --leading-relaxed:1.6;

  /* Letter spacing */
  --tracking-label: .5px;   /* small caps labels */
  --tracking-tight: .2px;
}

/* ---------------------------------------------------------------
   Reading size (users.reading_scale).

   `.reading-scope` marks the one subtree the setting applies to: the brief
   body and the delivery templates. Everything outside it — nav, settings,
   admin, onboarding, and the .btn/.card sizes in components.css — keeps the
   baseline above, which is what the Settings copy promises.

   The scope has to redeclare the tokens rather than just setting
   --reading-scale, because a custom property's var() is substituted where it
   is DECLARED, not where it is used: tokens declared at :root would resolve
   against :root's scale and inherit down already-frozen. Declaring both the
   scale and the tokens on the same element is what makes them track.

   <html data-reading-scale> is rendered server-side so the first paint is
   already at the chosen size, with no flash-and-resize.
   --------------------------------------------------------------- */
:root[data-reading-scale="large"]  .reading-scope { --reading-scale: 1.15; }
:root[data-reading-scale="xlarge"] .reading-scope { --reading-scale: 1.32; }

.reading-scope {
  --text-2xs: calc(11px * var(--reading-scale));
  --text-xs:  calc(12px * var(--reading-scale));
  --text-sm:  calc(13px * var(--reading-scale));
  --text-ui:  calc(14px * var(--reading-scale));
  --text-md:  calc(15px * var(--reading-scale));
  --text-lg:  calc(17px * var(--reading-scale));
  --display-sm: calc(22px * var(--reading-scale));
  --display-md: calc(25px * var(--reading-scale));
  --display-lg: calc(28px * var(--reading-scale));
  --display-xl: calc(31px * var(--reading-scale));
}
/* ---------------------------------------------------------------
   joris — Spacing, radius, shadow & motion tokens
   --------------------------------------------------------------- */
:root {
  /* Spacing scale (4px base, plus a couple of editorial in-betweens) */
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  20px;
  --space-6:  26px;
  --space-7:  34px;
  --space-8:  44px;

  /* Page gutter — the side padding on a full-page frame (.hist, .rt,
     .acct-page, .sup, .adm-scroll). Phones drop to 16px: at 32px a side, a
     390px screen spends 27% of its width on the frame plus the nested card
     and row padding inside it, and this is a reading app. */
  --page-gutter: 32px;
  --page-top: 38px;

  /* Radii */
  --radius-xs:  7px;
  --radius-sm:  9px;
  --radius-md:  11px;   /* inputs, buttons */
  --radius-lg:  14px;   /* cards */
  --radius-xl:  16px;   /* feature cards */
  --radius-2xl: 20px;   /* sheets, modals */
  --radius-pill:999px;

  /* Elevation — warm-tinted, low and soft */
  --shadow-sm:   0 2px 6px rgba(50,42,28,.06);
  --shadow-card: 0 10px 34px rgba(50,42,28,.08);
  --shadow-pop:  0 16px 48px rgba(50,42,28,.11);
  --shadow-primary: 0 3px 10px rgba(47,109,91,.25);

  /* Borders */
  --hairline: 1.5px;

  /* Placeholder hatch (reusable background) */
  --hatch: repeating-linear-gradient(45deg, var(--hatch-a), var(--hatch-a) 8px, var(--hatch-b) 8px, var(--hatch-b) 16px);

  /* Motion */
  --ease-out: cubic-bezier(.2,.6,.2,1);
  --dur-fast: .15s;
  --dur-mid:  .3s;
  --dur-rise: .45s;
}

@media (max-width: 720px) {
  :root {
    --page-gutter: 16px;
    --page-top: 22px;
  }
}
/* ---------------------------------------------------------------
   joris — Base reset, page background & shared keyframes.
   --------------------------------------------------------------- */
*, *::before, *::after {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  margin: 0;
  padding: 0;
  /* The app scrolls inside .app-main, not the document. Without this, hitting
     the end of that inner scroller chains the gesture out to the document,
     which drags the whole shell — and the top bar with it — before rubber-
     banding back. Also suppresses pull-to-refresh. */
  overscroll-behavior: none;
}

/* …but on phones the document IS the scroller now (see the mobile block in
   app_shell.css), so there is no inner pane whose gesture could chain out and
   drag the shell. The reason above no longer applies at this width, and the
   only thing `none` still buys us here is a dead pull-to-refresh gesture.

   Placed here rather than with the other phone rules in app_shell.css: that
   file loads before this one and a media query adds no specificity, so the
   override would lose to the rule directly above it. */
@media (max-width: 720px) {
  html, body { overscroll-behavior: auto; }
}

body {
  font-family: var(--font-sans);
  color: var(--text-body);
  background: var(--surface-page);
}

a {
  color: inherit;
  text-decoration: none;
}

.joris-page {
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
  background: radial-gradient(120% 120% at 50% 0%, var(--canvas-hi) 0%, var(--canvas-lo) 100%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-5);
}

.joris-hidden {
  display: none !important;
}

@keyframes riseIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes pulseDot {
  0%, 100% { transform: scale(1); opacity: 1; }
  50%      { transform: scale(.6); opacity: .5; }
}

@keyframes shimmer {
  0%   { background-position: -360px 0; }
  100% { background-position: 360px 0; }
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

.joris-rise {
  animation: riseIn var(--dur-rise) ease both;
}
/* ---------------------------------------------------------------
   joris — Core & form component classes
   Ported from the Claude Design handoff's Button/Card/Chip/Badge/
   ProgressBar/BrandMark/Input/Textarea/Checkbox reference components.
   --------------------------------------------------------------- */

/* ============ Button ============ */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-sans);
  font-weight: var(--weight-semibold);
  line-height: 1;
  cursor: pointer;
  border: 1.5px solid transparent;
  transition: background var(--dur-fast), border-color var(--dur-fast), transform var(--dur-fast);
  padding: 13px 16px;
  font-size: var(--text-md);
  border-radius: var(--radius-md);
}
.btn--block { display: flex; width: 100%; }
.btn--sm { padding: 7px 12px; font-size: var(--text-ui); border-radius: var(--radius-sm); }
.btn--lg { padding: 14px 18px; font-size: 14.5px; border-radius: var(--radius-md); }

.btn--primary {
  background: var(--action-primary);
  color: #fff;
  box-shadow: var(--shadow-primary);
}
.btn--primary:hover { background: var(--action-primary-press); }
.btn--primary:active { background: var(--action-primary-press); }

.btn--ghost {
  background: var(--surface-card);
  color: var(--primary);
  border-color: var(--primary-border);
}
.btn--ghost:hover { background: var(--primary-tint-2); }

.btn--subtle {
  background: var(--surface-raised);
  color: var(--text-body);
  border-color: var(--border-default);
}
.btn--subtle:hover { background: var(--paper-warm); border-color: var(--border-strong); }

.btn--danger {
  background: var(--danger);
  color: #fff;
  border-color: var(--danger);
}
.btn--danger:hover { background: var(--danger-press); border-color: var(--danger-press); }
.btn--danger:disabled {
  background: var(--danger-disabled);
  border-color: var(--danger-disabled);
  color: var(--danger-disabled-text);
  cursor: default;
}

/* ── In flight (busy.js) ──
   Deliberately class-based rather than :disabled: every button in the app gets
   this, including the many that are not .btn, and a bare [disabled] rule would
   also restyle controls disabled by the server for unrelated reasons. */
.is-busy {
  opacity: .62;
  cursor: progress;
  /* Not pointer-events:none — the cursor above has to survive the hover, and
     the control is genuinely disabled a tick later regardless. */
}
.is-busy:hover { background: inherit; }

/* Spinner only where there is room for one: a bare icon button (the copy and
   overflow triggers) would have its glyph shoved out of the box. */
.btn.is-busy::after,
a.is-busy[data-busy-link]::after {
  content: "";
  width: 1em;
  height: 1em;
  flex: none;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: busy-spin .62s linear infinite;
}
@keyframes busy-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn.is-busy::after,
  a.is-busy[data-busy-link]::after { animation-duration: 2.4s; }
}

/* ============ Card ============ */
.card {
  background: var(--surface-card);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  padding: var(--space-4);
  overflow: hidden;
}
.card--pad-0 { padding: 0; }
.card--flat { box-shadow: none; }
.card--card { box-shadow: var(--shadow-card); }
.card--pop  { box-shadow: var(--shadow-pop); }
.card--interactive {
  cursor: pointer;
  transition: transform var(--dur-fast), box-shadow var(--dur-fast), border-color var(--dur-fast);
}
.card--interactive:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-card);
  border-color: var(--primary-border);
}
.card--interactive:active {
  transform: translateY(0) scale(.98);
  box-shadow: var(--shadow-sm);
  border-color: var(--primary-border);
}

/* ============ Chip ============ */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-sans);
  font-weight: var(--weight-semibold);
  font-size: var(--text-xs);
  padding: 5px 10px;
  border-radius: var(--radius-pill);
  white-space: nowrap;
  background: var(--hatch-b);
  color: var(--ink-soft);
}
.chip[data-clickable] { cursor: pointer; }
.chip--green      { background: var(--primary-tint);  color: var(--primary); }
.chip--purple     { background: var(--provider-tint);  color: var(--provider); }
.chip--terracotta { background: rgba(180,91,62,.10);   color: var(--accent); }
.chip--selected   { background: var(--primary); color: #fff; }

/* ============ Badge ============ */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-family: var(--font-sans);
  font-weight: var(--weight-semibold);
  font-size: var(--text-2xs);
  letter-spacing: .3px;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  background: var(--hatch-b);
  color: var(--ink-soft);
}
.badge--green      { background: var(--primary-tint); color: var(--primary); }
.badge--solid      { background: var(--primary); color: #fff; }
.badge--terracotta { background: rgba(180,91,62,.12); color: var(--accent); }

/* ============ ProgressBar ============ */
.progress {
  height: 8px;
  border-radius: var(--radius-pill);
  background: var(--canvas);
  overflow: hidden;
}
.progress__fill {
  height: 100%;
  width: 0%;
  border-radius: inherit;
  background: var(--primary);
  transition: width .12s linear;
}

/* ============ BrandMark ============ */
.brandmark { display: inline-flex; align-items: center; gap: 10px; }
.brandmark__glyph {
  width: 30px;
  height: 30px;
  border-radius: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-primary);
  flex: none;
  overflow: hidden;
}
.brandmark__glyph span { color: #fff; font-size: 13px; }
.brandmark__glyph img { width: 100%; height: 100%; display: block; object-fit: cover; }
.brandmark__name {
  font-family: var(--font-display);
  font-size: var(--display-sm);
  font-weight: var(--weight-semibold);
  color: var(--ink);
  letter-spacing: var(--tracking-tight);
}
.brandmark--sm .brandmark__glyph { width: 24px; height: 24px; border-radius: 7px; }
.brandmark--sm .brandmark__glyph span { font-size: 10px; }
.brandmark--sm .brandmark__name { font-size: 17px; }
.brandmark--lg .brandmark__glyph { width: 38px; height: 38px; border-radius: 11px; }
.brandmark--lg .brandmark__glyph span { font-size: 16px; }
.brandmark--lg .brandmark__name { font-size: 26px; }

/* ============ Passkey prompt banner ============ */
.passkey-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px 16px;
  width: 100%;
  max-width: 640px;
  margin: var(--space-4) auto 0;
  padding: 12px 16px;
  background: var(--primary-tint);
  border: var(--hairline) solid var(--primary-border);
  border-radius: var(--radius-md);
}
.passkey-banner__msg {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  font-size: var(--text-sm);
  line-height: 1.45;
  color: var(--ink-soft);
}
.passkey-banner__msg strong { color: var(--ink); font-weight: var(--weight-semibold); }
.passkey-banner__icon { font-size: 17px; flex-shrink: 0; }
.passkey-banner__actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.passkey-banner__error { flex-basis: 100%; color: var(--accent); font-size: var(--text-xs); }

/* Full-width variant: a notice bar that sits directly under the reader topbar,
   sharing its horizontal padding so the copy lines up with the topbar chips. */
.passkey-banner--bar {
  max-width: none;
  width: 100%;
  margin: 0;
  padding: 12px var(--space-5);
  border: 0;
  border-bottom: var(--hairline) solid var(--primary-border);
  border-radius: 0;
}

/* ============ Form field label ============ */
.field { display: block; }
.field__label {
  display: block;
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-muted);
  margin-bottom: 7px;
}

/* ============ Input / Textarea ============ */
.input, .textarea {
  width: 100%;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  color: var(--text-body);
  background: var(--surface-card);
  outline: none;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.input {
  padding: 12px 13px;
  font-size: var(--text-md);
}
.textarea {
  padding: 11px 13px;
  min-height: 76px;
  font-size: var(--text-ui);
  line-height: var(--leading-normal);
  color: var(--ink);
  resize: none;
}
.input:focus, .textarea:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

/* A control that would only bounce you back. Inert rather than hidden: the
   affordance still shows where the action lives, and the title says why it is
   off — hiding it entirely reads as the feature having vanished. */
.is-caplocked {
  opacity: .45;
  cursor: not-allowed;
  pointer-events: auto;
  user-select: none;
}
.is-caplocked:hover { background: inherit; text-decoration: none; }

/* ============ Select ============ */
/* The caret lives in a variable because three rules draw it — the element
   rule, the combobox trigger, and the marketing field, which has to redeclare
   it since .mkt-form__input's `background` shorthand outranks a bare `select`
   and wiped the image. */
:root { --caret-down: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239a9384' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>"); }
/* One look for every dropdown in the product.
   There were six: two admin ones left on the OS default (so they looked like a
   different app on Windows), and four hand-rolled families that each drew their
   own caret out of a "▾" text node in a positioned <span> — a different glyph,
   colour and offset in each, and markup a <select> should not need.
   The chevron is a background image, so the base element rule alone is the whole
   control and nothing has to wrap it.
   Written as an ELEMENT rule on purpose: it is the floor for selects that do not
   exist yet, which is how the two admin ones drifted in the first place. */
select {
  box-sizing: border-box;
  height: 44px;
  padding: 0 38px 0 14px;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  color: var(--text-body);
  background-color: var(--surface-card);
  cursor: pointer;
  outline: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background-image: var(--caret-down);
  background-repeat: no-repeat;
  background-position: right 13px center;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
select:hover { border-color: var(--border-strong); }
select:focus-visible {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
select:disabled {
  cursor: default;
  opacity: .6;
  background-color: var(--surface-raised);
}
/* Safari and Firefox indent the option list off the padding; without this the
   selected label sits a couple of pixels right of every input beside it. */
select > option { color: var(--text-body); }

/* ── Searchable variant (select_search.js, desktop only) ──
   The <select> is still the form control; it is only taken out of the visual
   flow while the combobox stands in front of it. Never display:none — a hidden
   select is skipped by some autofill and password managers, and taking it out
   of the a11y tree would leave the label pointing at nothing. */
.csel { position: relative; }
.csel--on > select {
  position: absolute;
  width: 100%;
  height: 100%;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}
.csel__trigger {
  display: none;
  width: 100%;
  box-sizing: border-box;
  height: 44px;
  padding: 0 38px 0 14px;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  color: var(--text-body);
  background-color: var(--surface-card);
  background-image: var(--caret-down);
  background-repeat: no-repeat;
  background-position: right 13px center;
  cursor: pointer;
  transition: border-color var(--dur-fast), box-shadow var(--dur-fast);
}
.csel--on > .csel__trigger { display: block; }
.csel__trigger:hover { border-color: var(--border-strong); }
.csel__trigger:focus-visible { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }

.csel__pop {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 240px;
  background: var(--surface-card);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
  box-shadow: 0 18px 44px rgba(50, 42, 28, .16);
  padding: 7px;
}
.csel__pop[hidden] { display: none; }
.csel__search {
  width: 100%;
  box-sizing: border-box;
  height: 36px;
  padding: 0 11px;
  margin-bottom: 6px;
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-sm);
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  color: var(--text-body);
  background: var(--surface-raised);
  outline: none;
}
.csel__search:focus { border-color: var(--primary); }
.csel__list {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Tall enough to show the shape of the list, short enough not to run off the
     page from a field near the bottom of a form. */
  max-height: 264px;
  overflow-y: auto;
}
.csel__opt {
  padding: 9px 11px;
  border-radius: var(--radius-sm);
  font-size: var(--text-ui);
  color: var(--text-body);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.csel__opt[hidden] { display: none; }
/* .is-active follows the keyboard, .is-chosen is what is actually selected —
   they are different things and both need to be visible at once. */
.csel__opt.is-active { background: var(--primary-tint-2); }
.csel__opt.is-chosen { color: var(--primary); font-weight: var(--weight-semibold); }
.csel__opt.is-chosen::after { content: " ✓"; }
.csel__empty { padding: 11px; font-size: var(--text-ui); color: var(--text-faint); }
.csel__empty[hidden] { display: none; }

/* ============ Checkbox ============ */
.checkbox-row { display: inline-flex; align-items: center; gap: 10px; }
.checkbox {
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: var(--radius-xs);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 11px;
  background: transparent;
  border: 1.5px solid var(--border-strong);
  transition: background var(--dur-fast), border-color var(--dur-fast);
}
.checkbox.is-checked {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
}
.checkbox-row__label {
  font-family: var(--font-sans);
  font-size: var(--text-ui);
  color: var(--ink);
}

/* ============ Tabs ============
   Two or three views of one collection, switched in place. Introduced on
   Settings › Webhooks (Activity / Destinations) and now shared, because the
   admin LLMs screen splits the same way (Models / Providers) and a second
   copy of these five rules is how two screens start drifting apart.

   A tab is a LINK, not a button: each view has its own URL, so it can be
   bookmarked, reloaded and linked to from a flash message. The count is
   optional and sits inside the label — it is part of what the tab says, not a
   badge stuck on the side. */
.tabs { display: flex; gap: 6px; margin: 0 0 22px; flex-wrap: wrap; }
.tab {
  padding: 8px 15px; border-radius: var(--radius-pill);
  font: var(--weight-semibold) var(--text-sm)/1 var(--font-sans);
  color: var(--ink-soft); background: var(--paper);
  border: var(--hairline) solid var(--border);
  text-decoration: none; transition: border-color .12s, color .12s;
}
.tab:hover { border-color: var(--primary-border); text-decoration: none; }
.tab.is-active { color: var(--primary); background: var(--primary-tint); border-color: var(--primary-border); }
.tab__n { opacity: .65; font-variant-numeric: tabular-nums; }

/* ============ Filter pills ============
   A row of counted filters over the list below. Distinct from .tabs: tabs
   switch between different SUBJECTS (models vs providers), filters narrow one
   subject (all vs candidates vs never probed). Filled-active rather than
   tinted-active, so the two rows never read as the same control when a page
   shows both, as the LLMs screen does.

   Also links, also one URL each — same reason as .tabs. */
.filters { display: flex; gap: 7px; flex-wrap: wrap; margin: 0 0 10px; }
.filter {
  padding: 6px 12px; border-radius: var(--radius-pill);
  font: var(--weight-semibold) 11.5px var(--font-sans);
  color: #5f5949; background: #f5f2ea; text-decoration: none;
  transition: background .12s, color .12s;
}
.filter:hover { background: var(--border-divider); text-decoration: none; }
.filter.is-active { background: var(--primary); color: #fff; }
.filter__n { font-weight: var(--weight-regular); opacity: .8; font-variant-numeric: tabular-nums; }
/* ---------------------------------------------------------------
   joris — Onboarding flow screens
   Sign in -> magic link -> setup -> running -> delivery.
   --------------------------------------------------------------- */

.ob-brand { margin-bottom: 26px; }

.ob-screen { width: 100%; }
.ob-screen--sm  { max-width: 412px; }
.ob-screen--setup{ max-width: 500px; }
.ob-screen--run { max-width: 480px; }
.ob-screen--delivery{ max-width: 640px; }

/* ---- Sign in ---- */
.ob-signin-card { padding: 34px 30px; }
.ob-title {
  font-family: var(--font-display);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  margin: 0 0 8px;
  color: var(--ink);
}
.ob-title--signin { font-size: 28px; }
/* "You came from the House Hunt page" — continuity for a visitor who clicked a
   use-case CTA, so the sign-in card doesn't read as an unrelated detour. */
.ob-fromchip {
  display: inline-flex; align-items: center; gap: 7px;
  margin-bottom: 12px; padding: 5px 12px 5px 9px; border-radius: 999px;
  background: var(--primary-tint); color: var(--primary);
  font-size: var(--text-sm); font-weight: var(--weight-semibold);
}
.ob-fromchip span { font-size: 14px; line-height: 1; }
.ob-subtitle { margin: 0 0 var(--space-6); font-size: var(--text-md); line-height: var(--leading-normal); color: var(--text-muted); }

.ob-google-btn {
  gap: 11px;
  background: var(--surface-card);
  border-color: var(--border-default);
  color: var(--ink);
}
.ob-google-btn:hover {
  background: var(--paper-warm);
  border-color: var(--border-strong);
}
.ob-google-dot {
  width: 18px; height: 18px; border-radius: 50%;
  background: conic-gradient(from -45deg, #ea4335 0 25%, #fbbc05 0 50%, #34a853 0 75%, #4285f4 0);
  flex: none;
}

.ob-divider { display: flex; align-items: center; gap: 12px; margin: 18px 0; }
.ob-divider__line { flex: 1; height: 1px; background: var(--border-soft); }
.ob-divider__label { font-size: var(--text-xs); color: var(--ink-ghost); letter-spacing: var(--tracking-label); }

.ob-passkey { text-align: center; margin-top: 16px; }
.ob-passkey span { font-size: var(--text-md); color: var(--ink-faint); cursor: pointer; }

.ob-trust { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 16px; }
.ob-trust span { font-size: var(--text-sm); color: var(--ink-faint); }
.ob-trust strong { color: var(--primary); font-weight: var(--weight-semibold); }

/* ---- Magic link sent ---- */
.ob-magic-card { padding: 36px 30px; text-align: center; }
.ob-magic-icon {
  width: 56px; height: 56px; border-radius: var(--radius-xl);
  background: var(--primary-tint);
  display: flex; align-items: center; justify-content: center;
  margin: 0 auto 18px; font-size: 24px;
}
.ob-magic-copy { margin: 0 0 6px; font-size: var(--text-md); line-height: 1.55; color: var(--text-muted); }
.ob-magic-copy strong { color: var(--ink); }
.ob-magic-expiry { margin: 0 0 22px; font-size: 12.5px; color: var(--ink-faint); }
.ob-magic-links {
  margin-top: 24px; padding-top: 18px;
  border-top: var(--hairline) solid var(--primary-border);
  display: flex; align-items: center; justify-content: center; gap: 12px;
}
/* Resend is a real POST (button_to), "use a different email" is a link — both
   render as matching, chrome-free text links so the row reads as one unit. */
.ob-linkbtn-form { margin: 0; display: inline-flex; }
.ob-linkbtn {
  appearance: none; -webkit-appearance: none;
  background: none; border: 0; padding: 0; margin: 0;
  font-family: var(--font-sans); font-size: var(--text-sm); line-height: 1;
  font-weight: var(--weight-semibold); color: var(--primary);
  cursor: pointer; text-decoration: none; transition: opacity .15s ease;
}
.ob-linkbtn:hover { text-decoration: underline; }
.ob-linkbtn--muted { color: var(--ink-faint); font-weight: var(--weight-medium); }
.ob-magic-dot { color: var(--ink-ghost); font-size: var(--text-sm); user-select: none; }

/* ---- Setup ---- */
.ob-setup-header { text-align: center; margin-bottom: 20px; }
.ob-title--setup { font-size: 27px; }
.ob-setup-card { padding: 22px; }
.ob-field { margin-bottom: 16px; }
.ob-setup-divider { height: 1px; background: var(--border-soft); margin: 0 0 16px; }

.ob-row { display: flex; justify-content: space-between; align-items: center; }
.ob-row--label { font-size: var(--text-ui); font-weight: var(--weight-semibold); color: var(--ink); }
.ob-row-runs { margin-bottom: 13px; }
.ob-row-model { margin-bottom: 16px; }
.ob-row-actions { display: flex; align-items: center; gap: 8px; }
.ob-link { font-size: var(--text-sm); color: var(--accent); font-weight: var(--weight-semibold); cursor: pointer; }

.ob-calendar-row {
  display: flex; justify-content: space-between; align-items: center;
  padding: 12px 13px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-md);
  margin-bottom: 18px;
}
.ob-calendar-row__title { font-size: var(--text-ui); font-weight: var(--weight-semibold); color: var(--ink); }
.ob-calendar-row__hint { font-size: 11.5px; color: var(--ink-faint); }
.ob-calendar-row__actions { display: flex; align-items: center; gap: 9px; }
.ob-calendar-connect {
  font: var(--weight-semibold) var(--text-xs) var(--font-sans);
  padding: 6px 11px; border-radius: var(--radius-pill);
  background: var(--surface-card); border: 1.5px solid var(--primary-border);
  color: var(--primary); cursor: pointer;
}
.ob-calendar-skip { font-size: var(--text-sm); color: var(--ink-faint); cursor: pointer; }

.ob-back { text-align: center; margin-top: 16px; }
.ob-back span { font-size: var(--text-ui); color: var(--ink-faint); cursor: pointer; }

/* ---- Running ---- */
.ob-run-card { padding: 30px 28px; }
.ob-run-head { display: flex; align-items: center; gap: 11px; margin-bottom: 6px; }
.ob-spinner {
  width: 26px; height: 26px; border-radius: 50%;
  border: 2.5px solid var(--primary-chip);
  border-top-color: var(--primary);
  display: inline-block;
  animation: spin .8s linear infinite;
  flex: none;
}
.ob-title--run { font-size: 23px; margin: 0; }
.ob-run-hint { margin: 0 0 var(--space-5) 37px; font-size: var(--text-ui); color: var(--ink-faint); }

.ob-progress { margin-bottom: 22px; }

.ob-steps { margin-bottom: 0; }
.ob-step { display: flex; align-items: center; gap: var(--space-3); padding: 7px 0; }
.ob-step__mark { width: 20px; height: 20px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; flex: none; }
.ob-step__mark--done { background: var(--primary); color: #fff; font-size: var(--text-xs); }
.ob-step__mark--active { border: 2px solid var(--primary); }
.ob-step__mark--pending { border: 2px solid var(--border-default); }
.ob-step__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--primary); animation: pulseDot 1s ease-in-out infinite; }
.ob-step__label { font-size: 13.5px; color: #3a352c; }

.ob-shimmer {
  margin-top: var(--space-5);
  height: 64px;
  border-radius: var(--radius-md);
  background: linear-gradient(100deg, var(--paper-warm) 30%, var(--canvas-lo) 50%, var(--paper-warm) 70%);
  background-size: 720px 100%;
  animation: shimmer 1.4s linear infinite;
}

/* ---- First delivery ---- */
.ob-delivery-card { padding: 0; }
.ob-delivery-head {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 20px;
  border-bottom: var(--hairline) solid var(--border-soft);
  background: var(--paper-warm);
}
.ob-delivery-head__chips { display: flex; align-items: center; gap: 8px; }
.ob-delivery-head__version { font-size: var(--text-sm); color: var(--ink-faint); }

.ob-celebrate {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 20px;
  background: var(--primary-tint);
  border-bottom: var(--hairline) solid var(--primary-border);
}
.ob-celebrate__icon { font-size: 15px; }
.ob-celebrate__text { font-size: var(--text-ui); color: var(--primary); font-weight: var(--weight-semibold); }

.ob-delivery-body { padding: 26px 30px; }
.ob-delivery-meta { font-size: var(--text-sm); color: var(--ink-faint); margin-bottom: var(--space-2); }
.ob-title--delivery { font-size: 27px; line-height: 1.2; margin: 0 0 var(--space-4); }

.ob-delivery-footer {
  display: flex; gap: var(--space-2);
  padding: 16px 20px;
  border-top: var(--hairline) solid var(--border-soft);
  background: var(--paper-warm);
}
.ob-delivery-footer .btn { flex: 1; }

.ob-below { text-align: center; margin-top: 16px; }
.ob-below span { font-size: 12.5px; color: var(--ink-faint); }

/* -- Delivery: shared bits -- */
.ob-stat-row { display: flex; gap: var(--space-3); margin-bottom: var(--space-5); }
.ob-stat {
  flex: 1;
  border: var(--hairline) solid var(--border-soft);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}
.ob-stat__label { font-size: var(--text-xs); color: var(--ink-faint); margin-bottom: 4px; }
.ob-stat__value { font-family: var(--font-display); font-size: var(--display-md); }
.ob-stat__value--up { color: var(--primary); }

.ob-table { border: var(--hairline) solid var(--border-soft); border-radius: var(--radius-md); overflow: hidden; margin-bottom: var(--space-4); }
.ob-table__head, .ob-table__row {
  display: flex; gap: var(--space-3); padding: 9px 14px; align-items: center;
}
.ob-table__head { background: var(--paper-warm); font-size: var(--text-xs); color: var(--ink-faint); font-weight: var(--weight-semibold); }
.ob-table__row { border-top: var(--hairline) solid var(--border-soft); font-size: 13.5px; padding: 11px 14px; }
.ob-table__col--name { flex: 1; }
.ob-table__col--sets { width: 70px; color: var(--text-muted); }
.ob-table__col--rpe  { width: 44px; color: var(--text-muted); }

.ob-body-copy { font-size: 14.5px; line-height: var(--leading-relaxed); color: #3a352c; margin: 0 0 var(--space-4); }
.ob-body-copy--muted { font-size: 13.5px; line-height: 1.55; color: var(--text-muted); margin: 0; }

/* -- Nutrition -- */
.ob-macro-row { display: flex; gap: 14px; margin-bottom: var(--space-4); }
.ob-macro { flex: 1; }
.ob-macro__label { font-size: var(--text-xs); color: var(--ink-faint); margin-bottom: 5px; }
.ob-macro__track { height: 7px; border-radius: 5px; background: var(--canvas); }
.ob-macro__fill { width: 0; height: 100%; border-radius: 5px; }
.ob-macro__fill--protein { background: var(--primary); }
.ob-macro__fill--carbs { background: var(--accent); }
.ob-macro__fill--fat { background: var(--provider); }

.ob-meal-grid { display: grid; grid-template-columns: auto 1fr 1fr 1fr; gap: var(--space-2); margin-bottom: var(--space-4); }
.ob-meal-grid__head { font-size: var(--text-xs); color: var(--ink-faint); text-align: center; }
.ob-meal-grid__day { font-size: var(--text-sm); color: var(--ink-faint); align-self: center; }
.ob-meal { border: var(--hairline) solid var(--border-soft); border-radius: var(--radius-sm); padding: var(--space-2); }
.ob-meal__name { font-size: 12.5px; font-weight: var(--weight-semibold); }
.ob-meal__cal { font-size: var(--text-xs); color: var(--ink-faint); }

.ob-callout {
  display: flex; align-items: center; gap: 9px;
  padding: 11px 14px;
  border: var(--hairline) solid var(--primary-border);
  border-radius: var(--radius-md);
  background: var(--primary-tint-2);
}
.ob-callout span:last-child { font-size: var(--text-ui); color: var(--primary); font-weight: var(--weight-semibold); }

/* -- Brief -- */
.ob-listing-row { display: flex; gap: 14px; margin-bottom: var(--space-4); }
.ob-listing { flex: 1; border: var(--hairline) solid var(--border-soft); border-radius: var(--radius-md); overflow: hidden; }
.ob-listing__photo {
  height: 78px;
  background: var(--hatch);
  display: flex; align-items: center; justify-content: center;
  font: var(--weight-semibold) var(--text-2xs) var(--font-mono);
  color: var(--ink-ghost);
}
.ob-listing__body { padding: 11px; }
.ob-listing__price-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; }
.ob-listing__price { font-family: var(--font-display); font-size: 17px; }
.ob-listing__meta { font-size: var(--text-sm); color: var(--text-muted); }
.ob-listing__sub { font-size: var(--text-sm); color: var(--ink-faint); margin: 4px 0 9px; }
.ob-listing__actions { display: flex; gap: 6px; }
.ob-listing__save, .ob-listing__hide {
  font: var(--weight-semibold) var(--text-xs) var(--font-sans);
  padding: 5px 10px; border-radius: var(--radius-sm);
}
.ob-listing__save { background: var(--primary); color: #fff; }
.ob-listing__hide { background: var(--hatch-b); color: var(--text-muted); }

.ob-map-placeholder {
  height: 90px;
  border-radius: var(--radius-md);
  background: var(--hatch);
  display: flex; align-items: center; justify-content: center;
  font: var(--weight-semibold) var(--text-2xs) var(--font-mono);
  color: var(--ink-ghost);
}

/* -- Finance -- */

/* Desktop: widen the auth / onboarding cards and add generous padding so the
   flow reads as desktop-native instead of a phone screen floating in space.
   Single-field cards stay comfortably narrow. */
@media (min-width: 768px) {
  .ob-screen--sm { max-width: 480px; }
  .ob-signin-card { padding: 44px 40px; }
  .ob-magic-card { padding: 44px 40px; }
}
/* ---------------------------------------------------------------
   joris — Home reader + timeline (1c: Journal & Reader)
   --------------------------------------------------------------- */
.reader-shell {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
  width: 100%;
  background: var(--surface-page);
}

/* ============ Sidebar / timeline rail ============ */
.reader-sidebar {
  width: 260px;
  flex: none;
  display: flex;
  flex-direction: column;
  border-right: var(--hairline) solid var(--border-soft);
  background: var(--surface-raised);
  height: 100vh;
  height: 100dvh;
  position: sticky;
  top: 0;
}
.reader-sidebar__brand {
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: var(--hairline) solid var(--border-soft);
}
.reader-sidebar__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.reader-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: var(--space-2);
}
.reader-timeline-group__label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
  margin: var(--space-3) 0 4px;
  text-transform: uppercase;
}
.reader-timeline-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 8px;
  border-radius: var(--radius-sm);
  color: var(--text-body);
}
.reader-timeline-row:hover { background: var(--paper); }
.reader-timeline-row.is-active { background: var(--primary-tint); }
.reader-timeline-row__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  background: var(--ink-faint);
}
.reader-timeline-row__dot--success { background: var(--primary); }
.reader-timeline-row__dot--failed { background: var(--accent); }
.reader-timeline-row__dot--pending { background: var(--provider); }
.reader-timeline-row__text { display: flex; flex-direction: column; min-width: 0; }
.reader-timeline-row__title {
  font-size: var(--text-ui);
  font-weight: var(--weight-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.reader-timeline-row__meta { font-size: var(--text-xs); color: var(--text-faint); }
.reader-timeline-empty { color: var(--text-faint); font-size: var(--text-ui); padding: var(--space-2); }

.reader-sidebar__footer {
  padding: var(--space-3);
  border-top: var(--hairline) solid var(--border-soft);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.reader-sidebar__links { display: flex; gap: 8px; justify-content: center; }

/* ============ Main reader pane ============ */
.reader-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
/* Sticky delivery top bar (design: Delivery.dc.html main top bar). */
.reader-topbar {
  height: 56px; flex: none; display: flex; align-items: center; gap: 9px;
  padding: 0 22px; border-bottom: 1.5px solid #e6e1d6;
  background: rgba(245, 242, 236, .86); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
  position: sticky; top: 0; z-index: 5; overflow-x: auto;
}
.reader-topbar__name { font-family: 'Newsreader', serif; font-weight: 600; font-size: 13.5px; white-space: nowrap; flex: none; }
.reader-topbar__spacer { flex: 1; }
.rtop-chip {
  font: 600 11px 'Hanken Grotesk', system-ui, sans-serif; padding: 5px 10px; border-radius: 999px;
  background: #f1ede4; color: #6f6a5e; white-space: nowrap; flex: none;
}
.rtop-chip--web { background: #eef4f1; color: #2f6d5b; }

.ver-nav { display: flex; align-items: center; background: #efece4; border: 1.5px solid #e6e1d6; border-radius: 999px; padding: 2px; flex: none; }
.ver-nav a, .ver-nav span { font: 600 11px 'Hanken Grotesk', system-ui, sans-serif; padding: 5px 10px; border-radius: 999px; color: #9a9384; text-decoration: none; white-space: nowrap; }
.ver-nav a:hover { color: #2f6d5b; text-decoration: none; }
.ver-nav .is-current { background: #2f6d5b; color: #fff; }
.ver-nav .is-disabled { opacity: .4; }

.rtop-btn { font: 600 12px 'Hanken Grotesk', system-ui, sans-serif; padding: 8px 13px; border-radius: 10px; cursor: pointer; flex: none; text-decoration: none; }
.rtop-btn--ghost { border: 1.5px solid #e6e1d6; background: #fff; color: #26221b; }
.rtop-btn--ghost:hover { background: #faf8f3; text-decoration: none; }
.rtop-btn--primary { border: none; background: #2f6d5b; color: #fff; box-shadow: 0 3px 10px rgba(47, 109, 91, .25); }
.rtop-btn--primary:hover { background: #28604f; text-decoration: none; }
.rtop-btn--primary:disabled, .rtop-btn--primary[disabled] { background: #9db8ae; box-shadow: none; cursor: default; pointer-events: none; }
.rtop-btn--primary form, .rtop-btn--primary { margin: 0; }

/* Copy the delivery as markdown. Chrome, not template: every delivery gets the
   same button in the same corner, so the export doesn't depend on which shape
   the run produced. The glyph swaps to a tick on success (draft.js). */
.rtop-copy {
  position: relative; width: 34px; height: 34px; flex: none; padding: 0;
  border: 1.5px solid #e6e1d6; border-radius: 10px; background: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  color: #6f6a5e; cursor: pointer;
}
.rtop-copy:hover { background: #faf8f3; color: #26221b; }
.rtop-copy svg { width: 16px; height: 16px; display: block; }
.rtop-copy .rtop-copy__ok, .rtop-copy.is-copied .rtop-copy__i { display: none; }
.rtop-copy.is-copied { color: #2f6d5b; border-color: #cfe0d9; background: #f4f8f6; }
.rtop-copy.is-copied .rtop-copy__ok { display: block; }
/* Same scoped tooltip as the Article's export had — the app has no primitive.
   It sits to the LEFT, vertically centred, rather than below: .reader-topbar
   carries `overflow-x: auto` (its contents genuinely overflow on a narrow
   desktop), and overflow-x on its own is not a thing — the computed overflow-y
   becomes `auto` with it, so the bar is a scroll container that clips in both
   directions. Hung below the button, ~19px of a 24px tooltip was cut off by the
   bar's 56px floor. Beside it, the whole tooltip is inside that 56px. */
.rtop-copy::after {
  content: attr(data-tip);
  position: absolute; right: calc(100% + 7px); top: 50%; transform: translateY(-50%);
  font: 500 11.5px/1 'Hanken Grotesk', system-ui, sans-serif; white-space: nowrap;
  padding: 6px 9px; border-radius: 7px; background: #26221b; color: #fff;
  opacity: 0; transition: opacity .12s; pointer-events: none; z-index: 3;
}
.rtop-copy:hover::after, .rtop-copy:focus-visible::after { opacity: 1; }
.rtop-copy.is-copied::after { content: none; }

/* Reopen button — only visible in focus mode. */
.reader-topbar__reopen {
  width: 34px; height: 34px; flex: none; border-radius: 9px; border: 1.5px solid #e6e1d6; background: #fff;
  display: none; align-items: center; justify-content: center; color: #6f6a5e; cursor: pointer;
}
.reader-topbar__reopen:hover { background: #faf8f3; }
.reader-topbar__reopen svg { width: 17px; height: 17px; }
.reader-shell--focus .reader-topbar__reopen { display: flex; }
.reader-shell--focus .reader-sidebar,
.reader-shell--focus .ctx { display: none; }

/* The reader's mobile sections strip (shared/_reader_nav). Nothing above
   720px: the .ctx column is standing open there and says the same thing with
   more room. See the mobile block near the end of this file. */
.rnav { display: none; }

/* Mobile-only "Versions" pill — opens .ctx as a slide-in drawer instead of
   the desktop's persistent column. Hidden on desktop; see the mobile block
   near the end of this file for its @media (max-width: 720px) treatment. */
.reader-topbar__versions {
  display: none; align-items: center; gap: 5px;
  font: 600 11.5px "Hanken Grotesk", system-ui, sans-serif; color: #2f6d5b;
  padding: 6px 10px; border-radius: 9px; border: 1.5px solid #cfe1d9; background: #eef3f1;
  cursor: pointer; flex: none;
}
.reader-topbar__versions svg { width: 15px; height: 15px; }
.ctx-scrim { display: none; }

.chip--disabled { opacity: .4; cursor: default; }

/* ============ Context panel (per-routine runs) ============ */
.ctx {
  width: 260px; flex: none; height: 100vh; height: 100dvh; position: sticky; top: 0;
  display: flex; flex-direction: column;
  border-right: 1.5px solid #ece8df; background: #faf8f2;
}
.ctx__head { height: 56px; flex: none; display: flex; align-items: center; gap: 8px; padding: 0 10px 0 16px; border-bottom: 1.5px solid #ece8df; }
.ctx__name { flex: 1; min-width: 0; font-family: 'Newsreader', serif; font-size: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ctx__focus { width: 30px; height: 30px; flex: none; border: none; background: none; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #9a9384; cursor: pointer; }
.ctx__focus:hover { background: #efece4; }
.ctx__focus svg { width: 17px; height: 17px; }

/* Mode switch: this routine / all routines. Segmented control, same shape as
   the settings ones (.prof-seg) — a real two-state control in place of the
   inert "All" chip that used to imply a filter the panel never had. */
.ctx__modes {
  flex: none; display: flex; gap: 3px; margin: 12px 12px 8px; padding: 3px;
  background: #f1ede4; border-radius: 11px;
}
.ctx__mode {
  flex: 1; font: 600 12px 'Hanken Grotesk', system-ui, sans-serif; padding: 7px 8px;
  border: none; border-radius: 9px; background: none; color: #8f8877; cursor: pointer;
}
.ctx__mode:hover { color: #57513f; }
.ctx__mode.is-on { background: #fff; color: #322a1c; box-shadow: 0 1px 3px rgba(50,42,28,.10); }

/* Only one pane shows at a time; the head label follows the mode. */
.ctx__pane--all, .ctx__name--all { display: none; }
.ctx--all .ctx__pane--one, .ctx--all .ctx__name--one { display: none; }
.ctx--all .ctx__pane--all { display: block; }
.ctx--all .ctx__name--all { display: inline; }

/* All-routines rows: one per routine, its latest run. */
.ctx-rrow {
  display: block; padding: 11px 12px; margin-bottom: 8px; border-radius: 12px;
  border: 1.5px solid #e6ded1; background: #fff; text-decoration: none;
}
.ctx-rrow:hover { border-color: #cfe0d9; }
.ctx-rrow.is-current { border-color: #a9cabd; background: #f7fbf9; }
.ctx-rrow.is-paused { opacity: .62; }
.ctx-rrow__top { display: flex; align-items: center; gap: 7px; }
.ctx-rrow__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #2f6d5b; }
.ctx-rrow__dot--failed { background: #b45b3e; }
.ctx-rrow__dot--pending { background: #c2bbac; }
.ctx-rrow__name {
  flex: 1; min-width: 0; font-weight: 600; font-size: 14px; color: #322a1c;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ctx-rrow__ver { flex: none; font-size: 12px; color: #a49d8d; }
.ctx-rrow__meta {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  margin-top: 3px; padding-left: 15px; font-size: 12.5px; color: #9a9384;
}
.ctx-rrow__tag {
  font-size: 10px; font-weight: 700; letter-spacing: .4px; padding: 2px 6px;
  border-radius: 5px; background: #efece4; color: #8f8877;
}
.ctx-rrow__tag--flag { background: #f7e4de; color: #a3564c; }

.ctx__body { flex: 1; overflow: auto; padding: 4px 12px 12px; }

/* Routine card wrapping the version timeline */
.ctx-card { border: 1.5px solid #cfe0d9; border-radius: 12px; background: #fff; padding: 10px 10px 9px; }
.ctx-card__meta { font-size: 11px; color: #9a9384; margin-left: 15px; }

.ctx-runs { margin: 11px 0 2px 4px; border-left: 1.5px solid #ece8df; padding-left: 12px; display: flex; flex-direction: column; gap: 2px; }
.ctx-run { display: flex; align-items: center; gap: 8px; padding: 6px 8px; border-radius: 8px; text-decoration: none; color: inherit; }
.ctx-run:hover { background: #efece4; text-decoration: none; }
.ctx-run.is-active { background: #eef3f1; }
.ctx-run__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #9a9384; }
.ctx-run__dot--success { background: #2f6d5b; }
.ctx-run__dot--failed { background: #b45b3e; }
.ctx-run__dot--pending { background: #c8a24b; }
.ctx-run__label { flex: 1; font-weight: 600; font-size: 12px; color: #26221b; }
.ctx-run.is-active .ctx-run__label { color: #2f6d5b; }
.ctx-run__time { font-size: 11px; color: #9a9384; white-space: nowrap; }
.ctx__empty { color: #9a9384; font-size: 12px; padding: 4px; }
.ctx__legend { display: flex; gap: 12px; padding: 14px 6px 0; font-size: 10.5px; color: #9a9384; }
.ctx__legend span { display: flex; align-items: center; gap: 5px; }
.ctx__legend i { width: 7px; height: 7px; border-radius: 50%; display: inline-block; }

.reader-body {
  flex: 1;
  padding: var(--space-6) clamp(var(--space-5), 8vw, 80px);
  max-width: 860px;
  width: 100%;
  margin: 0 auto;

  /* The reader's own chrome — the run notice, the "joris noticed" advisory and
     the honesty line — sits outside the delivery but has to line up with it,
     and each output template picks its own column: 660px centred for the TL;DR
     brief, 940px for nutrition, the full 1040px for the house-hunt family
     (whose article starts at the left edge, beside a sidebar). Left-aligned
     720px is right only for that last group and for plain markdown, so on a
     brief the advisory sat 110px to the left of the delivery it was about.
     These two variables carry the column; each template stylesheet sets them
     for the columns it centres. */
  --reader-col: 720px;
  --reader-col-inline: 0;
}
/* The Article is read start to finish rather than scanned, so it opens with
   more air above the kicker than the briefing templates do. Doubled class for
   the same reason as the mobile rule below: the 16px it overrides comes from
   `.reader-body--template` in delivery_template.css, which loads after this. */
.reader-body.reader-body--article { padding-top: 31px; }

.reader-meta {
  font-size: var(--text-sm);
  color: var(--text-faint);
  margin-bottom: var(--space-3);
}

/* A run takes a couple of minutes, so the waiting state narrates the phase it's
   in rather than spinning silently. Steps come from the routine (no web step for
   a thinking routine, no formatting step without a template). */
.reader-running {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  background: var(--surface-raised);
  border-radius: var(--radius-lg);
  color: var(--text-muted);
}
.reader-running__head { display: flex; align-items: center; gap: var(--space-2); font-weight: 600; color: var(--ink); }
.reader-running__note { margin: 0; font-size: 12px; color: var(--text-muted); }

.reader-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.reader-step { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--text-muted); }
.reader-step__dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: var(--border-strong); transition: background .2s, box-shadow .2s;
}
.reader-step.is-done { color: var(--ink); }
.reader-step.is-done .reader-step__dot { background: var(--primary); }
/* The step in flight: filled and haloed, so the eye lands on it. */
.reader-step.is-now { color: var(--ink); font-weight: 600; }
.reader-step.is-now .reader-step__dot { background: var(--primary); box-shadow: 0 0 0 3px rgba(47,109,91,.18); }
/* Sets the expectation for a first run while it is still in flight: v1 is a
   draft to correct, not the finished thing. Separated from the steps by a rule
   because it is a different register — the steps report, this explains — and
   sized above them so it doesn't read as more progress chatter. */
.reader-firstrun {
  border-top: var(--hairline) solid var(--border-soft);
  padding-top: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.reader-firstrun__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: var(--weight-semibold);
  color: var(--ink);
}
.reader-firstrun__text {
  margin: 0;
  font-size: 13.5px;
  line-height: var(--leading-relaxed);
  color: var(--text-body);
}
.reader-firstrun__text strong { color: var(--ink); font-weight: 600; }

.reader-running__spinner {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  border-top-color: var(--primary);
  animation: spin .8s linear infinite;
  flex: none;
}

.reader-error {
  padding: var(--space-4);
  background: rgba(180,91,62,.08);
  border: var(--hairline) solid rgba(180,91,62,.25);
  border-radius: var(--radius-lg);
  color: var(--ink);
}
.reader-error p { color: var(--text-muted); white-space: pre-wrap; }

/* ============ Rendered markdown document ============ */
.reader-document {
  font-family: var(--font-sans);
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-body);
}
.reader-document h1, .reader-document h2, .reader-document h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  color: var(--ink);
  margin: var(--space-5) 0 var(--space-2);
}
.reader-document h1 { font-size: var(--display-lg); font-variant-numeric: oldstyle-nums; }
.reader-document h2 { font-size: var(--display-md); font-variant-numeric: oldstyle-nums; }
.reader-document h3 { font-size: var(--display-sm); font-variant-numeric: oldstyle-nums; }
/* Space is the only thing telling a reader where one item ends and the next
   begins, and 20px above a heading against 12px between paragraphs was not
   enough of a difference to read as a break — a five-item briefing came out as
   one even grey column. Much more above a heading than below it, so a heading
   sits with the text it introduces rather than floating between two blocks. */
.reader-document h1 { margin-top: var(--space-8); }
.reader-document h2 { margin-top: var(--space-8); }
.reader-document h3 { margin-top: var(--space-6); }
.reader-document > :first-child { margin-top: 0; }
.reader-document p { margin: 0 0 var(--space-4); }
.reader-document ul, .reader-document ol { margin: 0 0 var(--space-4); padding-left: 1.4em; }
.reader-document li { margin-bottom: var(--space-2); }
.reader-document li > ul, .reader-document li > ol { margin: var(--space-2) 0 0; }
/* Links have to look clickable. The global reset in base.css strips colour and
   underline from every `a` — right for nav, cards and rows, wrong inside a
   delivery, where "Ver notícia no PÚBLICO" is the one thing you are meant to
   click and was rendering as plain body text. Listed per container rather than
   as a bare descendant so the empty `a.anchor` commonmarker puts in every
   heading stays invisible. */
.reader-document p a,
.reader-document li a,
.reader-document td a,
.reader-document blockquote a {
  color: var(--primary);
  text-decoration: underline;
  text-decoration-color: var(--primary-border);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}
.reader-document p a:hover,
.reader-document li a:hover,
.reader-document td a:hover,
.reader-document blockquote a:hover {
  color: var(--primary-press);
  text-decoration-color: currentColor;
}
/* A source URL pasted as its own text can be longer than the column. Break it
   rather than letting one link set the width of the whole delivery. */
.reader-document a { overflow-wrap: anywhere; }
.reader-document strong { font-weight: var(--weight-semibold); }
.reader-document blockquote {
  margin: var(--space-3) 0;
  padding: var(--space-2) var(--space-3);
  border-left: 3px solid var(--primary-border);
  color: var(--text-muted);
}
.reader-document code {
  font-family: var(--font-mono);
  font-size: .92em;
  background: var(--paper-warm);
  padding: 1px 5px;
  border-radius: 4px;
}
.reader-document pre {
  background: var(--paper-warm);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  overflow-x: auto;
}
.reader-document pre code { background: none; padding: 0; }
.reader-document table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-3) 0;
  font-size: var(--text-md);
}
.reader-document th, .reader-document td {
  text-align: left;
  vertical-align: top;
  padding: 9px 12px;
  border-bottom: var(--hairline) solid var(--border-soft);
}
.reader-document th {
  background: var(--paper-warm);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
  white-space: nowrap;
}
.reader-document tbody tr:hover { background: var(--paper-warm); }

/* Every markdown table is wrapped in .md-table (DeliveryRenderer.wrap_tables!)
   so a wide one scrolls inside its own box. The table keeps `display: table`
   — the mobile rule used to set `display: block` on the table itself, which
   throws away the table layout algorithm: the header's tinted background
   stopped where its text stopped while the row rules ran full width.
   max-content + min-width:100% is the idiom the admin tables already use —
   a narrow table fills the column, a wide one overflows and scrolls. */
.md-table { margin: var(--space-3) 0; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.md-table > table { margin: 0; width: max-content; min-width: 100%; }
.reader-document hr { border: none; border-top: var(--hairline) solid var(--border-soft); margin: var(--space-5) 0; }
.reader-document img { max-width: 100%; border-radius: var(--radius-md); }

/* Desktop: keep the prose column at its centered reading width, but let wide
   TABLES break out symmetrically (left + right) — centered on the same axis —
   so dense data isn't cramped. Capped so it never overflows the 260px sidebar. */
@media (min-width: 1200px) {
  .reader-document > .md-table {
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    max-width: min(1180px, calc(100vw - 324px));
  }
}
/* Narrow screens: tighter cells, and the scroll is the wrapper's job. Cells
   wrap their text rather than being held on one line — on a phone `nowrap`
   turned a two-word heading into a horizontal scroll of its own. */
@media (max-width: 640px) {
  .reader-document th, .reader-document td { padding: 8px 10px; }
  .reader-document th { font-size: var(--text-2xs); }
}

/* ============ Grounding citations ============ */
.reader-sources {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: var(--hairline) solid var(--border-soft);
}
.reader-sources__label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--space-2);
}
.reader-sources__list {
  margin: 0;
  padding-left: 1.3em;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.reader-sources__list li { font-size: var(--text-md); }
.reader-sources__link { color: var(--text-link); }
.reader-sources__link:hover { text-decoration: underline; }

/* Feedback panel — captures a note that's fed into the routine's next run. */
.reader-feedback {
  margin-top: var(--space-6);
  padding-top: var(--space-4);
  border-top: var(--hairline) solid var(--border-soft);
}
.reader-feedback__label {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: var(--space-2);
}
.reader-feedback__saved {
  font-size: var(--text-sm);
  color: var(--primary);
  margin: 0 0 var(--space-2);
}

/* ── Mobile (<=720px): the versions/runs panel becomes a slide-in drawer ──
   The global mobile top bar (app_shell.css) already replaces the icon
   spine; this handles the delivery-page-specific runs panel on top of it. */
@media (max-width: 720px) {
  /* Folded into the global mobile bar — see deliveries/show.html.erb. It held
     745px of content in a 390px viewport, so half of it (including both
     actions) sat off-screen behind a horizontal scroll nobody discovers. */
  .reader-topbar { display: none; }

  .reader-topbar__reopen { display: none; }
  .reader-topbar__versions { display: flex; }
  .ctx__focus { display: none; }

  /* The clamp above resolves to 8vw — ~31px a side on a phone, the widest
     gutter in the app on the one surface where line length matters most.
     Use the page gutter instead. */
  .reader-body { padding-left: var(--page-gutter); padding-right: var(--page-gutter); }

  /* The mobile bar sits directly above, so the template reader's 16px leaves
     the kicker looking stuck to it. The doubled class is deliberate: the 16px
     comes from `.reader-body--template` in delivery_template.css, which loads
     after this file, so a single-class selector here would lose the cascade. */
  .reader-body,
  .reader-body.reader-body--template { padding-top: 36px; }

  /* 26px leaves the last card sitting on the bottom edge, and on a phone that
     edge is shared with the browser's own chrome. Give the end of the page
     somewhere to finish. */
  .reader-body { padding-bottom: 72px; }

  .ctx {
    position: fixed; top: 0; right: 0; bottom: 0; width: 86%; max-width: 300px;
    height: auto; z-index: 56; border-right: none;
    box-shadow: -6px 0 26px rgba(50, 42, 28, .22);
    transform: translateX(102%);
    transition: transform .24s ease;
  }

  /* Focus mode hides the reader's persistent side column. Here there is no side
     column — the panel is a drawer — so the rule had nothing to hide and hid the
     drawer instead. `display: none` cannot be slid in by a transform, so tapping
     the version pill faded the scrim over nothing.
     It was also a one-way door: focus is remembered in localStorage and
     re-applied on load, and the only control that turns it off lives in
     .reader-topbar, which is display:none at this width. Turn focus on once at
     any size and the phone loses its version switcher permanently. */
  .reader-shell--focus .ctx { display: block; }
  .reader-shell--versions-open .ctx { transform: translateX(0); }

  /* ── The sections strip ────────────────────────────────────────────
     Same rows, spacing and pill treatment as .snav and .adm-nav at this
     width — three surfaces, one answer to "where am I and what else is
     there". .ctx is position:fixed here, so the strip and .reader-main are
     the only children left in flow and they stack. */
  .reader-shell { flex-direction: column; }
  .rnav {
    display: block; order: 1; flex: none;
    border-bottom: 1.5px solid #ece8df; background: #faf8f2;
  }
  .rnav__list {
    display: flex; flex-direction: row; gap: 7px;
    overflow-x: auto; overflow-y: hidden;
    padding: 10px var(--page-gutter);
    scrollbar-width: none;
  }
  .rnav__list::-webkit-scrollbar { display: none; }
  .rnav__row {
    flex: none; display: flex; align-items: center; gap: 7px;
    padding: 8px 13px; border-radius: 999px;
    background: #fff; border: 1.5px solid #e6ded1;
    text-decoration: none; transition: border-color .12s, background .12s;
  }
  .rnav__row.is-active { background: #f7fbf9; border-color: #a9cabd; }
  .rnav__label {
    font-size: 13px; font-weight: 600; color: #26221b; white-space: nowrap;
  }
  .rnav__dot { width: 7px; height: 7px; flex: none; border-radius: 50%; background: #b45b3e; }
  .reader-main { order: 2; }
  /* The strip sits directly above, so the body no longer needs to clear the
     mobile bar on its own. */
  .reader-body,
  .reader-body.reader-body--template { padding-top: 26px; }

  /* The drawer is the run history now, nothing else — its other pane is the
     strip above. Forced rather than defaulted: the one/all choice is
     remembered in localStorage, so a reader left on "all" at desk width would
     otherwise open a drawer with no versions in it, from a chip that says v3. */
  .ctx__modes { display: none; }
  .ctx--all .ctx__pane--one { display: block; }
  .ctx--all .ctx__name--one { display: inline; }
  .ctx--all .ctx__pane--all, .ctx--all .ctx__name--all { display: none; }

  .ctx-scrim {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(38, 34, 27, .34); opacity: 0; pointer-events: none;
    transition: opacity .22s;
  }
  .reader-shell--versions-open .ctx-scrim { opacity: 1; pointer-events: auto; }
}

/* ==========================================================================
   Leave this run out / left-out state
   Shared by every delivery reader (plain markdown and all nine templates), so
   it carries its own neutral namespace rather than any one reader's prefix
   (hh-, tr-, nu-, db-). Sits under whichever feedback card the template shows.
   ========================================================================== */
.dexcl {
  display: flex; justify-content: space-between; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 14px; border-top: 1px dashed #dfe7e3;
}
.dexcl__txt { font-size: 12px; color: #9a9384; }
.dexcl__btn {
  font: 600 12.5px var(--font-sans, inherit); padding: 8px 14px; border-radius: 10px;
  border: 1.5px solid #d8cfc4; background: transparent; color: #6f6a5e; cursor: pointer;
}
.dexcl__btn:hover { border-color: #b9736a; color: #a3564c; background: #fdf6f5; }

/* The shaping-phase version of the same control (Routine#shaping?): a panel
   rather than a row, because it has to say what leaving a run out costs before
   someone does it, and it carries the move that actually fixes an early miss.
   Amber, like .reader-notice — this is a caveat about one run, not an error, and
   it must not read as the page's primary action next to "Save for next run". */
.dexcl-miss {
  margin-top: 16px; padding: 14px 16px;
  border: 1.5px solid #e0cd9a; border-radius: 13px; background: #fdf8ec;
}
.dexcl-miss__head { font-size: 13.5px; font-weight: 600; color: #6f5a1f; margin-bottom: 6px; }
.dexcl-miss__text { margin: 0 0 12px; font-size: 13px; line-height: 1.55; color: #7a6a3f; }
/* button_to wraps each button in its own form, so the row is laid out on the
   forms and the buttons fill them — otherwise they stack. */
.dexcl-miss__acts { display: flex; flex-wrap: wrap; gap: 10px; }
.dexcl-miss__acts form { margin: 0; }
.dexcl-miss__btn {
  font: 600 12.5px var(--font-sans, inherit); padding: 8px 14px; border-radius: 10px;
  border: 1.5px solid #ddc98f; background: #fff; color: #7a6224; cursor: pointer;
}
.dexcl-miss__btn:hover { background: #fbf3e0; }
/* The recommended one of the two, and still not a primary button: it ends in
   the Direction editor, which is a bigger detour than "put this one aside". */
.dexcl-miss__btn--go { background: #f7eed6; border-color: #d3b978; }
/* The escape hatch, for the early run that is just a fluke. Chromeless so the
   pair reads as one recommendation and one way past it, rather than a choice
   between two equals. */
.dexcl-miss__btn--quiet {
  border-color: transparent; background: transparent; color: #8b7a4e; font-weight: 500;
}
.dexcl-miss__btn--quiet:hover { background: #f7f0dd; color: #7a6224; }

/* The left-out state replaces the feedback card entirely. */
.dexcl-out {
  max-width: 720px; margin-top: 8px; border: 1.5px solid #e2d8cd; border-radius: 16px;
  background: #faf8f5; overflow: hidden; scroll-margin-top: 20px;
}
.dexcl-out__head {
  padding: 13px 20px; background: #f4efe8; border-bottom: 1.5px solid #e2d8cd;
  font-size: 14px; color: #8a6f60;
}
.dexcl-out__head span { color: #a09684; font-weight: 400; }
.dexcl-out__body { padding: 18px 20px; }
.dexcl-out__note { margin: 0 0 14px; font-size: 13px; color: #8f8877; line-height: 1.55; }
.dexcl-out__undo {
  font: 600 12.5px var(--font-sans, inherit); padding: 8px 14px; border-radius: 10px;
  border: 1.5px solid #cfe0d9; background: #fff; color: #2f6d5b; cursor: pointer;
}
.dexcl-out__undo:hover { background: #f4f8f6; }

/* ==========================================================================
   Delivery notice — a caveat on a delivery that is otherwise readable.
   Not the error state: there IS something to read, it just stops short. Amber
   rather than red for exactly that reason.
   ========================================================================== */
.reader-notice {
  display: flex; gap: 12px; align-items: flex-start;
  max-width: var(--reader-col); margin: 0 var(--reader-col-inline) 22px; padding: 14px 16px;
  border: 1.5px solid #e0cd9a; border-radius: 13px; background: #fdf8ec;
}
.reader-notice__icon { flex: none; font-size: 15px; line-height: 1.5; color: #9a7b28; }
.reader-notice__body { flex: 1; min-width: 0; }
.reader-notice__text { margin: 0 0 10px; font-size: 13.5px; line-height: 1.55; color: #6f5a1f; }
.reader-notice__btn {
  font: 600 12.5px var(--font-sans, inherit); padding: 7px 13px; border-radius: 9px;
  border: 1.5px solid #ddc98f; background: #fff; color: #7a6224; cursor: pointer;
}
.reader-notice__btn:hover { background: #fbf3e0; }
.reader-notice__btn:disabled { opacity: .55; cursor: default; }

/* The honesty line under a finished delivery. Deliberately quiet — it is a
   standing fact about the tool, not a warning about this particular run (that's
   .reader-advice's job, and it looks different for exactly that reason). */
.reader-honest {
  max-width: var(--reader-col); margin: 34px var(--reader-col-inline) 8px; padding-top: 16px;
  border-top: 1.5px solid #ece8df;
  font-size: 12px; line-height: 1.6; color: #9a9384;
}

/* "Something joris noticed" — the post-run review. Deliberately NOT the error
   palette: this is an observation about a delivery that is otherwise readable
   and shown in full, so it borrows the reader's own ink rather than shouting. */
.reader-advice {
  max-width: var(--reader-col); margin: 0 var(--reader-col-inline) 22px; padding: 14px 16px;
  border: 1.5px solid #cfe0d9; border-radius: 13px; background: #f5faf8;
}
.reader-advice__head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
/* Closing it is the reader's call and it sticks (see Delivery#advisory_dismissed_at),
   so the control is a real form rather than a decoration that forgets. Quiet:
   the note is worth reading once, and the × is for after you have. */
.reader-advice__closeform { margin-left: auto; line-height: 0; }
.reader-advice__close {
  border: 0; background: none; cursor: pointer; padding: 2px 4px;
  font: 400 16px/1 var(--font-sans, inherit); color: #9ab5aa; border-radius: 6px;
}
.reader-advice__close:hover { color: #2f6d5b; background: #e7f1ed; }
.reader-advice__icon { font-size: 14px; line-height: 1; }
.reader-advice__title { font: 700 12px var(--font-sans, inherit); letter-spacing: .3px; color: #2f6d5b; }
.reader-advice__text { margin: 0 0 8px; font-size: 13.5px; line-height: 1.6; color: #3a352c; }
.reader-advice__foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.reader-advice__btn {
  font: 600 12.5px var(--font-sans, inherit); padding: 7px 13px; border-radius: 9px;
  border: 1.5px solid #a9cabd; background: #fff; color: #2f6d5b; cursor: pointer;
}
.reader-advice__btn:hover { background: #eef4f1; }
.reader-advice__btn:disabled { opacity: .55; cursor: default; }
.reader-advice__note { font-size: 11.5px; color: #9a9384; }

/* Per-step timing on the run progress card. The clock time each step started
   and how long it took — the pair that distinguishes a slow run from a stuck
   one, which a step name on its own cannot. */
.reader-step__time { margin-left: auto; font-size: 11px; color: #9a9384;
  font-variant-numeric: tabular-nums; }
.reader-step__dur { min-width: 52px; text-align: right; font-size: 11px; color: #b3ac9d;
  font-variant-numeric: tabular-nums; }
.reader-step.is-now .reader-step__dur { color: #a4712f; font-weight: 600; }

/* ---------------------------------------------------------------
   Delivery provenance (design handoff §6) — "THIS RUN USED" chip
   strip under the run meta, plus its full-log disclosure. Only
   rendered when a run touched or skipped a connection; see
   deliveries/_tool_activity.html.erb.
   --------------------------------------------------------------- */
.ta-strip {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px;
  max-width: var(--reader-col); margin: 0 var(--reader-col-inline) 22px;
  padding: 11px 13px; border-radius: 11px; background: #efeae0;
}
.ta-strip__label {
  flex: none; align-self: center; margin-top: 1px;
  font: 700 10px 'Hanken Grotesk', system-ui, sans-serif; letter-spacing: .6px; color: #8f8877;
}

/* One pill per used connection ("Calendar · read 6 events") or the web
   search count ("Web · 4 searches"). Counts, never contents. */
.ta-pill {
  align-self: center;
  font: 600 12.5px 'Hanken Grotesk', system-ui, sans-serif; padding: 6px 11px; border-radius: 999px;
  background: #fff; border: 1.5px solid #e2ddd0; color: #3a352c;
}

/* A skipped connection — logged as a gap so an incomplete briefing says so
   while being read, rather than being noticed only by absence. */
.ta-pill--gap {
  display: inline-flex; align-items: center; gap: 5px;
  background: #fdf7e9; border-color: #e0c48f; color: #6f5a2c;
}
.ta-pill__mark {
  display: inline-flex; flex: none; align-items: center; justify-content: center;
  width: 14px; height: 14px; border-radius: 50%; background: #c9a24a; color: #fff;
  font: 700 9px 'Hanken Grotesk', system-ui, sans-serif; line-height: 1;
}

/* The outbound mirror: where this delivery WENT (deliveries/_sent_to).
   Provenance above the briefing is a promise being kept and earns its tinted
   box. A hand-off receipt is a footnote, so it is one — same column, same
   quiet ink and size as .reader-honest directly below it, so the two read as
   one set of end-notes rather than two competing blocks. */
.reader-sent {
  max-width: var(--reader-col); margin: 34px var(--reader-col-inline) 0; padding-top: 16px;
  border-top: 1.5px solid #ece8df;
  font-size: 12px; line-height: 1.6; color: #9a9384;
}
/* The one thing on this line worth interrupting for. */
.reader-sent--failed { color: #a04f34; }
.reader-sent__more { margin-left: 6px; color: inherit; font-weight: 600; text-decoration: underline; }
/* The rule belongs to whichever note comes first. .reader-honest carries its
   own; under the receipt it is the second line of the same group, not a new
   one, so it drops the rule and closes up. */
.reader-sent + .reader-honest { margin-top: 10px; padding-top: 0; border-top: 0; }

/* Full log — a native <details> disclosure, no JS. Always its own line under
   the pills rather than fighting them for room in the flex row. */
.ta-log { flex: 1 0 100%; }
.ta-log__summary {
  cursor: pointer; list-style: none;
  font: 600 12px 'Hanken Grotesk', system-ui, sans-serif; color: var(--primary);
}
.ta-log__summary::-webkit-details-marker { display: none; }
.ta-log__summary:hover { text-decoration: underline; }
.ta-log__body {
  display: grid; gap: 9px; margin-top: 12px; padding-top: 12px;
  border-top: 1.5px solid #e2ddd0; font-size: 13px; line-height: 1.5;
}
.ta-log__line { display: flex; gap: 11px; }
.ta-log__time {
  flex: none; font-family: ui-monospace, Menlo, monospace; font-size: 12.5px; color: #b3ac9d;
  font-variant-numeric: tabular-nums;
}
.ta-log__desc { color: #3a352c; }
/* Future-proofing: v1 only ever produces reads, but a write:true log line
   (a draft left in Gmail, say) is what people worry most about, so it
   already gets the emphasised treatment the design calls for. */
.ta-log__desc--write { color: #26221b; font-weight: 600; }
.ta-log__foot { margin: 12px 0 0; font-size: 12.5px; line-height: 1.55; color: #8f8877; }
/* -----------------------------------------------------------------
   joris — House-hunt output template (structured, interactive)
   Values mirror the Claude-Design spec (Delivery.dc.html), which
   already matches the brand palette.
   ----------------------------------------------------------------- */
.reader-body--template { max-width: 1040px; padding-top: var(--space-4); }

.hh-layout { display: flex; gap: 34px; align-items: flex-start; }
.hh-article { flex: 1; min-width: 0; max-width: 720px; }

.hh-metarow { display: flex; justify-content: space-between; align-items: center; margin-bottom: 18px; }
.hh-meta { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; }

@media (max-width: 720px) {
  /* Date and time stay together on one line; the run detail drops below.
     The date is unbreakable — a long weekday and month at the largest
     reading size will not share a row with it. */
  .hh-metarow { align-items: baseline; flex-wrap: wrap; }
  .hh-meta__sep { display: none; }
  .hh-meta__date, .hh-meta__detail { display: block; }
  .hh-meta__date { white-space: nowrap; }
}

.hh-title { font-family: var(--font-display); font-weight: 500; font-size: calc(34px * var(--reading-scale)); line-height: 1.15; margin: 0 0 6px; color: var(--ink); }
.hh-subtitle { font-size: calc(13px * var(--reading-scale)); color: #9a9384; margin-bottom: 22px; }

.hh-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 24px; }
.hh-kpi { border: 1.5px solid #e6e1d6; border-radius: 13px; padding: 14px 15px; background: #fff; }
.hh-kpi__value { font-family: var(--font-display); font-size: calc(27px * var(--reading-scale)); line-height: 1; color: var(--ink); }
.hh-kpi__value--accent { color: #b45b3e; }
.hh-kpi__label { font-size: calc(11.5px * var(--reading-scale)); color: #6f6a5e; margin-top: 6px; line-height: 1.35; }
.hh-kpi__label p { margin: 0; }

.hh-dofirst { border: 1.5px solid #cfe0d9; background: linear-gradient(180deg, #f4f8f6, #eef4f1); border-radius: 15px; padding: 18px 20px; margin-bottom: 30px; }
.hh-dofirst__body { margin: 8px 0 0; font-size: calc(14.5px * var(--reading-scale)); line-height: 1.55; color: var(--ink); }

/* "What changed since the last run" — the headline of a scheduled hunt, so it
   sits above the shortlist. Terracotta rather than the green used for
   recommendations: this is news, not advice. */
.hh-since { border: 1.5px solid #e8d3c8; background: linear-gradient(180deg, #fdf6f2, #faeee7); border-radius: 15px; padding: 18px 20px; margin-bottom: 26px; }

/* "Dropped, and why" — the two-column table from the Recipe Detail design:
   header strip, one row per drop with the failed rule in terracotta, an
   optional "+ N more" footer. Columns share the 1.6/1.2 flex split. */
.hh-dropped { border: 1.5px solid #e6e1d6; border-radius: 13px; overflow: hidden; background: #fff; margin-bottom: 34px; }
.hh-dropped__head { display: flex; gap: 12px; padding: 10px 15px; background: #faf8f3; font: 600 calc(10.5px * var(--reading-scale)) var(--font-sans); letter-spacing: .4px; color: #a49d8d; }
.hh-dropped__head span:first-child { flex: 1.6; }
.hh-dropped__head span:last-child { flex: 1.2; }
.hh-dropped__row { display: flex; gap: 12px; padding: 12px 15px; border-top: 1.5px solid #f0ece3; align-items: flex-start; }
.hh-dropped__posting { flex: 1.6; font-size: calc(12.5px * var(--reading-scale)); color: #3a352c; }
.hh-dropped__reason { flex: 1.2; font-size: calc(12.5px * var(--reading-scale)); color: #b45b3e; font-weight: 600; }
.hh-dropped__more { padding: 11px 15px; border-top: 1.5px solid #f0ece3; font-size: calc(12.5px * var(--reading-scale)); color: #a49d8d; }
.hh-since__body { margin: 8px 0 0; font-size: calc(14.5px * var(--reading-scale)); line-height: 1.55; color: var(--ink); }

.hh-pill { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; padding: 4px 9px; border-radius: 999px; }
.hh-pill--do { color: #2f6d5b; background: #dcebe5; }
.hh-pill--match { font-size: calc(9.5px * var(--reading-scale)); letter-spacing: .5px; color: #2f6d5b; background: #dcebe5; padding: 3px 8px; }
.hh-pill--since { color: #b45b3e; background: #f6e2d8; }
.hh-pill--new { font-size: calc(9.5px * var(--reading-scale)); letter-spacing: .5px; color: #b45b3e; background: #f6e2d8; padding: 3px 8px; }
.hh-pill--changed { font-size: calc(9.5px * var(--reading-scale)); letter-spacing: .3px; font-weight: 600; color: #6f6a5e; background: #efeae0; padding: 3px 8px; }

.hh-h2 { font-family: var(--font-display); font-weight: 500; font-size: calc(21px * var(--reading-scale)); margin: 0 0 4px; scroll-margin-top: 20px; color: var(--ink); }
.hh-note { font-size: calc(13px * var(--reading-scale)); color: #9a9384; margin: 0 0 16px; }
.hh-verdict { font-size: calc(14.5px * var(--reading-scale)); line-height: 1.65; color: #3a352c; margin: 6px 0 34px; }

.hh-cards { display: flex; flex-direction: column; gap: 11px; margin-bottom: 34px; }
.hh-card { border: 1.5px solid #e6e1d6; border-radius: 14px; padding: 16px 18px; background: #fff; transition: opacity .15s; }
.hh-card--top { border-color: #cfe0d9; background: #f8fbfa; }
.hh-card.is-dismissed { opacity: .4; }
.hh-card__head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 11px; }
.hh-card__title { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.hh-card__name { font-weight: 600; font-size: calc(14.5px * var(--reading-scale)); }
.hh-card__name a { color: var(--ink); }
.hh-card__name a:hover { color: #b45b3e; }
.hh-card__source { font-size: calc(12px * var(--reading-scale)); color: #9a9384; }
.hh-card__source a { color: #2f6d5b; text-decoration: none; border-bottom: 1px solid #cfe0d9; }
.hh-card__source a:hover { color: #b45b3e; border-bottom-color: #b45b3e; }
.hh-card__actions { display: flex; gap: 6px; flex: none; }
.hh-save { font: 600 calc(11px * var(--reading-scale)) var(--font-sans); padding: 6px 11px; border-radius: 9px; border: none; cursor: pointer; white-space: nowrap; background: #eef4f1; color: #2f6d5b; }
.hh-save.is-on { background: #2f6d5b; color: #fff; }
.hh-dismiss { font: 600 calc(11px * var(--reading-scale)) var(--font-sans); padding: 6px 10px; border-radius: 9px; border: none; cursor: pointer; background: #f1ede4; color: #9a9384; }
.hh-dismiss.is-on { background: #b45b3e; color: #fff; }
.hh-card__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-bottom: 12px; }
.hh-card__k { font-size: calc(10px * var(--reading-scale)); letter-spacing: .4px; color: #a49d8d; margin-bottom: 3px; }
.hh-card__v { font-size: calc(13px * var(--reading-scale)); font-weight: 600; }
.hh-card__vs { font-size: calc(12px * var(--reading-scale)); color: #6f6a5e; }
.hh-card__v2 { font-size: calc(13px * var(--reading-scale)); color: #3a352c; }
.hh-card__tags { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; border-top: 1.5px solid #f0ece3; padding-top: 11px; }
.hh-card__why { font-size: calc(11px * var(--reading-scale)); color: #9a9384; margin-right: 2px; }
.hh-tag { font: 600 calc(11px * var(--reading-scale)) var(--font-sans); padding: 4px 9px; border-radius: 999px; background: rgba(180,91,62,.1); color: #b45b3e; }

.hh-otable { border: 1.5px solid #e6e1d6; border-radius: 13px; overflow: hidden; background: #fff; margin-bottom: 20px; }
.hh-otable__head { display: flex; gap: 12px; padding: 10px 15px; background: #faf8f3; font: 600 calc(10.5px * var(--reading-scale)) var(--font-sans); letter-spacing: .4px; color: #a49d8d; }
.hh-otable__row { display: flex; gap: 12px; padding: 12px 15px; border-top: 1.5px solid #f0ece3; align-items: flex-start; font-size: calc(12.5px * var(--reading-scale)); }
.hh-oc1 { flex: 1.6; color: #3a352c; } .hh-oc1 a { color: #3a352c; }
.hh-oc2 { flex: 1; font-weight: 600; }
.hh-oc3 { flex: 1.2; color: #b45b3e; font-weight: 600; }

.hh-flag { border-left: 4px solid #b45b3e; background: #fbf3ef; border-radius: 0 12px 12px 0; padding: 14px 18px; margin: 0 0 34px; }
.hh-flag__label { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; color: #b45b3e; margin-bottom: 6px; }
.hh-flag__body { margin: 0; font-size: calc(13.5px * var(--reading-scale)); line-height: 1.6; color: #3a352c; }

.hh-custom { margin: 0 0 30px; font-size: calc(14.5px * var(--reading-scale)); }

.hh-steps { display: flex; flex-direction: column; gap: 14px; margin-bottom: 38px; }
.hh-step { display: flex; gap: 13px; align-items: flex-start; }
.hh-step__n { width: 24px; height: 24px; flex: none; border-radius: 50%; background: #eef4f1; color: #2f6d5b; font: 600 calc(12px * var(--reading-scale)) var(--font-sans); display: flex; align-items: center; justify-content: center; margin-top: 1px; }
.hh-step__body { margin: 0; font-size: calc(14px * var(--reading-scale)); line-height: 1.6; color: #3a352c; }

/* Sources close the delivery, so they get a rule to sit under — without one
   the numbered list reads as one more section of the briefing rather than the
   apparatus at the end of it. */
.hh-sources-label { font: 700 calc(11px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; color: #a49d8d; margin: 26px 0 12px; padding-top: 22px; border-top: 1.5px solid #ece8df; scroll-margin-top: 20px; }
.hh-sources { margin: 0; padding-left: 20px; display: flex; flex-direction: column; gap: 7px; }
.hh-sources li { font-size: calc(13px * var(--reading-scale)); line-height: 1.4; }
.hh-sources a { color: #b45b3e; }

/* top: clears the 56px sticky reader-topbar (+12px breathing room) so the nav
   parks just below it instead of sliding behind it. */
.hh-nav { width: 156px; flex: none; position: sticky; top: 68px; align-self: flex-start; }

/* Anchor jumps (#verdict, #candidates …) must stop below the sticky topbar,
   not underneath it — matches the nav's 68px offset. */
.hh-h2, .hh-sources-label, .hh-shape { scroll-margin-top: 68px; }
.hh-nav__label { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; color: #a49d8d; margin-bottom: 11px; }
.hh-nav__links { display: flex; flex-direction: column; gap: 2px; border-left: 1.5px solid #e6e1d6; }
.hh-nav__links a { font-size: calc(12.5px * var(--reading-scale)); color: #6f6a5e; padding: 5px 0 5px 13px; margin-left: -1.5px; border-left: 1.5px solid transparent; }
.hh-nav__links a:hover { color: #2f6d5b; border-left-color: #2f6d5b; }
.hh-nav__shape { display: flex; align-items: center; gap: 6px; font-size: calc(12.5px * var(--reading-scale)); color: #2f6d5b; font-weight: 600; margin-top: 16px; padding-top: 14px; border-top: 1.5px solid #e6e1d6; }

.hh-shape { max-width: 720px; margin-top: 0; scroll-margin-top: 20px; }
.hh-shape__card { border: 1.5px solid #cfe0d9; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 10px 34px rgba(50,42,28,.06); }
.hh-shape__head { padding: 13px 20px; background: #f4f8f6; border-bottom: 1.5px solid #cfe0d9; font-size: calc(14px * var(--reading-scale)); color: #2f6d5b; }
.hh-shape__head span { color: #8f8877; font-weight: 400; }
.hh-shape__body { padding: 18px 20px; }
.hh-shape__lbl { font-size: calc(12.5px * var(--reading-scale)); font-weight: 600; color: #6f6a5e; margin-bottom: 9px; }
.hh-refine { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.hh-refine__chip { font: 600 calc(12px * var(--reading-scale)) var(--font-sans); padding: 7px 13px; border-radius: 999px; cursor: pointer; background: #f1ede4; color: #6f6a5e; transition: .15s; }
.hh-refine__chip.is-on { background: #2f6d5b; color: #fff; }
.hh-notes { width: 100%; min-height: 84px; padding: 12px 14px; border: 1.5px solid #e6e1d6; border-radius: 12px; font: 400 calc(13.5px * var(--reading-scale))/1.55 var(--font-sans); color: #3a352c; outline: none; resize: vertical; }
.hh-notes:focus { border-color: #2f6d5b; box-shadow: 0 0 0 3px rgba(47,109,91,.2); }
.hh-shape__foot { display: flex; justify-content: space-between; align-items: center; gap: 14px; margin-top: 16px; }
.hh-shape__count { font-size: calc(12px * var(--reading-scale)); color: #9a9384; }
.hh-shape__foot-right { display: flex; align-items: center; gap: 14px; }
.hh-shape__applies { font-size: calc(12px * var(--reading-scale)); color: #9a9384; }
.hh-shape__save {
  font: 600 calc(13px * var(--reading-scale)) var(--font-sans); padding: 11px 18px; border-radius: 11px; border: none;
  background: #2f6d5b; color: #fff; cursor: pointer; box-shadow: 0 3px 10px rgba(47, 109, 91, .25);
}
.hh-shape__save:hover { background: #28604f; }
.hh-shape__save:disabled { opacity: .6; cursor: default; }

/* "Save for next run" and the line saying when it applies can't share a row on
   a phone — the button gives up and wraps its own label to two lines, which
   reads as a mistake beside a one-line note. Stack them: the note becomes a
   caption above a full-width button. Shared by every reader carrying this
   footer (watch, house hunt), not only the Article.

   This block sits here rather than with the other phone rules at the top of the
   file: a media query adds no specificity, so an override written above the
   rule it overrides simply loses. */
@media (max-width: 720px) {
  .hh-shape__foot,
  .hh-shape__foot-right { flex-direction: column; align-items: stretch; gap: 10px; }
  .hh-shape__save { width: 100%; }
}

/* "Leave this run out" lives in every reader, so its styles are shared —
   see the .dexcl block in reader.css, not here. */

@media (max-width: 900px) {
  .hh-layout { flex-direction: column; }
  .hh-nav { display: none; }
  .hh-kpis, .hh-card__grid { grid-template-columns: repeat(2, 1fr); }
}

/* ── Brief provenance (collapsible; shared by reader + templates) ── */
.brief { max-width: 720px; margin: 40px 0 16px; border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; overflow: hidden; }
.brief__summary { display: flex; align-items: center; gap: 11px; padding: 15px 18px; cursor: pointer; list-style: none; }
.brief__summary::-webkit-details-marker { display: none; }
.brief__icon { font-size: calc(16px * var(--reading-scale)); }
.brief__headings { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.brief__title { font-weight: 600; font-size: calc(14px * var(--reading-scale)); color: var(--ink); }
.brief__sub { font-size: calc(12px * var(--reading-scale)); color: #9a9384; }
.brief__chev { font: 600 calc(11px * var(--reading-scale)) var(--font-sans); color: #9a9384; }
.brief__chev--open { display: none; }
.brief[open] .brief__chev--closed { display: none; }
.brief[open] .brief__chev--open { display: inline; }
.brief__body { border-top: 1.5px solid #f0ece3; padding: 18px; display: flex; flex-direction: column; gap: 18px; }
.brief__ltag { display: flex; align-items: baseline; gap: 9px; margin-bottom: 9px; flex-wrap: wrap; }
.brief__pill { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .5px; color: #6f6a5e; background: #f1ede4; padding: 4px 9px; border-radius: 999px; }
.brief__pill--accent { color: #2f6d5b; background: #dcebe5; }
.brief__hint { font-size: calc(11.5px * var(--reading-scale)); color: #9a9384; margin: 0; }
.brief__link { color: #b45b3e; }
.brief__quote { margin: 0; font-size: calc(13.5px * var(--reading-scale)); line-height: 1.65; color: #3a352c; background: #faf8f3; border-left: 3px solid #cfe0d9; border-radius: 0 10px 10px 0; padding: 12px 15px; white-space: pre-wrap; }
.brief__chips { display: flex; flex-wrap: wrap; gap: 7px; }
.brief__chip { font: 600 calc(12px * var(--reading-scale)) var(--font-sans); padding: 6px 11px; border-radius: 999px; background: #eef4f1; color: #2f6d5b; }
.brief__feedback { display: flex; flex-direction: column; gap: 10px; }
.brief__fitem { display: flex; gap: 10px; align-items: flex-start; }
.brief__forigin { font: 600 calc(10.5px * var(--reading-scale)) var(--font-sans); color: #9a9384; background: #f1ede4; padding: 3px 8px; border-radius: 6px; flex: none; margin-top: 1px; }
.brief__ftext { font-size: calc(13px * var(--reading-scale)); line-height: 1.5; color: #3a352c; }
.brief__foot { font-size: calc(11.5px * var(--reading-scale)); color: #9a9384; border-top: 1.5px solid #f0ece3; padding-top: 13px; }

/* ── Watch template: change rows inside the reused hh-card ─────────────────── */
.wt-changes { display: flex; flex-direction: column; gap: 2px; margin-top: 12px; }
.wt-change { display: flex; align-items: baseline; gap: 10px; padding: 9px 0; border-top: 1.5px solid #f0ece3; }
.wt-change:first-child { border-top: none; }
.wt-change__sig { flex: none; width: calc(78px * var(--reading-scale)); font: 700 calc(9px * var(--reading-scale)) var(--font-sans); letter-spacing: .5px; color: #6a4c86; background: #efe9f2; border-radius: 5px; padding: 3px 6px; text-align: center; }
.wt-change__text { flex: 1; font-size: calc(13.5px * var(--reading-scale)); line-height: 1.5; color: #3a352c; }
.wt-change__text a { color: #2f6d5b; text-decoration: none; border-bottom: 1px solid #cfe0d9; }
.wt-change__text a:hover { color: #b45b3e; border-bottom-color: #b45b3e; }
.wt-change__new { flex: none; font: 700 calc(8.5px * var(--reading-scale)) var(--font-sans); letter-spacing: .5px; color: #b45b3e; background: #f6e2d8; border-radius: 999px; padding: 2px 7px; }
.wt-change__when { flex: none; font-size: calc(11px * var(--reading-scale)); color: #9a9384; }
.wt-quiet { opacity: .72; }
.wt-quiet__tag { flex: none; font: 600 calc(11px * var(--reading-scale)) var(--font-sans); color: #9a9384; background: #f1ede4; border-radius: 999px; padding: 3px 10px; }

/* A rejected note must not look like a saved one. */
.hh-shape__count.is-error, .tr-fb__status.is-error,
.nu-fb__status.is-error, .db-fb__status.is-error { color: #a3564c; font-weight: 600; }
/* ---------------------------------------------------------------
   joris — Create-routine wizard
   --------------------------------------------------------------- */
.wizard-shell {
  width: 100%;
  max-width: 460px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
}
.wizard-brand { margin-bottom: var(--space-2); }
.wizard-card { width: 100%; padding: 0; overflow: hidden; }
.wizard-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  background: var(--paper-warm);
  border-bottom: var(--hairline) solid var(--border-soft);
}
.wizard-step-label {
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-label);
  color: var(--text-faint);
  text-transform: uppercase;
}
.wizard-card__body {
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.wizard-card__body .field__label, .wizard-card__body label { margin-top: var(--space-2); }
.wizard-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.wizard-toggle-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  border: var(--hairline) solid var(--border-default);
  border-radius: var(--radius-md);
}
.wizard-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-3);
}
.wizard-nav--end { justify-content: flex-end; }
.wizard-nav [data-wizard-next], .wizard-nav [data-wizard-back] { cursor: pointer; }
.wizard-review-card { display: flex; flex-direction: column; gap: 6px; }
/* Preserve the user's line breaks / indentation in the direction preview. */
#wizard-review-direction { white-space: pre-wrap; word-break: break-word; }
.wizard-errors {
  color: var(--accent);
  font-size: var(--text-sm);
  background: rgba(180,91,62,.08);
  border-radius: var(--radius-md);
  padding: var(--space-2) var(--space-3);
}
[data-skill-pick], [data-frequency-pick], [data-provider-pick] { cursor: pointer; }

/* Desktop: give the wizard more room (roomier direction textarea, less cramped
   forms) and more generous padding. Mobile layout is unchanged. */
@media (min-width: 768px) {
  .wizard-shell { max-width: 600px; gap: var(--space-5); }
  .wizard-card__head { padding: var(--space-4) var(--space-6); }
  .wizard-card__body { padding: var(--space-6); gap: var(--space-3); }
}
/* ---------------------------------------------------------------
   joris — Settings screens (routines manage list, providers)
   --------------------------------------------------------------- */
.settings-shell {
  width: 100%;
  max-width: 620px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.settings-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.settings-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}
.settings-row__main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.settings-row__actions { display: flex; align-items: center; gap: 6px; flex: none; }

/* --- M3: routine management, edit tabs, history --- */
.settings-row.is-paused { opacity: .6; }
.edit-tabs { display: flex; gap: 6px; margin: var(--space-3) 0 var(--space-2); flex-wrap: wrap; }
.edit-tab { font: 600 12px system-ui; padding: 6px 12px; border-radius: 999px; cursor: pointer; color: var(--ink-mut, #6b665c); background: var(--paper-2, #f4f2ec); }
.edit-tab.is-active { background: var(--primary, #2f6d5b); color: #fff; }
.history-search { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: var(--space-3); }

/* --- M4: plans & usage --- */
.plan-grid { display: flex; gap: var(--space-3); flex-wrap: wrap; }
.plan-card { flex: 1 1 240px; display: flex; flex-direction: column; gap: var(--space-2); }
.plan-card--pro { border-color: var(--primary-border, #cfe0d9); background: var(--primary-tint-2, #f4f8f6); }
.plan-card--current { outline: 2px solid var(--primary, #2f6d5b); outline-offset: -2px; }
.plan-card__head { display: flex; align-items: baseline; justify-content: space-between; }
.plan-card__price { font: 600 15px var(--font-sans, system-ui); color: var(--ink, #26221b); }
.plan-card__rule { height: 1px; background: var(--border-soft, #ece8df); margin: 2px 0; }
.plan-card__features { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }
.plan-card__features li { font-size: 13px; color: var(--ink-soft, #6f6a5e); }
.plan-card__features li::before { content: "✓ "; color: var(--primary, #2f6d5b); font-weight: 600; }
.plan-card__foot { margin-top: auto; padding-top: var(--space-2); }

.usage-card { display: flex; flex-direction: column; }
.usage-nudge { margin-top: var(--space-3); padding: 10px 12px; border-radius: var(--radius-md, 11px);
  background: var(--primary-tint, #eef4f1); color: var(--ink, #26221b); font-size: 13px; }
.usage-nudge--warn { background: rgba(180,91,62,.10); }
.usage-nudge__link { color: var(--accent, #b45b3e); font-weight: 600; }
.usage-row { display: flex; align-items: center; justify-content: space-between;
  padding: 8px 2px; border-bottom: 1px solid var(--border-soft, #ece8df); }
.usage-row__name { font-size: 13px; color: var(--ink, #26221b); }

/* Standard account/settings page frame — matches Home/History/Routines
   (880px, left-aligned, hero + content) instead of the centered onboarding shell. */
.acct-page { width: 100%; max-width: 880px; margin: 0 auto; padding: var(--page-top) var(--page-gutter) 90px; }
.acct-page .settings-shell { max-width: 620px; }

/* Profile settings. --prose is one measure for every paragraph on these pages,
   in px on purpose: a `ch` cap looks consistent in the stylesheet and is not —
   it scales with the element's own font-size, so an 11px hint and a 13.5px
   lead capped at the same ch count wrap ~15% apart and the page ends up with
   several different ragged right edges. */
.acct-page { --prose: 660px; }
.prof-divider { display: flex; align-items: baseline; gap: 9px; margin: 26px 0 12px; }
.prof-divider > span:first-child { font: 700 10px "Hanken Grotesk"; letter-spacing: .6px; color: #9a9384; }
.prof-divider__rule { flex: 1; height: 1.5px; background: #e2ddd0; }
.prof-card { border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 2px 6px rgba(50,42,28,.04); }

/* Danger zone — same shell, terracotta-tinted. */
.prof-divider--danger > span:first-child { color: var(--danger); }
.prof-divider--danger .prof-divider__rule { background: var(--danger-border); }

/* The leaving question. Deliberately quieter than the confirmation above it —
   it is an ask, not a step, and must not read as one more thing standing
   between someone and the door. */

.prof-id { display: flex; align-items: center; gap: 15px; padding: 18px 20px; border-bottom: 1.5px solid #f3f0e8; }
.prof-id__av { width: 52px; height: 52px; flex: none; border-radius: 50%; background: #dcebe5; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font: 700 18px "Hanken Grotesk"; }
.prof-id__main { flex: 1; min-width: 0; }
.prof-id__name { font-weight: 600; font-size: 14px; }
.prof-id__email { color: #9a9384; margin-top: 2px; }
.prof-plan { flex: none; font: 600 10px "Hanken Grotesk"; padding: 5px 11px; border-radius: 999px; background: #efe9f2; color: #6a4c86; }

.prof-row { display: flex; align-items: flex-start; gap: 16px; padding: 14px 20px; border-bottom: 1.5px solid #f3f0e8; }
.prof-row--last { border-bottom: none; }
.prof-row__lbl { width: 150px; flex: none; font-size: 12.5px; font-weight: 600; color: #3a352c; padding-top: 9px; }
.prof-row__hint { font-size: 11px; font-weight: 400; color: #9a9384; margin-top: 2px; }
.prof-row__field { flex: 1; min-width: 0; }
.prof-row__note { font-size: 11px; color: #9a9384; margin-top: 7px; line-height: 1.5; }
.prof-input { width: 100%; border: 1.5px solid #e6e1d6; border-radius: 10px; padding: 10px 13px; font: 400 13.5px "Hanken Grotesk"; color: #26221b; outline: none; background: #fff; }
.prof-input:focus { border-color: #cfe0d9; }
/* Below .prof-input deliberately: its `background` shorthand would otherwise
   wipe the chevron, since both rules carry the same specificity. */
.prof-input--select { appearance: none; background-image: url("data:image/svg+xml;charset=UTF-8,%3Csvg width='10' height='6' viewBox='0 0 10 6' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%239a9384' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 13px center; padding-right: 32px; }
.prof-input--area { resize: vertical; line-height: 1.5; }
.prof-tz { width: 100%; }
.prof-seg { display: inline-flex; gap: 6px; }
.prof-seg__opt { display: inline-flex; align-items: center; font: 600 11.5px "Hanken Grotesk"; padding: 8px 14px; border-radius: 9px; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; cursor: pointer; }
.prof-seg__opt.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.prof-seg__radio { position: absolute; opacity: 0; width: 0; height: 0; }

/* Reading-size preview. With the in-reader control gone this is the only
   feedback the setting has, so it renders the real brief template (see
   SettingsHelper#reading_size_sample_delivery) instead of a mock-up.

   .reading-scope (in tokens/typography.css) makes the type tokens track
   --reading-scale; reading_scale_preview.js sets that variable inline so the
   sample shows the PENDING selection rather than the saved one. */
.prof-rsize__preview {
  margin-top: 14px; border-radius: 12px; overflow: hidden;
  border: 1.5px solid #e6e1d6; background: #fcfbf7;
}
.prof-rsize__label {
  font: 700 9.5px "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d;
  padding: 10px 15px 0;
}
/* The brief template sets its own page-level padding and title size; rein
   both in so the sample sits as a card inside the settings row. */
.prof-rsize__doc { padding: 4px 15px 15px; }
.prof-rsize__doc .db { padding: 0; }
.prof-rsize__doc .db-title { margin-top: 6px; }
/* The TL;DR block carries a page-flow bottom margin that leaves a gap at the
   end of the card here, since it's the last thing in the sample. */
.prof-rsize__doc .db > :last-child { margin-bottom: 0; }
.prof-tf-now { margin-left: auto; flex: none; font-size: 12px; color: #9a9384; }
.prof-tf-now strong { color: #3a352c; font-weight: 600; }
/* Text-only rows (e.g. Email) center vertically — no input to align a top edge to. */
.prof-row--center { align-items: center; }
.prof-row--center .prof-row__lbl { padding-top: 0; }
.prof-email { display: flex; align-items: center; gap: 10px; }
.prof-email .mono { color: #6f6a5e; }
.prof-verified { display: inline-flex; align-items: center; gap: 4px; font: 600 10px "Hanken Grotesk"; color: #2f6d5b; }
.prof-change { margin-left: auto; font: 600 11px "Hanken Grotesk"; padding: 7px 12px; border-radius: 9px; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; cursor: pointer; }
.prof-change:hover { border-color: #cfe0d9; color: #2f6d5b; }

/* Email-change reveal — CSS-only, toggled by the row's "Change" label. */
.prof-echange { max-height: 0; overflow: hidden; transition: max-height .25s ease; }
.prof-echange__cb:checked + .prof-echange { max-height: 220px; }
.prof-echange__body { border: 1.5px solid #e6e1d6; border-radius: 14px; background: #faf8f3; padding: 15px 17px; margin-top: 14px; }
.prof-echange__note { font-size: 12px; color: #6f6a5e; line-height: 1.5; margin: 0 0 11px; }
.prof-echange__form { display: flex; gap: 9px; align-items: center; }
.prof-echange__form .prof-input { flex: 1; }



/* Transparent plans page — 4-tier comparison. */
.plan-note { display: flex; gap: 11px; align-items: flex-start; border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 12px; padding: 13px 16px; margin-bottom: 18px; font-size: 12.5px; line-height: 1.55; color: #2f5f52; }
.plan-note strong { color: #245043; }
.plan-note__icon { width: 26px; height: 26px; flex: none; border-radius: 8px; background: #dcebe5; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font-size: 14px; }

/* Shared CTA control (matrix footer + mobile cards). button_to wraps a form;
   display:contents lets the button sit directly in the grid cell / card. */
.pmx form.button_to, .plan-cards form.button_to { display: contents; }
.plan-cta { display: inline-block; text-align: center; font: 600 11.5px "Hanken Grotesk"; padding: 8px 15px; border-radius: 9px; border: 1.5px solid transparent; cursor: pointer; }
.plan-cta--block { display: block; width: 100%; padding: 12px; font-size: 12.5px; border-radius: 11px; }
.plan-cta--go { background: #2f6d5b; color: #fff; border: none; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.plan-cta--go:hover { background: #28604f; text-decoration: none; }
.plan-cta--ghost { border-color: #e6e1d6; color: #26221b; background: #fff; }
.plan-cta--ghost:hover { border-color: #cfe0d9; text-decoration: none; }
.plan-cta--current { background: #faf8f3; border-color: #e6e1d6; color: #9a9384; cursor: default; }
.plan-cta--muted { background: #fff; border-color: #e6e1d6; color: #c2bbac; cursor: default; }

/* Desktop comparison matrix. */
.pmx { border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
/* One label column plus one per tier. --pmx-tiers is set inline from
   @tiers.size: this was hardcoded to 4 tiers from v1 (free/pro/pro_plus/custom),
   so when v2 dropped to 3 the grid stayed 5 wide and every row rendered one
   cell out of step — labels drifted into the rightmost column. */
.pmx__grid { display: grid; grid-template-columns: 1.6fr repeat(var(--pmx-tiers, 3), 1fr); }
.pmx__corner { background: #f7f4ee; border-bottom: 1.5px solid #ece8df; }
.pmx__col { padding: 14px 10px; text-align: center; background: #f7f4ee; border-bottom: 1.5px solid #ece8df; }
.pmx__col.is-rec { background: #f4f8f6; box-shadow: inset 0 0 0 1.5px #cfe0d9; }
.pmx__col.is-current { background: #eef3f1; box-shadow: inset 0 0 0 1.5px #2f6d5b; }
.pmx__pname { font-family: "Newsreader", serif; font-size: 15px; font-weight: 600; }
.pmx__tag { display: inline-flex; align-items: center; gap: 3px; margin-top: 6px; font: 700 9.5px "Hanken Grotesk"; letter-spacing: .5px; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; background: #f1ede4; color: #9a9384; }
.pmx__tag--rec { background: #2f6d5b; color: #fff; }
.pmx__tag--cur { background: #dcebe5; color: #2f6d5b; box-shadow: inset 0 0 0 1.5px #2f6d5b; }
.pmx__tag--cur::before { content: "✓"; font-size: 9px; font-weight: 800; }
.pmx__price { font-size: 11.5px; color: #9a9384; margin-top: 4px; }
.pmx__trial { font: 600 9.5px "Hanken Grotesk"; color: #2f6d5b; margin-top: 4px; }
.pmx__label { padding: 11px 16px; display: flex; flex-direction: column; justify-content: center; gap: 2px; border-bottom: 1.5px solid #f3f0e8; }
.pmx__name { font-size: 12.5px; color: #3a352c; }
/* The row's own explanation, in the same register the marketing comparison
   uses. No width cap: the label is a fixed grid track, so it wraps to the
   column it belongs to. */
.pmx__hint { font-size: 11px; line-height: 1.45; color: #9a9384; }
.pmx__cell { padding: 11px 10px; display: flex; align-items: center; justify-content: center; text-align: center; border-bottom: 1.5px solid #f3f0e8; }
.pmx__cell.is-rec { background: #f9fbfa; }
.pmx__cell--cta { border-bottom: none; background: #faf8f3; padding: 14px 10px; }
.pmx__cell--cta.is-rec { background: #f4f8f6; }
.pmx__yes { width: 20px; height: 20px; border-radius: 6px; background: #eef4f1; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; }
.pmx__no { width: 20px; height: 20px; border-radius: 6px; background: #f1ede4; color: #c2bbac; display: flex; align-items: center; justify-content: center; font-size: 11px; }
.pmx__txt { font-size: 12px; font-weight: 600; color: #3a352c; white-space: pre-line; line-height: 1.5; }
.pmx__txt--dim { color: #c2bbac; }
.pmx__cell.is-rec .pmx__txt { color: #245043; }

/* Mobile stacked plan cards. */
.plan-cards { display: none; flex-direction: column; gap: 12px; }
.plan-card2 { border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; padding: 16px; }
.plan-card2--rec { border: 2px solid #2f6d5b; box-shadow: 0 10px 30px rgba(47,109,91,.13); }
.plan-card2--current { box-shadow: inset 0 0 0 1.5px #2f6d5b; }
.plan-card2__head { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.plan-card2__name { font-family: "Newsreader", serif; font-size: 18px; font-weight: 500; }
.plan-card2__price { margin-left: auto; font-family: "Newsreader", serif; font-size: 18px; font-weight: 500; }
.plan-card2__tagline { font-size: 11.5px; color: #9a9384; margin-bottom: 12px; }
.plan-card2__feats { display: flex; flex-direction: column; gap: 7px; margin-bottom: 14px; }
.plan-card2__feat { display: flex; gap: 9px; align-items: flex-start; }
.plan-card2__ic { width: 18px; height: 18px; flex: none; border-radius: 5px; display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 700; margin-top: 1px; }
.plan-card2__ic.is-yes { background: #eef4f1; color: #2f6d5b; }
.plan-card2__ic.is-hero { background: #dcebe5; color: #2f6d5b; }
.plan-card2__ic.is-no { background: #f1ede4; color: #c2bbac; }
.plan-card2__ft { font-size: 12px; line-height: 1.4; color: #3a352c; }
.plan-card2__ft.is-dim { color: #9a9384; }

.plan-foot { font-size: 11.5px; color: #9a9384; line-height: 1.6; margin-top: 16px; }

/* Matrix → stacked cards on narrow screens. */
@media (max-width: 720px) {
  .pmx { display: none; }
  .plan-cards { display: flex; }

  /* The 150px label column plus a flex:1 field leaves ~180px for the control
     on a phone, which squeezes selects, segmented controls and the reading
     preview into a sliver. Stack label over field instead. */
  .prof-row, .prof-row--center { flex-direction: column; align-items: stretch; gap: 10px; }
  .prof-row__lbl { width: auto; padding-top: 0; }
  .prof-seg { flex-wrap: wrap; }
  .prof-seg__opt { flex: 1 1 auto; justify-content: center; }
}

/* Usage page — web/thinking meters + by-routine (three states). */
.use-muted { color: #9a9384; font-weight: 400; }
.use-card { border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; padding: 20px 22px; margin-bottom: 12px; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
.use-card--flush { padding: 0; overflow: hidden; }

.use-trial { display: flex; align-items: center; gap: 13px; border: 1.5px solid #cfe0d9; border-radius: 16px; background: linear-gradient(#f4f8f6, #eef4f1); padding: 16px 19px; margin-bottom: 14px; }
.use-trial__icon { width: 40px; height: 40px; flex: none; border-radius: 12px; background: #2f6d5b; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 18px; }
.use-trial__text { flex: 1; min-width: 0; }
.use-trial__title { font-weight: 700; font-size: 13.5px; color: #245043; }
.use-trial__sub { font-size: 12px; color: #2f5f52; }
.use-trial__btn { flex: none; padding: 10px 17px; border-radius: 11px; background: #2f6d5b; color: #fff; font: 600 12.5px "Hanken Grotesk"; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.use-trial__btn:hover { background: #28604f; text-decoration: none; }

.use-meter__head { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.use-meter__icon { width: 26px; height: 26px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; }
.use-meter__icon--web { background: #dcebe5; }
.use-meter__icon--think { background: #f1ede4; }
.use-meter__label { font-weight: 600; font-size: 14px; flex: 1; }
.use-meter__count { font-size: 13px; color: #9a9384; }
.use-meter__used { font-family: "Newsreader", serif; font-size: 22px; font-weight: 500; }
.use-bar { height: 11px; border-radius: 999px; background: #f0ece3; overflow: hidden; margin-bottom: 11px; }
.use-bar__fill { height: 100%; border-radius: 999px; }
.use-meter__foot { display: flex; align-items: center; justify-content: space-between; font-size: 12.5px; color: #6f6a5e; }

/* Thinking runs are a second meter now, not a one-line card, so .use-thinking
   is gone and both bars share the .use-meter rules above. What the card used to
   carry that the bar does not is the sentence naming which routines it counts. */
.use-meter__note { margin-top: 9px; font-size: 11.5px; line-height: 1.5; color: #9a9384; }

.use-warn { display: flex; align-items: center; gap: 11px; border: 1.5px solid #f0e6d6; background: #faf6ef; border-radius: 14px; padding: 13px 16px; margin-bottom: 12px; }
.use-warn__icon { color: #a4712f; flex: none; font-size: 15px; }
.use-warn__text { flex: 1; font-size: 12px; line-height: 1.5; color: #8a6420; }
.use-warn__link { font: 600 11.5px "Hanken Grotesk"; color: #a4712f; flex: none; }

.use-freeweb { display: flex; gap: 15px; align-items: flex-start; }
.use-freeweb .use-meter__icon { width: 42px; height: 42px; font-size: 20px; color: #2f6d5b; background: #eef4f1; }
.use-freeweb__text { flex: 1; }
.use-freeweb__title { font-family: "Newsreader", serif; font-size: 18px; font-weight: 500; margin-bottom: 4px; }
.use-freeweb__sub { font-size: 12.5px; line-height: 1.55; color: #6f6a5e; margin-bottom: 12px; }
.use-freeweb__btn { display: inline-block; padding: 10px 16px; border-radius: 11px; background: #2f6d5b; color: #fff; font: 600 12.5px "Hanken Grotesk"; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.use-freeweb__btn:hover { background: #28604f; text-decoration: none; }

.use-divider { display: flex; align-items: baseline; gap: 9px; margin: 22px 0 12px; }
.use-divider span:first-child { font: 700 10px "Hanken Grotesk"; letter-spacing: .6px; color: #9a9384; }
.use-divider__rule { flex: 1; height: 1.5px; background: #e2ddd0; }

.use-row { display: flex; align-items: center; gap: 12px; padding: 13px 18px; border-bottom: 1.5px solid #f3f0e8; }
.use-row--last { border-bottom: none; }
.use-row__emoji { font-size: 15px; flex: none; width: 22px; text-align: center; }
.use-row__main { flex: 1; min-width: 0; }
.use-row__head { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.use-row__name { font-weight: 600; font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.use-tag { font: 600 9px "Hanken Grotesk"; letter-spacing: .3px; padding: 2px 7px; border-radius: 999px; flex: none; }
.use-tag--web { background: #dcebe5; color: #2f6d5b; }
.use-tag--think { background: #f1ede4; color: #9a9384; }
.use-row__bar { height: 6px; border-radius: 999px; background: #f0ece3; overflow: hidden; max-width: 420px; }
.use-row__fill { height: 100%; border-radius: 999px; }
.use-row__count { flex: none; font-size: 13px; font-weight: 600; color: #26221b; width: 34px; text-align: right; }
.use-empty { padding: 22px; text-align: center; color: #9a9384; font-size: 12.5px; border: 1.5px solid #f0ece3; border-radius: 16px; }
.use-foot { font-size: 11.5px; color: #9a9384; margin-top: 16px; line-height: 1.55; }
/* Sits tight under the breakdown it is explaining, not down with the footnote. */
.use-note { font-size: 11.5px; color: #9a9384; margin-top: 9px; line-height: 1.55; }

/* Plan page — current-plan card, upsell banner, compare head, upgrade modal. */
.plan-current { border: 1.5px solid #e6e1d6; border-radius: 16px; background: #fff; overflow: hidden; margin-bottom: 26px; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
.plan-current__head { display: flex; align-items: center; gap: 14px; padding: 18px 20px; }
.plan-current__badge-icon { width: 44px; height: 44px; flex: none; border-radius: 12px; background: #f1ede4; color: #6f6a5e; display: flex; align-items: center; justify-content: center; font: 700 15px "Hanken Grotesk"; }
.plan-current__id { flex: 1; min-width: 0; }
.plan-current__name { font-family: "Newsreader", serif; font-size: 19px; font-weight: 500; display: flex; align-items: center; gap: 8px; }
.plan-current__tag { font: 600 10px "Hanken Grotesk"; padding: 3px 9px; border-radius: 999px; background: #e8efe8; color: #2f6d5b; }
.plan-current__desc { font-size: 12.5px; color: #9a9384; margin-top: 2px; }
.plan-current__price { text-align: right; flex: none; }
.plan-current__amount { font-family: "Newsreader", serif; font-size: 26px; font-weight: 500; line-height: 1; }
.plan-current__per { display: block; font-size: 10.5px; color: #9a9384; }
.plan-current__meter { padding: 0 20px 18px; }
/* One row per allowance. Gap rather than a margin on the row, so the last one
   sits flush against the shared reset line below instead of pushing it away. */
.plan-current__meter { display: flex; flex-direction: column; gap: 12px; }
.plan-current__meterrow { display: flex; flex-direction: column; }
.plan-current__meterhead { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 7px; font-size: 12px; color: #6f6a5e; }
.plan-current__resets { font-size: 11.5px; color: #9a9384; }

/* Subscription management (Stripe portal) + the billing-trouble escape hatch. */
/* A footer bar on the card, like the reply box's. It had vertical padding only,
   so it sat flush against the card's left edge while every other section was
   inset by 20px — the button visibly hung outside the content column. The
   margin-top on top of the meter's own bottom padding also left a dead gap. */
.plan-current__manage { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 13px 20px; border-top: 1.5px solid #ece8df; background: #faf8f3; }
.plan-current__managenote { flex: 1 1 220px; font-size: 11.5px; line-height: 1.5; color: #9a9384; }
.plan-help { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin: -14px 0 26px; font-size: 12.5px; color: #6f6a5e; }
.plan-help__form { display: inline; }
.plan-help__link { border: none; background: none; padding: 0; font: inherit; color: #2f6d5b; text-decoration: underline; cursor: pointer; }
.plan-help__link:hover { color: #28604f; }

.plan-upsell { display: flex; align-items: center; gap: 14px; border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 16px; padding: 18px 20px; margin-bottom: 26px; }
.plan-upsell__icon { width: 42px; height: 42px; flex: none; border-radius: 12px; background: #dcebe5; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.plan-upsell__text { flex: 1; min-width: 0; }
.plan-upsell__title { font-weight: 700; font-size: 14px; color: #245043; margin-bottom: 2px; }
.plan-upsell__sub { font-size: 12.5px; line-height: 1.5; color: #2f5f52; }
.plan-upsell__btn { flex: none; padding: 11px 18px; border-radius: 11px; background: #2f6d5b; color: #fff; font: 600 13px "Hanken Grotesk"; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.plan-upsell__btn:hover { background: #28604f; text-decoration: none; }

.plan-compare-head { display: flex; align-items: baseline; gap: 9px; margin-bottom: 13px; }
.plan-compare-head span:first-child { font: 700 10px "Hanken Grotesk"; letter-spacing: .6px; color: #9a9384; }
.plan-compare-head__rule { flex: 1; height: 1.5px; background: #e2ddd0; }
.plan-compare-head__note { font-size: 11px; color: #9a9384; }

/* upgrade modal via :target */
.plan-modal { display: none; position: fixed; inset: 0; z-index: 60; align-items: center; justify-content: center; padding: 30px; }
.plan-modal:target { display: flex; }
.plan-modal__scrim { position: absolute; inset: 0; background: rgba(38,34,27,.4); }
.plan-modal__card { position: relative; width: 430px; max-width: 100%; background: #fff; border-radius: 20px; overflow: hidden; box-shadow: 0 30px 70px rgba(50,42,28,.3); }
.plan-modal__hero { position: relative; padding: 26px 26px 22px; background: linear-gradient(#f4f8f6, #eef4f1); }
.plan-modal__close { position: absolute; top: 16px; right: 16px; width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; color: #9a9384; }
.plan-modal__close:hover { background: rgba(0,0,0,.05); text-decoration: none; }
.plan-modal__icon { width: 46px; height: 46px; border-radius: 13px; background: #2f6d5b; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 22px; margin-bottom: 14px; }
.plan-modal__title { font-family: "Newsreader", serif; font-size: 23px; font-weight: 500; line-height: 1.15; margin-bottom: 6px; }
.plan-modal__sub { font-size: 13.5px; line-height: 1.6; color: #5c6b62; }
.plan-modal__body { padding: 20px 26px 24px; }
.plan-modal__perks { display: flex; flex-direction: column; gap: 10px; margin-bottom: 20px; }
.plan-modal__perk { display: flex; gap: 11px; align-items: flex-start; font-size: 13px; line-height: 1.5; color: #3a352c; }
.plan-modal__check { width: 20px; height: 20px; flex: none; border-radius: 6px; background: #dcebe5; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font-size: 12px; margin-top: 1px; }
.plan-modal__cta { width: 100%; padding: 14px; border: none; border-radius: 12px; background: #2f6d5b; color: #fff; font: 600 14px "Hanken Grotesk"; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); margin-bottom: 9px; }
.plan-modal__cta:hover { background: #28604f; }
.plan-modal__fine { text-align: center; font-size: 11px; color: #9a9384; }

/* ── Settings inner sidebar (shared/_settings_nav) ─────────────────
   Design: Settings - Connections.dc.html. A sibling of .app-main inside
   .app-shell, so it holds still while the page scrolls. */
.snav {
  width: 260px; flex: none; z-index: 11;
  background: #faf8f2; border-right: 1.5px solid #ece8df;
  display: flex; flex-direction: column;
}
.snav__head {
  height: 56px; flex: none; display: flex; align-items: center; gap: 8px;
  padding: 0 10px 0 16px; border-bottom: 1.5px solid #ece8df;
}
.snav__collapse {
  width: 30px; height: 30px; flex: none; margin-left: auto;
  border: none; background: none; border-radius: 8px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; color: #9a9384;
}
.snav__collapse:hover { background: #efece4; color: #6f6a5e; }
.snav__collapse svg { width: 17px; height: 17px; }

/* ── Collapsed ──────────────────────────────────────────────────────
   The column is hidden and the top bar grows a way back. Both controls are
   present in the DOM at all times; which one is reachable is the only thing
   that changes, so neither needs JS to exist. */
.app-shell--snav-collapsed .snav { display: none; }
.app-topbar__reopen {
  width: 30px; height: 30px; flex: none; margin-right: 2px;
  border: none; background: none; border-radius: 8px; cursor: pointer;
  display: none; align-items: center; justify-content: center; color: #9a9384;
}
.app-topbar__reopen:hover { background: #efece4; color: #6f6a5e; }
.app-topbar__reopen svg { width: 17px; height: 17px; }
.app-shell--snav-collapsed .app-topbar__reopen { display: flex; }
.snav__title {
  position: relative; top: .15em;
  font-family: 'Newsreader', Georgia, serif; font-weight: 600; font-size: 16px; color: #26221b;
}
.snav__list {
  flex: 1; overflow: auto; padding: 12px 12px 16px;
  display: flex; flex-direction: column; gap: 8px;
}
.snav__row {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px; border-radius: 12px;
  background: #fff; border: 1.5px solid #e6ded1;
  text-decoration: none; transition: border-color .12s, background .12s;
}
.snav__row:hover { border-color: #cfe0d9; text-decoration: none; }
.snav__row.is-active { background: #f7fbf9; border-color: #a9cabd; }
.snav__label { flex: 1; min-width: 0; font-size: 14px; font-weight: 600; color: #26221b; }
.snav__meta { font-size: 12px; color: #8f8877; }
.snav__meta--num { font-variant-numeric: tabular-nums; }
.snav__meta--alert { color: #8a6b33; }
.snav__dot { width: 7px; height: 7px; flex: none; border-radius: 50%; background: #c9a24a; }

/* The design hides this column below 880px, but it is a desktop mock — hiding
   it in the product would strand Plan & billing, because the flyout that used
   to carry it is identity-only now and the spine (with its gear) is itself gone
   at 720px. So it narrows first, then becomes a scrolling strip. */
@media (max-width: 880px) {
  .snav { width: 196px; }
  .snav__list { padding: 10px 9px 14px; }
  .snav__row { padding: 10px; }
  .snav__label { font-size: 13px; }
}

/* At this width .app-shell is already `flex-direction: column` and the spine is
   hidden (app_shell.css), so the rows lie down under the mobile top bar. */
@media (max-width: 720px) {
  .snav {
    width: 100%; order: 1;
    border-right: none; border-bottom: 1.5px solid #ece8df;
  }
  .snav__head { display: none; }
  .snav__list {
    flex-direction: row; overflow-x: auto; overflow-y: hidden;
    padding: 10px 14px; gap: 7px;
    scrollbar-width: none;
  }
  .snav__list::-webkit-scrollbar { display: none; }
  .snav__row { flex: none; padding: 8px 13px; border-radius: 999px; }
  .snav__label { white-space: nowrap; }
  .app-main { order: 2; }
}

/* ── Close account (design: Profile Settings.dc.html) ───────────────────────
   A quiet disclosure at the foot of the page, not a permanently-open DANGER
   ZONE card. Deleting an account is sought out; it does not need to be in
   front of someone who came here to change their display name. */
.dclose { border-top: 1.5px solid #e2ddd0; margin-top: 30px; padding-top: 14px; }
.dclose__summary {
  display: inline-flex; align-items: center; gap: 7px; padding: 4px 0;
  font: 500 13px "Hanken Grotesk"; color: #9a9384; cursor: pointer;
  list-style: none;
}
/* Both spellings: WebKit still wants the pseudo-element, the rest take the
   `list-style` above. Without them a stock triangle sits beside the caret. */
.dclose__summary::-webkit-details-marker { display: none; }
.dclose__summary::marker { content: ""; }
.dclose__summary:hover { color: #6f6a5e; }
.dclose__caret { flex: none; transition: transform .18s ease; }
.dclose[open] .dclose__caret { transform: rotate(90deg); }

.dclose__card {
  margin-top: 14px; padding: 22px 24px;
  border: 1.5px solid var(--danger-border); border-radius: 16px; background: #fff;
  box-shadow: 0 2px 6px rgba(50, 42, 28, .04);
}
.dclose__title { font: 600 19px 'Newsreader', serif; color: #26221b; margin: 0 0 8px; }
.dclose__lead { margin: 0 0 22px; font-size: 14px; line-height: 1.6; color: #6f6a5e; text-wrap: pretty; max-width: 560px; }

/* Three numbered stages. An <ol> because they are a sequence and the order is
   the content: two things you can do first, then the one that ends it. */
.dclose__stages { list-style: none; margin: 0; padding: 0; }
.dclose__stage {
  display: grid; grid-template-columns: 26px 1fr; gap: 14px;
  padding: 22px 0; border-bottom: 1.5px solid #f3f0e8;
}
.dclose__stage:first-child { padding-top: 0; }
.dclose__stage:last-child { padding-bottom: 0; border-bottom: 0; }
.dclose__num {
  width: 26px; height: 26px; border-radius: 50%;
  border: 1.5px solid #e6e1d6; background: #f7f5ef; color: #6f6a5e;
  font: 600 13px "Hanken Grotesk"; display: flex; align-items: center; justify-content: center;
}
/* The two stages that are not neutral: one is a way out of leaving, one is
   the end of it. */
.dclose__num--talk { border-color: #cfe0d9; background: #eef4f1; color: #2f6d5b; }
.dclose__num--danger { border-color: #e2c0b2; background: #fdf1ec; color: #b0553a; }
.dclose__stage-body { min-width: 0; }
.dclose__stage-title { font-size: 15px; font-weight: 600; color: #26221b; margin: 0 0 3px; }
.dclose__stage-lead { margin: 0 0 13px; font-size: 13.5px; line-height: 1.6; color: #6f6a5e; text-wrap: pretty; max-width: 520px; }
.dclose__stage-lead--dark { color: #4a453b; margin-bottom: 6px; }
.dclose__stage-lead a { color: #9a9384; text-decoration: underline; }
.dclose__stage-lead--dark a { color: #b45b3e; }

/* Step 1: the form that can end this without an account being deleted. */
.dclose__talk { display: flex; flex-direction: column; align-items: flex-start; gap: 9px; max-width: 340px; }
.dclose__field { width: 100%; }
.dclose__talk textarea.dclose__field { min-height: 74px; }

/* Step 2: two things that stop being possible once the row is destroyed.
   Actions, not advice — each row carries the control that performs it. */
.dclose__tasks { display: flex; flex-direction: column; gap: 10px; }
.dclose__task {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 13px 15px; border: 1.5px solid #e6e1d6; border-radius: 12px; background: #faf8f3;
}
.dclose__task-main { flex: 1; min-width: 200px; }
.dclose__task-title { font-size: 14px; font-weight: 600; color: #26221b; margin-bottom: 2px; }
.dclose__task-hint { font-size: 13px; line-height: 1.55; color: #9a9384; }
/* The billing row is the one with a consequence attached, so it carries the
   danger palette rather than a second paragraph explaining itself. */
.dclose__task--warn { border-color: var(--danger-border); background: #fdf6f2; }
.dclose__task--warn .dclose__task-hint { color: #8f6a5c; }
.dclose__task-btn {
  flex: none; white-space: nowrap; font: 600 13px "Hanken Grotesk";
  padding: 9px 15px; border-radius: 10px;
  border: 1.5px solid #d9b8a8; background: #fff; color: #8f3f28;
}
.dclose__task-btn:hover { background: #fdf1ec; text-decoration: none; }

/* Step 3: the gate and the act it gates, on one line where there is room. */
.dclose__confirm { display: block; font-size: 13px; color: #6f6a5e; margin: 16px 0 8px; }
.dclose__confirm .mono { font-family: var(--font-mono); font-size: 13px; color: #b0553a; }
.dclose__final-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.dclose__input { width: 250px; flex: none; border-color: #e6cfc5; }
.dclose__input:focus { border-color: #d98a6f; }
.dclose__actions { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
@media (max-width: 720px) {
  .dclose__input { width: 100%; }
  .dclose__actions { width: 100%; }
  .dclose__actions .btn { flex: 1 1 auto; justify-content: center; }
  .dclose__stage { grid-template-columns: 22px 1fr; gap: 11px; }
  .dclose__num { width: 22px; height: 22px; font-size: 12px; }
}
.dclose__foot { margin-top: 16px; padding-top: 14px; border-top: 1.5px solid #f3f0e8; font-size: 12.5px; color: #a49d8d; }
/* Global app navigation shell (shared/_app_shell + layouts/app).
   Design: Delivery.dc.html — Option B (permanent icon spine + flyouts).
   At <=720px the spine gives way to a top bar + slide-in drawer instead
   (see the mobile nav block near the end of this file). */

/* dvh, not vh: on mobile browsers 100vh is the LARGE viewport (URL bar
   retracted), so with the bar showing the shell is taller than the visible
   area. The page then scrolls by the height of the browser chrome even when
   the content fits, carrying .mobile-topbar off the top. dvh tracks the
   viewport as the bar shows and hides. vh first as the fallback. */
.app-shell { display: flex; height: 100vh; height: 100dvh; width: 100%; overflow: hidden; background: #efece4; }

/* ── Icon spine (always present) ─────────────────────────────── */
.spine {
  width: 62px; flex: none; z-index: 12;
  border-right: 1.5px solid #ece8df; background: #f4f1ea;
  display: flex; flex-direction: column; align-items: center;
  padding: 12px 0; gap: 5px;
}
.spine__mark {
  width: 32px; height: 32px; border-radius: 9px; flex: none; margin-bottom: 6px;
  overflow: hidden; cursor: pointer; border: none;
  box-shadow: 0 2px 7px rgba(47, 109, 91, .28);
}
.spine__mark img { width: 100%; height: 100%; display: block; object-fit: cover; }
.spine__btn {
  width: 40px; height: 40px; border-radius: 11px; border: none; background: none;
  display: flex; align-items: center; justify-content: center;
  color: #6f6a5e; cursor: pointer; transition: background .12s, color .12s;
}
.spine__btn:hover { background: #ece7dd; }
.spine__btn.is-active { background: #eef3f1; color: #2f6d5b; }
.spine__btn--muted { color: #9a9384; }
.spine__divider { width: 26px; height: 1.5px; background: #e0dacd; margin: 2px 0; }
.spine__spacer { flex: 1; }
.spine__new {
  width: 40px; height: 40px; border-radius: 11px; border: none;
  display: flex; align-items: center; justify-content: center;
  background: #2f6d5b; color: #fff; cursor: pointer;
  box-shadow: 0 3px 9px rgba(47, 109, 91, .28); transition: background .12s;
}
.spine__new:hover { background: #28604f; }
.spine__avatar {
  width: 32px; height: 32px; flex: none; border-radius: 50%; border: none;
  margin-top: 6px; cursor: pointer;
  background: #dcebe5; color: #2f6d5b;
  display: flex; align-items: center; justify-content: center;
  font: 700 11px 'Hanken Grotesk', system-ui, sans-serif;
}

/* ── Main content area ───────────────────────────────────────── */
/* contain: stop a gesture that reaches the end of this scroller from chaining
   out to the document and dragging the shell (and the top bar) with it. */
.app-main { flex: 1; min-width: 0; overflow: auto; overscroll-behavior-y: contain; background: #efece4; }

/* Sticky per-page top bar (design: Delivery.dc.html main top bar). */
.app-topbar {
  position: sticky; top: 0; z-index: 5;
  height: 56px; flex: none; display: flex; align-items: center; gap: 10px;
  padding: 0 22px; border-bottom: 1.5px solid #e6e1d6;
  background: rgba(245, 242, 236, .86); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.app-topbar__title { font-family: 'Newsreader', serif; font-size: 17px; font-weight: 600; color: #26221b; }

/* Optical centring for every serif title that sits in a bar — this bar, the
   mobile one, the reader's two.
   Newsreader's ascent is shallow and its descent deep, so centring the line BOX
   leaves the cap band ~0.15em above the bar's middle with the unused descender
   space sitting below it. That reads as a title pinned to the top of the bar,
   and it is the same amount wrong everywhere because it comes from the font's
   metrics, not the bar's height.
   `top` moves the glyphs without touching layout, and an em keeps it correct at
   both sizes in use (17px chrome titles, 13.5px in .reader-topbar).
   Line-height cannot fix this: leading is symmetric about the baseline, so it
   moves the box and the glyphs together. */
.app-topbar__title,
.mobile-topbar__title,
.mtop-ctx__name,
.reader-topbar__name { /* defined in reader.css; same correction, same reason */
  position: relative;
  top: 0.15em;
}
.app-topbar__spacer { flex: 1; }
.app-topbar__actions { display: flex; align-items: center; gap: 8px; }
/* A page under the top bar starts at the top, not vertically centered. */
.app-topbar + .joris-page { justify-content: flex-start; }

/* Page hero — eyebrow + serif title + subtitle (Home/History/Routines). */
.page-hero__eyebrow { font-size: 12.5px; color: #9a9384; margin-bottom: 5px; }
.page-hero__title { font-family: 'Newsreader', serif; font-weight: 500; font-size: 30px; margin: 0 0 4px; color: #26221b; }
.page-hero__sub { font-size: 13.5px; color: #6f6a5e; margin: 0 0 22px; }
.page-hero__sub strong { color: #3a352c; font-weight: 600; }

/* ── Flyouts (nav + account) ─────────────────────────────────── */
.flyout { position: fixed; inset: 0; z-index: 30; background: rgba(38, 34, 27, .12); display: none; }
.flyout.is-open { display: block; }

.acctflyout {
  position: absolute; left: 70px; bottom: 14px; width: 250px;
  background: #fff; border: 1.5px solid #e6e1d6; border-radius: 14px;
  box-shadow: 0 20px 50px rgba(50, 42, 28, .18); padding: 7px;
}
/* No bottom rule of its own. It had one when seven settings rows sat between
   it and .acctflyout__sep; with those gone the two lines land a few pixels
   apart and read as a double separator. The sep is the one that means
   something — "below here is not a setting" — so it is the one that stays. */
.acctflyout__head {
  display: flex; align-items: center; gap: 9px; padding: 8px 9px 10px;
}
.acctflyout__head--link { border-radius: 10px; }
.acctflyout__head--link:hover { background: #f4f1ea; text-decoration: none; }
.acctflyout__row {
  display: flex; align-items: center; gap: 11px; padding: 9px 10px; border-radius: 9px;
  color: #26221b; font: 600 12.5px 'Hanken Grotesk', system-ui, sans-serif;
  cursor: pointer; text-decoration: none; width: 100%; border: none; background: none; text-align: left;
}
.acctflyout__row:hover { background: #f4f1ea; text-decoration: none; }
.acctflyout__row .meta { margin-left: auto; font-size: 10.5px; color: #9a9384; font-weight: 600; }
.acctflyout__row--danger { color: #b45b3e; }
/* Separates the two ways OUT of the app from the settings above them. Matches
   .moremenu__sep — 1px, inset from the rows' own padding. */
.acctflyout__sep { height: 1px; background: #f0ece3; margin: 5px 9px; }

.av { width: 28px; height: 28px; flex: none; border-radius: 50%; background: #dcebe5; color: #2f6d5b;
  display: flex; align-items: center; justify-content: center; font: 700 11px 'Hanken Grotesk', system-ui, sans-serif; }
.av--sm { width: 28px; height: 28px; }
.nav-name { font-weight: 600; font-size: 12.5px; color: #26221b; }
.nav-sub { font-size: 11px; color: #9a9384; }
.nav-ic { width: 18px; height: 18px; flex: none; }

/* Icon sprite host */
.nav-sprite { position: absolute; width: 0; height: 0; }

/* Impersonation banner — shown app-wide while an admin is "viewing as" a user.
   z-index 11 puts it over .app-topbar (5), which shares its top: 0, but UNDER
   the mobile bar (12) and both drawers (.flyout, 30). At 40 it outranked
   everything: on a phone it painted across the open nav drawer, hiding whatever
   row sat behind it, and the drawer is the one place you can't dismiss it from. */
.imp-banner { position: sticky; top: 0; z-index: 11; display: flex; align-items: center; gap: 10px; padding: 9px 18px; background: #b45b3e; color: #fff; font: 600 12.5px "Hanken Grotesk"; box-shadow: 0 2px 8px rgba(50,42,28,.18); }
.imp-banner strong { font-weight: 700; }
.imp-banner__eye { font-size: 14px; }
.imp-banner__msg { min-width: 0; }
.imp-banner__spacer { flex: 1; }
.imp-banner__stop { font: 600 11.5px "Hanken Grotesk"; padding: 6px 13px; border-radius: 8px; border: 1.5px solid rgba(255,255,255,.6); background: rgba(255,255,255,.14); color: #fff; cursor: pointer; }
.imp-banner__stop:hover { background: rgba(255,255,255,.26); }

/* ── Mobile top bar + nav drawer (<=720px) ───────────────────────
   Replaces the icon spine: a hamburger opens .mobilenav as a slide-in
   drawer (reusing the .flyout backdrop/open mechanics used by the account
   flyout below), and the same avatar button reopens that existing flyout —
   repositioned for a top-anchored trigger instead of the spine's. */
.mobile-topbar { display: none; }
.mobilenav { display: none; }

@media (max-width: 720px) {
  .app-shell { flex-direction: column; }
  .spine { display: none; }

  /* Let the DOCUMENT scroll on phones rather than an inner pane.
     Android Chrome only retracts its URL bar for document scrolls, so with the
     shell pinned to the dynamic viewport and .app-main scrolling inside it, the
     visible area never grows and the last stretch of a long page sits under the
     browser's chrome — unreachable. Intermittently so, which is the tell: dvh
     re-measures whenever the bar does happen to move, so how much you can reach
     depends on what the bar was doing when the shell was last laid out.

     The admin shell already carries this fix for the same reason. Making the
     bar sticky keeps the guarantee the dvh comment at the top of this file was
     protecting — it stays put without the shell having to pin the viewport. */
  .app-shell { height: auto; min-height: 100vh; min-height: 100dvh; overflow: visible; }
  .app-main { overflow: visible; }
  .mobile-topbar { position: sticky; top: 0; }

  /* Both drawers are fixed over a scrim, and the shell used to be unscrollable
     underneath them. Now that the document scrolls, a drag on the scrim would
     move the page behind the drawer — so hold it still while one is open. */
  html:has(.reader-shell--versions-open),
  html:has(.flyout.is-open) { overflow: hidden; }

  .mobile-topbar {
    display: flex; align-items: center; gap: 10px;
    height: 52px; flex: none; padding: 0 14px;
    border-bottom: 1.5px solid #ece8df; background: #f4f1ea; z-index: 12;
  }
  .mobile-topbar__menu {
    width: 34px; height: 34px; flex: none; border: none; background: none; border-radius: 9px;
    display: flex; align-items: center; justify-content: center; color: #26221b; cursor: pointer;
  }
  .mobile-topbar__menu:hover { background: #ece7dd; }
  /* The page title and actions live here on mobile — .app-topbar is hidden at
     this width, so this is the only bar. */
  .mobile-topbar__title {
    font-family: "Newsreader", serif; font-weight: 600; font-size: 17px; color: #26221b;
    min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .mobile-topbar__actions { display: flex; align-items: center; gap: 8px; flex: none; }
  .mobile-topbar__spacer { flex: 1; }

  .app-topbar { display: none; }

  /* The bar and the banner live in different containers but both stick to the
     top of the same scrolling document, so at top: 0 they landed on each other.
     52px is the bar's height: the banner parks directly beneath it.
     It also has to wrap here — two full email addresses and a button do not fit
     across a phone, and nowrap pushed "Stop impersonating" off the edge. */
  .imp-banner { top: 52px; flex-wrap: wrap; gap: 8px; padding: 8px 14px; font-size: 11.5px; }
  .imp-banner__spacer { display: none; }
  .imp-banner__msg { flex: 1 1 auto; }
  /* button_to wraps the button in a form, so the form is the flex child. */
  .imp-banner .button_to { margin-left: auto; }
  .imp-banner__stop { white-space: nowrap; }

  /* Reader: routine name + current version, doubling as the runs-drawer
     trigger, in place of the folded-away .reader-topbar. */
  /* `center`, not `baseline`: the version is a chip with its own padding now, so
     sitting the two on a shared baseline pushed it low against the title. */
  /* Not a button any more. The name is a page title and read as one, so making
     the whole thing the runs-drawer trigger meant the reader's only control was
     invisible. The chip below is the control; this is just the title beside it. */
  .mtop-ctx {
    display: flex; align-items: center; gap: 7px; min-width: 0; text-align: left;
  }
  /* Vertical position comes from the shared optical-centring rule above. */
  .mtop-ctx__name {
    font-family: "Newsreader", serif; font-weight: 600; font-size: 17px; line-height: 20px;
    color: #26221b; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  /* A chip, not grey text: this opens the runs drawer, and as a bare label
     beside the title nothing said it could be tapped. */
  .mtop-ctx__ver {
    flex: none; display: inline-flex; align-items: center; gap: 1px;
    font: 600 11px "Hanken Grotesk"; color: #6f6a5e;
    background: #ece7dd; border-radius: 7px; padding: 3px 4px 3px 7px;
    border: none; cursor: pointer;
  }
  .mtop-ctx__ver:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
  .mtop-ctx__caret { width: 13px; height: 13px; flex: none; }
  .mtop-ctx__ver:active { background: #ded7c8; color: #26221b; }

  /* Overflow trigger — the page's actions collapse behind this instead of each
     taking a slot in the bar. */
  .mobile-topbar__more {
    width: 34px; height: 34px; flex: none; border: none; background: none; border-radius: 9px;
    display: flex; align-items: center; justify-content: center; color: #26221b; cursor: pointer;
  }
  .mobile-topbar__more:active { background: #ece7dd; }

  /* Anchored under the bar's right edge. 58px clears the 52px bar, which is
     always at the very top — the impersonation banner renders inside .app-main,
     below the shell, so it never pushes this down. */
  .moremenu {
    position: absolute; right: 10px; top: 58px; width: 246px; max-width: calc(100vw - 20px);
    background: #fff; border: 1.5px solid #e6e1d6; border-radius: 14px;
    box-shadow: 0 20px 50px rgba(50, 42, 28, .18); padding: 7px;
  }
  .moremenu__row {
    display: flex; align-items: center; gap: 11px; width: 100%; padding: 12px 11px;
    border: none; border-radius: 9px; background: none; cursor: pointer; text-align: left;
    color: #26221b; font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif; text-decoration: none;
  }
  .moremenu__row:active { background: #f4f1ea; }
  .moremenu__row:hover { text-decoration: none; }
  .moremenu__row[disabled] { color: #9a9384; cursor: default; }
  .moremenu__row .nav-ic { flex: none; width: 17px; height: 17px; }
  .moremenu__row--go { color: #2f6d5b; }
  .moremenu__meta { margin-left: auto; font: 600 10.5px "Hanken Grotesk"; color: #9a9384; }
  .moremenu__sep { height: 1px; background: #f0ece3; margin: 5px 9px; }
  /* button_to wraps its button in a form; the form must not become the flex row. */
  .moremenu__form { display: block; }

  /* Copy confirms in place — the handler only toggles .is-copied, because
     rewriting the label would delete the row's icon with it. The confirmation
     REPLACES the label rather than sitting beside it: at 246px the two together
     wrap onto a second line, and the panel would change height for 1.6s. */
  .moremenu__done { display: none; color: #2f6d5b; font-weight: 700; }
  .moremenu__row.is-copied .moremenu__label { display: none; }
  .moremenu__row.is-copied .moremenu__done { display: inline; }

  .mobilenav {
    display: flex; flex-direction: column;
    position: absolute; left: 0; top: 0; bottom: 0; width: 82%; max-width: 284px;
    background: #faf8f3; box-shadow: 6px 0 26px rgba(50,42,28,.22);
    padding: 14px 12px 18px;
  }
  .mobilenav__brand {
    display: flex; align-items: center; gap: 9px; padding: 4px 8px 16px;
    color: #26221b; text-decoration: none;
    font-family: "Newsreader", serif; font-weight: 600; font-size: 17px;
  }
  .mobilenav__brand img { border-radius: 8px; box-shadow: 0 2px 7px rgba(47,109,91,.28); }
  .mobilenav__row {
    display: flex; align-items: center; gap: 11px; padding: 10px 11px; border-radius: 10px;
    color: #6f6a5e; text-decoration: none; font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif;
  }
  .mobilenav__row:hover { background: #f1ede4; text-decoration: none; }
  .mobilenav__row.is-active { background: #eef3f1; color: #2f6d5b; }
  /* Inset from the rows' own padding, like .moremenu__sep — a rule running the
     full width of the sheet would read as the end of the menu rather than a
     break inside it. */
  .mobilenav__sep { height: 1.5px; background: #e8e3d9; margin: 7px 11px; }
  .mobilenav__spacer { flex: 1; }
  .mobilenav__cta {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    padding: 12px; border-radius: 11px; background: #2f6d5b; color: #fff; text-decoration: none;
    font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif;
  }
  /* Sits under the locked CTA on phones, where there is no hover to carry a
     title attribute. */
  .mobilenav__ctanote { margin-top: 7px; font-size: 11.5px; line-height: 1.5; color: #9a9384; padding: 0 2px; }
  .mobilenav__cta:hover { background: #28604f; text-decoration: none; }

  /* Account row — the drawer's footer, under the New routine CTA. Carded rather
     than another __row so it reads as the end of the list instead of a fourth
     destination, and so the CTA above it stays the one green thing in here. */
  .mobilenav__acct {
    display: flex; align-items: center; gap: 10px; width: 100%; margin-top: 10px;
    padding: 9px 11px; border: 1.5px solid #ece8df; border-radius: 12px;
    background: #fff; cursor: pointer; text-align: left; color: #26221b;
  }
  .mobilenav__acct:active { background: #f4f1ea; }
  .mobilenav__acct-text { flex: 1; min-width: 0; }
  .mobilenav__acct-name {
    display: block; font: 600 13px "Hanken Grotesk", system-ui, sans-serif;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .mobilenav__acct-sub {
    display: block; font: 500 11px "Hanken Grotesk", system-ui, sans-serif; color: #9a9384;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  }
  .mobilenav__acct-gear { flex: none; width: 17px; height: 17px; color: #9a9384; }

  /* The account menu's trigger moved from the top bar into the drawer's footer,
     so it can no longer hang off the top right. It opens in the drawer's own
     column, directly above the row that opened it — the drawer stays put
     underneath, because it is the navigation and this is part of it.
     `bottom` clears the drawer's 18px floor plus the ~51px account row. */
  .acctflyout {
    left: 12px; right: auto; top: auto; bottom: 77px;
    width: calc(min(82vw, 284px) - 24px);
  }
  /* The drawer below is already dimming the page; a second scrim on top of it
     would darken twice and make the still-open drawer look disabled. */
  #acct-flyout { background: none; }
  /* 9px around a 12.5px label is a ~36px target — fine for a cursor, short for
     a thumb, and these are now the only way to reach settings on a phone. */
  .acctflyout__row { padding: 12px 11px; font-size: 13.5px; }
  .acctflyout__head { padding: 10px 9px 12px; }
}

/* ── Navigation progress (navigating.js) ──────────────────────────────────
   A plain MPA hands off to the browser on click and the old page stays put,
   fully painted and completely inert, until the new document arrives. This is
   the only thing between the tap and that moment.

   Fixed to the viewport and above everything, including a <dialog> in the top
   layer — a link inside a modal navigates too, and a bar hidden behind the
   scrim would be telling nobody. */
.navbar-progress {
  position: fixed; top: 0; left: 0; z-index: 2147483647;
  width: 100%; height: 2.5px; transform-origin: 0 50%;
  background: linear-gradient(90deg, #2f6d5b, #4f9b83);
  /* scaleX rather than width: it runs on the compositor, so the bar keeps
     moving while the main thread is busy parsing the response — which is
     exactly the moment it has a job to do. */
  transform: scaleX(0.04);
  transition: transform 8s cubic-bezier(.05, .7, .1, 1);
}
/* Never reaches the end. The navigation is what finishes it, by replacing the
   document — a bar that completes and sits there has told a lie about a page
   that has not arrived. */
.navbar-progress.is-running { transform: scaleX(0.92); }

@media (prefers-reduced-motion: reduce) {
  /* Still shown — it is information, not decoration — but it arrives at its
     resting length instead of crawling there. */
  .navbar-progress { transition: none; transform: scaleX(0.35); }
  .navbar-progress.is-running { transform: scaleX(0.35); }
}

/* The row you pressed, looking pressed. Nav rows are the case that needs it:
   you tap a pill in the settings strip or a routine in the reader strip and
   the answer is a page away. */
.is-navigating { opacity: .62; }
.snav__row.is-navigating,
.rnav__row.is-navigating,
.adm-navrow.is-navigating,
.mobilenav__row.is-navigating { opacity: 1; background: #eef3f1; border-color: #a9cabd; }
/* History — searchable, date-grouped feed of every delivery.
   Design: Delivery.dc.html isHistory view. */

.hist { max-width: 880px; margin: 0 auto; padding: var(--page-top) var(--page-gutter) 90px; }

/* All three controls share one height for a balanced search header. */
.hist-search { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 24px; }
.hist-search__field {
  display: flex; align-items: center; gap: 8px; flex: 1; min-width: 220px; max-width: 360px;
  height: 44px; padding: 0 14px; border: 1.5px solid #e6e1d6; border-radius: 11px; background: #fff;
}
.hist-search__field svg { width: 16px; height: 16px; color: #9a9384; flex: none; }
.hist-search__field input {
  flex: 1; min-width: 0; height: 100%; border: none; outline: none; background: transparent;
  font: 400 13.5px 'Hanken Grotesk', system-ui, sans-serif; color: #26221b;
}
.hist-search__field input::placeholder { color: #9a9384; }

/* The shared select rule in components.css supplies the look — this was the
   family it was promoted from. Only the width is local. */
.hist-search__filter { max-width: 210px; margin: 0; }

/* Search button matches the input height (was btn--sm, too small). */
.hist-search .btn { height: 44px; padding: 0 20px; border-radius: 11px; }

.hist-day {
  font: 700 10.5px 'Hanken Grotesk', system-ui, sans-serif; letter-spacing: .6px;
  color: #a49d8d; text-transform: uppercase; margin: 0 0 10px;
}
.hist-group { display: flex; flex-direction: column; gap: 8px; margin-bottom: 22px; }

.hist-row {
  display: flex; align-items: center; gap: 11px; padding: 11px 14px;
  border: 1.5px solid #e6e1d6; border-radius: 11px; background: #fff;
  cursor: pointer; text-decoration: none; color: inherit; transition: border-color .12s;
}
.hist-row:hover { border-color: #cfe0d9; text-decoration: none; }
.hist-row__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #9a9384; }
.hist-row__dot--success { background: #2f6d5b; }
.hist-row__dot--failed { background: #b45b3e; }
.hist-row__dot--pending { background: #c8a24b; }
.hist-row__chip {
  font: 600 11px 'Hanken Grotesk', system-ui, sans-serif; padding: 4px 9px; border-radius: 999px;
  background: #eef4f1; color: #2f6d5b; white-space: nowrap; flex: none;
}
.hist-row__title { flex: 1; min-width: 0; font-size: 13px; color: #3a352c; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hist-row__meta { font-size: 11.5px; color: #9a9384; white-space: nowrap; flex: none; }

.hist-empty { color: #8a8478; font-size: 13.5px; }
/* Routines list — overview table (design: Delivery.dc.html isRoutinesView). */

.rt { max-width: 880px; margin: 0 auto; padding: var(--page-top) var(--page-gutter) 90px; }

.rt-table { border: 1.5px solid #e6e1d6; border-radius: 14px; background: #fff; }
.rt-head, .rt-row { display: flex; gap: 12px; align-items: center; padding: 12px 18px; }
.rt-head {
  background: #faf8f3; border-radius: 14px 14px 0 0;
  font: 600 10.5px 'Hanken Grotesk', system-ui, sans-serif; letter-spacing: .4px; color: #a49d8d;
}
.rt-row { border-top: 1.5px solid #f0ece3; }
.rt-row:last-child { border-radius: 0 0 14px 14px; }
.rt-row:hover { background: #faf8f3; }
/* A parked row is quieter, NOT shaded.
   It was `opacity: .68`, which did two things nobody wanted: opacity below 1
   creates a stacking context, trapping an open ⋯ menu inside its own row so
   later rows painted over it, and it faded the whole subtree so the menu panel
   went translucent. Replacing it with a background band was worse in a
   different way — interleaved with white rows it reads as broken zebra
   striping rather than a status, and on the Paused filter EVERY row is banded,
   where dimming says nothing at all because there is nothing to be dim against.
   Shading is relative; text colour is not.
   The fact is already in the row twice — "You paused it" in NEXT, and a Resume
   button where an active row has Pause — so this only has to make the row read
   quieter, not announce anything. */
/* A parked row is greyed out. Neutral grey, not the warm cream the rest of the
   table is built from — that is the point of the colour rather than an accident
   of it: a desaturated band against a warm palette reads as "switched off",
   where the warm #f3efe6 tried earlier just read as an alternate row and looked
   like broken zebra striping.
   Its own hover step is required, not decorative: .rt-row:hover and
   .rt-row.is-paused have equal specificity and this one is declared later, so
   without it a paused row would silently stop responding to the cursor. */
.rt-row.is-paused { background: #f3f3f3; }
.rt-row.is-paused:hover { background: #ebebeb; }
.rt-row.is-paused .rt-name,
.rt-row.is-paused .rt-run__title { color: #9a9384; }

/* Columns (header + rows share these widths) */
.rt-c-routine { flex: 1.6; display: flex; align-items: center; min-width: 0; }
.rt-c-routine__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
/* Last run replaced the schedule and provider columns. The schedule moved under
   the name (it is a property of the routine, not a peer of "when did it last
   run"), and the provider chip went entirely — since §2 of product-direction
   there is one provider and nobody can choose it, so the column printed the
   same word on every row forever. */
.rt-c-run { width: 232px; flex: none; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.rt-c-next { width: 104px; flex: none; display: flex; flex-direction: column; gap: 2px; }
.rt-c-act { width: 140px; flex: none; display: flex; align-items: center; justify-content: flex-end; gap: 4px; }

.rt-routine-link { min-width: 0; text-decoration: none; color: inherit; }
.rt-routine-link:hover .rt-name { text-decoration: underline; }
.rt-name { flex: 1 1 auto; min-width: 0; font-weight: 600; font-size: 13.5px; color: #26221b; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-sub { font-size: 11.5px; color: #9a9384; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- last run ----
   Three facts on two lines: did it work, when, and what it produced. The title
   is the only link in the cell because it is the only one with somewhere to go. */
.rt-run__line { display: flex; align-items: baseline; gap: 7px; min-width: 0; }
.rt-run__state { display: inline-flex; align-items: center; gap: 6px; flex: none; font: 600 11.5px 'Hanken Grotesk', system-ui, sans-serif; }
.rt-run__dot { width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }
.rt-run__state--success { color: #2f6d5b; }
.rt-run__state--pending { color: #8a6b33; }
.rt-run__state--failed { color: #b45b3e; }
.rt-run__when { font-size: 11.5px; color: #9a9384; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-run__title { font-size: 12.5px; color: #2f6d5b; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.rt-run__none { font-size: 12.5px; color: #9a9384; }

.rt-next__day { font-size: 12.5px; color: #3a352c; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-next__time { font-size: 11.5px; color: #9a9384; }
.rt-row.is-paused .rt-next__day { color: #9a9384; }

/* ---- row actions ----
   Run now and Pause/Resume left the ⋯ menu, because they are what people open
   this page to do and a menu made the common act cost two clicks. They rest at
   55% and come up on row hover, so six rows of buttons do not shout. */
.rt-act__form { margin: 0; display: inline-flex; }
.rt-act {
  font: 600 12px 'Hanken Grotesk', system-ui, sans-serif; padding: 7px 11px;
  border-radius: 9px; border: none; cursor: pointer; white-space: nowrap;
  background: #f2efe8; color: #3a352c;
}
.rt-act:hover { background: #e6e1d6; }
.rt-act--resume { background: #e4efe9; color: #2f6d5b; }
.rt-act--resume:hover { background: #d7e7df; }
.rt-act--icon { width: 30px; padding: 7px 0; text-align: center; font-size: 10px; letter-spacing: 1px; }
.rt-c-act { opacity: .55; transition: opacity var(--dur-fast, .12s); }
/* :has() on the parent — `.rt-menu[open] { opacity: 1 }` cannot lift an opacity
   set on its own ancestor, so an open menu would have faded with the row. */
.rt-row:hover .rt-c-act, .rt-c-act:focus-within, .rt-c-act:has(.rt-menu[open]) { opacity: 1; }
@media (hover: none) { .rt-c-act { opacity: 1; } }

/* Row actions — native <details> menu (no JS), escapes the table via overflow. */
.rt-menu { position: relative; }
.rt-menu > summary {
  list-style: none; cursor: pointer; width: 26px; height: 26px; border-radius: 7px;
  display: flex; align-items: center; justify-content: center;
  color: #9a9384; font-weight: 700; font-size: 16px; line-height: 1;
}
.rt-menu > summary::-webkit-details-marker { display: none; }
.rt-menu > summary:hover { background: #ece7dd; color: #6f6a5e; }
.rt-menu[open] > summary { background: #ece7dd; color: #2f6d5b; }
/* Belt and braces, and only that — worth being accurate about. Removing the
   paused row's opacity is what actually fixed this: a later row's `.rt-c-act`
   opacity context paints at effective z-index 0, which the panel's z-index 20
   already beats. This makes the intent explicit and survives someone giving a
   row a z-index later. */
.rt-row:has(.rt-menu[open]) { position: relative; z-index: 30; }

.rt-menu__panel {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 20; width: 172px;
  background: #fff; border: 1.5px solid #e6e1d6; border-radius: 12px; padding: 6px;
  box-shadow: 0 16px 40px rgba(50, 42, 28, .16); display: flex; flex-direction: column; gap: 1px;
}
/* Uniform rows whether link_to (<a>) or button_to (<form><button>) */
.rt-menu__panel a,
.rt-menu__panel button {
  display: flex; align-items: center; width: 100%; text-align: left;
  padding: 8px 10px; border: none; background: none; border-radius: 8px; cursor: pointer;
  font: 600 12.5px 'Hanken Grotesk', system-ui, sans-serif; color: #26221b; text-decoration: none;
}
.rt-menu__panel form { margin: 0; }
.rt-menu__panel a:hover,
.rt-menu__panel button:hover { background: #f4f1ea; text-decoration: none; }
.rt-menu__panel .is-danger { color: #b45b3e; }
.rt-menu__divider { height: 1.5px; background: #f0ece3; margin: 4px 2px; }

.rt-empty { color: #8a8478; font-size: 13.5px; }

/* ---------------------------------------------------------------
   First routine — the empty state for an account with none.

   Not a variant of .rt-empty: that one still serves "nothing ACTIVE right now"
   under the filters, where a paragraph is right because the page is otherwise
   full. This is the whole page, and it is the only thing selling the idea to
   someone who has just arrived.
   --------------------------------------------------------------- */

.rt-first {
  background: var(--paper); border: 1.5px solid var(--border-default);
  border-radius: 18px; padding: 30px 32px 26px; max-width: 760px;
  /* The hero's whole bottom margin lives on .page-hero__sub (app_shell.css),
     and that line is suppressed when there are no routines — so without this
     the card sat 4px under the h1. Slightly more than a populated page's 26px,
     because this card is the only thing on the page. */
  margin-top: var(--space-7);
}
.rt-first__h {
  font-family: "Newsreader", serif; font-weight: 500; font-size: 25px;
  line-height: 1.2; margin: 0; color: var(--ink);
}
.rt-first__lede {
  font-size: 14px; line-height: 1.65; color: var(--text-muted);
  margin: 10px 0 0; max-width: 600px;
}

.rt-first__steps {
  list-style: none; margin: 26px 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--border-divider);
  border: 1.5px solid var(--border-divider); border-radius: 14px; overflow: hidden;
}
.rt-first__step { background: var(--paper-warm); padding: 17px 18px; }
.rt-first__n {
  display: inline-flex; width: 22px; height: 22px; border-radius: 7px;
  align-items: center; justify-content: center; margin-bottom: 9px;
  background: var(--primary-tint); color: var(--primary);
  font: 500 11px "JetBrains Mono", ui-monospace, monospace;
}
.rt-first__sh { display: block; font-weight: 600; font-size: 13.5px; color: var(--ink); margin-bottom: 3px; }
.rt-first__sb { display: block; font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }

.rt-first__acts { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 28px; }
.rt-first__go {
  font: 600 14px "Hanken Grotesk", system-ui, sans-serif;
  padding: 14px 22px; border-radius: 12px;
  background: var(--primary); color: #fff;
  box-shadow: 0 4px 14px rgba(47, 109, 91, .26);
}
.rt-first__go:hover { background: var(--primary-press); color: #fff; text-decoration: none; }
.rt-first__alt { font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif; color: var(--primary); }

.rt-first__tour { display: flex; align-items: center; gap: 7px; margin-top: 16px; flex-wrap: wrap; }
.rt-first__tourform { display: inline; }
.rt-first__tourbtn {
  border: none; background: transparent; padding: 0; cursor: pointer;
  font: 600 12.5px "Hanken Grotesk", system-ui, sans-serif; color: var(--text-muted);
  text-decoration: underline; text-decoration-color: var(--border-strong); text-underline-offset: 3px;
}
.rt-first__tourbtn:hover { color: var(--ink); }
.rt-first__tournote { font-size: 12.5px; color: var(--text-faint); }

@media (max-width: 720px) {
  .rt-first { padding: 24px 20px 22px; }
  .rt-first__steps { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------
   Needs you — routines that will not fix themselves, lifted OUT of the table.
   Previously this was a gold left edge plus a pill inside the row, which gave
   the one thing needing a decision the same visual weight as five things that
   did not. The row keeps a quiet gold edge so the two are obviously the same
   routine; the card is where the reason and the fix live.
   --------------------------------------------------------------- */
.rt-attn__label {
  font: 600 10.5px 'Hanken Grotesk', system-ui, sans-serif; letter-spacing: .05em;
  text-transform: uppercase; color: #8a6b33; margin-bottom: 8px;
}
.rt-attn { display: flex; flex-direction: column; gap: 8px; margin-bottom: 26px; }
.rt-attn__card {
  display: flex; align-items: flex-start; gap: 12px; flex-wrap: wrap;
  border-radius: 14px; background: #fffdf7; border: 1.5px solid #ecdcb4;
  border-left: 4px solid #c9a24a; padding: 14px 16px;
  box-shadow: 0 1px 3px rgba(50, 42, 28, .05);
}
.rt-attn__body { flex: 1; min-width: 190px; }
.rt-attn__name { font-weight: 600; font-size: 14px; color: #26221b; text-decoration: none; }
.rt-attn__name:hover { text-decoration: underline; color: #26221b; }
.rt-attn__reason { font-size: 12.5px; line-height: 1.5; color: #6f6a5e; margin-top: 4px; }
.rt-attn__fix {
  flex: none; display: inline-block; border: none; cursor: pointer; text-decoration: none;
  font: 600 12.5px 'Hanken Grotesk', system-ui, sans-serif;
  padding: 9px 14px; border-radius: 10px; background: #c9a24a; color: #2b2109;
}
.rt-attn__fix:hover { background: #ba9440; color: #2b2109; text-decoration: none; }

.rt-row--broken { border-left: 4px solid #c9a24a; background: #fffdf7; padding-left: 14px; }

/* ---- mobile ----
   The fixed columns total 476px plus gaps, wider than a phone before
   .rt-c-routine gets anything. Stack: name and actions on one line, last run
   and next on a second. Next collapses to a single line — on a phone "when is
   it next" is one fact, not a stacked pair. */
@media (max-width: 720px) {
  .rt-head { display: none; }

  .rt-row { flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 14px 16px; }
  .rt-row--broken { padding-left: 12px; }
  .rt-c-routine { order: 1; flex: 1 1 auto; min-width: 0; }
  .rt-c-act { order: 2; width: auto; }
  .rt-c-run { order: 3; flex: 1 1 100%; width: auto; }
  .rt-c-next { order: 4; flex: 1 1 100%; width: auto; flex-direction: row; gap: 6px; align-items: baseline; }

  .rt-attn__fix { width: 100%; text-align: center; }
}
/* Admin console — owner-only dashboard shell + Overview. Same palette as the app. */
.adm { display: flex; height: 100vh; height: 100dvh; width: 100%; overflow: hidden; background: #efece4; color: #26221b; }
.adm .mono { font-family: ui-monospace, Menlo, monospace; font-size: 11.5px; }

/* icon spine */
.adm-spine { width: 62px; flex: none; border-right: 1.5px solid #ece8df; background: #f4f1ea; display: flex; flex-direction: column; align-items: center; padding: 12px 0; gap: 6px; z-index: 12; }
.adm-spine__logo { width: 32px; height: 32px; border-radius: 9px; box-shadow: 0 2px 7px rgba(47,109,91,.28); margin-bottom: 4px; display: block; }
.adm-spine__icon { width: 38px; height: 38px; border-radius: 11px; display: flex; align-items: center; justify-content: center; color: #6f6a5e; }
.adm-spine__icon:hover { background: #ece7dd; }
.adm-spine__icon.is-current { background: #26221b; color: #fff; }
.adm-spine__grow { flex: 1; }
.adm-spine__avatar { width: 32px; height: 32px; flex: none; border-radius: 50%; background: #dcebe5; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font: 700 11px "Hanken Grotesk"; margin-top: 6px; }

/* section nav */
/* The same column the settings sidebar uses (joris/settings.css .snav) —
   56px head with a rule under it, then white cards on a warm ground, green
   tint for where you are. It used to be a tighter list with a filled-black
   active row, which read as a different product from the one two clicks away.
   Admin is still admin: what says so is the wordmark and the OWNER chip, not
   a second visual language. */
.adm-nav {
  width: 260px; flex: none; background: #faf8f2;
  border-right: 1.5px solid #ece8df; display: flex; flex-direction: column;
}
.adm-nav__head {
  height: 56px; flex: none; display: flex; align-items: center; gap: 8px;
  padding: 0 10px 0 16px; border-bottom: 1.5px solid #ece8df;
}
.adm-nav__title { position: relative; top: .15em; font-family: "Newsreader", serif; font-size: 16px; font-weight: 600; color: #26221b; }
.adm-nav__owner { font: 700 8.5px "Hanken Grotesk"; letter-spacing: .4px; background: #26221b; color: #fff; padding: 2px 7px; border-radius: 5px; }
.adm-nav__list { flex: 1; overflow: auto; padding: 12px 12px 16px; display: flex; flex-direction: column; gap: 8px; }
.adm-navrow {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 12px; border-radius: 12px;
  background: #fff; border: 1.5px solid #e6ded1;
  font: 600 14px "Hanken Grotesk"; color: #26221b; cursor: pointer;
  text-decoration: none; transition: border-color .12s, background .12s;
}
.adm-navrow:hover { border-color: #cfe0d9; text-decoration: none; }
.adm-navrow.is-active { background: #f7fbf9; border-color: #a9cabd; color: #322a1c; }
.adm-navrow.is-active:hover { border-color: #a9cabd; }
.adm-navrow svg { flex: none; color: #6f6a5e; }
.adm-navrow.is-active svg { color: #2f6d5b; }
.adm-navrow__label { flex: 1; min-width: 0; }
.adm-navrow.is-disabled { color: #b7b0a1; cursor: default; background: #faf8f2; }
.adm-navrow.is-disabled:hover { border-color: #e6ded1; }
.adm-navrow.is-disabled svg { color: #b7b0a1; }
.adm-navrow__soon { font: 600 8.5px "Hanken Grotesk"; letter-spacing: .3px; background: #ece7dd; color: #9a9384; padding: 2px 6px; border-radius: 5px; }

/* main */
.adm-main { flex: 1; min-width: 0; display: flex; flex-direction: column; background: #efece4; }
.adm-topbar { height: 56px; flex: none; display: flex; align-items: center; gap: 11px; padding: 0 26px; border-bottom: 1.5px solid #e6e1d6; background: rgba(245,242,236,.86); backdrop-filter: blur(8px); }
.adm-topbar__title { font-family: "Newsreader", serif; font-size: 19px; font-weight: 500; }
.adm-topbar__spacer { flex: 1; }
.adm-topbar__crumb { color: #9a9384; }

/* No mobile drawer here. Admin used to slide .adm-nav in from the right behind
   a scrim, while Settings — the same column, two clicks away — lay its rows
   down as a scrolling strip above the page. Two different answers to the same
   question on a phone, and the drawer was the worse one: it hid where you are
   behind a tap. The strip is in the @media blocks below, matching .snav. */
.adm-guidetoggle { font: 600 11px "Hanken Grotesk"; padding: 6px 12px; border-radius: 999px; cursor: pointer; border: 1.5px solid #e6e1d6; background: #fff; color: #9a9384; }
.adm-guidetoggle.is-on { border-color: #e0d3b8; background: #fbf3e4; color: #a4712f; }
.adm-scroll { flex: 1; overflow: auto; padding: 28px 30px 80px; }
.adm-content { max-width: 1040px; margin: 0 auto; }

/* guide banner */
.adm-guide { border: 1.5px solid #e0d3b8; background: linear-gradient(#fdf8ee, #fbf3e4); border-radius: 14px; padding: 16px 18px; margin-bottom: 18px; display: flex; gap: 13px; }
.adm-guide[hidden] { display: none; }
.adm-guide__icon { width: 32px; height: 32px; flex: none; border-radius: 9px; background: #f0e2c6; color: #a4712f; display: flex; align-items: center; justify-content: center; font-size: 16px; }
.adm-guide__body { flex: 1; min-width: 0; }
.adm-guide__title { font-weight: 700; font-size: 13px; margin-bottom: 4px; color: #5c4a28; }
.adm-guide__text { font-size: 12.5px; line-height: 1.6; color: #7a6a4c; }
.adm-guide__watch { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 11px; }
.adm-guide__chip { font: 600 11px "Hanken Grotesk"; padding: 5px 11px; border-radius: 999px; background: #fff; border: 1.5px solid #ecdcbf; color: #8a6420; }
.adm-guide__close { flex: none; width: 24px; height: 24px; border: none; background: none; border-radius: 7px; display: flex; align-items: center; justify-content: center; color: #b8a06f; cursor: pointer; font-size: 14px; }
.adm-guide__close:hover { background: #f0e2c6; }

/* KPIs */
.adm-kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: 13px; margin-bottom: 14px; }
.adm-kpi { border: 1.5px solid #e0dacd; border-radius: 14px; background: #fff; padding: 15px 16px; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
.adm-kpi__label { font: 600 10px "Hanken Grotesk"; letter-spacing: .4px; color: #9a9384; margin-bottom: 10px; }
.adm-kpi__val { font-family: "Newsreader", serif; font-size: 27px; font-weight: 500; line-height: 1; }
.adm-kpi__delta { font-size: 10.5px; margin-top: 6px; }

/* the business goal: one bar, read at a glance */
.adm-goal { margin-bottom: 14px; }
.adm-goal__bar { height: 10px; border-radius: 5px; background: #efe9dc; overflow: hidden; margin: 12px 0 8px; }
.adm-goal__fill { height: 100%; border-radius: 5px; background: linear-gradient(90deg, #8fbca9, #2f6d5b); }
.adm-goal__row { display: flex; justify-content: space-between; gap: 10px; font-size: 11px; flex-wrap: wrap; }

/* two-column: bars + attention */
.adm-grid2 { display: grid; grid-template-columns: 1.6fr 1fr; gap: 14px; }
.adm-card { border: 1.5px solid #e0dacd; border-radius: 14px; background: #fff; padding: 18px 20px; }
.adm-card__head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 16px; }
.adm-card__title { font-weight: 600; font-size: 13px; }
.adm-card__sub { color: #9a9384; }
.adm-bars { display: flex; align-items: flex-end; gap: 6px; height: 132px; }
.adm-bar { flex: 1; background: linear-gradient(#cfe0d9, #b6d1c6); border-radius: 4px 4px 0 0; min-height: 2px; }
.adm-attn { display: flex; flex-direction: column; gap: 9px; }
.adm-attn__row { display: flex; align-items: center; gap: 11px; padding: 10px 11px; border: 1.5px solid #f0ece3; border-radius: 10px; }
.adm-attn__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.adm-attn__text { flex: 1; font-size: 12.5px; }
.adm-attn__n { font-weight: 600; color: #6f6a5e; }

/* unit economics */
.adm-econ { margin-top: 14px; }
.adm-econ__head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 12px; }
.adm-econ__spacer { flex: 1; }
.adm-econ__legend { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; color: #9a9384; }
.adm-econ__sq { width: 8px; height: 8px; border-radius: 2px; display: inline-block; }
.adm-econ__stub { font-size: 12px; line-height: 1.6; color: #6f6a5e; background: #faf8f3; border: 1.5px solid #f0ece3; border-radius: 11px; padding: 12px 14px; margin-bottom: 16px; }
.adm-econ__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.adm-econ__card { border-radius: 12px; padding: 13px 15px; border: 1.5px solid #e0dacd; background: #fff; }
.adm-econ__card--input { border-color: #d7e0e6; background: #f7fafb; }
.adm-econ__label { display: flex; align-items: center; gap: 7px; font: 600 10px "Hanken Grotesk"; letter-spacing: .4px; color: #9a9384; margin-bottom: 9px; }
.adm-econ__val { font-family: "Newsreader", serif; font-size: 24px; font-weight: 500; line-height: 1; color: #c2bbac; }
.adm-econ__note { font-size: 10.5px; color: #9a9384; margin-top: 5px; line-height: 1.4; }
.adm-econ__plain { font-size: 11px; color: #6f6a5e; margin-top: 9px; padding-top: 9px; border-top: 1.5px solid #f3f0e8; line-height: 1.5; }

/* Matches shared/_app_shell's own breakpoint: below this .mobile-topbar (a
   flex child of .adm, same as every other page) becomes visible and must
   stack full-width above the nav+main row instead of sharing it. */
/* Mirrors .snav's first step (joris/settings.css): narrow, then lie down. */
@media (max-width: 880px) {
  .adm-nav { width: 196px; }
  .adm-nav__list { padding: 10px 9px 14px; }
  .adm-navrow { padding: 10px; }
}

@media (max-width: 720px) {
  .adm { flex-direction: column; }

  /* The desktop shell pins itself to the viewport and scrolls .adm-scroll
     internally. Stacked, that inner pane grows to its full content height
     inside a 100vh clip, so nothing below the fold is reachable. On phones
     let the document scroll instead — the nav is position:fixed here, so it
     doesn't need the pinned parent. */
  .adm { height: auto; min-height: 100vh; min-height: 100dvh; overflow: visible; }
  .adm-scroll { overflow: visible; padding: 20px var(--page-gutter) 90px; }

  /* Folded into the global bar. Stacked under .mobile-topbar this was the same
     108px of chrome the app pages just shed. */
  .adm-topbar { display: none; }

  /* The sections, as a scrolling strip under the top bar — the same shape,
     spacing and pill treatment as Settings (.snav at this width). Rows keep
     their icons and badges; only the axis changes. */
  .adm-nav {
    width: 100%; order: 1;
    border-right: none; border-bottom: 1.5px solid #ece8df;
  }
  .adm-nav__head { display: none; }
  .adm-nav__list {
    flex-direction: row; overflow-x: auto; overflow-y: hidden;
    padding: 10px 14px; gap: 7px;
    scrollbar-width: none;
  }
  .adm-nav__list::-webkit-scrollbar { display: none; }
  .adm-navrow { flex: none; padding: 8px 13px; border-radius: 999px; }
  .adm-navrow__label { flex: none; white-space: nowrap; }
  .adm-main { order: 2; }
}

@media (max-width: 860px) {
  .adm-kpis { grid-template-columns: repeat(2, 1fr); }
  .adm-grid2, .adm-econ__grid { grid-template-columns: 1fr; }

  /* Dense data tables (Users, Providers, Tickets) keep their desktop column
     widths and scroll horizontally rather than squeezing — fixed-width
     columns can't shrink to fit a phone without overlapping. */
  .adm-table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .adm-table__head, .adm-urow { width: max-content; min-width: 100%; }

  /* The one flexible column in each table sizes to its own content under
     max-content, so the header and every row would land on a different
     width and the columns would stop lining up. Pin it. */
  .adm-uc-user, .adm-tc-sub { flex: none; width: 190px; }
  .adm-pc-name { flex: none; width: 160px; }
  /* Empty in the header, buttons in the rows — pin it so the header strip
     ends where the rows do. */
  .adm-pc-act { width: 64px; }

  /* ...except where a row carries four of them. Blog posts have read/edit/
     publish/delete, and 64px is not a width they fit in: they overflowed the
     column, the table clipped them, and there was no way to publish or delete
     a post from a phone at all. Sideways scrolling is the wrong answer for a
     row this tall, so this table stacks — title on its own line, meta under
     it, actions as a full-width strip. */
  .adm-table--stack .adm-table__head { display: none; }
  .adm-table--stack .adm-urow {
    width: auto; min-width: 0; flex-wrap: wrap; gap: 3px 12px; padding: 14px 16px;
  }
  .adm-table--stack .adm-pc-name { flex: 1 1 100%; width: auto; }
  .adm-table--stack .adm-pc-kind,
  .adm-table--stack .adm-pc-model,
  .adm-table--stack .adm-pc-key { width: auto; flex: 0 0 auto; font-size: 11px; color: #9a9384; }
  /* Providers carries three more columns than Blog does, and two of them are
     controls rather than facts. They join the action strip instead of the meta
     line: "make default" and the On/Off toggle are things you press. */
  .adm-table--stack .adm-pc-def,
  .adm-table--stack .adm-pc-state { width: auto; flex: 0 0 auto; }
  .adm-table--stack .adm-pc-act {
    flex: 1 1 100%; width: auto; margin: 8px 0 0; flex-wrap: wrap; gap: 6px 18px;
  }
  /* A bare 11px word is not a tap target; give them a real one now that there
     is a whole line to spend. */
  .adm-table--stack .adm-linkbtn { padding: 6px 0; font-size: 12px; }

  .adm-usearch { flex-wrap: wrap; }
  .adm-usearch__field { flex: 1 1 100%; }
  .adm-usearch__select, .adm-usearch__btn { flex: 1 1 auto; }
}

/* ---------------- Users: search + table ---------------- */
.adm-usearch { display: flex; gap: 10px; margin-bottom: 16px; }
.adm-usearch__field { flex: 1; display: flex; align-items: center; gap: 9px; border: 1.5px solid #e0dacd; border-radius: 11px; background: #fff; padding: 0 14px; color: #9a9384; }
.adm-usearch__input { flex: 1; border: none; outline: none; background: none; font: 400 12.5px "Hanken Grotesk"; color: #26221b; padding: 10px 0; }
/* Was left on the browser default, so it rendered as a system widget next to
   hand-built fields. The shared select rule owns it now; admin keeps its
   smaller, denser type. */
.adm-usearch__select { height: 40px; font: 600 11.5px "Hanken Grotesk"; padding: 0 34px 0 12px; color: #6f6a5e; }
.adm-usearch__btn { font: 600 11.5px "Hanken Grotesk"; padding: 10px 16px; border: none; border-radius: 11px; background: #2f6d5b; color: #fff; cursor: pointer; }
.adm-usearch__btn:hover { background: #28604f; }

.adm-table { border: 1.5px solid #e0dacd; border-radius: 14px; background: #fff; overflow: hidden; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
.adm-table__head { display: flex; gap: 12px; padding: 11px 18px; background: #f7f4ee; border-bottom: 1.5px solid #ece8df; font: 700 9.5px "Hanken Grotesk"; letter-spacing: .4px; color: #a49d8d; }
.adm-urow { display: flex; gap: 12px; align-items: center; padding: 12px 18px; border-bottom: 1.5px solid #f3f0e8; color: #26221b; }
.adm-urow:hover { background: #fcfbf7; text-decoration: none; }
.adm-urow:last-child { border-bottom: none; }
.adm-uc-id { width: 40px; flex: none; }
.adm-uc-user { flex: 2; display: flex; align-items: center; gap: 11px; min-width: 0; }
.adm-uc-plan { width: 74px; flex: none; }
.adm-uc-auth { width: 56px; flex: none; font-size: 11.5px; color: #6f6a5e; }
.adm-uc-joined { width: 78px; flex: none; display: flex; flex-direction: column; gap: 2px; }
.adm-ujoined__age { font-size: 12.5px; color: #26221b; }
.adm-ujoined__date { font-size: 10.5px; color: #a49d8d; white-space: nowrap; }
.adm-uc-runs { width: 104px; flex: none; }
.adm-uc-rt { width: 52px; flex: none; }
.adm-uc-pk { width: 56px; flex: none; font-size: 12px; }
.adm-uc-st { width: 66px; flex: none; }
.adm-uavatar { width: 30px; height: 30px; flex: none; border-radius: 50%; background: #ece7db; color: #6f6a5e; display: flex; align-items: center; justify-content: center; font: 700 11px "Hanken Grotesk"; }
.adm-uuser__text { min-width: 0; }
.adm-uuser__name { display: flex; align-items: center; gap: 6px; font-weight: 600; font-size: 12.5px; }
.adm-uuser__email { display: block; font-size: 10.5px; color: #9a9384; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-ubadge { font: 700 8.5px "Hanken Grotesk"; letter-spacing: .4px; padding: 2px 6px; border-radius: 5px; background: #26221b; color: #fff; }
.adm-urunbar { display: block; height: 4px; border-radius: 2px; background: #f0ece3; margin-top: 4px; overflow: hidden; width: 82px; }
.adm-urunbar__fill { display: block; height: 100%; }
.adm-empty { padding: 22px; text-align: center; color: #9a9384; font-size: 12.5px; }
.adm-pager { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; font-size: 11.5px; color: #9a9384; }
.adm-pager__nav { display: flex; gap: 14px; }

/* ---------------- User detail ---------------- */
.adm-back { display: inline-flex; align-items: center; gap: 6px; font: 600 12px "Hanken Grotesk"; color: #6f6a5e; margin-bottom: 16px; }
.adm-back:hover { color: #2f6d5b; text-decoration: none; }
.adm-muted { color: #9a9384; font-weight: 400; }
.adm-udetail { display: flex; gap: 16px; align-items: flex-start; }
.adm-udetail__main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.adm-udetail__side { width: 288px; flex: none; display: flex; flex-direction: column; gap: 14px; }

.adm-uhero { display: flex; align-items: center; gap: 15px; }
.adm-uhero__avatar { width: 52px; height: 52px; flex: none; border-radius: 50%; background: #e8efe8; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font: 700 17px "Hanken Grotesk"; }
.adm-uhero__id { flex: 1; min-width: 0; }
.adm-uhero__name { font-family: "Newsreader", serif; font-size: 22px; font-weight: 500; }
.adm-uhero__meta { font-size: 11.5px; color: #9a9384; }

.adm-ustats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
.adm-ustat { border: 1.5px solid #e0dacd; border-radius: 12px; background: #fff; padding: 13px 15px; }
.adm-ustat__label { font: 600 9.5px "Hanken Grotesk"; letter-spacing: .4px; color: #9a9384; margin-bottom: 7px; }
.adm-ustat__val { font-family: "Newsreader", serif; font-size: 20px; font-weight: 500; }

.adm-urt { display: flex; align-items: center; gap: 11px; padding: 9px 0; border-top: 1.5px solid #f3f0e8; }
.adm-urt:first-of-type { border-top: none; }
.adm-urt__dot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.adm-urt__name { flex: 1; font-size: 12.5px; font-weight: 600; }
.adm-urt__meta { font-size: 11px; color: #9a9384; }

.adm-ubars { display: flex; align-items: flex-end; gap: 10px; height: 76px; }
.adm-ubar { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
.adm-ubar__stack { width: 100%; display: flex; flex-direction: column-reverse; border-radius: 3px 3px 0 0; overflow: hidden; min-height: 2px; }
.adm-ubar__web { background: #8a6fae; }
.adm-ubar__nonweb { background: #cfe0d9; }
.adm-ubar__m { font-size: 9px; color: #9a9384; }
.adm-ulegend { display: flex; gap: 16px; margin-top: 12px; font-size: 11px; color: #6f6a5e; }
.adm-ulegend span { display: flex; align-items: center; gap: 6px; }
.adm-sq { width: 9px; height: 9px; border-radius: 2px; display: inline-block; }

.adm-umix { display: flex; height: 34px; border-radius: 9px; overflow: hidden; margin-bottom: 14px; }
.adm-umix__web { background: #8a6fae; display: flex; align-items: center; padding: 0 12px; color: #fff; font: 600 12px "Hanken Grotesk"; }
.adm-umix__nonweb { background: #dfe8e2; display: flex; align-items: center; padding: 0 10px; color: #3f5b4f; font: 600 12px "Hanken Grotesk"; }
.adm-umixgrid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.adm-umixcard { border: 1.5px solid #f0ece3; border-radius: 10px; padding: 10px 12px; }
.adm-umixcard__head { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; font-size: 11px; color: #6f6a5e; }
.adm-umixcard__dot { width: 7px; height: 7px; border-radius: 50%; }
.adm-umixcard__n { font-size: 13px; font-weight: 600; color: #26221b; }

/* actions + security */
.adm-actions { display: flex; flex-direction: column; gap: 8px; }
.adm-action { display: block; width: 100%; padding: 10px 12px; border-radius: 10px; font: 600 12px "Hanken Grotesk"; cursor: pointer; text-align: center; border: 1.5px solid #e6e1d6; color: #26221b; background: #fff; }
.adm-action:hover { border-color: #cfe0d9; }
.adm-action--danger { border-color: #e5c3ba; color: #b45b3e; background: #fbf3f0; }
.adm-action--ok { border-color: #cfe0d9; color: #2f6d5b; background: #f4f8f6; }
.adm-action.is-disabled { color: #c2bbac; cursor: default; background: #faf8f3; }
/* `display: block` above outranks the browser's own [hidden] rule, so hiding one
   of these from JS silently does nothing without this. */
.adm-action[hidden] { display: none; }
/* Delete. Sits below the reversible actions and behind a typed confirmation —
   it is the only one on this page that cannot be undone. */
.adm-del { margin-top: 12px; padding-top: 12px; border-top: 1.5px solid #f3f0e8; }
.adm-del__panel { border: 1.5px solid #e5c3ba; background: #fbf3f0; border-radius: 10px; padding: 12px 13px; }
.adm-del__title { font: 600 12px "Hanken Grotesk"; color: #b45b3e; margin-bottom: 5px; line-height: 1.45; }
.adm-del__body { font-size: 11.5px; color: #6f5b4a; line-height: 1.55; margin-bottom: 10px; }
.adm-del__body .mono { font-family: var(--font-mono); font-size: 11px; color: #b45b3e; }
.adm-del__form { display: flex; flex-direction: column; gap: 7px; }
.adm-del__input { width: 100%; border: 1.5px solid #e5c3ba; border-radius: 9px; padding: 8px 11px; font: 400 12px "Hanken Grotesk"; color: #26221b; background: #fff; outline: none; }
.adm-del__input:focus { border-color: #b45b3e; }
.adm-del__form .adm-action:disabled { color: #d3b3a8; background: #fdf9f7; cursor: default; }

.adm-action-inline { display: flex; gap: 7px; }
.adm-action-select { flex: 1; height: 40px; font: 600 12px "Hanken Grotesk"; padding: 0 32px 0 10px; }
.adm-action-inline .adm-action { width: auto; padding: 9px 12px; }
.adm-action-input { flex: 1; min-width: 0; height: 40px; padding: 0 12px; border: 1.5px solid #e6e1d6; border-radius: 10px; font: 400 12px "Hanken Grotesk"; color: #26221b; background: #fff; outline: none; }
.adm-action-input:focus { border-color: #cfe0d9; }

.adm-seclist { display: flex; flex-direction: column; gap: 9px; font-size: 12px; color: #6f6a5e; }
.adm-secrow { display: flex; justify-content: space-between; align-items: center; }
.adm-secval { font-weight: 600; color: #26221b; }
/* A referrer is an arbitrary URL somebody else chose the length of, and this
   row sits in a fixed-width panel. Everything else on the list is short. */
.adm-brk { word-break: break-word; text-align: right; }

@media (max-width: 900px) {
  .adm-udetail { flex-direction: column; }
  .adm-udetail__side { width: 100%; }
}

/* ---------------- Support inbox ---------------- */
.adm-navrow__badge { font: 600 9.5px "Hanken Grotesk"; padding: 2px 7px; border-radius: 999px; background: #cf8f7e; color: #fff; }
/* The active row is a light card now, not a filled black one, so a
   translucent-white badge on it would be invisible. */
.adm-navrow.is-active .adm-navrow__badge { background: #cf8f7e; color: #fff; }

.adm-tfilters { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.adm-tfilter { font: 600 11.5px "Hanken Grotesk"; padding: 8px 14px; border: 1.5px solid #e0dacd; border-radius: 999px; background: #fff; color: #6f6a5e; }
.adm-tfilter:hover { border-color: #cfe0d9; text-decoration: none; }
.adm-tfilter.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.adm-tfilters__spacer { flex: 1; }
.adm-tfilters__note { font-size: 11.5px; color: #9a9384; }

.adm-tc-id { width: 60px; flex: none; }
.adm-tc-sub { flex: 2; min-width: 0; display: flex; align-items: center; gap: 8px; }
.adm-tc-user { width: 150px; flex: none; display: flex; align-items: center; gap: 7px; min-width: 0; }
.adm-tc-cat { width: 92px; flex: none; }
.adm-tc-st { width: 78px; flex: none; }
.adm-tc-up { width: 74px; flex: none; font-size: 11px; color: #9a9384; }
.adm-tunread { width: 8px; height: 8px; border-radius: 50%; background: #2f6d5b; flex: none; }
.adm-tsub__text { min-width: 0; }
.adm-tsub__subject { display: block; font-weight: 600; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-tsub__preview { display: block; font-size: 10.5px; color: #9a9384; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-uavatar--sm { width: 22px; height: 22px; font-size: 9px; }
.adm-tuser__email { font-size: 11.5px; color: #6f6a5e; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.adm-catpill { font: 600 9.5px "Hanken Grotesk"; padding: 3px 8px; border-radius: 999px; background: #f1ede4; color: #6f6a5e; }

.adm-tickethead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.adm-tickethead__subject { font-family: "Newsreader", serif; font-size: 20px; font-weight: 500; line-height: 1.2; }

.adm-reply { border: 1.5px solid #cfe0d9; border-radius: 14px; background: #fff; overflow: hidden; }
.adm-reply__input { display: block; width: 100%; border: none; outline: none; padding: 14px 16px; font: 400 13px/1.6 "Hanken Grotesk"; color: #3a352c; resize: vertical; }
.adm-reply__foot { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-top: 1.5px solid #f0ece3; background: #faf8f3; }
.adm-reply__resolve { font: 600 12px "Hanken Grotesk"; padding: 8px 15px; border-radius: 9px; border: none; background: #2f6d5b; color: #fff; cursor: pointer; }
.adm-reply__resolve:hover { background: #28604f; }

.adm-statusset { display: flex; gap: 6px; }
.adm-statusbtn { flex: 1; font: 600 10px "Hanken Grotesk"; padding: 6px 8px; border-radius: 8px; border: 1.5px solid #e6e1d6; background: #fff; color: #9a9384; cursor: pointer; }
.adm-statusbtn.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.adm-tuserctx { display: flex; align-items: center; gap: 10px; }
.adm-tuserctx__name { font-weight: 600; font-size: 12.5px; }
.adm-tuserctx__link { display: inline-block; margin-top: 12px; font: 600 11.5px "Hanken Grotesk"; color: #2f6d5b; }

/* ---------------- Security & abuse ---------------- */
.adm-kpis--4 { grid-template-columns: repeat(4, 1fr); }
.adm-seccluster__head { display: flex; align-items: center; gap: 9px; padding: 14px 18px; border-bottom: 1.5px solid #ece8df; }
.adm-cluster { display: flex; gap: 14px; align-items: center; padding: 13px 18px; border-bottom: 1.5px solid #f3f0e8; }
.adm-cluster:last-child { border-bottom: none; }
.adm-cluster__ip { width: 128px; flex: none; color: #26221b; }
.adm-cluster__main { flex: 1; min-width: 0; }
.adm-cluster__count { font-size: 12.5px; font-weight: 600; margin-bottom: 2px; }
.adm-cluster__meta { font-size: 11px; color: #9a9384; }
.adm-risk { font: 600 10px "Hanken Grotesk"; padding: 4px 10px; border-radius: 999px; }
.adm-risk--high { background: #f4dcd4; color: #b45b3e; }
.adm-risk--medium { background: #faece0; color: #a4712f; }
.adm-risk--low { background: #ece7dd; color: #9a9384; }
.adm-cluster__review { font: 600 11.5px "Hanken Grotesk"; padding: 7px 13px; border-radius: 9px; border: 1.5px solid #e5c3ba; color: #b45b3e; background: #fbf3f0; cursor: pointer; }
.adm-cluster__review:hover { background: #f7e9e3; }

/* Closed accounts. Rows are mostly hash-only, so the address is a search input
   rather than a column — the search box sits in the head and pushes right. */
.adm-closure__search { margin-left: auto; }
.adm-closure__q { width: 208px; border: 1.5px solid #e6e1d6; border-radius: 9px; padding: 6px 11px; font: 400 11.5px "Hanken Grotesk"; color: #26221b; background: #fff; outline: none; }
.adm-closure__q:focus { border-color: #cfe0d9; }
.adm-closure { display: flex; gap: 14px; align-items: flex-start; padding: 13px 18px; border-bottom: 1.5px solid #f3f0e8; }
.adm-closure:last-child { border-bottom: none; }
.adm-closure--flag { background: #fdf7f4; }
.adm-closure__main { flex: 1; min-width: 0; }
.adm-closure__id { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; margin-bottom: 3px; }
.adm-closure__warn { color: #b45b3e; }
.adm-closure__meta { font-size: 11px; color: #9a9384; }
.adm-closure__via { color: #a4712f; }
.adm-closure__why { font-size: 11.5px; color: #6f6a5e; margin-top: 5px; line-height: 1.5; }
.adm-closure__when { flex: none; font-size: 11px; color: #9a9384; padding-top: 2px; }

.adm-secbars { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
.adm-secbar { height: 9px; border-radius: 999px; background: #f0ece3; overflow: hidden; }
.adm-secbar__fill { height: 100%; border-radius: 999px; }

.adm-audit { display: flex; align-items: baseline; gap: 12px; padding: 8px 0; border-top: 1.5px solid #f3f0e8; }
.adm-audit:first-of-type { border-top: none; }
.adm-audit__action { flex: none; font: 600 11px "Hanken Grotesk"; padding: 3px 9px; border-radius: 7px; background: #f1ede4; color: #6f6a5e; }
.adm-audit__who { flex: 1; font-size: 12px; color: #6f6a5e; }
.adm-audit__time { flex: none; font-size: 11px; color: #9a9384; }

.adm-secnote { margin-top: 14px; border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 12px; padding: 14px 17px; font-size: 12px; line-height: 1.55; color: #2f5f52; }

/* ---------------- Providers ---------------- */
.adm-secnote--info { margin-top: 0; margin-bottom: 16px; border-color: #b7d0c7; background: #f1f6f3; }
.adm-pc-name { flex: 1.4; display: flex; align-items: center; gap: 10px; min-width: 0; }
.adm-pc-kind { width: 150px; flex: none; }
.adm-pc-model { width: 150px; flex: none; }
.adm-pc-key { width: 70px; flex: none; font-size: 11.5px; }
.adm-pc-def { width: 78px; flex: none; font-size: 11.5px; color: #6f6a5e; }
.adm-pc-state { width: 66px; flex: none; }
.adm-ptile { width: 30px; height: 30px; flex: none; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 14px; }
.adm-pname { font-weight: 600; font-size: 12.5px; }
.adm-pstate { font: 600 10px "Hanken Grotesk"; padding: 3px 9px; border-radius: 999px; }
.adm-pstate.is-on { background: #e8efe8; color: #2f6d5b; }
.adm-pstate.is-off { background: #ece7dd; color: #9a9384; }
.adm-provfoot { display: flex; align-items: center; gap: 12px; margin-top: 14px; }

/* ---------------- System health ---------------- */
.adm-health__link { font: 600 11px "Hanken Grotesk"; color: #3d5c72; }
.adm-queue { display: flex; align-items: center; gap: 11px; padding: 9px 0; border-top: 1.5px solid #f3f0e8; }
.adm-queue:first-of-type { border-top: none; }
.adm-queue__name { flex: 1; }
.adm-queue__latency { font-size: 11px; color: #9a9384; }
.adm-queue__depth { width: 44px; text-align: right; font-weight: 600; }
.adm-outcomes { display: flex; height: 15px; border-radius: 8px; overflow: hidden; margin-bottom: 14px; background: #f0ece3; }
.adm-outcomes__legend { display: flex; flex-direction: column; gap: 8px; font-size: 12px; color: #6f6a5e; }
.adm-outcomes__legend > div { display: flex; align-items: center; gap: 8px; }
.adm-outcomes__l { flex: 1; }
.adm-dot { width: 8px; height: 8px; border-radius: 50%; }
.adm-provhealth { display: flex; align-items: center; gap: 13px; padding: 10px 0; border-top: 1.5px solid #f3f0e8; }
.adm-provhealth:first-of-type { border-top: none; }
.adm-provhealth__name { width: 140px; font-size: 12.5px; font-weight: 600; }
.adm-provhealth__track { flex: 1; height: 8px; border-radius: 4px; background: #f0ece3; overflow: hidden; }
.adm-provhealth__fill { height: 100%; }
.adm-provhealth__rate { width: 52px; text-align: right; }
.adm-provhealth__tokens { width: 92px; text-align: right; color: #9a9384; }

/* ---------------- Plans & billing ---------------- */
.adm-plans { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 16px; }
.adm-plan { border: 1.5px solid #e0dacd; border-radius: 14px; background: #fff; padding: 17px 18px; display: flex; flex-direction: column; }
.adm-plan--hi { border-color: #cfe0d9; background: #f4f8f6; }
.adm-plan__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 3px; }
.adm-plan__name { font-family: "Newsreader", serif; font-size: 19px; font-weight: 500; }
.adm-plan__tagline { font-size: 11.5px; color: #9a9384; margin-bottom: 13px; }
.adm-plan__price { display: flex; align-items: baseline; gap: 5px; margin-bottom: 14px; }
.adm-plan__amount { font-family: "Newsreader", serif; font-size: 30px; font-weight: 500; line-height: 1; }
.adm-plan__per { font-size: 11.5px; color: #9a9384; }
.adm-plan__rows { display: flex; flex-direction: column; gap: 8px; border-top: 1.5px solid #f0ece3; padding-top: 12px; }
.adm-plan__row { display: flex; justify-content: space-between; font-size: 12px; color: #6f6a5e; }
.adm-plan__count { border-top: 1.5px solid #f0ece3; margin-top: 12px; padding-top: 11px; display: flex; justify-content: space-between; align-items: baseline; font-size: 14px; font-weight: 600; }

.adm-trial { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.adm-trial__icon { width: 34px; height: 34px; flex: none; border-radius: 9px; background: #f1ede4; color: #a4712f; display: flex; align-items: center; justify-content: center; font-size: 16px; }
.adm-trial__text { flex: 1; }
.adm-trial__title { font-weight: 600; font-size: 12.5px; margin-bottom: 2px; }

.adm-billing { border: 1.5px solid #b7c9d6; background: #eef3f6; border-radius: 14px; padding: 18px 20px; }
.adm-billing__head { display: flex; align-items: center; gap: 9px; margin-bottom: 14px; }
.adm-billing__icon { width: 24px; height: 24px; border-radius: 7px; background: #5b7f9e; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 13px; }
.adm-billing__badge { font: 600 9px "Hanken Grotesk"; letter-spacing: .4px; background: #5b7f9e; color: #fff; padding: 2px 7px; border-radius: 5px; }
.adm-billing__spacer { flex: 1; }
.adm-billing__link { font: 600 11.5px "Hanken Grotesk"; color: #3d5c72; cursor: pointer; }
.adm-billing__grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.adm-billing__val { font-family: "Newsreader", serif; font-size: 23px; font-weight: 500; color: #c2bbac; }
.adm-billing__label { font-size: 10.5px; color: #5c6b76; margin-top: 3px; }
.adm-billing__note { font-size: 11px; color: #5c6b76; margin-top: 14px; line-height: 1.55; border-top: 1.5px solid #d7e0e6; padding-top: 12px; }

@media (max-width: 900px) {
  .adm-plans, .adm-billing__grid { grid-template-columns: repeat(2, 1fr); }
}

/* System provider management controls */
.adm-pc-act { flex: none; display: flex; gap: 8px; align-items: center; margin-left: auto; }
.adm-linkbtn { font: 600 11px "Hanken Grotesk"; color: #2f6d5b; background: none; border: none; cursor: pointer; padding: 0; }
.adm-linkbtn:hover { text-decoration: underline; }
.adm-linkbtn--danger { color: #b45b3e; }
.adm-pstate--btn { border: none; cursor: pointer; }
.adm-provform__lbl { display: block; font: 600 11px "Hanken Grotesk"; color: #6f6a5e; margin: 12px 0 6px; }
.adm-provform__input { width: 100%; padding: 10px 12px; border: 1.5px solid #e6e1d6; border-radius: 10px; font: 400 13px "Hanken Grotesk"; color: #26221b; background: #fff; outline: none; }
.adm-provform__input:focus { border-color: #cfe0d9; }
.adm-provform__check { display: flex; align-items: center; gap: 8px; margin: 14px 0 4px; font-size: 12.5px; color: #6f6a5e; }
.adm-provform__errors { background: #fbf3f0; border: 1.5px solid #e5c3ba; color: #b45b3e; border-radius: 10px; padding: 10px 13px; font-size: 12.5px; margin-bottom: 12px; }
.adm-provform__foot { display: flex; align-items: center; gap: 10px; margin-top: 18px; }

/* ---- mobile overrides that must outrank later base rules ----
   A media query adds no specificity, so anything declared further down the
   file beats an earlier @media block. .adm-kpis--4 is defined below the
   860px block, so it kept its 4 columns on phones and overflowed the
   viewport by 26px on Security and System health. */
@media (max-width: 860px) {
  .adm-kpis--4 { grid-template-columns: repeat(2, 1fr); }
}

/* What a delivery searched for — the search direction built for that run, and
   the queries it produced. Indented under the delivery row it belongs to. */
.adm-srch { margin: -2px 0 8px 18px; padding-left: 10px; border-left: 2px solid #ece8df; }
.adm-srch__dir { font-size: 11.5px; color: #6f6a5e; line-height: 1.5; word-break: break-word; }
.adm-srch__dir--none { color: #b45b3e; }
.adm-srch__q { font-family: var(--font-mono); font-size: 10.5px; color: #9a9384;
  line-height: 1.5; word-break: break-word; }

/* Field hints on the provider form. The two model fields do different jobs and
   the difference is not guessable from their names. */
/* A positive top gap, not the -6px this used to carry. The negative margin is
   the right idiom where the field above it has a bottom margin of its own to
   eat into (.nrw-input does, and its hints pull up by design) — .adm-provform__
   input has none, so -6px was six pixels of overlap: the hint's first line sat
   under the input's border, and on a phone, where it wraps to two lines, that
   is the line you read first. */
.adm-provform__hint { margin: 6px 0 14px; font-size: 11.5px; color: #8b8577; line-height: 1.5; }
.adm-provform__hint code { font-family: var(--font-mono); font-size: 11px; color: #6f6a5e; }
.adm-pc-coach { display: block; font-size: 10.5px; color: #9a9384; margin-top: 2px; }
.adm-provsync { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid #ece8df; }
.adm-provsync__meta { font-size: 11.5px; color: #8b8577; }

/* ── Deliveries — the fleet view ──────────────────────────────────────────
   The rest of this console builds rows out of divs. This page is genuinely
   tabular — seven columns, scanned down rather than read across — so it uses a
   real <table> and gets its own styles rather than bending .adm-urow into a
   shape it was not built for. */
.adm-dlvfilters { display: flex; flex-wrap: wrap; gap: 18px; margin-bottom: 14px; }
.adm-dlvfilters__row { display: flex; flex-wrap: wrap; gap: 6px; }
.adm-chip {
  font: 600 11.5px "Hanken Grotesk"; padding: 6px 12px; border-radius: 999px;
  border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; text-decoration: none;
}
.adm-chip:hover { border-color: #cfe0d9; color: #2f6d5b; }
.adm-chip.is-on { background: #eef4f1; border-color: #2f6d5b; color: #2f6d5b; }

.adm-dlvsplit { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
@media (max-width: 900px) { .adm-dlvsplit { grid-template-columns: 1fr; } }

/* The deliveries page is the one genuinely tabular screen in here — seven
   columns, scanned down rather than read across — so its rows are a real
   <table> instead of the flex divs the other admin lists use.
   
   The FRAME still comes from .adm-table, the existing wrapper: hairline
   border, 14px radius, clipped corners. .adm-grid only styles cells, so the
   table never draws a second border inside the first, and the caption bar
   (.adm-table__cap) sits in the frame above it — which is what the frame is
   for, per the design note: "the frame is where a caption could live". */
.adm-table__cap {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 12px 18px; background: #f7f4ee; border-bottom: 1.5px solid #ece8df;
}
.adm-table__cap-title { font: 600 12.5px "Hanken Grotesk"; color: #3a352c; }
.adm-table__cap-meta { font-size: 11px; color: #a49d8d; }

.adm-grid { width: 100%; border-collapse: collapse; font-size: 12.5px; background: #fff; }
.adm-grid thead th {
  text-align: left; padding: 9px 18px; background: #fbf9f5;
  border-bottom: 1.5px solid #ece8df;
  font: 700 9.5px "Hanken Grotesk"; letter-spacing: .4px; color: #a49d8d; text-transform: uppercase;
}
.adm-grid td { padding: 12px 18px; border-bottom: 1.5px solid #f3f0e8; vertical-align: middle; color: #6f6a5e; }
.adm-grid tbody tr:last-child td { border-bottom: 0; }
.adm-grid tbody tr:hover td { background: #fcfbf7; }
/* The first column is what the row IS; the rest describe it. */
.adm-grid tbody td:first-child { color: #26221b; font-weight: 600; }
.adm-grid .num { text-align: right; font-variant-numeric: tabular-nums; }
.adm-grid .num.is-bad { color: #b45b3e; font-weight: 600; }
/* Absent reads as absent, not as zero. */
.adm-grid .is-dim { color: #b3ac9d; }
.adm-grid--tight thead th { padding: 8px 14px; }
.adm-grid--tight td { padding: 9px 14px; }

.adm-link { color: #2f6d5b; font-weight: 600; text-decoration: none; }
.adm-link:hover { text-decoration: underline; }

/* Status, as a shape and not only a word — this column is scanned, not read. */
.adm-dlvstatus {
  display: inline-block; font: 600 10px "Hanken Grotesk"; letter-spacing: .3px;
  padding: 3px 8px; border-radius: 999px; text-transform: uppercase;
}
.adm-dlvstatus--success { background: #e8efe8; color: #2f6d5b; }
.adm-dlvstatus--failed { background: #f4dcd4; color: #b45b3e; }
.adm-dlvstatus--queued,
.adm-dlvstatus--running { background: #f1ede4; color: #8f8877; }
/* Stuck is not a status the model has — it is running plus elapsed time, and
   it is the one an admin most needs to see, so it gets the loudest tone. */
.adm-dlvstatus--stuck { background: #faece0; color: #a4712f; }

.adm-dlvchip {
  font: 600 9.5px "Hanken Grotesk"; padding: 2px 6px; border-radius: 999px;
  background: #eef4f1; color: #2f6d5b; margin-left: 4px;
}
.adm-dlvnotes { max-width: 320px; }
.adm-dlvnote { font-size: 11px; line-height: 1.45; }
.adm-dlvnote.is-bad { color: #b45b3e; }
.adm-dlvnote.is-warn { color: #a4712f; }

.adm-dlvreasons { padding: 4px 18px; background: #fff; }
.adm-dlvreason { display: flex; gap: 11px; align-items: flex-start; padding: 8px 0; border-bottom: 1px solid #f3f0e8; }
.adm-dlvreason:last-child { border-bottom: 0; }
.adm-dlvreason__n {
  flex: none; min-width: 26px; text-align: right;
  font: 600 13px "Hanken Grotesk"; color: #3a352c; font-variant-numeric: tabular-nums;
}
.adm-dlvreason__body { min-width: 0; }
.adm-dlvreason__msg { font-size: 11.5px; line-height: 1.5; color: #6f6a5e; }
.adm-dlvkind {
  display: inline-block; margin-right: 6px; font: 600 9.5px "Hanken Grotesk";
  letter-spacing: .3px; padding: 2px 7px; border-radius: 999px; text-transform: uppercase;
  background: #f1ede4; color: #8f8877;
}
.adm-dlvkind--content-rejected { background: #f4dcd4; color: #b45b3e; }
.adm-dlvkind--refused { background: #faece0; color: #a4712f; }

@media (max-width: 720px) {
  /* Seven columns do not fit a phone. Scroll the table rather than stacking
     it: the value here is comparing rows down a column. The frame keeps its
     corners — the scroll happens inside it. */
  .adm-dlvtable { display: block; overflow-x: auto; white-space: nowrap; }
  .adm-dlvnotes { max-width: none; }
  .adm-table__cap { flex-direction: column; gap: 2px; }
}

/* ---- LLMs ------------------------------------------------------------------
   The models screen is a list of CARDS, not a table. It was a six-column grid
   and nothing lined up: two of the columns were chip-filled and variable-width,
   and the action group varied per row (a row holding a role has one button
   fewer), so the one flexible column absorbed a different amount of slack on
   every line. A card also gives each model room for the thing the table had
   nowhere to put — why it is or is not a candidate.

   Design: "Admin LLMs.dc.html". Tabs and filter pills are the shared
   .tabs / .filters components in components.css. Everything else here reuses
   the admin vocabulary — .adm-pstate for pills, .adm-action for buttons. */
/* No width of its own. The canvas draws this page in an 816px column, but
   every other admin screen is .adm-content's 1040px, and a console where one
   page is narrower than its neighbours reads as a mistake rather than as
   emphasis. Consistency wins over the mockup here. */
.llm-filters { margin-bottom: 14px; }
.llm-list { display: flex; flex-direction: column; gap: 8px; }
.llm-foot { margin: 20px 0 0; font: 400 13px/1.6 "Hanken Grotesk"; color: #8f8877; }

/* ── The two decisions ──
   Above the list on purpose: enabling a model makes it a candidate, and these
   are what actually put one to work. The page reads top-down as "here is what
   runs, here is what could". */
.llm-roles { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 22px; }
.llm-role {
  border: 1.5px solid var(--primary-border); border-radius: 14px;
  background: #fff; padding: 15px 17px; box-shadow: 0 2px 6px rgba(50,42,28,.04);
}
.llm-role.is-empty { border-color: #e0dacd; }
.llm-role__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.llm-role__does { font-size: 12.5px; color: #6f6a5e; }
.llm-role__model { font-family: var(--font-mono); font-weight: 700; font-size: 14px; color: #26221b; margin-top: 11px; }
.llm-role__meta { font-family: var(--font-mono); font-size: 12px; color: #8f8877; margin-top: 4px; }
.llm-role__none { margin-top: 11px; font-size: 12.5px; line-height: 1.55; color: #b45b3e; }
.llm-role__why { margin-top: 9px; font-size: 12.5px; line-height: 1.55; color: #57513f; }
.llm-role__when { color: #a49d8d; }
.llm-role__foot { margin-top: 10px; }

/* The model id is this page's primary identifier, so it sets its own size and
   its own face. `.adm .mono` pins every monospace run in the admin shell to
   11.5px — right for an id in a table cell, wrong here, and a descendant
   selector it would win the cascade against anything single-class below. Hence
   `font-family: var(--font-mono)` on the classes rather than the .mono helper. */

/* ── One model, or one provider ──
   Same card either way: a summary line you can scan, and the detail folded
   behind it. The caret is .wh-send__caret's, which is the app's established
   "this row opens" affordance. */
.llm-card {
  border: 1.5px solid #e0dacd; border-radius: 14px; background: #fff;
  overflow: hidden; box-shadow: 0 2px 6px rgba(50,42,28,.04);
}
.llm-card.is-off { background: #faf8f3; }
.llm-card.is-off .llm-card__id, .llm-card.is-off .llm-card__name { color: #6f6a5e; }
.llm-card__sum { display: flex; align-items: center; gap: 10px; padding: 11px 16px; cursor: pointer; }
.llm-card__caret {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  background: #e9e5db; color: var(--primary);
  font-size: 12px; line-height: 22px; text-align: center;
  transition: transform .14s, background .12s;
}
.llm-card[open] .llm-card__caret { transform: rotate(180deg); background: var(--primary-chip); }
.llm-card__sum:hover .llm-card__caret { background: var(--primary-chip); }
.llm-card__id { font-family: var(--font-mono); font-weight: 700; font-size: 13px; color: #26221b; }
.llm-card__name { font: 600 14px "Hanken Grotesk"; color: #26221b; }
.llm-card__sub {
  font-size: 12.5px; color: #6f6a5e;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0;
}
.llm-card__spacer { flex: 1; }
.llm-card__body { padding: 0 17px 17px; }
.llm-card__url { font-family: var(--font-mono); font-size: 12px; color: #8f8877; margin-bottom: 11px; }

/* ── Why it is a candidate ──
   The justification, dated. Given the top of the card body because it is the
   question the list cannot answer and the one an operator actually has. */
.llm-why { margin-bottom: 12px; }
.llm-why__lbl {
  display: block; margin-bottom: 4px;
  font: 700 10.5px "Hanken Grotesk"; letter-spacing: .5px; text-transform: uppercase; color: #a49d8d;
}
.llm-why__text { margin: 0; font: 400 12.5px/1.55 "Hanken Grotesk"; color: #57513f; }
.llm-why__text--empty { color: #8f8877; }
.llm-why__when { color: #a49d8d; }

/* ── A block of facts, labelled with where they come from ──
   Three of these per model: measured, recorded, chosen. The label is not
   decoration — it is the whole reason this registry exists. */
.llm-facts { border-radius: 11px; background: #f7f4ee; padding: 12px 14px; margin-bottom: 9px; }
.llm-fact__lbl {
  margin-bottom: 9px;
  font: 700 10.5px "Hanken Grotesk"; letter-spacing: .5px; text-transform: uppercase; color: #8f8877;
}
.llm-fact__note { margin: 9px 0 0; font: 400 12.5px/1.55 "Hanken Grotesk"; color: #8f8877; }

.llm-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.llm-chip {
  font: 600 11.5px "Hanken Grotesk"; padding: 4px 10px; border-radius: 8px;
  background: var(--primary-chip); color: var(--primary); border: 1px solid var(--primary-border);
}
/* Absent, not missing. A greyed-out capability answers "why can't I turn that
   option on?"; an omitted chip leaves the question open. */
.llm-chip.is-off { background: #efece4; color: #a8a293; border-color: #e6e1d6; }
.llm-chip--quiet { background: #efece4; color: #6f6a5e; border-color: #e6e1d6; }

.llm-kv { display: flex; align-items: baseline; gap: 12px; font-size: 12.5px; line-height: 1.5; }
.llm-kv + .llm-kv { margin-top: 7px; }
.llm-kv__k { flex: none; width: 132px; color: #6f6a5e; }
.llm-kv__v { font-size: 12.5px; color: #3a352c; }
/* Only for a figure. The provider card's values are prose — "OpenAI-compatible",
   "7 of 7 models resolved" — and monospacing those just makes them harder to read. */
.llm-kv__v--num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }

.llm-opts { display: flex; flex-direction: column; gap: 7px; }
.llm-opt { display: flex; align-items: baseline; gap: 12px; font-size: 12.5px; line-height: 1.5; }
.llm-opt__k { flex: none; width: 132px; color: #6f6a5e; }
.llm-opt__v { font-family: var(--font-mono); font-size: 12.5px; color: #6f6a5e; }
.llm-opt.is-changed .llm-opt__v { font-weight: 700; color: #26221b; }
.llm-opt__tag {
  font: 600 10px "Hanken Grotesk"; letter-spacing: .4px; text-transform: uppercase;
  color: var(--accent); background: #f8e3dc; padding: 2px 7px; border-radius: 999px;
}

/* The one-model edit form. AGENTS.md § "Claude Design → code": structure and
   semantic classes only, zero style= left in the view. */
.llm-edit { max-width: 560px; padding: 22px; }
.llm-edit__title { margin-bottom: 13px; }
.llm-edit__lead { margin-top: 0; }
.llm-edit__cancel { width: auto; }
.llm-edit__caps { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 4px; }

.llm-card__acts { display: flex; flex-wrap: wrap; gap: 9px; align-items: center; margin-top: 12px; }
/* .adm-action is block/full-width by default — it was built for the stacked
   action column on the user detail page. Here they sit in a row, the same
   override .adm-action-inline makes. */
.llm-card__acts .adm-action { width: auto; padding: 9px 14px; font-size: 12.5px; }
.llm-card__acts form { display: inline; }
.llm-card__locked { font: 400 12.5px/1.5 "Hanken Grotesk"; color: #8f8877; }

/* Admin selects lost their chevron. components.css sets it as an ELEMENT rule
   on `select` (deliberately — the comment there records that two admin selects
   left on the OS default "looked like a different app on Windows"), but
   `.adm-provform__input` is a CLASS and its `background: #fff` shorthand resets
   background-image. So every select wearing the admin form class rendered as a
   text field. Restore the caret rather than dropping the shorthand, which other
   controls rely on. Affects Recipes and Blog too, not only this screen. */
select.adm-provform__input {
  appearance: none;
  -webkit-appearance: none;
  background-image: var(--caret-down);
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
}

/* ---- LLMs mobile -----------------------------------------------------------
   Repeated here rather than folded into the media query at :508, for the same
   reason .adm-kpis--4 is: a media query adds no specificity, so rules declared
   later in the file would otherwise win on a phone. */
@media (max-width: 860px) {
  .llm-roles { grid-template-columns: 1fr; }
  .llm-card__sub { display: none; }
  .llm-kv, .llm-opt { flex-wrap: wrap; gap: 4px 10px; }
  .llm-kv__k, .llm-opt__k { width: 100%; }
  .llm-card__acts .adm-action { width: 100%; }
  .llm-card__acts form { display: block; width: 100%; }
}
/* ==========================================================================
   "joris explains" — the dogfooding blog.
   Rides the marketing tokens (.mkt-*) so the section matches the rest of the
   site; only the list and the article column are new.
   ========================================================================== */

/* ── Tokens ─────────────────────────────────────────────────────────────── */
.blog-index, .blog-post {
  --blog-ink: #322a1c;
  --blog-muted: #8f8877;
  --blog-rule: #e6ded1;
  --blog-accent: #2f6d5b;
  --blog-measure: 720px;
}

/* ── Index list ─────────────────────────────────────────────────────────── */
.blog-list { display: grid; gap: 18px; max-width: var(--blog-measure); margin: 32px auto 0; }

.blog-card { display: block; padding: 22px 24px; text-decoration: none; }
.blog-card__date {
  display: block; font-size: 12.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--blog-muted); margin-bottom: 8px;
}
.blog-card__title { margin: 0 0 8px; font-size: 21px; line-height: 1.3; color: var(--blog-ink); }
.blog-card__lead { margin: 0 0 14px; color: var(--blog-muted); line-height: 1.55; }
.blog-card--draft { border-style: dashed; }
.blog-card__warn { margin: 0; font-size: 13px; color: #a3564c; }

.blog-empty { text-align: center; color: var(--blog-muted); margin-top: 32px; }

/* Preview-only affordances. Loud on purpose — they must never be mistaken for
   published state by whoever is reviewing. */
.blog-preview-flag {
  max-width: var(--blog-measure); margin: 24px auto; padding: 12px 16px; border-radius: 12px;
  background: #fdf6e8; border: 1.5px dashed #d9c48f; color: #7a5f22; font-size: 14px; line-height: 1.5;
}
.blog-drafts { margin-top: 56px; }
.blog-drafts__head { text-align: center; color: var(--blog-muted); }

/* ── Article ────────────────────────────────────────────────────────────── */
.blog-post { max-width: var(--blog-measure); margin: 0 auto; }
.blog-post__head {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding-bottom: 14px; border-bottom: 1px solid var(--blog-rule); margin-bottom: 32px;
}
.blog-post__back { color: var(--blog-accent); text-decoration: none; font-weight: 600; font-size: 14px; }
.blog-post__back:hover { text-decoration: underline; }

.blog-post__body { color: var(--blog-ink); line-height: 1.65; }
.blog-post__body h1 { font-size: 34px; line-height: 1.2; margin: 0 0 20px; }
.blog-post__body h2 { font-size: 23px; line-height: 1.3; margin: 40px 0 14px; }
.blog-post__body h3 { font-size: 18px; margin: 28px 0 10px; }
.blog-post__body p { margin: 0 0 18px; }
.blog-post__body ul, .blog-post__body ol { margin: 0 0 18px; padding-left: 22px; }
.blog-post__body li { margin-bottom: 8px; }
.blog-post__body a { color: var(--blog-accent); }
.blog-post__body blockquote {
  margin: 0 0 20px; padding: 14px 18px; border-left: 3px solid var(--blog-accent);
  background: #f4f8f6; color: #3d5f55; border-radius: 0 10px 10px 0;
}
.blog-post__body blockquote p:last-child { margin-bottom: 0; }
.blog-post__body pre {
  margin: 0 0 20px; padding: 16px 18px; border-radius: 12px; background: #f6f2ea;
  border: 1px solid var(--blog-rule); overflow-x: auto; font-size: 13.5px; line-height: 1.55;
}
.blog-post__body code { font-size: .92em; background: #f6f2ea; padding: 2px 5px; border-radius: 5px; }
.blog-post__body pre code { background: none; padding: 0; }
/* Tables can be wider than the measure; scroll them, never the page. */
.blog-post__body table { width: 100%; border-collapse: collapse; margin: 0 0 20px; font-size: 14.5px; display: block; overflow-x: auto; }
.blog-post__body th, .blog-post__body td { padding: 9px 12px; border-bottom: 1px solid var(--blog-rule); text-align: left; }
.blog-post__body th { font-weight: 600; color: var(--blog-muted); }
.blog-post__body img { max-width: 100%; height: auto; }
.blog-post__body hr { border: 0; border-top: 1px solid var(--blog-rule); margin: 36px 0; }

.blog-post__cta { margin-top: 56px; }

/* ── Responsive ─────────────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .blog-post__body h1 { font-size: 27px; }
  .blog-post__body h2 { font-size: 20px; }
  .blog-card { padding: 18px 18px; }
  .blog-post__head { flex-direction: column; gap: 6px; }
}
/* ---------------------------------------------------------------
   joris — Settings › Connections (design handoff §5, option 3a)

   The ledger. One list, and a 4px left edge is the entire status
   system: green holding, gold asking, muted for a server nobody
   vetted or a stub whose token is gone.

   Everything here references the app's tokens
   (joris/tokens/*.css) EXCEPT the attention-gold family and two
   chrome colours, which have no token yet — see the block below.

   Sections: local tokens → layout → ledger rows → status edge →
   permissions → custom server → preview mode → nav signal →
   responsive.
   --------------------------------------------------------------- */

/* ── Local tokens ─────────────────────────────────────────────────
   The handoff's "attention gold" is a colour the app does not own.
   tokens/colors.css maps --warning to --accent (#b45b3e, terracotta)
   — that is the destructive/accent hue, not the calm gold the design
   uses for "this needs you". Declared here rather than invented at
   each use site; when a gold lands in tokens/colors.css these become
   aliases and nothing else changes.

   Scoped to :root, not to .conx-page, because the nav dot and the
   flyout pill render in the app shell on every page. */
:root {
  --conx-gold:            #c9a24a;
  --conx-gold-ink:        #8a6b33;
  --conx-gold-ink-strong: #4d3c12;
  --conx-gold-on:         #2b2109; /* ink on a solid gold button */
  --conx-gold-tint:       #fdf7e9;
  --conx-gold-wash:       #fffdf7;
  --conx-gold-pill:       #f7edd6;
  --conx-gold-border:     #e0c48f;

  --conx-edge-muted:      #b7c9c1; /* custom / unvetted server, severed stub */
  --conx-dashed:          #ddd6c9; /* advanced affordances */
  --conx-nav-ring:        #f4f1ea; /* .spine background — the dot's ring */
}

/* ── Layout ──────────────────────────────────────────────────────── */
.conx-page .prof-divider { margin: 26px 0 10px; }
.conx-page .prof-divider:first-of-type { margin-top: 0; }

.conx-list {
  border: var(--hairline) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--paper);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.conx-list > * + * { border-top: var(--hairline) solid var(--border-divider); }

/* First visit on Business. Calm, and it says the product still works
   without any of this — never a dead end. */
.conx-first {
  padding: 26px 22px;
  border: var(--hairline) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--paper);
}
.conx-first__title {
  margin: 0 0 10px;
  max-width: 22em;
  font: var(--weight-medium) var(--display-md) / var(--leading-tight) var(--font-display);
  color: var(--ink);
}
.conx-first__lead {
  margin: 0 0 8px; max-width: 46em;
  font-size: var(--text-ui); line-height: var(--leading-relaxed); color: var(--ink);
}
.conx-first__note {
  margin: 0; max-width: 46em;
  font-size: var(--text-sm); line-height: var(--leading-relaxed); color: var(--ink-faint);
}

/* ── Page-level attention banner ─────────────────────────────────── */
.conx-banner {
  display: flex; gap: var(--space-3); align-items: flex-start;
  padding: 15px 17px; margin-bottom: 18px;
  border: var(--hairline) solid var(--conx-gold-border);
  border-left: 4px solid var(--conx-gold);
  border-radius: 4px var(--radius-lg) var(--radius-lg) 4px;
  background: var(--conx-gold-tint);
}
.conx-banner__ic { width: 19px; height: 19px; flex: none; margin-top: 2px; color: var(--conx-gold-ink); }
.conx-banner__body { flex: 1; min-width: 0; }
.conx-banner__title {
  font-weight: var(--weight-semibold); font-size: var(--text-ui);
  color: var(--conx-gold-ink-strong); margin-bottom: 3px;
}
.conx-banner__text {
  margin: 0; font-size: var(--text-sm); line-height: var(--leading-normal);
  color: var(--conx-gold-ink);
}
.conx-banner__text strong { font-weight: var(--weight-semibold); color: var(--conx-gold-ink-strong); }
.conx-banner__act { flex: none; white-space: nowrap; }

/* ── Waiting card (§4.2) ─────────────────────────────────────────── */
.conx-waiting {
  display: flex; gap: var(--space-3); align-items: center; flex-wrap: wrap;
  padding: 14px 17px; margin-bottom: 18px;
  border: var(--hairline) solid var(--primary-border);
  border-radius: var(--radius-lg);
  background: var(--primary-tint-2);
}
/* The `display: flex` above outranks the browser's own [hidden] rule, so the
   card rendered permanently — every Business user arrived at Connections to a
   spinner saying "Waiting for Google" with nothing pending. Same trap already
   patched in six other places in this stylesheet family; see .adm-action. */
.conx-waiting[hidden] { display: none; }
.conx-waiting__spin {
  width: 12px; height: 12px; flex: none; border-radius: 50%;
  border: 2.5px solid var(--primary); border-top-color: transparent;
  animation: conx-spin 0.8s linear infinite;
}
@keyframes conx-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .conx-waiting__spin { animation: none; }
}
.conx-waiting__body { flex: 1 1 240px; min-width: 0; }
.conx-waiting__title {
  font-weight: var(--weight-semibold); font-size: var(--text-ui); color: var(--primary-press);
}
.conx-waiting__text { margin: 2px 0 0; font-size: var(--text-sm); line-height: var(--leading-normal); color: var(--ink-soft); }
.conx-waiting__acts { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; flex: none; }
.conx-waiting__again-lbl { font-size: var(--text-xs); color: var(--ink-faint); }
.conx-waiting__again { font: var(--weight-semibold) var(--text-xs) var(--font-sans); color: var(--primary); }
.conx-waiting__cancel { font: var(--weight-semibold) var(--text-xs) var(--font-sans); color: var(--ink-faint); }

/* ── Ledger rows ─────────────────────────────────────────────────── */
.conx-row {
  display: flex; gap: var(--space-3);
  padding: 15px 17px;
  background: var(--paper);
  border-left: 4px solid transparent;
}
.conx-row__main { flex: 1; min-width: 0; }
.conx-row__head { display: flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; margin-bottom: 2px; }
.conx-row__name { font-weight: var(--weight-semibold); font-size: 14.5px; color: var(--ink); }
.conx-row__meta { font-size: var(--text-sm); color: var(--ink-soft); }
.conx-row__url {
  font-size: var(--text-xs); color: var(--ink-ghost);
  margin-top: 2px; overflow-wrap: anywhere;
}
.conx-row__paused { margin-top: 4px; font-size: var(--text-sm); color: var(--conx-gold-ink); }
.conx-row__paused-link { font-weight: var(--weight-semibold); color: var(--conx-gold-ink); }
.conx-row__perm {
  margin: 6px 0 0; max-width: 62em;
  font-size: var(--text-sm); line-height: var(--leading-relaxed); color: var(--ink);
}
.conx-row__perm strong { font-weight: var(--weight-semibold); }
.conx-row__acts {
  display: flex; align-items: flex-start; gap: var(--space-2); flex: none;
}
/* button_to wraps its button in a form; it must not add a line box. */
.conx-row__acts form,
.conx-row__acts .button_to { margin: 0; display: contents; }

/* Service mark. Letter tiles stand in until the real brand SVGs land. */
.conx-tile {
  width: 34px; height: 34px; flex: none;
  border-radius: var(--radius-sm);
  display: flex; align-items: center; justify-content: center;
  font: var(--weight-bold) var(--text-ui) var(--font-sans);
}
.conx-tile--sm { width: 29px; height: 29px; font-size: var(--text-sm); }
.conx-tile--green   { background: var(--primary-tint);  color: var(--primary); }
.conx-tile--gold    { background: #f2ece0;              color: var(--conx-gold-ink); }
.conx-tile--neutral { background: #f1efe9;              color: #4b463c; }
.conx-tile--custom  { background: #eaf0ed;              color: #4b6a5f; }
.conx-tile--muted   { background: var(--paper-warm);    color: var(--ink-faint); }

/* Status pills */
.conx-pill {
  font: var(--weight-semibold) 10.5px var(--font-sans);
  letter-spacing: .05em; text-transform: uppercase;
  padding: 3px 8px; border-radius: var(--radius-pill);
  white-space: nowrap;
}
.conx-pill--ok        { color: var(--primary);         background: var(--primary-tint); }
.conx-pill--attention { color: var(--conx-gold-ink);   background: var(--conx-gold-pill); }
.conx-pill--severed   { color: var(--ink-faint);       background: var(--paper-warm); }
.conx-pill--custom    { color: #4b6a5f;                background: #eaf0ed; }
.conx-pill--locked    { color: var(--ink-soft);        background: var(--paper-warm); display: inline-flex; align-items: center; gap: 5px; }
/* Not the same state as --locked: that one opens when you pay, this one has no
   vendor OAuth app yet and opens for nobody. No padlock, because there is no
   key. */
.conx-pill--soon      { color: var(--conx-gold-ink);  background: var(--conx-gold-pill); }
.conx-pill__lock { font-size: 9px; line-height: 1; }

/* ── Status edge — the whole status system ───────────────────────── */
.conx-row--connected { border-left-color: var(--primary); }
.conx-row--attention { border-left-color: var(--conx-gold); background: var(--conx-gold-wash); }
.conx-row--custom    { border-left-color: var(--conx-edge-muted); }
.conx-row--severed   { border-left-color: var(--conx-edge-muted); background: var(--paper-warm); }
.conx-row--locked    { border-left-color: transparent; }

/* ── Buttons ─────────────────────────────────────────────────────── */
.conx-btn {
  display: inline-flex; align-items: center; justify-content: center;
  font: var(--weight-semibold) 12.5px var(--font-sans);
  padding: 9px 14px; border-radius: var(--radius-sm);
  border: var(--hairline) solid transparent; background: none;
  cursor: pointer; white-space: nowrap; text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
}
.conx-btn:hover { text-decoration: none; }
.conx-btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.conx-btn--primary { background: var(--action-primary); color: #fff; }
.conx-btn--primary:hover { background: var(--action-primary-press); color: #fff; }
.conx-btn--gold { background: var(--conx-gold); color: var(--conx-gold-on); }
.conx-btn--gold:hover { background: var(--conx-gold-ink); color: #fff; }
.conx-btn--outline {
  border-color: var(--primary-border); background: var(--paper); color: var(--primary);
  padding: 8px 14px; font-size: var(--text-xs);
}
.conx-btn--outline:hover { background: var(--primary-tint-2); color: var(--primary-press); }
.conx-btn--quiet { color: var(--ink-faint); padding: 9px 8px; }
.conx-btn--quiet:hover { color: var(--accent); }

/* ── Permissions & tool disclosures ──────────────────────────────── */
.conx-disc { margin-top: 9px; }
.conx-disc__summary {
  display: inline-block; cursor: pointer; list-style: none;
  font: var(--weight-semibold) 12.5px var(--font-sans); color: var(--primary);
}
.conx-disc__summary::-webkit-details-marker { display: none; }
.conx-disc__summary::after { content: " ›"; }
.conx-disc[open] > .conx-disc__summary::after { content: " ⌄"; }
.conx-disc__body {
  margin-top: 10px; padding: 13px 15px;
  border-radius: var(--radius-md);
  background: var(--paper-warm);
  border: var(--hairline) solid var(--border-divider);
}
.conx-perms__label {
  font: var(--weight-bold) 10px var(--font-sans);
  letter-spacing: var(--tracking-label); color: var(--ink-faint);
  margin-bottom: 7px;
}
.conx-perms__label--can { color: var(--primary); }
.conx-perms__list { margin: 0 0 14px; padding: 0; list-style: none; display: grid; gap: 6px; }
.conx-perms__list:last-child { margin-bottom: 0; }
.conx-perms__list li {
  font-size: var(--text-sm); line-height: var(--leading-normal);
  padding-left: 18px; position: relative;
}
.conx-perms__list--can li { color: var(--ink); }
.conx-perms__list--can li::before { content: "✓"; position: absolute; left: 0; color: var(--primary); }
.conx-perms__list--cannot li { color: var(--ink-soft); }
.conx-perms__list--cannot li::before { content: "—"; position: absolute; left: 0; color: var(--ink-ghost); }

/* Per-tool approval on a custom server row */
.conx-tools__form { display: grid; gap: var(--space-2); }
.conx-tool {
  display: flex; gap: 10px; align-items: flex-start;
  padding: 8px 10px; border-radius: var(--radius-sm);
  background: var(--paper); border: var(--hairline) solid var(--border-divider);
  cursor: pointer;
}
.conx-tool__cb { margin-top: 2px; flex: none; accent-color: var(--primary); }
.conx-tool__text { min-width: 0; }
.conx-tool__name { display: block; font-size: var(--text-xs); color: var(--primary); }
.conx-tool__desc { display: block; font-size: var(--text-sm); line-height: var(--leading-normal); color: var(--ink-soft); }
.conx-tools__note { margin: 2px 0 0; font-size: var(--text-xs); line-height: var(--leading-normal); color: var(--ink-faint); }
.conx-tools__form .conx-btn { justify-self: start; }

/* ── Available register — a visibly lighter read ─────────────────── */
.conx-list--available { background: var(--paper-warm); }
.conx-offer {
  display: flex; align-items: center; gap: var(--space-3);
  padding: 13px 17px; background: var(--paper-warm);
}
.conx-offer__main { flex: 1; min-width: 0; }
.conx-offer__name { font-weight: var(--weight-semibold); font-size: var(--text-sm); color: var(--ink); }
.conx-offer__sum { font-size: var(--text-xs); color: var(--ink-faint); }
.conx-offer__soon { font: var(--weight-semibold) var(--text-xs) var(--font-sans); color: var(--ink-ghost); }

/* The custom-server form used to live here as a <details> with its own field
   and input styles. It is a modal now — the same .fdlg component the webhook
   form uses (dialog.css) — so both the disclosure and the duplicate form
   styling are gone. */

/* ── Preview mode (Standard) ─────────────────────────────────────── */
.conx-list--preview .conx-row { opacity: .65; }
.conx-upsell {
  display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
  margin-top: 20px; padding: 18px 20px;
  border: var(--hairline) solid var(--primary-border);
  border-radius: var(--radius-lg);
  background: var(--primary-tint-2);
}
.conx-upsell__main { flex: 1 1 320px; min-width: 0; }
.conx-upsell__title {
  font: var(--weight-semibold) var(--display-sm) / var(--leading-snug) var(--font-display);
  color: var(--ink); margin-bottom: 5px;
}
.conx-upsell__text { margin: 0 0 6px; font-size: var(--text-sm); line-height: var(--leading-relaxed); color: var(--ink); }
.conx-upsell__fine { margin: 0; font-size: var(--text-xs); line-height: var(--leading-normal); color: var(--ink-faint); }
.conx-upsell__cta { flex: none; padding: 11px 18px; font-size: var(--text-sm); border-radius: var(--radius-md); }

/* ── Nav signal (app shell) ──────────────────────────────────────────
   The gold dot rides the spine's SETTINGS gear — the entry to the page that
   fixes it — and it clears itself the moment nothing is broken, so it never
   becomes wallpaper. It sat on the avatar until Connections moved out of the
   account flyout and behind the gear; a dot pointing at a menu that no longer
   holds the thing is worse than no dot. */
.acctflyout__row .conx-need,
.mobilenav__row .conx-need {
  margin-left: auto;
  font: var(--weight-semibold) 11px var(--font-sans);
  color: var(--conx-gold-ink); background: var(--conx-gold-pill);
  padding: 3px 8px; border-radius: var(--radius-pill);
}
.spine__btn--dotted { position: relative; }
.conx-navdot {
  position: absolute; top: -2px; right: -2px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--conx-gold);
  border: 2px solid var(--conx-nav-ring);
}
/* The spine's ring colour; kept as a variable so the two agree. */
.conx-navdot--on-paper { border-color: var(--paper); }

/* ── Responsive — single column below 720px ──────────────────────────
   The 4px edge, the tile and the rows all reflow with no layout change;
   only the action column moves under the text. */
@media (max-width: 720px) {
  .conx-row { flex-wrap: wrap; }
  .conx-row__acts {
    flex: 1 0 100%;
    margin-top: 10px; padding-left: 46px;
    justify-content: flex-start;
  }
  .conx-banner { flex-wrap: wrap; }
  .conx-banner__act { flex: 1 0 100%; margin-top: 4px; }
  .conx-upsell__cta { flex: 1 0 100%; }
  .conx-offer { flex-wrap: wrap; }
  .conx-offer__main { flex: 1 1 60%; }
}
/* Daily-brief output templates — TL;DR and Newspaper styles share these tokens. */
.db-metarow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.db-meta { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; }

@media (max-width: 720px) {
  /* Date and time stay together on one line; the run detail drops below.
     The date is unbreakable — a long weekday and month at the largest
     reading size will not share a row with it. */
  .db-metarow { align-items: baseline; flex-wrap: wrap; }
  .db-meta__date { white-space: nowrap; }
}

/* ---- shared feedback card ---- */
.db-fb { border: 1.5px solid #cfe0d9; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 10px 34px rgba(50,42,28,.06); margin-top: 22px; }
.db-fb__head { padding: 16px 18px 4px; }
.db-fb__title { font-family: "Newsreader", serif; font-size: calc(18px * var(--reading-scale)); font-weight: 500; }
.db-fb__sub { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; margin-top: 2px; }
.db-fb__body { padding: 12px 18px 18px; }
.db-fb__chips { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.db-fb__chip { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; padding: 6px 11px; border-radius: 999px; cursor: pointer; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; }
.db-fb__chip.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.db-fb__notes { display: block; width: 100%; min-height: 56px; padding: 12px 14px; border: 1.5px solid #e6e1d6; border-radius: 11px; font: 400 calc(13px * var(--reading-scale))/1.6 "Hanken Grotesk"; color: #3a352c; outline: none; background: #fcfbf7; resize: vertical; }
.db-fb__notes:focus { border-color: #cfe0d9; }
.db-fb__foot { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.db-fb__spacer { flex: 1; }
.db-fb__status { font-size: calc(12px * var(--reading-scale)); color: #2f6d5b; }
.db-fb__save { font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; padding: 11px 18px; border-radius: 11px; border: none; background: #2f6d5b; color: #fff; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.db-fb__save:hover { background: #28604f; }

.db-colophon { text-align: center; padding: 22px 0 0; font-size: calc(11px * var(--reading-scale)); line-height: 1.6; color: #9a9384; }

/* =================== TL;DR =================== */
.db--tldr { max-width: 660px; margin: 0 auto; }
/* Both brief columns are centred and narrower than the template body, so the
   reader chrome above and below them follows suit — see --reader-col in
   reader.css. */
.reader-body:has(> .db--tldr) { --reader-col: 660px; --reader-col-inline: auto; }
.db-title { font-family: "Newsreader", serif; font-weight: 500; font-size: calc(30px * var(--reading-scale)); line-height: 1.1; margin: 0 0 20px; }
/* Reading cue, under the title: how long the brief takes, not when it ran. */
.db-readtime {
  display: flex; align-items: center; gap: 6px;
  font-size: calc(12.5px * var(--reading-scale)); color: #9a9384;
  margin: -12px 0 20px;
}

.db-tldr { background: #eef4f1; border: 1.5px solid #cfe0d9; border-radius: 16px; padding: 18px 20px; margin-bottom: 26px; }
.db-tldr__head { display: flex; align-items: center; gap: 8px; margin-bottom: 13px; }
.db-tldr__badge { width: 24px; height: 24px; border-radius: 7px; background: #2f6d5b; color: #fff; display: flex; align-items: center; justify-content: center; font-size: calc(12px * var(--reading-scale)); }
.db-tldr__label { font: 700 calc(11px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .8px; color: #2f6d5b; }
.db-tldr__list { display: flex; flex-direction: column; gap: 11px; }
.db-tldr__item { display: flex; gap: 11px; align-items: flex-start; }
.db-tldr__n { font-family: "Newsreader", serif; font-weight: 600; font-size: calc(15px * var(--reading-scale)); color: #2f6d5b; flex: none; line-height: 1.3; }
.db-tldr__text { font-size: calc(14px * var(--reading-scale)); line-height: 1.5; color: #245043; }
.db-tldr__text strong { font-weight: 700; color: #1f3f36; }

.db-divider { display: flex; align-items: center; gap: 10px; margin-bottom: 6px; }
.db-divider__label { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: 1px; color: #9a9384; }
.db-divider__rule { flex: 1; height: 1.5px; background: #e2ddd0; }
.db-divider__hint { font-size: calc(11px * var(--reading-scale)); color: #9a9384; }

.db-theme { margin-top: 16px; }
.db-theme__head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.db-theme__sq { width: 7px; height: 7px; border-radius: 2px; background: var(--tone, #2f6d5b); }
.db-theme__name { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .6px; color: #6f6a5e; }
.db-theme__count { font-size: calc(10.5px * var(--reading-scale)); color: #b9b2a3; }
.db-theme__items { border: 1.5px solid #e6e1d6; border-radius: 13px; background: #fff; overflow: hidden; }

.db-item + .db-item { border-top: 1.5px solid #f0ece3; }
.db-item__head { display: flex; align-items: center; gap: 11px; padding: 13px 15px; cursor: pointer; width: 100%; background: none; border: none; text-align: left; }
.db-item__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: #d8d2c5; }
.db-item.is-open .db-item__dot { background: var(--dot, #2f6d5b); }
.db-item__headline { flex: 1; font-weight: 600; font-size: calc(13.5px * var(--reading-scale)); line-height: 1.35; min-width: 0; }
.db-item__time { font-size: calc(11px * var(--reading-scale)); color: #9a9384; flex: none; }
.db-item__chev { flex: none; color: #b9b2a3; font-size: calc(15px * var(--reading-scale)); transition: transform .2s; }
.db-item.is-open .db-item__chev { transform: rotate(90deg); }
.db-item__detail { display: none; padding: 0 15px 15px 41px; flex-direction: column; gap: 10px; }
.db-item.is-open .db-item__detail { display: flex; }
.db-item__body { font-size: calc(13px * var(--reading-scale)); line-height: 1.6; color: #443f34; margin: 0; }
.db-item__why { display: flex; gap: 8px; align-items: flex-start; background: #f4f8f6; border-radius: 9px; padding: 9px 12px; font-size: calc(12px * var(--reading-scale)); line-height: 1.5; color: #2f5f52; }
.db-item__whylbl { font: 700 calc(8px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .4px; color: #2f6d5b; flex: none; margin-top: 4px; }
.db-item__source { font: 600 calc(10.5px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; }

/* =================== NEWSPAPER =================== */
.db--news { max-width: 860px; margin: 0 auto; }
.reader-body:has(> .db--news) { --reader-col: 860px; --reader-col-inline: auto; }
.db-paper { background: #fdfcf9; border: 1.5px solid #e2ddd0; border-radius: 6px; box-shadow: 0 8px 30px rgba(50,42,28,.08); padding: 34px 44px 40px; }
.db--news .dropcap p:first-of-type::first-letter { font-family: "Newsreader", serif; font-weight: 500; font-size: calc(52px * var(--reading-scale)); line-height: .82; float: left; margin: 5px 9px 0 0; color: #2f6d5b; }

.db-masthead { text-align: center; border-bottom: 3px double #26221b; padding-bottom: 14px; margin-bottom: 8px; }
.db-masthead__eyebrow { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: 3px; color: #9a9384; margin-bottom: 6px; }
.db-masthead__name { font-family: "Newsreader", serif; font-weight: 600; font-size: calc(44px * var(--reading-scale)); line-height: 1; letter-spacing: .5px; }
.db-dateline { display: flex; align-items: center; justify-content: center; gap: 14px; flex-wrap: wrap; font: 600 calc(10.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .4px; color: #6f6a5e; border-bottom: 1.5px solid #e2ddd0; padding-bottom: 16px; margin-bottom: 22px; }
.db-dateline__sep { color: #cbc4b6; }

.db-lead { display: grid; grid-template-columns: 1.55fr 1fr; gap: 30px; padding-bottom: 22px; border-bottom: 1.5px solid #e2ddd0; margin-bottom: 20px; }
.db-lead__kicker { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: 1px; color: #b45b3e; margin-bottom: 8px; }
.db-lead__headline { font-family: "Newsreader", serif; font-weight: 600; font-size: calc(31px * var(--reading-scale)); line-height: 1.08; margin: 0 0 10px; }
.db-lead__body p { font-family: "Newsreader", serif; font-size: calc(15.5px * var(--reading-scale)); line-height: 1.62; color: #2b2820; margin: 0 0 12px; }
.db-lead__body p:last-child { margin-bottom: 0; }
.db-lead__aside { display: flex; flex-direction: column; gap: 14px; }
.db-lead__why { background: #f4f8f6; border: 1.5px solid #dcebe5; border-radius: 11px; padding: 14px 16px; }
.db-lead__whylbl { font: 700 calc(9px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .6px; color: #2f6d5b; margin-bottom: 7px; }
.db-lead__whytxt { font-size: calc(13px * var(--reading-scale)); line-height: 1.55; color: #2f5f52; }
.db-glance { border-top: 1.5px solid #e2ddd0; padding-top: 12px; }
.db-glance__lbl { font: 700 calc(9px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; margin-bottom: 6px; }
.db-glance__row { display: flex; justify-content: space-between; font-size: calc(12.5px * var(--reading-scale)); color: #6f6a5e; margin-bottom: 7px; }
.db-glance__val { font-weight: 600; color: #26221b; }

.db-section { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.db-section__label { font: 700 calc(11px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: 1.5px; color: #26221b; }
.db-section__rule { flex: 1; height: 1.5px; background: #e2ddd0; }

.db-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 26px 34px; margin-bottom: 24px; }
.db-story__kicker { font: 700 calc(9.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .7px; margin-bottom: 7px; color: var(--tone, inherit); }
.db-story__headline { font-family: "Newsreader", serif; font-weight: 600; font-size: calc(19px * var(--reading-scale)); line-height: 1.15; margin: 0 0 7px; }
.db-story__standfirst { font-family: "Newsreader", serif; font-size: calc(14px * var(--reading-scale)); line-height: 1.55; color: #443f34; margin: 0 0 10px; }
.db-story__why { display: flex; gap: 7px; align-items: flex-start; margin-bottom: 9px; font-size: calc(11.5px * var(--reading-scale)); line-height: 1.45; color: #5c574c; }
.db-story__whytag { font: 700 calc(8px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .4px; color: #2f6d5b; background: #eef4f1; padding: 3px 6px; border-radius: 5px; flex: none; margin-top: 1px; }
.db-story__source { font: 600 calc(10.5px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; }

.db-inbrief { background: #f7f4ee; border: 1.5px solid #e2ddd0; border-radius: 11px; padding: 16px 20px; margin-bottom: 20px; }
.db-inbrief__label { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: 1px; color: #26221b; margin-bottom: 12px; }
.db-inbrief__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 9px 26px; }
.db-inbrief__item { display: flex; gap: 9px; align-items: flex-start; font-size: calc(12.5px * var(--reading-scale)); line-height: 1.45; color: #3a352c; }
.db-inbrief__cat { font: italic 700 calc(10px * var(--reading-scale)) "Newsreader", serif; color: #b45b3e; flex: none; }

.db-colophon--paper { border-top: 1.5px solid #e2ddd0; padding-top: 16px; }

@media (max-width: 720px) {
  .db-paper { padding: 24px 20px 30px; }
  .db-masthead__name { font-size: calc(32px * var(--reading-scale)); }
  .db-lead, .db-grid, .db-inbrief__grid { grid-template-columns: 1fr; }
}

/* ---- mobile vertical rhythm ----
   Must come after the base .db-title / .db-readtime / .db-tldr rules above:
   a media query adds no specificity, so an earlier block would simply lose to
   them. Kept at the end of the file for that reason. */
@media (max-width: 720px) {
  /* The timestamp, a 40px headline and the read time were stacking ~6px
     apart, reading as one dense clump before the brief even started. */
  .db-metarow { margin-bottom: 16px; }
  .db-title { margin-bottom: 0; line-height: 1.15; }
  .db-readtime { margin: 10px 0 24px; }
  .db-tldr { padding: 20px 18px; margin-bottom: 30px; }
  .db-tldr__list { gap: 18px; }
  .db-divider { margin-bottom: 16px; }
  .db-theme { margin-bottom: 22px; }
}
/* ── Draft family (newsletter, social posts) ─────────────────────────────────
   Publish-ready content the user copies out. Reuses the reader shell; the dr-*
   classes below add the draft header, the copy affordance, and the post cards. */

.dr-raw { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; white-space: pre-wrap; }

.dr-head { display: flex; align-items: flex-start; gap: 16px; padding-bottom: 16px; margin-bottom: 20px; border-bottom: 1.5px solid #e6e1d6; }
.dr-head__main { flex: 1; min-width: 0; }
.dr-kicker { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; color: #9a9384; margin-bottom: 8px; }
.dr-subject { font-family: var(--font-display); font-weight: 600; font-size: calc(27px * var(--reading-scale)); line-height: 1.15; color: #26221b; margin: 0 0 8px; }
.dr-preview { font-size: calc(14px * var(--reading-scale)); color: #6f6a5e; line-height: 1.5; }
.dr-meta { font-size: calc(12px * var(--reading-scale)); color: #9a9384; margin-top: 8px; }

.dr-copy { flex: none; display: inline-flex; align-items: center; gap: 6px; font: 600 calc(12.5px * var(--reading-scale)) var(--font-sans); color: #fff; background: #2f6d5b; border: none; border-radius: 10px; padding: 9px 14px; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.dr-copy:hover { background: #28604f; }
.dr-copy.is-copied { background: #28604f; }
.dr-copy--ghost { color: #2f6d5b; background: #fff; border: 1.5px solid #cfe0d9; box-shadow: none; }
.dr-copy--ghost:hover { background: #f4f8f6; }

/* Icon-only export, with the label moved into a hover tooltip. The glyph swaps
   to a tick on success — see draft.js, which skips its textContent confirmation
   for these so the inline SVG survives. */
.dr-copy--icon { position: relative; width: 36px; height: 36px; padding: 0; justify-content: center; }
.dr-copy--icon svg { width: 17px; height: 17px; display: block; }
/* Both selectors carry .dr-copy--icon so they outrank `.dr-copy--icon svg`
   above — a bare .dr-copy__ok loses to it and shows both glyphs at once. */
.dr-copy--icon .dr-copy__ok,
.dr-copy--icon.is-copied .dr-copy__i { display: none; }
.dr-copy--icon.is-copied .dr-copy__ok { display: block; }

/* The app has no tooltip primitive, so this one is scoped to the button rather
   than invented as a system. Hover and keyboard focus both reveal it; the
   aria-label carries the same words for anyone who gets neither. */
.dr-copy--icon::after {
  content: attr(data-tip);
  position: absolute; top: calc(100% + 7px); right: 0;
  font: 500 11.5px/1 var(--font-sans); white-space: nowrap;
  color: #f7f4ec; background: #33302a; border-radius: 7px; padding: 6px 9px;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
  z-index: 5;
}
.dr-copy--icon:hover::after,
.dr-copy--icon:focus-visible::after { opacity: 1; }
/* Nothing to explain while the tick is showing — it just said "copied". */
.dr-copy--icon.is-copied::after { content: none; }

/* Phone: the headline and the export button fight over one row. "Copy as
   Markdown" takes nearly half the width, so a title wraps to five lines beside
   a button that isn't why anyone opened the page. Give the title the whole
   column and let the button wrap below the standfirst, where it reads as an
   aside rather than the delivery's main action. */
@media (max-width: 720px) {
  .dr-head { flex-wrap: wrap; gap: 12px; }
  .dr-head__main { flex: 1 0 100%; }
  .dr-copy { margin-left: auto; padding: 8px 12px; }

  /* The Article's export is a 36px icon, so it costs the headline almost no
     width — it stays on the title's row rather than wrapping to one of its own,
     where a lone small icon would read as stranded. */
  .dr-prose .dr-head__main { flex: 1 1 0; min-width: 0; }
  .dr-prose .dr-copy--icon { padding: 0; }
}

/* Newsletter body — long-form prose the user edits and sends. */
.dr-intro { font-size: calc(16px * var(--reading-scale)); line-height: 1.7; color: #3a352c; margin-bottom: 8px; }
.dr-intro p { margin: 0 0 14px; }
.dr-dek { font-family: var(--font-display); font-size: calc(17px * var(--reading-scale)); font-style: italic; color: #6f6a5e; margin: 0 0 18px; }
.dr-section { margin: 26px 0; }
.dr-section__h { font-family: var(--font-display); font-weight: 600; font-size: calc(20px * var(--reading-scale)); color: #26221b; margin: 0 0 10px; }
.dr-section__body { font-size: calc(15.5px * var(--reading-scale)); line-height: 1.7; color: #3a352c; }
.dr-section__body p { margin: 0 0 14px; }
.dr-section__src { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; margin-top: 6px; }
.dr-section__src a { color: #2f6d5b; text-decoration: none; border-bottom: 1px solid #cfe0d9; }
.dr-signoff { margin-top: 26px; padding-top: 18px; border-top: 1.5px solid #f0ece3; font-size: calc(15.5px * var(--reading-scale)); line-height: 1.7; color: #3a352c; }

/* Block weight. An issue is not a run of equal sections: most formats have one
   or two pieces they're built on and a tail of short stuff. `lead` gets the
   headline treatment, `brief` gets a rule and tighter type so a tail of five
   reads as a tail rather than five more chapters. */
.dr-section--lead .dr-section__h { font-size: calc(24px * var(--reading-scale)); line-height: 1.2; letter-spacing: -.2px; }
.dr-section--lead .dr-section__body { font-size: calc(16.5px * var(--reading-scale)); }
.dr-section--brief { margin: 18px 0; padding-left: 14px; border-left: 2px solid #e6e1d6; }
.dr-section--brief .dr-section__h { font-family: var(--font-sans); font-weight: 700; font-size: calc(13px * var(--reading-scale)); letter-spacing: .3px; color: #6f6a5e; margin-bottom: 6px; }
.dr-section--brief .dr-section__body { font-size: calc(14.5px * var(--reading-scale)); line-height: 1.6; }

/* An `items` block: a list of things, where a prose block would have been a
   list of chapters. The blurb is a second line, and is legitimately absent —
   "bare links, no blurbs" is a format, not an incomplete delivery. */
.dr-items { margin: 0; padding: 0; list-style: none; }
.dr-items--num { counter-reset: dr-item; }
.dr-item { padding: 10px 0; border-bottom: 1px solid #f0ece3; }
.dr-item:last-child { border-bottom: 0; }
.dr-item__t { display: block; font-size: calc(15.5px * var(--reading-scale)); line-height: 1.45; color: #26221b; }
.dr-item__t a { color: #26221b; text-decoration: none; border-bottom: 1px solid #cfe0d9; }
.dr-item__t a:hover { color: #2f6d5b; }
.dr-item__b { display: block; font-size: calc(14px * var(--reading-scale)); line-height: 1.55; color: #6f6a5e; margin-top: 3px; }
/* The number is part of the format ("5 things this week"), so it's set as a
   deliberate marker rather than left to the browser's list indent. */
.dr-items--num .dr-item { display: grid; grid-template-columns: 26px 1fr; gap: 10px; align-items: baseline; counter-increment: dr-item; }
.dr-items--num .dr-item::before {
  content: counter(dr-item);
  font: 700 calc(13px * var(--reading-scale)) var(--font-sans); color: #2f6d5b;
}

/* Social posts — a few copy-ready cards. */
.dr-angle { font-size: calc(14px * var(--reading-scale)); color: #6f6a5e; line-height: 1.6; margin-bottom: 20px; }
.dr-posts { display: flex; flex-direction: column; gap: 16px; }
.dr-post { border: 1.5px solid #e6e1d6; border-radius: 14px; background: #fff; padding: 18px 20px; }
/* The Copy button is pushed right by the head itself. It used to be pushed by
   an empty <div class="hh-spacer" style="flex:1">, which was both a borrowed
   house-hunt class that had no rule anywhere and the one genuinely static
   inline style left in the reader templates. The platform pill may be absent,
   so `margin-left: auto` on the button beats space-between — with one child
   the button must still sit right, not left. */
.dr-post__head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.dr-post__head .dr-copy { margin-left: auto; }
.dr-post__platform { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .5px; color: #2f6d5b; background: #dcebe5; border-radius: 999px; padding: 4px 10px; }
.dr-post__hook { font-family: var(--font-display); font-weight: 500; font-size: calc(17px * var(--reading-scale)); line-height: 1.3; color: #26221b; margin-bottom: 10px; }
.dr-post__body { font-size: calc(14.5px * var(--reading-scale)); line-height: 1.6; color: #3a352c; white-space: pre-wrap; }
.dr-post__body p { margin: 0 0 10px; }
.dr-post__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.dr-post__tag { font: 600 calc(12px * var(--reading-scale)) var(--font-sans); color: #2f6d5b; }
.dr-post__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 14px; padding-top: 12px; border-top: 1.5px solid #f0ece3; }
.dr-post__chars { font-size: calc(11.5px * var(--reading-scale)); color: #9a9384; }
.dr-post__src { font-size: calc(11.5px * var(--reading-scale)); color: #9a9384; }
.dr-post__src a { color: #2f6d5b; text-decoration: none; border-bottom: 1px solid #cfe0d9; }

/* Article template (blog_post) — adds a category chip, an example-Delivery
   figure, and a limitation section to the shared draft chrome. */
.dr-cat { color: #2f6d5b; background: #dcebe5; border-radius: 6px; padding: 2px 8px; letter-spacing: .4px; }
.dr-excerpt {
  margin: 22px 0; border: 1.5px solid var(--primary-border, #cfe0d9); border-radius: 14px;
  background: var(--primary-tint-2, #f4f8f6); padding: 16px 18px;
}
.dr-excerpt__cap { font: 700 calc(10px * var(--reading-scale)) var(--font-sans); letter-spacing: .6px; color: #2f6d5b; margin-bottom: 8px; }
.dr-excerpt__body {
  font: 400 calc(12.5px * var(--reading-scale))/1.75 "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  color: #3a352c; white-space: pre-wrap; word-break: break-word; margin: 0; background: none; border: 0; padding: 0;
}
.dr-section--limit { border-top: 1.5px solid #e6e1d6; margin-top: 30px; padding-top: 22px; }
.dr-cta { font-family: var(--font-display); font-size: calc(16px * var(--reading-scale)); color: #2f6d5b; margin: 26px 0 0; }
.dr-cta p { margin: 0 0 8px; }
.dr-cta a { color: #2f6d5b; text-decoration: underline; }

/* ── Article: long-form prose ─────────────────────────────────────────────
   The Article template is read start-to-finish, not scanned like a briefing,
   so its column opts out of the sans reader body and into the same serif
   measure the public joris explains reader uses. Scoped to .dr-prose so the
   briefing templates are untouched. */
.dr-prose .reader-document {
  font-family: var(--font-display);
  font-size: calc(18.5px * var(--reading-scale));
  line-height: 1.72;
  color: #33302a;
}
.dr-prose .reader-document p { margin: 0 0 calc(18px * var(--reading-scale)); }
.dr-prose .reader-document em { font-style: italic; }
.dr-prose .dr-section { margin-bottom: calc(26px * var(--reading-scale)); }
.dr-prose .dr-section__h {
  font-size: calc(23px * var(--reading-scale)); line-height: 1.2;
  letter-spacing: -.3px; margin: calc(34px * var(--reading-scale)) 0 12px;
}
.dr-prose .dr-dek {
  font-family: var(--font-display); font-size: calc(17.5px * var(--reading-scale));
  font-style: italic; line-height: 1.5; color: #6f6a5e; margin: 0 0 18px;
}
.dr-prose .dr-dek p { margin: 0; }
/* The excerpt stays monospace — it is the Delivery, not prose. */
.dr-prose .dr-excerpt__body { font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace; }
/* Nutrition-plan output template — weekly meal plan + shopping list. */
.nu { max-width: 940px; margin: 0 auto; }
/* The reader chrome lines up with this column, not the template body — see
   --reader-col in reader.css. */
.reader-body:has(> .nu) { --reader-col: 940px; --reader-col-inline: auto; }

.nu-metarow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 6px; }
.nu-meta { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; }

@media (max-width: 720px) {
  /* Date and time stay together on one line; the run detail drops below.
     The date is unbreakable — a long weekday and month at the largest
     reading size will not share a row with it. */
  .nu-metarow { align-items: baseline; flex-wrap: wrap; }
  .nu-meta__sep { display: none; }
  .nu-meta__date, .nu-meta__detail { display: block; }
  .nu-meta__date { white-space: nowrap; }
}

.nu-title { font-family: "Newsreader", serif; font-weight: 500; font-size: calc(32px * var(--reading-scale)); line-height: 1.1; margin: 0 0 8px; }
.nu-intro { font-size: calc(14.5px * var(--reading-scale)); line-height: 1.6; color: #3a352c; max-width: 680px; margin: 0 0 22px; }
.nu-intro p { margin: 0; }

/* day strip */
.nu-daystrip { display: flex; gap: 7px; margin-bottom: 20px; }
.nu-day { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 10px 0; border-radius: 12px; cursor: pointer; background: #fff; color: #6f6a5e; border: 1.5px solid #e6e1d6; }
.nu-day__dow { font-size: calc(10px * var(--reading-scale)); font-weight: 600; letter-spacing: .3px; opacity: .7; }
.nu-day__date { font: 700 calc(15px * var(--reading-scale)) "Hanken Grotesk"; }
.nu-day__dot { width: 5px; height: 5px; border-radius: 50%; background: #cfe0d9; }
.nu-day.is-active { background: #2f6d5b; color: #fff; border-color: #2f6d5b; box-shadow: 0 4px 12px rgba(47,109,91,.28); }
.nu-day.is-active .nu-day__dot { background: rgba(255,255,255,.8); }

/* day view (only active shows) */
.nu-dayview { display: none; }
.nu-dayview.is-active { display: block; }

/* today hero */
.nu-hero { border: 1.5px solid #e6e1d6; border-radius: 18px; background: #fff; padding: 22px 24px; margin-bottom: 16px; box-shadow: 0 4px 16px rgba(50,42,28,.05); }
.nu-hero__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; }
.nu-hero__eyebrow { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; }
.nu-hero__theme { font-family: "Newsreader", serif; font-size: calc(20px * var(--reading-scale)); font-weight: 500; }
.nu-badge { font: 600 calc(11px * var(--reading-scale)) "Hanken Grotesk"; padding: 6px 12px; border-radius: 999px; background: #f1ede4; color: #9a9384; }
.nu-badge--today { background: #dcebe5; color: #2f6d5b; }
.nu-hero__body { display: flex; gap: 26px; align-items: center; flex-wrap: wrap; }

/* The ring is a gauge, so its geometry scales with the text inside it —
   otherwise a 4-digit calorie count outgrows the fixed inner circle at the
   larger reading sizes. */
/* --kp is the day's calories as a percentage of target, stamped on the element
   by _nutrition.html.erb. A per-delivery number cannot live in a stylesheet, so
   it arrives as a custom property rather than as a full inline `background`:
   the gradient's COLOURS stay here where they can be themed, and only the
   number crosses over. Same pattern as --dot in delivery_brief.css. */
.nu-ring { position: relative; width: calc(132px * var(--reading-scale)); height: calc(132px * var(--reading-scale)); flex: none; border-radius: 50%; background: conic-gradient(#2f6d5b 0 var(--kp, 0%), #ece7db var(--kp, 0%) 100%); }
.nu-ring__inner { position: absolute; inset: calc(15px * var(--reading-scale)); border-radius: 50%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.nu-ring__kcal { font-family: "Newsreader", serif; font-size: calc(30px * var(--reading-scale)); font-weight: 500; line-height: 1; }
.nu-ring__target { font-size: calc(10.5px * var(--reading-scale)); color: #9a9384; margin-top: 2px; }
.nu-ring__pct { font: 600 calc(10px * var(--reading-scale)) "Hanken Grotesk"; color: #2f6d5b; margin-top: 3px; }

.nu-macros { flex: 1; min-width: 230px; display: flex; flex-direction: column; gap: 13px; }
.nu-macro__row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; }
.nu-macro__label { font-weight: 600; font-size: calc(12.5px * var(--reading-scale)); color: #3a352c; }
.nu-macro__val { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; color: #6f6a5e; }
.nu-macro__val span { color: #b9b2a3; }
.nu-macro__track { height: 9px; border-radius: 999px; background: #f0ece3; overflow: hidden; }
.nu-macro__fill { height: 100%; border-radius: 999px; width: var(--pct, 0%); background: var(--macro, #2f6d5b); }
.nu-macro__note { display: flex; align-items: center; gap: 6px; font-size: calc(11.5px * var(--reading-scale)); color: #9a9384; margin-top: 2px; }

/* meals */
.nu-meals { display: flex; flex-direction: column; gap: 11px; margin-bottom: 30px; }
.nu-meal { border: 1.5px solid #e6e1d6; border-radius: 15px; background: #fff; overflow: hidden; box-shadow: 0 2px 6px rgba(50,42,28,.04); }
.nu-meal__head { display: flex; gap: 14px; align-items: center; padding: 13px 15px; cursor: pointer; width: 100%; background: none; border: none; text-align: left; }
.nu-meal__swatch { width: 58px; height: 58px; border-radius: 12px; flex: none; background: #f3ede0; display: flex; align-items: center; justify-content: center; font-size: calc(24px * var(--reading-scale)); }
.nu-meal__main { flex: 1; min-width: 0; }
.nu-meal__slot { display: block; font: 700 calc(9.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .4px; color: #a49d8d; margin-bottom: 2px; }
.nu-meal__name { display: block; font-weight: 600; font-size: calc(15px * var(--reading-scale)); line-height: 1.2; margin-bottom: 4px; }
.nu-meal__tags { display: flex; gap: 6px; flex-wrap: wrap; }
.nu-tag { font: 600 calc(10px * var(--reading-scale)) "Hanken Grotesk"; padding: 3px 8px; border-radius: 999px; background: #f1ede4; color: #6f6a5e; }
.nu-tag--p { background: #eef4f1; color: #2f6d5b; }
.nu-meal__nums { text-align: right; flex: none; }
.nu-meal__kcal { font-family: "Newsreader", serif; font-size: calc(19px * var(--reading-scale)); font-weight: 500; line-height: 1; }
.nu-meal__kcallbl { display: block; font-size: calc(10px * var(--reading-scale)); color: #9a9384; }
.nu-meal__time { display: block; font: 600 calc(10.5px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; margin-top: 6px; }
.nu-meal__chev { flex: none; color: #9a9384; font-size: calc(18px * var(--reading-scale)); transition: transform .2s; }
.nu-meal.is-open .nu-meal__chev { transform: rotate(90deg); }

.nu-meal__detail { display: none; border-top: 1.5px solid #f0ece3; padding: 16px 17px; gap: 22px; flex-wrap: wrap; background: #fcfbf7; }
.nu-meal.is-open .nu-meal__detail { display: flex; }
.nu-meal__col { flex: 1; min-width: 180px; }
.nu-meal__col--wide { flex: 1.4; min-width: 220px; }
.nu-meal__collbl { font: 700 calc(9px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; margin-bottom: 9px; }
.nu-ing { display: flex; justify-content: space-between; font-size: calc(12.5px * var(--reading-scale)); color: #3a352c; margin-bottom: 6px; }
.nu-ing__qty { color: #9a9384; }
.nu-step { display: flex; gap: 9px; margin-bottom: 8px; }
.nu-step__n { width: 19px; height: 19px; flex: none; border-radius: 6px; background: #eef4f1; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; }
.nu-step span:last-child { font-size: calc(12.5px * var(--reading-scale)); line-height: 1.5; color: #3a352c; }

/* shopping list */
.nu-shop { border: 1.5px solid #e6e1d6; border-radius: 18px; background: #fff; overflow: hidden; margin-bottom: 26px; box-shadow: 0 4px 16px rgba(50,42,28,.05); scroll-margin-top: 20px; }
.nu-shop__head { display: flex; align-items: center; gap: 11px; padding: 16px 20px; border-bottom: 1.5px solid #f0ece3; }
.nu-shop__icon { width: 36px; height: 36px; flex: none; border-radius: 10px; background: #eef4f1; display: flex; align-items: center; justify-content: center; font-size: calc(18px * var(--reading-scale)); }
.nu-shop__titles { flex: 1; }
.nu-shop__title { font-family: "Newsreader", serif; font-size: calc(18px * var(--reading-scale)); font-weight: 500; }
.nu-shop__sub { font-size: calc(12px * var(--reading-scale)); color: #9a9384; }
.nu-shop__track { width: 120px; height: 8px; border-radius: 999px; background: #f0ece3; overflow: hidden; }
.nu-shop__fill { height: 100%; background: #2f6d5b; width: var(--pct, 0%); }
.nu-shop__grid { padding: 16px 20px; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 30px; }
.nu-aisle { margin-bottom: 8px; }
.nu-aisle__name { font: 700 calc(9.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #2f6d5b; margin-bottom: 8px; }
.nu-item { display: flex; align-items: center; gap: 10px; padding: 5px 4px; border-radius: 8px; cursor: pointer; width: 100%; background: none; border: none; text-align: left; }
.nu-item:hover { background: #faf8f3; }
.nu-item__box { width: 18px; height: 18px; flex: none; border-radius: 6px; display: flex; align-items: center; justify-content: center; border: 1.5px solid #cbc4b6; background: #fff; color: transparent; font-size: calc(11px * var(--reading-scale)); }
.nu-item__name { flex: 1; font-size: calc(13px * var(--reading-scale)); color: #3a352c; }
.nu-item__qty { font-size: calc(11.5px * var(--reading-scale)); color: #b9b2a3; }
.nu-item.is-on .nu-item__box { border-color: #2f6d5b; background: #2f6d5b; color: #fff; }
.nu-item.is-on .nu-item__name { color: #b9b2a3; text-decoration: line-through; }

/* feedback */
/* The provenance + feedback should span the full plan width, not sit narrower
   than the meal and shopping cards above them (which fill .nu at 940px). */
.nu .brief { max-width: none; }
.nu-fb { border: 1.5px solid #cfe0d9; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 10px 34px rgba(50,42,28,.06); }
.nu-fb__head { padding: 16px 18px 4px; }
.nu-fb__title { font-family: "Newsreader", serif; font-size: calc(18px * var(--reading-scale)); font-weight: 500; }
.nu-fb__sub { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; margin-top: 2px; }
.nu-fb__body { padding: 12px 18px 18px; }
.nu-fb__chips { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.nu-fb__chip { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; padding: 6px 11px; border-radius: 999px; cursor: pointer; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; }
.nu-fb__chip.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.nu-fb__notes { display: block; width: 100%; min-height: 64px; padding: 12px 14px; border: 1.5px solid #e6e1d6; border-radius: 11px; font: 400 calc(13px * var(--reading-scale))/1.6 "Hanken Grotesk"; color: #3a352c; outline: none; background: #fcfbf7; resize: vertical; }
.nu-fb__notes:focus { border-color: #cfe0d9; }
.nu-fb__foot { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.nu-fb__spacer { flex: 1; }
.nu-fb__status { font-size: calc(12px * var(--reading-scale)); color: #2f6d5b; }
.nu-fb__save { font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; padding: 11px 18px; border-radius: 11px; border: none; background: #2f6d5b; color: #fff; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.nu-fb__save:hover { background: #28604f; }

@media (max-width: 640px) {
  .nu-shop__grid { grid-template-columns: 1fr; }
}
/* Personal-trainer output template — follow-along session stepper. */
.tr { max-width: 720px; margin: 0 auto; }
/* Same width as the default chrome column but centred, not left-aligned — see
   --reader-col in reader.css. */
.reader-body:has(> .tr) { --reader-col: 720px; --reader-col-inline: auto; }

/* 6px was the gap to the kicker; the title follows the run meta directly now
   and a 30px serif needs more air above it than a line of small caps did. */
.tr-metarow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.tr-meta { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; }

@media (max-width: 720px) {
  /* Date and time stay together on one line; the run detail drops below.
     The date is unbreakable — a long weekday and month at the largest
     reading size will not share a row with it. */
  .tr-metarow { align-items: baseline; flex-wrap: wrap; }
  .tr-meta__sep { display: none; }
  .tr-meta__date, .tr-meta__detail { display: block; }
  .tr-meta__date { white-space: nowrap; }
}

/* Order is title then kicker (see _trainer.html.erb): the title closes tight on
   its caption, and the caption carries the gap to the focus card below. */
.tr-title { font-family: "Newsreader", serif; font-weight: 500; font-size: calc(30px * var(--reading-scale)); line-height: 1.12; margin: 0 0 6px; }
.tr-eyebrow { font: 700 calc(11px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; margin-bottom: 18px; }

.tr-focus { border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 13px; padding: 13px 16px; margin-bottom: 14px; display: flex; gap: 11px; }
.tr-focus__icon { width: 26px; height: 26px; flex: none; border-radius: 8px; background: #dcebe5; display: flex; align-items: center; justify-content: center; font-size: calc(14px * var(--reading-scale)); }
.tr-focus__body { font-size: calc(13px * var(--reading-scale)); line-height: 1.55; color: #2f5f52; }
.tr-focus__body strong { color: #245043; }

.tr-stats { display: flex; gap: 8px; margin: 0 0 22px; }
.tr-stat { flex: 1; border: 1.5px solid #e6e1d6; border-radius: 11px; background: #fff; padding: 11px 13px; text-align: center; }
.tr-stat__value { font-family: "Newsreader", serif; font-size: calc(20px * var(--reading-scale)); font-weight: 500; line-height: 1; }
.tr-stat__value--accent { color: #2f6d5b; }
.tr-stat__label { font-size: calc(10.5px * var(--reading-scale)); color: #9a9384; margin-top: 3px; }

.tr-stepper-head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.tr-stepper-head__pos { font: 700 calc(11px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .4px; color: #6f6a5e; white-space: nowrap; }
.tr-dots { flex: 1; display: flex; gap: 4px; }
.tr-dot { flex: 1; height: 5px; border-radius: 999px; background: #e0dacd; }
.tr-dot.is-active { background: #8fb9ab; }
.tr-dot.is-done { background: #2f6d5b; }
.tr-skip { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; cursor: pointer; }
.tr-skip:hover { color: #2f6d5b; }

/* only the active block shows (stepper). If JS is off, first block shows. */
.tr-block { display: none; border: 1.5px solid #d9d3c7; border-radius: 18px; background: #fff; overflow: hidden; box-shadow: 0 10px 34px rgba(50, 42, 28, .09); margin-bottom: 16px; }
.tr-block.is-active { display: block; }

.tr-block__body { padding: 18px 20px; }
/* The block's category, e.g. "MAIN LIFT · CHEST" — was a pill over the (removed)
   video thumbnail; now a plain eyebrow above the name. */
.tr-block__eyebrow { font: 700 calc(10px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; text-transform: uppercase; color: #9a9384; margin-bottom: 6px; }
.tr-block__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 3px; }
.tr-block__name { font-family: "Newsreader", serif; font-size: calc(23px * var(--reading-scale)); font-weight: 500; line-height: 1.1; }
.tr-block__target { flex: none; font: 700 calc(12px * var(--reading-scale)) "Hanken Grotesk"; padding: 6px 12px; border-radius: 999px; background: #eef4f1; color: #2f6d5b; white-space: nowrap; }
.tr-block__sub { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; margin-bottom: 16px; }

.tr-sets-label { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font: 700 calc(9.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; }
.tr-sets-label__hint { font-weight: 500; font-size: calc(11px * var(--reading-scale)); color: #9a9384; letter-spacing: 0; }
.tr-rest { margin-left: auto; font: 600 calc(11px * var(--reading-scale)) "Hanken Grotesk"; color: #6f6a5e; letter-spacing: 0; }
.tr-sets { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.tr-set { position: relative; width: 66px; height: 60px; border-radius: 12px; cursor: pointer; display: flex; flex-direction: column; align-items: center; justify-content: center; border: 1.5px solid #e6e1d6; background: #fff; color: #26221b; }
.tr-set__load { font: 700 calc(13px * var(--reading-scale)) "Hanken Grotesk"; line-height: 1; }
.tr-set__reps { font-size: calc(9.5px * var(--reading-scale)); opacity: .8; margin-top: 1px; }
.tr-set__tick { position: absolute; top: -6px; right: -6px; width: 18px; height: 18px; border-radius: 50%; background: #2f6d5b; color: #fff; font-size: calc(10px * var(--reading-scale)); display: none; align-items: center; justify-content: center; border: 2px solid #fff; }
.tr-set.is-on { border-color: #2f6d5b; background: #2f6d5b; color: #fff; }
.tr-set.is-on .tr-set__tick { display: flex; }

.tr-moves { display: flex; flex-direction: column; gap: 6px; margin-bottom: 16px; }
.tr-move { display: flex; align-items: center; gap: 11px; padding: 10px 12px; border-radius: 10px; cursor: pointer; border: 1.5px solid #f0ece3; background: #fff; text-align: left; }
.tr-move__box { width: 20px; height: 20px; flex: none; border-radius: 6px; display: flex; align-items: center; justify-content: center; border: 1.5px solid #cbc4b6; background: #fff; color: transparent; font-size: calc(11px * var(--reading-scale)); }
.tr-move__name { flex: 1; font-weight: 600; font-size: calc(13px * var(--reading-scale)); color: #26221b; }
.tr-move__detail { font: 600 calc(11px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; }
.tr-move.is-on { border-color: #cfe0d9; background: #f4f8f6; }
.tr-move.is-on .tr-move__box { border-color: #2f6d5b; background: #2f6d5b; color: #fff; }
.tr-move.is-on .tr-move__name { color: #9a9384; }

.tr-cues { border-top: 1.5px solid #f0ece3; padding-top: 13px; margin-bottom: 16px; }
.tr-cues__label { font: 700 calc(9px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; margin-bottom: 8px; }
.tr-cue { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 6px; }
.tr-cue__dot { width: 5px; height: 5px; border-radius: 50%; background: #2f6d5b; flex: none; margin-top: 6px; }
.tr-cue span:last-child { font-size: calc(12.5px * var(--reading-scale)); line-height: 1.5; color: #3a352c; }

.tr-reg { display: flex; gap: 9px; background: #faf6ef; border: 1.5px solid #f0e6d6; border-radius: 11px; padding: 10px 13px; margin-bottom: 16px; font-size: calc(12px * var(--reading-scale)); line-height: 1.5; color: #6f6a5e; }
.tr-reg__icon { color: #b8862f; flex: none; }
.tr-reg strong { color: #8a6420; }

.tr-block__actions { display: flex; gap: 9px; }
.tr-next { flex: 1; padding: 13px; border: none; border-radius: 12px; background: #2f6d5b; color: #fff; font: 600 calc(13.5px * var(--reading-scale)) "Hanken Grotesk"; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.tr-next:hover { background: #28604f; }
.tr-swap { flex: none; padding: 13px 15px; border: 1.5px solid #e6e1d6; border-radius: 12px; background: #fff; color: #6f6a5e; font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; cursor: pointer; }
.tr-swap:hover { border-color: #cfe0d9; }

.tr-navrow { display: flex; align-items: center; gap: 10px; margin-bottom: 26px; }
.tr-stepbtn {
  min-height: 40px; padding: 10px 16px;
  border: 1.5px solid #e6e1d6; border-radius: 12px; background: #fff;
  color: #6f6a5e; font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; cursor: pointer;
}
.tr-stepbtn--next { margin-left: auto; color: #2f6d5b; border-color: #cfe0d9; }
.tr-stepbtn:hover { border-color: #cfe0d9; }
.tr-stepbtn:active { background: #f4f1ea; }
/* Disabled is the real attribute now, not a class with pointer-events: none —
   that left the control focusable and firing on Enter while looking dead. */
.tr-stepbtn[disabled] { color: #c8c1b2; border-color: #efebe2; background: #faf8f3; cursor: default; }
.tr-stepbtn[disabled]:hover { border-color: #efebe2; }

@media (max-width: 720px) {
  /* A session is followed on a phone, between sets. Half the row each, 48px
     tall, so either is a thumb-sized target wherever the hand happens to be. */
  .tr-stepbtn { flex: 1; min-height: 48px; padding: 12px; font-size: calc(14px * var(--reading-scale)); }
  .tr-stepbtn--next { margin-left: 0; }
}

/* End of session. The stepper is put away rather than left sitting under the
   summary — the card IS the answer to "did that tap do anything?", and the
   session's controls competing with it undoes that. Reversible: "Back to the
   exercises" drops .is-finished. */
.tr.is-finished .tr-stepper-head,
.tr.is-finished .tr-blocks,
.tr.is-finished .tr-navrow,
.tr.is-finished .tr-upnext { display: none; }

.tr-done { border: 1.5px solid #cfe0d9; border-radius: 18px; background: #f4f8f6; padding: 26px 22px; margin-bottom: 26px; text-align: center; box-shadow: 0 10px 34px rgba(47,109,91,.09); }
.tr-done[hidden] { display: none; }
.tr-done__badge { width: 44px; height: 44px; margin: 0 auto 12px; border-radius: 50%; background: #2f6d5b; color: #fff; display: flex; align-items: center; justify-content: center; font-size: calc(20px * var(--reading-scale)); box-shadow: 0 4px 14px rgba(47,109,91,.28); }
.tr-done__title { font-family: "Newsreader", serif; font-weight: 500; font-size: calc(24px * var(--reading-scale)); line-height: 1.15; }
.tr-done__sub { font-size: calc(13px * var(--reading-scale)); line-height: 1.55; color: #2f5f52; margin-top: 5px; }
.tr-done__next { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; color: #6f6a5e; margin-top: 10px; }
.tr-done__actions { display: flex; align-items: center; justify-content: center; gap: 9px; margin-top: 18px; flex-wrap: wrap; }
.tr-done__primary { min-height: 44px; padding: 12px 20px; border: none; border-radius: 12px; background: #2f6d5b; color: #fff; font: 600 calc(13.5px * var(--reading-scale)) "Hanken Grotesk"; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.tr-done__primary:hover { background: #28604f; }
.tr-done__ghost { min-height: 44px; padding: 12px 18px; border: 1.5px solid #cfe0d9; border-radius: 12px; background: #fff; color: #6f6a5e; font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; cursor: pointer; }
.tr-done__ghost:hover { border-color: #8fb9ab; }

@media (max-width: 720px) {
  /* Same reasoning as the navrow: full-width, thumb-sized, stacked in the order
     you would actually use them. */
  .tr-done__actions { flex-direction: column; align-items: stretch; }
  .tr-done__primary, .tr-done__ghost { min-height: 48px; width: 100%; }
}

.tr-upnext { margin-bottom: 30px; }
.tr-upnext__label { font: 700 calc(9.5px * var(--reading-scale)) "Hanken Grotesk"; letter-spacing: .5px; color: #a49d8d; margin-bottom: 10px; }
.tr-upnext__list { display: flex; flex-direction: column; gap: 7px; }
.tr-upnext__item { display: flex; align-items: center; gap: 12px; padding: 11px 14px; border: 1.5px solid #e6e1d6; border-radius: 12px; background: #fff; cursor: pointer; }
.tr-upnext__item:hover { border-color: #cfe0d9; }
.tr-upnext__item.is-current { display: none; }
.tr-upnext__num { width: 26px; height: 26px; flex: none; border-radius: 8px; background: #f1ede4; color: #9a9384; display: flex; align-items: center; justify-content: center; font: 700 calc(11px * var(--reading-scale)) "Hanken Grotesk"; }
.tr-upnext__name { flex: 1; font-weight: 600; font-size: calc(13px * var(--reading-scale)); }
.tr-upnext__detail { font: 600 calc(11px * var(--reading-scale)) "Hanken Grotesk"; color: #9a9384; }
.tr-upnext__after { padding: 14px; border: 1.5px dashed #cfe0d9; border-radius: 12px; text-align: center; font-size: calc(12.5px * var(--reading-scale)); color: #2f6d5b; background: #f4f8f6; }

.tr-fb { border: 1.5px solid #cfe0d9; border-radius: 16px; background: #fff; overflow: hidden; box-shadow: 0 10px 34px rgba(50,42,28,.06); }
.tr-fb__head { padding: 16px 18px 4px; }
.tr-fb__title { font-family: "Newsreader", serif; font-size: calc(18px * var(--reading-scale)); font-weight: 500; }
.tr-fb__sub { font-size: calc(12.5px * var(--reading-scale)); color: #9a9384; margin-top: 2px; }
.tr-fb__body { padding: 12px 18px 18px; }
.tr-fb__chips { display: flex; gap: 7px; flex-wrap: wrap; margin-bottom: 12px; }
.tr-fb__chip { font: 600 calc(11.5px * var(--reading-scale)) "Hanken Grotesk"; padding: 6px 11px; border-radius: 999px; cursor: pointer; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; }
.tr-fb__chip.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.tr-fb__notes { display: block; width: 100%; min-height: 60px; padding: 12px 14px; border: 1.5px solid #e6e1d6; border-radius: 11px; font: 400 calc(13px * var(--reading-scale))/1.6 "Hanken Grotesk"; color: #3a352c; outline: none; background: #fcfbf7; resize: vertical; }
.tr-fb__notes:focus { border-color: #cfe0d9; }
.tr-fb__foot { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.tr-fb__spacer { flex: 1; }
.tr-fb__status { font-size: calc(12px * var(--reading-scale)); color: #2f6d5b; }
.tr-fb__save { font: 600 calc(13px * var(--reading-scale)) "Hanken Grotesk"; padding: 11px 18px; border-radius: 11px; border: none; background: #2f6d5b; color: #fff; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.tr-fb__save:hover { background: #28604f; }
/* Confirmation dialog (shared/_confirm_dialog + the [data-confirm] gate in
   app_nav.js). Visual language follows .plan-modal in settings.css — white
   card, 20px radius, warm scrim — so the app has one modal look. */

.cdlg {
  width: 400px;
  max-width: calc(100vw - 32px);
  padding: 0;
  border: none;
  border-radius: 18px;
  background: #fff;
  color: var(--text-body);
  box-shadow: 0 30px 70px rgba(50, 42, 28, .3);
}
/* A <dialog> is display:none until opened; showModal() flips it, so the open
   state is what carries the layout. */
.cdlg[open] { display: block; }
.cdlg::backdrop { background: rgba(38, 34, 27, .4); }

.cdlg__body { display: flex; gap: 14px; padding: 24px 26px 20px; }

.cdlg__icon {
  width: 40px; height: 40px; flex: none; border-radius: 12px;
  display: flex; align-items: center; justify-content: center; font-size: 19px;
  background: var(--primary-tint-2); color: var(--primary);
}
.cdlg--danger .cdlg__icon { background: var(--danger-tint); color: var(--danger); }

.cdlg__text { min-width: 0; }
.cdlg__title {
  font-family: "Newsreader", serif; font-weight: 500; font-size: 20px; line-height: 1.25;
  margin: 2px 0 0; color: var(--ink);
}
/* Only rendered when the trigger gives a title as well — see the partial. */
.cdlg__msg {
  font-size: 13.5px; line-height: 1.6; color: var(--text-muted); margin: 7px 0 0;
}
.cdlg__msg[hidden] { display: none; }

.cdlg__actions {
  display: flex; justify-content: flex-end; gap: 9px;
  padding: 4px 26px 22px;
}
.cdlg__btn {
  min-height: 42px; padding: 11px 18px; border-radius: 11px;
  font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif; cursor: pointer;
  border: 1.5px solid transparent;
}
.cdlg__btn--cancel {
  background: #fff; color: var(--text-body); border-color: var(--border-default);
}
.cdlg__btn--cancel:hover { background: var(--paper-warm); border-color: var(--border-strong); }
.cdlg__btn--go {
  background: var(--primary); color: #fff; border-color: var(--primary);
  box-shadow: 0 3px 10px rgba(47, 109, 91, .25);
}
.cdlg__btn--go:hover { background: var(--primary-press); border-color: var(--primary-press); }
.cdlg--danger .cdlg__btn--go {
  background: var(--danger); border-color: var(--danger); box-shadow: none;
}
.cdlg--danger .cdlg__btn--go:hover { background: var(--danger-press); border-color: var(--danger-press); }

@media (max-width: 720px) {
  /* Full-width card pinned to the bottom: the actions land under the thumb
     instead of mid-screen, and the buttons stop being two small targets in a
     row. Cancel first in the DOM stays first here too — the destructive one
     should not be the one your thumb rests on. */
  .cdlg {
    width: 100%; max-width: none;
    margin: auto auto 0;
    border-radius: 20px 20px 0 0;
  }
  .cdlg__body { padding: 22px 20px 18px; }
  .cdlg__actions { flex-direction: column-reverse; padding: 4px 20px 20px; }
  .cdlg__btn { width: 100%; min-height: 48px; }
}

/* ── Routine-cap gate ─────────────────────────────────────────────────────
   Shown when someone reaches for a routine their plan has no slot for. It
   replaces a disabled "+": the point is not to state the limit but to offer
   the two ways past it — upgrade, or pause something — with the numbers that
   are actually enforced (RoutinesHelper#routine_cap_gate reads the catalog). */
.capgate {
  width: 460px;
  max-width: calc(100vw - 28px);
  padding: 0;
  border: none;
  border-radius: 20px;
  background: #fff;
  color: var(--text-body);
  box-shadow: 0 30px 70px rgba(50, 42, 28, .3);
  overflow: hidden;
}
.capgate::backdrop { background: rgba(38, 34, 27, .45); }

.capgate__dismiss { position: absolute; top: 0; right: 0; }
.capgate__x {
  border: none; background: none; cursor: pointer; padding: 14px 16px;
  font-size: 14px; color: var(--text-faint); line-height: 1;
}
.capgate__x:hover { color: var(--text-body); }

/* The tinted half — what the situation is. */
.capgate__head { background: var(--surface-raised); padding: 22px 26px 20px; border-bottom: var(--hairline) solid var(--border-soft); }
/* padding-right clears the close button, which is absolutely positioned over
   this row's top-right corner. */
.capgate__meta { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 13px; padding-right: 30px; }
.capgate__chip {
  font: 700 9.5px var(--font-sans); letter-spacing: .5px; text-transform: uppercase;
  background: var(--primary-tint); color: var(--primary);
  padding: 5px 9px; border-radius: var(--radius-pill);
}
.capgate__count { font-size: var(--text-sm); color: var(--text-faint); margin-left: auto; }
.capgate__title {
  font-family: var(--font-display); font-weight: 500; font-size: 23px; line-height: 1.15;
  color: var(--ink); margin: 0 0 9px;
}
.capgate__body { font-size: var(--text-sm); line-height: 1.6; color: var(--text-soft); margin: 0; }
.capgate__body--tight { margin-bottom: 14px; }

/* One bar per slot held, then a dashed one for the slot just reached for —
   "3 of 3" as something you can see rather than read. */
.capgate__slots { display: flex; gap: 6px; margin: 16px 0 8px; }
.capgate__slot { flex: 1; height: 6px; border-radius: 999px; }
.capgate__slot.is-used { background: var(--primary); }
.capgate__slot.is-wanted { border: 1.5px dashed var(--accent); background: none; }
.capgate__slotnote { font-size: var(--text-xs); color: var(--text-faint); }

.capgate__body-wrap { padding: 20px 26px 22px; }
.capgate__label {
  font: 700 9.5px var(--font-sans); letter-spacing: .5px; text-transform: uppercase;
  color: var(--text-faint); margin-bottom: 10px;
}
.capgate__label--row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.capgate__altlink { font: 600 11.5px var(--font-sans); color: var(--accent); text-transform: none; letter-spacing: 0; }

.capgate__plan { border: 1.5px solid var(--primary-border); border-radius: var(--radius-lg); padding: 18px 20px; }
.capgate__planhead { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 13px; }
.capgate__planname { font-family: var(--font-display); font-size: 21px; font-weight: 500; color: var(--ink); }
.capgate__price { font-family: var(--font-display); font-size: 25px; font-weight: 500; color: var(--ink); }
.capgate__per { font-family: var(--font-sans); font-size: 11.5px; font-weight: 400; color: var(--text-faint); margin-left: 3px; }
.capgate__feats { list-style: none; margin: 0 0 16px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.capgate__feats li { display: flex; align-items: flex-start; gap: 9px; font-size: var(--text-sm); color: var(--text-body); line-height: 1.45; }
.capgate__tick {
  flex: none; width: 17px; height: 17px; border-radius: 50%;
  background: var(--primary-tint); color: var(--primary);
  display: flex; align-items: center; justify-content: center; font-size: 9.5px; font-weight: 700;
  margin-top: 1px;
}
/* button_to wraps its button in a form; both need to fill the card. */
.capgate__plan .button_to { width: 100%; }
.capgate__cta {
  display: block; width: 100%; box-sizing: border-box; text-align: center;
  padding: 13px 16px; border: none; border-radius: var(--radius-md);
  background: var(--action-primary); color: #fff; cursor: pointer;
  font: var(--weight-semibold) var(--text-md) var(--font-sans); text-decoration: none;
}
.capgate__cta:hover { background: var(--action-primary-press); text-decoration: none; }
.capgate__fine { margin-top: 10px; font-size: var(--text-xs); color: var(--text-faint); text-align: center; }

.capgate__alt { margin-top: 20px; padding-top: 18px; border-top: var(--hairline) solid var(--border-soft); }
.capgate__altbody { font-size: var(--text-sm); line-height: 1.6; color: var(--text-soft); margin: 0; }

.capgate__foot {
  display: flex; align-items: flex-start; gap: 9px; flex-wrap: wrap;
  margin-top: 18px; padding-top: 14px; border-top: var(--hairline) solid var(--border-soft);
  font-size: var(--text-xs); line-height: 1.55; color: var(--text-faint);
}
.capgate__foot > span:nth-child(2) { flex: 1; min-width: 180px; }
.capgate__footlink { font-weight: var(--weight-semibold); color: var(--accent); margin-left: auto; }

@media (max-width: 560px) {
  .capgate__head { padding: 20px 18px 18px; }
  .capgate__body-wrap { padding: 18px 18px 20px; }
  .capgate__title { font-size: 21px; }
  .capgate__count { margin-left: 0; }
}


/* ── .fdlg — the form dialog ──────────────────────────────────────────────
   The sibling of .cdlg: .cdlg asks a question, .fdlg collects a short form.
   Both wear the same frame (markup is `class="cdlg fdlg"`), so the app has one
   modal look whether you are confirming a delete or adding a destination.

   It lives here rather than in webhooks.css because Connections adds a custom
   MCP server through the identical shape — two or three fields and one
   outcome — and "the same as adding a webhook" has to mean one component, not
   a second copy of its stylesheet that drifts a fortnight later. */
.fdlg { width: 460px; max-width: calc(100vw - 28px); }
.fdlg--wide { width: 620px; }
.fdlg__dismiss { position: absolute; top: 0; right: 0; }
.fdlg__x {
  display: block; padding: 14px 16px; font-size: 14px; line-height: 1;
  color: var(--ink-faint); background: none; border: none; cursor: pointer;
}
.fdlg__x:hover { color: var(--ink); }
.fdlg__body { padding: 24px 26px 22px; }
.fdlg__title {
  margin: 2px 0 0; padding-right: 30px;
  font: var(--weight-medium) 20px/1.25 var(--font-display); color: var(--ink);
}
.fdlg__lead { margin: 7px 0 0; font: 400 var(--text-sm)/1.6 var(--font-sans); color: var(--ink-soft); }
.fdlg__form { display: flex; flex-direction: column; gap: 14px; margin-top: 18px; }
.fdlg__actions { display: flex; justify-content: flex-end; gap: 9px; margin-top: 4px; }
.fdlg__actions--split { align-items: center; }
/* A standing note above the buttons — "custom servers are not reviewed by us",
   "this is shown once". Left-aligned against the right-aligned actions. */
.fdlg__note {
  margin: 2px 0 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--ink-soft);
}

.fdlg-field { width: 100%; }
.fdlg-field__lbl {
  display: block; margin-bottom: 5px;
  font: var(--weight-semibold) var(--text-sm) var(--font-sans); color: var(--ink);
}
.fdlg-field__opt {
  margin-left: 6px; font: 400 var(--text-sm) var(--font-sans); color: var(--ink-faint);
}
.fdlg-field__hint { margin: 5px 0 0; font: 400 var(--text-sm)/1.5 var(--font-sans); color: var(--ink-soft); }
.fdlg-input {
  width: 100%; padding: 10px 12px; border-radius: var(--radius-md);
  border: var(--hairline) solid var(--border); background: var(--paper);
  font: 400 var(--text-ui) var(--font-sans); color: var(--ink);
}
.fdlg-input::placeholder { color: var(--text-placeholder); }
/* A URL or a token, where a monospace face is the difference between spotting
   a typo and not. .conx-input carried this rule and .wh-input never did, so the
   webhook URL field has been rendering proportional since it shipped — the two
   only diverged because they were two stylesheets. */
.fdlg-input.mono { font-family: var(--font-mono); font-size: var(--text-sm); }
.fdlg-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(47, 109, 91, .35); }
/* A <select> wearing this class lost its chevron and rendered as a text field.
   components.css sets the caret as an ELEMENT rule on `select`, and the
   `background:` shorthand three lines up resets background-image — so the
   provider dialog's Kind field has been caretless since it shipped. Same fix,
   same cause as select.adm-provform__input in admin.css. */
select.fdlg-input {
  appearance: none; -webkit-appearance: none;
  background-image: var(--caret-down);
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 36px;
}

/* The dialog's own buttons, so the two pages don't reach for their own page
   button set inside a shared component and land a pixel apart. */
.fdlg__btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 14px; border-radius: var(--radius-md);
  font: var(--weight-semibold) var(--text-sm)/1 var(--font-sans);
  border: var(--hairline) solid transparent; cursor: pointer; text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
}
.fdlg__btn:hover { text-decoration: none; }
.fdlg__btn:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 2px; }
.fdlg__btn--primary { background: var(--primary); color: #fff; }
.fdlg__btn--primary:hover { background: var(--primary-press); color: #fff; }
.fdlg__btn--ghost { background: var(--paper); color: var(--primary); border-color: var(--border); }
.fdlg__btn--ghost:hover { border-color: var(--primary-border); color: var(--primary); }
/* ==========================================================================
   joris explains — the public ideas blog.
   Extracted from the "Joris Explains" Claude Design file: every value below
   is the computed style taken from that render, not an approximation.
   Titles Newsreader, UI labels Hanken Grotesk, Delivery excerpts JetBrains Mono.
   ========================================================================== */
.exp{
  --exp-canvas: #efece4;
  --exp-paper: #faf8f3;      /* card + featured surface */
  --exp-ink: #26221b;
  --exp-body: #33302a;       /* long-form body text */
  --exp-soft: #6f6a5e;
  --exp-meta: #9a9384;
  --exp-rule: #e6e1d6;
  --exp-rule-2: #e0dacd;
  --exp-green: #2f6d5b;
  --exp-serif: var(--font-serif, Newsreader, Georgia, serif);
  --exp-sans: var(--font-sans, "Hanken Grotesk", system-ui, sans-serif);
  --exp-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  background: var(--exp-canvas);
  color: var(--exp-ink);
}

/* ── Category chip ────────────────────────────────────────────────────────── */
.exp .exp-chip{
  display: inline-block; font: 700 10.5px var(--exp-sans); letter-spacing: .6px;
  text-transform: uppercase; padding: 4px 10px; border-radius: 6px;
  color: var(--exp-green); background: #e4efe9;
}
.exp .exp-chip--green{ color: #2f6d5b; background: #e4efe9; }
.exp .exp-chip--terracotta{ color: #b45b3e; background: rgba(180, 91, 62, .10); }
.exp .exp-chip--purple{ color: #7a5cc0; background: rgba(122, 92, 192, .10); }
.exp .exp-chip--gold{ color: #b58a1f; background: rgba(192, 138, 44, .12); }
.exp .exp-chip--blue{ color: #3a6ea5; background: rgba(58, 110, 165, .10); }

/* ── Hero ─────────────────────────────────────────────────────────────────── */
.exp .exp-hero{ max-width: 900px; margin: 0 auto; padding: 64px 24px 0; text-align: center; }
.exp .exp-hero__kicker{
  font: 700 12px var(--exp-sans); letter-spacing: 2px; text-transform: uppercase;
  color: var(--exp-green); margin-bottom: 16px;
}
.exp .exp-hero__title{
  font-family: var(--exp-serif); font-weight: 500; font-size: 64px; line-height: 1.03;
  letter-spacing: -.6px; color: var(--exp-ink); max-width: 630px; margin: 0 auto 20px;
}
.exp .exp-hero__blurb{
  font: 400 17.5px/28px var(--exp-sans); color: var(--exp-soft);
  max-width: 588px; margin: 0 auto 12px;
}
.exp .exp-hero__meta{
  display: inline-flex; align-items: center; gap: 8px;
  font: 400 13px var(--exp-sans); color: var(--exp-meta); margin-top: 6px;
}
.exp .exp-hero__meta::before{ content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--exp-green); }

/* ── Filter tabs ──────────────────────────────────────────────────────────── */
.exp .exp-tabs{
  display: flex; flex-wrap: wrap; justify-content: center; gap: 9px;
  max-width: 900px; margin: 34px auto 0; padding: 0 24px;
}
.exp .exp-tab{
  font: 600 12.5px var(--exp-sans); padding: 8px 15px; border-radius: 999px;
  border: 1px solid var(--exp-rule); background: #fff; color: var(--exp-soft);
  text-decoration: none; transition: border-color .12s, color .12s;
}
.exp .exp-tab:hover{ border-color: #cfe0d9; color: var(--exp-green); }
.exp .exp-tab.is-on{ background: var(--exp-green); border-color: var(--exp-green); color: #fff; }

/* ── Layout ───────────────────────────────────────────────────────────────── */
.exp .exp-main{ max-width: 1040px; margin: 0 auto; padding: 34px 24px 0; }

/* ── Featured card ────────────────────────────────────────────────────────── */
.exp .exp-featured{
  display: grid; grid-template-columns: minmax(0, 404px) 1fr;
  background: var(--exp-paper); border: 1px solid var(--exp-rule); border-radius: 20px;
  overflow: hidden; margin-bottom: 26px; text-decoration: none; color: inherit;
}
.exp .exp-featured:hover{ border-color: #cfe0d9; }
.exp .exp-featured__panel{
  background: linear-gradient(150deg, #2f6d5b, #1f4a3d); color: #fff;
  padding: 26px; display: flex; flex-direction: column; justify-content: space-between;
}
.exp .exp-featured__flag{
  font: 700 10.5px var(--exp-sans); letter-spacing: .8px; text-transform: uppercase;
  color: rgba(255, 255, 255, .72); margin-bottom: 26px;
}
.exp .exp-featured__excerpt{
  font: 400 12px/22.2px var(--exp-mono); color: rgba(255, 255, 255, .9);
  white-space: pre-wrap; margin: 0; overflow: hidden;
}
.exp .exp-featured__body{ padding: 30px 34px; }
.exp .exp-featured__meta{
  font: 600 11px var(--exp-sans); letter-spacing: .5px; text-transform: uppercase;
  color: var(--exp-meta); margin-bottom: 12px;
}
.exp .exp-featured__title{
  font-family: var(--exp-serif); font-weight: 500; font-size: 34px; line-height: 1.08;
  letter-spacing: -.4px; color: var(--exp-ink); margin: 0 0 12px;
}
.exp .exp-featured__dek{ font: 400 16px/25px var(--exp-sans); color: var(--exp-soft); margin: 0 0 16px; }
.exp .exp-readlink{ font: 600 13.5px var(--exp-sans); color: var(--exp-green); }

/* ── Grid of cards ────────────────────────────────────────────────────────── */
.exp .exp-grid{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; }
.exp .exp-card{
  display: flex; flex-direction: column;
  background: var(--exp-paper); border: 1px solid var(--exp-rule); border-radius: 18px;
  padding: 24px 24px 22px; text-decoration: none; color: inherit;
  transition: border-color .12s, box-shadow .12s;
}
.exp .exp-card:hover{ border-color: #cfe0d9; box-shadow: 0 6px 20px rgba(50, 42, 28, .05); }
.exp .exp-card__meta{ display: flex; align-items: center; gap: 10px; margin-bottom: 14px; }
.exp .exp-card__time{ font: 400 12.5px var(--exp-sans); color: var(--exp-meta); }
.exp .exp-card__title{
  font-family: var(--exp-serif); font-weight: 500; font-size: 22px; line-height: 1.14;
  letter-spacing: -.3px; color: var(--exp-ink); margin: 0 0 9px;
}
.exp .exp-card__dek{ font: 400 14.5px/22px var(--exp-sans); color: var(--exp-soft); margin: 0 0 18px; flex: 1; }
.exp .exp-card__foot{ font: 600 12.5px var(--exp-sans); color: var(--exp-green); }

.exp .exp-empty{ text-align: center; color: var(--exp-meta); padding: 40px 0; }

/* ── Article reader ───────────────────────────────────────────────────────── */
.exp .exp-article{ max-width: 720px; margin: 0 auto; padding: 44px 30px 40px; }
.exp .exp-article__top{ display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 34px; }
.exp .exp-back{ font: 600 13px var(--exp-sans); color: var(--exp-green); text-decoration: none; }
.exp .exp-back:hover{ text-decoration: underline; }
.exp .exp-article__date{ font: 600 12px var(--exp-sans); letter-spacing: .5px; text-transform: uppercase; color: var(--exp-meta); }
.exp .exp-article__tagrow{ display: inline-flex; align-items: center; gap: 8px; margin-bottom: 16px; }
.exp .exp-article__cadence{ font: 400 12.5px var(--exp-sans); color: var(--exp-meta); }
.exp .exp-article__title{
  font-family: var(--exp-serif); font-weight: 600; font-size: 46px; line-height: 1.06;
  letter-spacing: -.6px; color: var(--exp-ink); margin: 0 0 30px;
}

/* Long-form body is SERIF — the single biggest thing that makes it read as an
   article rather than a UI screen. */
.exp .exp-body{ font: 400 19.5px/33.5px var(--exp-serif); color: var(--exp-body); }
.exp .exp-body p{ margin: 0 0 20px; }
.exp .exp-body h1{
  font-family: var(--exp-serif); font-weight: 600; font-size: 30px; line-height: 1.12;
  letter-spacing: -.3px; color: var(--exp-ink); margin: 40px 0 18px;
}
.exp .exp-body h2{
  font-family: var(--exp-serif); font-weight: 600; font-size: 28px; line-height: 1.1;
  letter-spacing: -.3px; color: var(--exp-ink); margin: 44px 0 20px;
}
.exp .exp-body h3{ font-family: var(--exp-serif); font-weight: 600; font-size: 22px; margin: 32px 0 14px; }
.exp .exp-body ul, .exp .exp-body ol{ margin: 0 0 20px; padding-left: 24px; }
.exp .exp-body li{ margin-bottom: 8px; }
.exp .exp-body a{ color: var(--exp-green); }
.exp .exp-body em{ font-style: italic; }
.exp .exp-body blockquote{
  margin: 0 0 22px; padding: 14px 20px; border-left: 3px solid var(--exp-green);
  background: #f4f8f6; color: #3d5f55; border-radius: 0 10px 10px 0;
}
.exp .exp-body hr{ border: 0; border-top: 1px solid var(--exp-rule); margin: 34px 0; }
.exp .exp-body pre:not(.exp-delivery__body){
  margin: 8px 0 30px; padding: 20px 22px; border: 1px solid var(--exp-rule-2);
  border-radius: 16px; background: #f7f4ec; overflow-x: auto;
  font: 400 13px/22.75px var(--exp-mono); color: #3a352c; white-space: pre-wrap; word-break: break-word;
}
.exp .exp-body pre code{ background: none; padding: 0; font-size: inherit; }
.exp .exp-body code{ font: 400 .85em var(--exp-mono); background: #f7f4ec; padding: 2px 6px; border-radius: 5px; }

/* The Delivery excerpt: raw markdown in monospace on warm paper — it is meant
   to look like the thing the Routine actually returns, not rendered prose. */
.exp .exp-delivery{
  margin: 8px 0 30px; padding: 24px 26px; border: 1px solid var(--exp-rule-2);
  border-radius: 16px; background: #f7f4ec;
}
.exp .exp-delivery__body{ border: 0; background: none; padding: 0; border-radius: 0;
  font: 400 13px/22.75px var(--exp-mono); color: #3a352c;
  white-space: pre-wrap; margin: 0;
}

.exp .exp-limit{ margin-top: 8px; }

/* ── Closing CTA — the dark green block, shared by index and reader ───────── */
.exp .exp-cta{
  background: linear-gradient(160deg, #22392f, #182a22); border-radius: 22px;
  /* 64px below, matching .mkt-cta on the marketing pages — with 0 the block
     butted straight into the footer, so the page ended without a breath. */
  padding: 48px 40px; margin: 46px auto 64px; max-width: 1040px; text-align: center; color: #fff;
}
.exp .exp-cta__title{
  font-family: var(--exp-serif); font-weight: 500; font-size: 40px; line-height: 1.08;
  color: #fff; margin: 0 0 14px;
}
.exp .exp-cta__text{ font: 400 16px/26px var(--exp-sans); color: rgba(255, 255, 255, .72); max-width: 520px; margin: 0 auto 24px; }
.exp .exp-cta__btn{
  display: inline-block; font: 600 14px var(--exp-sans); background: #f5f2ec; color: #22392f;
  text-decoration: none; padding: 13px 24px; border-radius: 12px;
}
.exp .exp-cta__btn:hover{ background: #fff; }
.exp .exp-cta__fine{ margin-top: 14px; font: 400 12.5px var(--exp-sans); color: rgba(255, 255, 255, .5); }

/* "TRY IT YOURSELF" label above the CTA in the reader */
.exp .exp-tryit{ border-top: 1px solid var(--exp-rule); margin-top: 40px; padding-top: 26px; }
.exp .exp-tryit__label{ font: 700 11px var(--exp-sans); letter-spacing: .8px; text-transform: uppercase; color: var(--exp-green); margin-bottom: 10px; }
.exp .exp-tryit__text{ font: 400 16px/26px var(--exp-sans); color: var(--exp-soft); margin: 0; }
.exp .exp-tryit__text p{ margin: 0 0 10px; }
.exp .exp-tryit__related{ margin: 14px 0 0; font: 600 14px var(--exp-sans); }
.exp .exp-tryit__related a{ color: var(--exp-green); text-decoration: none; }
.exp .exp-tryit__related a:hover{ text-decoration: underline; }
.exp .exp-tryit__text a{ color: var(--exp-green); }

/* Preview / draft affordances */
.exp .exp-flag{ max-width: 720px; margin: 20px auto; padding: 12px 16px; border-radius: 12px; background: #fdf6e8; border: 1px dashed #d9c48f; color: #7a5f22; font: 400 14px/1.5 var(--exp-sans); }
.exp .exp-drafts{ margin-top: 52px; }
.exp .exp-drafts__head{ text-align: center; color: var(--exp-meta); font-family: var(--exp-serif); font-weight: 500; }

/* ── Responsive ───────────────────────────────────────────────────────────── */
@media (max-width: 1000px) { .exp .exp-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) {
  .exp .exp-hero { padding-top: 44px; }
  .exp .exp-hero__title { font-size: 38px; }
  .exp .exp-hero__blurb { font-size: 16px; line-height: 26px; }
  .exp .exp-featured { grid-template-columns: 1fr; }
  .exp .exp-grid { grid-template-columns: 1fr; }
  .exp .exp-article__title { font-size: 32px; }
  .exp .exp-body { font-size: 18px; line-height: 30px; }
  .exp .exp-cta { padding: 36px 24px; margin-bottom: 44px; }
  .exp .exp-cta__title { font-size: 30px; }
}
/* ---------------------------------------------------------------
   joris — First run: the welcome dialog and the wizard tour.
   Rendered by routines/_first_run, on routines/new only.

   Sections: tokens -> welcome -> tour ring -> tour card -> responsive.
   --------------------------------------------------------------- */

.frun, .frtour {
  --frun-w: 560px;
  /* 320, not 340, and the rail is why. Step 2 rings the whole right column, so
     the card has to live in the gutter the rail occupies — a fixed 300px at
     every desktop width (new_routine.css). 320 clears it with room either side;
     340 did not, and the card fell to "below the target", off the fold. */
  --frun-card-w: 320px;
  /* The tour sits over the wizard, which has no stacking of its own above the
     app shell. Below the native <dialog> top layer, so the welcome always wins
     if both are somehow up. */
  --frun-z: 60;
}

/* ---------------------------------------------------------------
   The welcome — a .cdlg with more to say, not a new modal language.
   --------------------------------------------------------------- */

.frun-dlg { width: var(--frun-w); position: relative; }

.frun-dlg__x {
  position: absolute; top: 14px; right: 14px;
  width: 30px; height: 30px; border: none; border-radius: 9px;
  background: transparent; color: var(--ink-faint);
  font-size: 14px; line-height: 1; cursor: pointer;
}
.frun-dlg__x:hover { background: var(--paper-warm); color: var(--ink); }

.frun-dlg__body { padding: 30px 32px 4px; }

.frun-dlg__title {
  font-family: "Newsreader", serif; font-weight: 500; font-size: 25px;
  line-height: 1.2; margin: 0; color: var(--ink);
}
.frun-dlg__lede {
  font-size: 15px; font-weight: 600; line-height: 1.5;
  margin: 10px 0 0; color: var(--ink);
}
.frun-dlg__sub {
  font-size: 13.5px; line-height: 1.65; margin: 7px 0 0; color: var(--text-muted);
}

.frun-steps {
  list-style: none; margin: 22px 0 0; padding: 0;
  border: 1.5px solid var(--border-divider); border-radius: 14px;
  background: var(--border-divider);
  display: grid; gap: 1px; overflow: hidden;
}
.frun-steps__item {
  display: grid; grid-template-columns: 22px 1fr; column-gap: 11px; row-gap: 2px;
  background: var(--paper-warm); padding: 15px 17px;
}
.frun-steps__n {
  grid-row: span 2;
  width: 22px; height: 22px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--primary-tint); color: var(--primary);
  font: 500 11px "JetBrains Mono", ui-monospace, monospace;
}
.frun-steps__h { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.frun-steps__b { font-size: 12.5px; line-height: 1.5; color: var(--text-muted); }

.frun-dlg__doors {
  display: flex; align-items: center; gap: 16px;
  padding: 22px 32px 0;
}
.frun-dlg__go {
  min-height: 44px; padding: 12px 22px; border-radius: 12px;
  border: 1.5px solid var(--primary); background: var(--primary); color: #fff;
  font: 600 14px "Hanken Grotesk", system-ui, sans-serif; cursor: pointer;
  box-shadow: 0 4px 14px rgba(47, 109, 91, .26);
}
.frun-dlg__go:hover { background: var(--primary-press); border-color: var(--primary-press); }
.frun-dlg__quiet {
  border: none; background: transparent; padding: 0; cursor: pointer;
  font: 600 13.5px "Hanken Grotesk", system-ui, sans-serif; color: var(--text-muted);
}
.frun-dlg__quiet:hover { color: var(--ink); }
.frun-dlg__quiet-narrow { display: none; }

.frun-dlg__foot {
  margin: 14px 0 0; padding: 0 32px 26px;
  font-size: 12.5px; line-height: 1.55; color: var(--text-faint);
}

/* ---------------------------------------------------------------
   The tour ring.

   The scrim IS the ring's box-shadow, which is what keeps the cut-out and the
   dimming as one element that can never disagree about where the hole is. The
   whole thing is pointer-events:none on purpose — see first_run.js: step 2
   waits for the person to pick a template, so the page underneath has to stay
   live while the tour is up.
   --------------------------------------------------------------- */

.frtour[hidden] { display: none; }

.frtour__ring {
  position: fixed; z-index: var(--frun-z);
  border: 2px solid var(--primary); border-radius: 14px;
  box-shadow: 0 0 0 100vmax rgba(38, 34, 27, .45);
  pointer-events: none;
  transition: top .18s ease, left .18s ease, width .18s ease, height .18s ease;
}

/* ---------------------------------------------------------------
   The tour card.
   --------------------------------------------------------------- */

.frtour__card {
  position: fixed; z-index: calc(var(--frun-z) + 1);
  width: var(--frun-card-w); max-width: calc(100vw - 24px);
  background: #fff; border-radius: 14px; padding: 16px 18px 13px;
  box-shadow: 0 20px 50px rgba(50, 42, 28, .28);
}

.frtour__head { display: flex; align-items: center; gap: 9px; margin-bottom: 7px; }
.frtour__count {
  font: 500 11px "JetBrains Mono", ui-monospace, monospace;
  color: var(--primary); background: var(--primary-tint);
  padding: 3px 7px; border-radius: 6px;
}
.frtour__kicker {
  font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--text-faint);
}
.frtour__title { font-weight: 600; font-size: 14.5px; line-height: 1.3; color: var(--ink); }
.frtour__body { font-size: 13px; line-height: 1.6; color: var(--text-muted); margin-top: 6px; }

.frtour__foot { display: flex; align-items: center; gap: 10px; margin-top: 13px; }
.frtour__spacer { flex: 1; }
.frtour__back, .frtour__skip {
  border: none; background: transparent; padding: 0; cursor: pointer;
  font: 600 12.5px "Hanken Grotesk", system-ui, sans-serif; color: var(--text-faint);
}
.frtour__back:hover, .frtour__skip:hover { color: var(--ink); }
.frtour__back[hidden] { display: none; }
.frtour__next {
  min-height: 34px; padding: 8px 15px; border-radius: 10px;
  border: 1.5px solid var(--primary); background: var(--primary); color: #fff;
  font: 600 12.5px "Hanken Grotesk", system-ui, sans-serif; cursor: pointer;
}
.frtour__next:hover { background: var(--primary-press); border-color: var(--primary-press); }
.frtour__next[hidden] { display: none; }

/* ---------------------------------------------------------------
   Responsive.
   --------------------------------------------------------------- */

/* new_routine.css hides the rail and the browse panel at `max-width: 900px` and
   builds the desktop layout at `min-width: 901px`. This block must use the SAME
   bound — at 899px it left exactly one viewport width (900px) offering a tour of
   two regions that were not on screen. first_run.js keeps the same boundary so a
   hidden button cannot be reached by keyboard either. */
@media (max-width: 900px) {
  .frun-dlg__go { display: none; }
  .frun-dlg__doors { padding-top: 18px; }
  .frun-dlg__quiet {
    min-height: 44px; padding: 12px 22px; border-radius: 12px;
    border: 1.5px solid var(--primary); background: var(--primary); color: #fff;
    font-size: 14px;
  }
  .frun-dlg__quiet:hover { background: var(--primary-press); color: #fff; }
  .frun-dlg__quiet-wide { display: none; }
  .frun-dlg__quiet-narrow { display: inline; }
}

@media (max-width: 720px) {
  .frun-dlg { width: 100%; }
  .frun-dlg__body { padding: 26px 22px 4px; }
  .frun-dlg__doors, .frun-dlg__foot { padding-left: 22px; padding-right: 22px; }
}
/* ============================================================================
   joris — public marketing site (landing page)

   Everything the landing needs, organized top-to-bottom:
     1. Tokens          — palette, fonts, shadows (change the brand here)
     2. Base            — body, links, page wrapper
     3. Layout          — section containers, dividers, responsive padding
     4. Typography      — kicker / headings / lead
     5. Buttons         — .mkt-btn + variants
     6. Pills & badges  — chips, plan badges, proof row, eyebrow
     7. Nav + announcement
     8. Hero + reader mock
     9. How it works
    10. (removed — templates merged)
    11. Output templates (tabs / dots / arrows / panels + preview mocks)
   11b. Recipes band
    12. Pricing
    13. Trust
    14. Final CTA
    15. Footer
    16. Animation
    17. Responsive

   The ERB carries structure only — no inline styles. Every color/font flows
   from the tokens block, so re-theming is a one-place change.
   ============================================================================ */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */
body.mkt {
  --ink: #26221b; --muted: #6f6a5e; --faint: #9a9384;
  --green: #2f6d5b; --green-d: #28604f; --forest: #22463c;
  --deep: #245043; --deeper: #1f3f36;
  --rust: #b45b3e;
  --mint: #eef4f1; --mint-2: #dcebe5; --mint-br: #cfe0d9; --mint-soft: #f4f8f6;
  --cream: #efece4; --panel: #faf8f3; --tan: #f1ede4;
  --line: #e6e1d6; --line-2: #ece8df; --line-3: #f0ece3;
  /* A structural rule — the full-width lines that divide a page into
     sections, one step stronger than the --line hairline that draws a
     card's edge. The family strip and the section heads use it. */
  --rule: #e0dacd;
  --pro: #6a4c86; --pro-bg: #efe9f2;
  --serif: "Newsreader", serif;
  --sans: "Hanken Grotesk", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;

  /* Reading type scale. Every piece of PAGE COPY reads its size from here, so
     the marketing surface can be re-tuned in one place instead of across ~40
     hardcoded declarations. Raised one step on 2026-07-26: the pages were set at
     app-chrome sizes (14px body, 15px leads), which is a size for scanning a UI
     you already use, not for reading an argument you haven't bought yet.
     Deliberately NOT applied to the delivery mocks (.mkt-hh__*, .mkt-nl__*,
     .mkt-pl__*, .mkt-wk__*, .mkt-sp__*, chips and badges): those are miniature
     recreations of the real product UI, and scaling their type alone would break
     the proportion that makes them read as screenshots. */
  --text-fine: 13px;      /* legal/fine print under a form or CTA */
  --text-body-sm: 14px;   /* secondary copy: feature lines, captions, notes */
  --text-body: 15px;      /* default page copy */
  --text-lead: 16px;      /* section leads, the sentence under a heading */
  --text-lead-xl: 18px;   /* the hero's own lead, one step above the rest */
  --text-question: 18px;  /* FAQ questions (serif, so it carries more weight) */
  --sh-sm: 0 2px 6px rgba(50, 42, 28, .06);
  --sh-md: 0 10px 34px rgba(50, 42, 28, .08);
  --sh-lg: 0 16px 48px rgba(50, 42, 28, .13);
  --edge: 1.5px solid var(--line);
}

/* ── 2. Base ─────────────────────────────────────────────────────────────── */
body.mkt { margin: 0; color: var(--ink); font-family: var(--sans); -webkit-font-smoothing: antialiased; }
body.mkt ::selection { background: var(--mint-2); }
/* Reset UA heading/paragraph margins so the explicit spacing in the component
   classes is the single source of truth (mirrors the design's own reset).
   .mkt-live-doc marks a region that hosts the REAL app document partials
   (the recipe page's sample delivery renders hh-* et al.) and is exempt:
   those families' margin rules are also single-class, :where() ties with
   them, and this file loads after delivery_template.css — so without the
   exemption the reset silently flattened the reader's authored rhythm (the
   "vertical space is not right" bug, 2026-08-06). The hook is defined HERE
   and only used by marketing views (CSS isolation: this file may not name
   another sheet's classes). The inner :where() keeps the selector at
   zero-plus-.mkt-page specificity, so nothing else in the cascade moves. */
.mkt-page :where(h1, h2, h3, p):where(:not(.mkt-live-doc *)) { margin: 0; }
/* Generic link default at ZERO specificity (via :where), so any component that
   sets its own link color — nav, announcement, footer, buttons — always wins
   without !important. Only undecorated body links fall back to rust. */
.mkt-page :where(a) { color: var(--rust); text-decoration: none; }
.mkt-page :where(a):hover { text-decoration: underline; }
.mkt-mono { font-family: var(--mono); }
.mkt-em { font-style: italic; font-family: var(--serif); color: var(--rust); }

/* overflow-x: CLIP, not hidden — this one matters more than it looks.
   Per spec, `overflow-x: hidden` with `overflow-y: visible` forces the y axis to
   compute as `auto`, which quietly made this element a second scroll container
   stacked inside the document's. It sat harmless for as long as it had nothing
   to scroll; the moment the scroll reveal put a `translateY(14px)` on any
   not-yet-revealed section, it had 14px of its own — and a touch scroll started
   being handed between the two, sticking mid-gesture, releasing, then sticking
   again on the next direction change.

   `clip` is exempted from that rule: it clips the overflow without creating a
   scroll container and without touching the other axis. The `hidden` above it is
   the fallback for browsers that don't know `clip`, where the old behaviour
   stands.

   dvh, not vh, for the same reason every other shell in this codebase uses it:
   100vh is the URL-bar-hidden height on mobile, so the page is over-tall until
   the bar retracts. */
.mkt-page {
  width: 100%;
  min-height: 100vh;
  min-height: 100dvh;
  overflow-x: hidden;
  overflow-x: clip;
  background: radial-gradient(120% 90% at 50% 0%, #f5f2ec 0%, var(--cream) 46%, #eae6dd 100%);
}
.mkt-sprite { position: absolute; width: 0; height: 0; }

/* ── 3. Layout ───────────────────────────────────────────────────────────── */
.mkt-section { max-width: 1080px; margin: 0 auto; padding: 0 30px; }
.mkt-wrap { max-width: 1080px; margin: 0 auto; padding: 0 30px; }

/* How-it-works is a band (panel bg), so the top of the page alternates
   gradient → band → gradient → band (assist) instead of reading flat. */
.mkt-how { background: var(--panel); border-top: 1.5px solid var(--line-2); border-bottom: 1.5px solid var(--line-2); }
.mkt-how .mkt-wrap { padding-top: 48px; padding-bottom: 56px; }
.mkt-tpl { padding-top: 60px; padding-bottom: 62px; }
.mkt-pricing { padding-top: 60px; padding-bottom: 30px; }
.mkt-trust { padding-top: 44px; padding-bottom: 60px; }
.mkt-cta { padding-bottom: 64px; }

.mkt-spacer { flex: 1; }

/* ── 4. Typography ───────────────────────────────────────────────────────── */
.mkt-kicker { font: 700 11px var(--sans); letter-spacing: .6px; color: var(--green); }
.mkt-h2 { font-family: var(--serif); font-weight: 500; font-size: clamp(28px, 3.6vw, 40px); line-height: 1.1; margin: 8px 0 10px; text-wrap: balance; }
.mkt-lead { font-size: var(--text-lead); line-height: 1.6; color: var(--muted); }

/* Section headers */
.mkt-head { margin-bottom: 34px; }
.mkt-head--center { text-align: center; margin-bottom: 40px; }
.mkt-head--center .mkt-lead { max-width: 560px; margin-left: auto; margin-right: auto; }
.mkt-head--tpl { max-width: 680px; }
.mkt-head--pricing { margin-bottom: 38px; }
.mkt-head--pricing .mkt-h2 { font-size: clamp(30px, 4vw, 46px); line-height: 1.06; margin-bottom: 12px; }
.mkt-head--pricing .mkt-lead { font-size: var(--text-lead); max-width: 580px; margin: 0 auto 14px; }

/* ── 5. Buttons ──────────────────────────────────────────────────────────── */
.mkt-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; font-weight: 600; font-size: 15px; border-radius: 12px; padding: 14px 24px; border: 1.5px solid transparent; cursor: pointer; text-decoration: none; }
.mkt-btn:hover { text-decoration: none; }
.mkt-btn svg { width: 16px; height: 16px; }
.mkt-btn--green { color: #fff; background: var(--green); box-shadow: 0 3px 10px rgba(47, 109, 91, .25); }
.mkt-btn--green:hover { background: var(--green-d); }
.mkt-btn--ghost { color: var(--green); background: #fff; border-color: var(--mint-br); padding: 14px 22px; }
.mkt-btn--ghost:hover { background: var(--mint-soft); }
/* A tier that's shown but not yet buyable (e.g. Custom's "let's talk"
   conversation, or a future tier waiting on what it promises). Inert, muted,
   no pointer. Scout used this until Connections shipped and made it buyable. */
.mkt-btn--disabled { color: #9a9384; background: #f1ede4; border-color: transparent; cursor: default; }
.mkt-btn--disabled:hover { background: #f1ede4; }
.mkt-btn--cream { color: var(--forest); background: #f4f1e9; padding: 14px 26px; }
.mkt-btn--cream:hover { background: #fff; }
/* The secondary on a dark ground (final CTA). Outline only — it has to read as
   the quieter of the two next to --cream, which is the whole point of pairing
   them. */
.mkt-btn--outline { color: #f4f1e9; background: transparent; border-color: rgba(244, 241, 233, .35); padding: 14px 24px; }
.mkt-btn--outline:hover { border-color: #f4f1e9; }
.mkt-btn--sm { font-size: 13.5px; padding: 10px 17px; border-radius: 11px; gap: 7px; }
.mkt-btn--block { display: flex; width: 100%; padding: 12px 0; border-radius: 11px; font-size: 14px; margin-bottom: 18px; }

/* ── 6. Pills, badges, small bits ────────────────────────────────────────── */
.mkt-chip { display: inline-flex; align-items: center; gap: 4px; font: 600 11px var(--sans); padding: 4px 9px; border-radius: 999px; }
.mkt-chip--mint { background: var(--mint); color: var(--green); }
.mkt-chip--tan { background: var(--tan); color: var(--muted); }
.mkt-chip--pro { background: var(--pro-bg); color: var(--pro); }
.mkt-chip svg { width: 11px; height: 11px; }

/* square rounded icon holder */
.mkt-glyph { display: inline-flex; align-items: center; justify-content: center; flex: none; border-radius: 11px; background: var(--mint); color: var(--green); }

.mkt-eyebrow { display: inline-flex; align-items: center; gap: 8px; background: #fff; border: var(--edge); border-radius: 999px; padding: 6px 12px 6px 8px; font-size: 12px; color: var(--muted); margin-bottom: 22px; }
.mkt-eyebrow__ico { width: 20px; height: 20px; border-radius: 6px; background: var(--mint-2); color: var(--green); display: inline-flex; align-items: center; justify-content: center; }
.mkt-eyebrow__ico svg { width: 12px; height: 12px; }

.mkt-proof { display: flex; flex-wrap: wrap; gap: 8px 18px; font-size: 12.5px; color: var(--faint); }
.mkt-proof span { display: inline-flex; align-items: center; gap: 6px; }
.mkt-proof svg { width: 14px; height: 14px; color: var(--green); }

/* ── 7. Announcement + nav ───────────────────────────────────────────────── */
.mkt-anno { background: var(--ink); color: #f2efe7; font-size: 12.5px; text-align: center; padding: 9px 18px; letter-spacing: .1px; }
.mkt-anno b { color: var(--mint-2); font-weight: 600; }
.mkt-anno a { color: #f2efe7; text-decoration: underline; text-underline-offset: 2px; }

/* --mkt-nav-h is the nav's own height, published so anything that sticks BELOW
   it offsets by exactly that. marketing.js MEASURES the nav and overwrites this
   on load and on resize; the value here is only the no-JS fallback.
   
   It is measured rather than computed because the height is content-driven: the
   CTA button is taller than the logo (70px, not the 63.5px that padding + logo
   arithmetic predicts), and it differs again signed-in and at mobile
   breakpoints. A hardcoded offset that is 6px short leaves a gap the page
   scrolls through. Same lesson as the use-cases dropdown on 2026-08-27, which
   had to be anchored to .mkt-nav instead of a fixed `top: 64px`. */
:root { --mkt-nav-h: 70px; }
.mkt-nav { position: sticky; top: 0; z-index: 40; display: flex; align-items: center; gap: 18px; padding: 14px 30px; background: rgba(245, 242, 236, .82); backdrop-filter: blur(10px); border-bottom: var(--edge); }
.mkt-nav__brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.mkt-nav__brand:hover { text-decoration: none; }
.mkt-nav__logo { width: 34px; height: 34px; border-radius: 9px; box-shadow: 0 2px 8px rgba(47, 109, 91, .28); }
.mkt-nav__name { font-family: var(--serif); font-weight: 600; font-size: 23px; color: var(--ink); letter-spacing: -.2px; }
/* Every link carries the pill's geometry so the row doesn't reflow when the
   mint fill moves between pages: gap 0 + 13px side padding keeps the same
   26px text-to-text rhythm the row had as plain links. */
.mkt-nav__links { display: flex; align-items: center; gap: 0; }
.mkt-nav__links a { color: var(--muted); font-weight: 600; font-size: 13.5px; padding: 7px 13px; border-radius: 999px; }
/* The section you are in (nav renders with `active:`, e.g. the recipes pages). */
/* The mint pill: the current page reads as a place you're in rather than a
   link — the same reading as the app's own selected states. */
.mkt-nav__links a[aria-current="page"] { color: var(--green); font-weight: 700; background: #dcebe5; }
.mkt-nav__links a[aria-current="page"]:hover { text-decoration: none; color: var(--green); }

/* The Use-cases dropdown. Native <details>, so it opens with no JavaScript and
   Esc closes it for free — the same mechanism as the mobile sheet below, which
   is the point: one nav should not need two. */
/* Deliberately NOT positioned: the panel below resolves against .mkt-nav
   (sticky, so it is already a containing block), which right-aligns it to the
   nav's own padding edge and keeps it under the bar wherever the bar sits. The
   design pinned it at a fixed `top: 64px`, which the landing page's
   announcement strip pushes the nav below. */
.mkt-drop { position: static; }
.mkt-drop > summary {
  list-style: none; cursor: pointer;
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted); font-weight: 600; font-size: 13.5px;
  padding: 7px 13px; border-radius: 999px;
}
.mkt-drop > summary::-webkit-details-marker { display: none; }
.mkt-drop > summary:hover { color: var(--green); }
/* The page you are on, not a link to it — the same reading as aria-current
   elsewhere in this nav. A <summary> can't carry aria-current, so it is a
   class; the colour and pill are identical on purpose. */
.mkt-drop > summary.is-here { color: var(--green); font-weight: 700; background: var(--mint-2); }
.mkt-drop[open] > summary { color: var(--green); background: var(--mint); }
.mkt-drop__caret { font-size: 9px; transform: translateY(1px); }
.mkt-drop[open] .mkt-drop__caret { transform: translateY(1px) rotate(180deg); }
/* Pinned to the page edge, not to the summary: the panel is four columns wide
   and the trigger sits mid-row, so anchoring it to the trigger left it hanging
   off-centre with no guard against running past the viewport. */
.mkt-drop__sheet {
  position: absolute; top: calc(100% + 8px); right: 30px; z-index: 50; max-width: calc(100vw - 60px);
  display: grid; grid-template-columns: repeat(4, minmax(148px, 1fr)); gap: 20px;
  background: #fff; border: var(--edge); border-radius: 16px;
  box-shadow: 0 16px 48px rgba(50, 42, 28, .13); padding: 20px 22px;
}
.mkt-drop__label { font: 700 10px var(--sans); letter-spacing: .6px; color: var(--green); }
.mkt-drop__links { display: flex; flex-direction: column; gap: 7px; margin-top: 10px; }
/* Padding and radius are RESET, not merely unset: these sit inside
   .mkt-nav__links, whose own `a` rule paints the 7px/13px nav pill at equal
   specificity. Inherited, it spaced the rows ~5px further apart than the design
   and indented every link off its own group label. */
.mkt-drop__links a {
  padding: 0; border-radius: 0;
  font-size: 13.5px; font-weight: 500; line-height: 1.3; color: var(--ink); white-space: nowrap;
}
.mkt-drop__links a:hover { color: var(--green); text-decoration: none; }
/* Scoped through .mkt-drop__sheet to outrank `.mkt-nav__links a` — one class
   alone loses to class+element, which is how the nav pill's 999px radius kept
   bending this row's `border-top` into a curved rail instead of the hairline it
   is meant to be. */
.mkt-drop__sheet .mkt-drop__all {
  grid-column: 1 / -1; border-top: 1.5px solid var(--line-3); border-radius: 0;
  padding: 12px 0 0;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
}
.mkt-drop__sheet .mkt-drop__all:hover { color: var(--green); text-decoration: none; }

/* ── 8. Hero ─────────────────────────────────────────────────────────────── */
.mkt-hero { max-width: 1180px; margin: 0 auto; padding: 54px 30px 34px; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 44px; align-items: center; animation: riseIn .5s cubic-bezier(.2, .6, .2, 1) both; }
.mkt-hero__title { font-family: var(--serif); font-weight: 500; font-size: clamp(38px, 5.4vw, 60px); line-height: 1.04; letter-spacing: -.5px; margin-bottom: 20px; }
.mkt-hero__lead { font-size: var(--text-lead-xl); line-height: 1.6; color: var(--muted); max-width: 520px; margin-bottom: 14px; }
.mkt-hero__sub { font-size: var(--text-body); line-height: 1.55; color: var(--faint); max-width: 500px; margin-bottom: 28px; }
.mkt-hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 20px; }
.mkt-hero__visual { position: relative; display: flex; justify-content: center; }

/* reader mock (the product visual) */
.mkt-reader { position: relative; background: #fff; border: var(--edge); border-radius: 20px; box-shadow: var(--sh-lg); overflow: hidden; width: 100%; max-width: 460px; }
.mkt-reader__bar { display: flex; align-items: center; gap: 7px; padding: 13px 16px; border-bottom: 1.5px solid var(--line-2); background: var(--panel); flex-wrap: wrap; }
.mkt-reader__bar .mkt-chip { padding: 5px 10px; }
.mkt-reader__ver { font-size: 11px; color: #b6afa0; }
.mkt-reader__body { padding: 20px 22px 24px; }
.mkt-reader__meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--faint); margin-bottom: 5px; }
.mkt-reader__meta .dot { color: #cbc4b6; }
.mkt-reader__ran { display: inline-flex; align-items: center; gap: 4px; }
.mkt-reader__ran svg { width: 11px; height: 11px; color: var(--green); }
.mkt-reader__title { font-family: var(--serif); font-weight: 500; font-size: 24px; line-height: 1.12; margin-bottom: 16px; }

.mkt-tldr { background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 14px; padding: 15px 16px; margin-bottom: 16px; }
.mkt-tldr__head { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; }
.mkt-tldr__ico { width: 22px; height: 22px; border-radius: 6px; background: var(--green); color: #fff; display: flex; align-items: center; justify-content: center; }
.mkt-tldr__ico svg { width: 12px; height: 12px; }
.mkt-tldr__label { font: 700 10px var(--sans); letter-spacing: .8px; color: var(--green); }
.mkt-tldr__list { display: flex; flex-direction: column; gap: 9px; }
.mkt-tldr__item { display: flex; gap: 9px; align-items: flex-start; }
.mkt-tldr__n { font-family: var(--serif); font-weight: 600; font-size: 14px; color: var(--green); line-height: 1.3; }
.mkt-tldr__txt { font-size: 13px; line-height: 1.5; color: var(--deep); }
.mkt-tldr__txt strong { color: var(--deeper); }

.mkt-seclabel { display: flex; align-items: center; gap: 9px; margin-bottom: 11px; }
.mkt-seclabel span:first-child { font: 700 9px var(--sans); letter-spacing: 1px; color: var(--faint); }
.mkt-seclabel span:last-child { flex: 1; height: 1.5px; background: #e2ddd0; }

.mkt-skel { display: flex; flex-direction: column; gap: 9px; }
.mkt-skel span { height: 9px; border-radius: 3px; background: var(--cream); }
.mkt-skel span:nth-child(1) { width: 96%; }
.mkt-skel span:nth-child(2) { width: 88%; }
.mkt-skel span:nth-child(3) { width: 74%; }

.mkt-reader__badge { position: absolute; left: -14px; bottom: 34px; background: #fff; border: 1.5px solid var(--mint-br); border-radius: 12px; box-shadow: 0 10px 34px rgba(50, 42, 28, .12); padding: 10px 13px; display: flex; align-items: center; gap: 9px; }
.mkt-reader__badge-ico { width: 26px; height: 26px; border-radius: 8px; background: var(--mint-2); color: var(--green); display: flex; align-items: center; justify-content: center; }
.mkt-reader__badge-ico svg { width: 14px; height: 14px; }
.mkt-reader__badge-t { font-size: 11.5px; font-weight: 700; color: var(--ink); }
.mkt-reader__badge-s { font-size: 10.5px; color: var(--faint); }

/* ── 9. How it works ─────────────────────────────────────────────────────── */

/* The landing's three-step row: one panel divided into three, each step closing
   on a fragment of the product rather than only describing it. */
.mkt-flow {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  background: #fff; border: var(--edge); border-radius: 18px;
  box-shadow: var(--sh-sm); overflow: hidden;
}
.mkt-flow__step { padding: 26px 26px 28px; border-left: 1.5px solid var(--line-3); }
.mkt-flow__step:first-child { border-left: none; }

/* Number chip, then a rule running out to the column edge. */
.mkt-flow__num { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.mkt-flow__num::after { content: ""; flex: 1; height: 1.5px; background: var(--line-3); }
.mkt-flow__n {
  font: 600 11px var(--mono); letter-spacing: .5px; color: var(--green);
  background: var(--mint); border-radius: 6px; padding: 4px 8px;
}

.mkt-flow__title { font-family: var(--serif); font-weight: 500; font-size: 20px; margin-bottom: 8px; }
.mkt-flow__body { font-size: var(--text-body); line-height: 1.55; color: var(--muted); margin-bottom: 18px; }

/* The three closers. Same box, three fillings. */
.mkt-flow__quote,
.mkt-flow__note { border-radius: 10px; padding: 12px 14px; line-height: 1.5; }
.mkt-flow__quote { font-family: var(--serif); font-style: italic; font-size: 15px; color: var(--muted); background: var(--tan); }
.mkt-flow__note { font-size: var(--text-body-sm); color: var(--muted); background: var(--mint); }
.mkt-flow__applied { color: var(--green); font-weight: 600; }

.mkt-flow__pills { display: flex; flex-wrap: wrap; gap: 7px; }
.mkt-flow__pill {
  font: 600 12.5px var(--sans); padding: 6px 12px; border-radius: 999px;
  background: var(--panel); color: var(--muted); border: 1.5px solid var(--line-3);
}
.mkt-flow__pill--on { background: var(--green); color: #fff; border-color: var(--green); }

/* ── 10. Skills ──────────────────────────────────────────────────────────── */

/* ── 11. Output templates ────────────────────────────────────────────────── */
.mkt-tpl__foot { font-size: 13px; color: var(--faint); margin: 26px auto 0; max-width: 620px; text-align: center; }
/* Always-visible links to each template's /use-cases page (the per-panel links
   sit inside `hidden` panels for every tab but the active one). */
.mkt-tpl__cta { text-align: center; margin: 18px 0 0; }

.mkt-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 20px; }
.mkt-tpltab { display: inline-flex; align-items: center; gap: 8px; font: 600 13px var(--sans); padding: 9px 15px; border-radius: 999px; cursor: pointer; background: #fff; color: var(--muted); border: var(--edge); }
.mkt-tpltab__emoji { font-size: 15px; }
.mkt-tpltab.is-on { background: var(--green); color: #fff; border-color: var(--green); box-shadow: 0 3px 10px rgba(47, 109, 91, .22); }

.mkt-tpldot { height: 7px; width: 7px; border-radius: 999px; background: #d9d3c6; cursor: pointer; transition: all .3s; flex: none; }
.mkt-tpldot.is-on { width: 22px; background: var(--green); }
.mkt-arrow { width: 32px; height: 32px; border-radius: 9px; border: var(--edge); background: #fff; color: var(--muted); display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 16px; }
.mkt-arrow:hover { background: var(--mint-soft); }

.mkt-tplpanel { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 38px; align-items: center; background: #fff; border: var(--edge); border-radius: 20px; padding: 34px 38px; box-shadow: var(--sh-md); }
/* attribute selector outspecifies the base class → hides without !important */
.mkt-tplpanel[hidden] { display: none; }
.mkt-tplpanel__kicker { font: 700 10px var(--sans); letter-spacing: .6px; color: var(--green); margin-bottom: 10px; }
.mkt-tplpanel__title { font-family: var(--serif); font-weight: 500; font-size: clamp(23px, 2.5vw, 31px); line-height: 1.1; margin-bottom: 13px; text-wrap: balance; }
.mkt-tplpanel__body { font-size: var(--text-body); line-height: 1.6; color: var(--muted); margin-bottom: 17px; }
.mkt-tplpanel__tag { display: inline-flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--muted); background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 999px; padding: 6px 13px; margin-bottom: 24px; }
.mkt-tplpanel__tag span { width: 7px; height: 7px; border-radius: 2px; background: var(--green); flex: none; }
/* the tag's own bottom margin is the panel's breathing room when it's the last
   thing before the nav; with a link after it, the link owns that gap instead */
.mkt-tplpanel__tag:has(+ .mkt-tplpanel__more) { margin-bottom: 14px; }
/* flex (not inline-flex) so it breaks onto its own line after the inline tag */
.mkt-tplpanel__more { display: flex; width: fit-content; align-items: center; gap: 6px; font: 700 13px var(--sans); color: var(--green); margin-bottom: 22px; }
.mkt-tplpanel__more svg { width: 15px; height: 15px; }
.mkt-tplpanel__more:hover { text-decoration: underline; }
.mkt-tplpanel__nav { display: flex; align-items: center; gap: 9px; }
.mkt-tplpanel__viz { display: flex; justify-content: center; min-height: 300px; align-items: center; }

/* preview mock shell */
.mkt-mock { width: 100%; max-width: 392px; animation: riseIn .4s cubic-bezier(.2, .6, .2, 1) both; }
.mkt-mock__card { border: var(--edge); border-radius: 16px; background: #fff; overflow: hidden; box-shadow: var(--sh-md); }

/* workout preview */
.mkt-wk__head { padding: 16px 18px; border-bottom: 1.5px solid var(--line-3); }
.mkt-wk__kicker { font: 700 9px var(--sans); letter-spacing: .5px; color: #a49d8d; margin-bottom: 6px; }
.mkt-wk__title { font-family: var(--serif); font-size: 19px; font-weight: 500; margin-bottom: 11px; }
.mkt-wk__progress { display: flex; align-items: center; gap: 9px; }
.mkt-wk__track { flex: 1; height: 7px; border-radius: 999px; background: var(--line-3); overflow: hidden; }
.mkt-wk__fill { width: 38%; height: 100%; background: var(--green); }
.mkt-wk__count { font: 600 11px var(--sans); color: var(--muted); }
.mkt-wk__list { padding: 14px 16px 18px; display: flex; flex-direction: column; gap: 7px; }
.mkt-wk__row { display: flex; align-items: center; gap: 10px; padding: 9px 11px; border-radius: 9px; border: 1.5px solid var(--line-3); background: #fff; }
.mkt-wk__row--done { border-color: var(--mint-2); background: var(--mint-soft); }
.mkt-wk__check { width: 17px; height: 17px; flex: none; border-radius: 5px; border: 1.5px solid #cbc4b6; background: #fff; }
.mkt-wk__check--done { border: none; background: var(--green); color: #fff; display: flex; align-items: center; justify-content: center; font: 700 10px var(--sans); }
.mkt-wk__ex { flex: 1; }
.mkt-wk__ex-name { font-weight: 600; font-size: 13px; }
.mkt-wk__ex-name--done { color: var(--faint); }
.mkt-wk__ex-sub { font-size: 11px; color: var(--faint); }
.mkt-wk__reps { font: 600 12px var(--sans); color: var(--green); }

/* plate preview */
.mkt-pl__head { padding: 15px 17px; border-bottom: 1.5px solid var(--line-3); display: flex; justify-content: space-between; align-items: baseline; }
.mkt-pl__title { font-family: var(--serif); font-size: 18px; font-weight: 500; }
.mkt-pl__day { font: 600 11px var(--sans); color: var(--green); }
.mkt-pl__macros { padding: 17px 18px; display: flex; gap: 16px; align-items: center; border-bottom: 1.5px solid var(--line-3); }
.mkt-pl__ring { width: 70px; height: 70px; border-radius: 50%; flex: none; background: conic-gradient(var(--green) 0 72%, #e9e5db 72% 100%); display: flex; align-items: center; justify-content: center; }
.mkt-pl__ring-in { width: 50px; height: 50px; border-radius: 50%; background: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.mkt-pl__kcal { font: 700 13px var(--sans); color: var(--ink); }
.mkt-pl__kcal-u { font-size: 8px; color: var(--faint); }
.mkt-pl__bars { flex: 1; display: flex; flex-direction: column; gap: 8px; }
.mkt-pl__bar-top { display: flex; justify-content: space-between; font: 600 10.5px var(--sans); color: var(--muted); margin-bottom: 3px; }
.mkt-pl__track { height: 6px; border-radius: 999px; background: var(--line-3); overflow: hidden; }
.mkt-pl__fill { height: 100%; background: var(--green); }
.mkt-pl__bars > div:nth-child(1) .mkt-pl__fill { width: 100%; }
.mkt-pl__bars > div:nth-child(2) .mkt-pl__fill { width: 90%; }
.mkt-pl__bars > div:nth-child(3) .mkt-pl__fill { width: 88%; }
.mkt-pl__shop { padding: 13px 17px; background: var(--panel); }
.mkt-pl__shop-h { font: 700 9px var(--sans); letter-spacing: .5px; color: var(--green); margin-bottom: 8px; }
.mkt-pl__tags { display: flex; flex-wrap: wrap; gap: 5px; }
.mkt-pl__tags .mkt-chip { font-size: 10.5px; }

/* brief preview */
.mkt-br__tldr { padding: 15px 18px; background: var(--mint); border-bottom: 1.5px solid var(--mint-2); }
.mkt-br__tldr-h { font: 700 9px var(--sans); letter-spacing: .6px; color: var(--green); margin-bottom: 8px; }
.mkt-br__tldr-list { display: flex; flex-direction: column; gap: 7px; }
.mkt-br__tldr-item { display: flex; gap: 8px; align-items: flex-start; }
.mkt-br__bullet { width: 5px; height: 5px; border-radius: 50%; background: var(--green); flex: none; margin-top: 5px; }
.mkt-br__tldr-txt { font-size: 12.5px; color: #3a352c; line-height: 1.4; }
.mkt-br__rows { padding: 8px 10px; }
.mkt-br__row { display: flex; align-items: center; gap: 10px; padding: 11px 9px; }
.mkt-br__row + .mkt-br__row { border-top: 1.5px solid #f6f3ec; }
.mkt-br__tag { font: 700 8px var(--sans); letter-spacing: .3px; color: var(--faint); background: var(--tan); padding: 3px 6px; border-radius: 5px; flex: none; width: 52px; text-align: center; }
.mkt-br__row-txt { flex: 1; font-size: 12.5px; color: #3a352c; }
.mkt-br__chev { color: var(--faint); font-size: 14px; }

/* The two ways out of the OUTPUT TEMPLATES showcase, side by side. The left is
   wider because it carries the argument; the right is a destination, so it only
   needs to be legible and obviously clickable. */
.mkt-tplrow { display: grid; grid-template-columns: 1.3fr 1fr; gap: 16px; margin-top: 26px; }

/* Custom — the open-ended catch-all. Dashed edge signals "not a fixed thing",
   and the palette stays neutral on purpose: all the colour in this row belongs
   to the solid block beside it, or neither card reads as the louder offer. */
.mkt-tplcustom { display: flex; gap: 16px; padding: 22px 24px; border: 1.5px dashed var(--line); border-radius: 16px; background: #fff; }
.mkt-tplcustom__glyph { flex: none; width: 38px; height: 38px; border-radius: 11px; background: var(--tan); color: var(--muted); display: inline-flex; align-items: center; justify-content: center; font-size: 19px; }
.mkt-tplcustom__text { flex: 1; }
.mkt-tplcustom__title { font-family: var(--serif); font-weight: 500; font-size: 17px; color: var(--ink); margin-bottom: 5px; }
.mkt-tplcustom__body { font-size: var(--text-body-sm); line-height: 1.55; color: var(--muted); margin-bottom: 14px; }
.mkt-tplcustom__links { display: flex; flex-wrap: wrap; gap: 8px 20px; }
.mkt-tpllink { display: inline-flex; align-items: center; gap: 6px; font: 600 var(--text-body-sm)/1 var(--sans); color: var(--rust); }
.mkt-tpllink svg { width: 14px; height: 14px; }

/* Browse-all — one solid block, the whole card is the link. */
.mkt-tplall { display: flex; flex-direction: column; justify-content: center; gap: 8px; padding: 22px 26px; border-radius: 16px; background: var(--deep); text-decoration: none; }
.mkt-tplall:hover { background: var(--deeper); text-decoration: none; }
.mkt-tplall__title { font-family: var(--serif); font-weight: 500; font-size: 22px; line-height: 1.2; color: #fff; }
.mkt-tplall__body { font-size: var(--text-body-sm); line-height: 1.5; color: rgba(255, 255, 255, .78); }

/* ── 11b. Recipes band ───────────────────────────────────────────────────────
   Sits directly under the templates showcase and answers what it leaves open:
   the words you actually write. Its own horizontal band on --panel, because on
   the showcase's cream it read as that section's tail rather than the answer to
   it; `assist` below it turned dark in the same pass, so the page alternates
   ground instead of running two light bands together. The cards are the
   /recipes cards said shorter: template label, title, the Direction in its own
   voice (serif, quoted), cadence · mode. */
.mkt-rcp { background: var(--panel); border-top: 1.5px solid var(--line-2); border-bottom: 1.5px solid var(--line-2); }
.mkt-rcp .mkt-wrap { padding-top: 62px; padding-bottom: 66px; }
.mkt-head--rcp { max-width: 660px; margin-bottom: 30px; }
.mkt-rcp__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px; }

.mkt-rcpcard { display: flex; flex-direction: column; padding: 20px 22px; background: #fff; border: var(--edge); border-radius: 16px; color: var(--ink); box-shadow: var(--sh-sm); transition: border-color .16s cubic-bezier(.2, .6, .2, 1); }
.mkt-rcpcard:hover { border-color: var(--mint-br); text-decoration: none; }
.mkt-rcpcard__top { display: flex; align-items: center; gap: 8px; margin-bottom: 9px; }
.mkt-rcpcard__glyph { font-size: 14px; }
.mkt-rcpcard__label { font: 700 10px var(--sans); letter-spacing: .6px; color: var(--faint); }
.mkt-rcpcard__title { font-family: var(--serif); font-weight: 500; font-size: 20px; line-height: 1.18; margin-bottom: 10px; }
/* The Direction, in the shape it has everywhere else on the site: quoted, set
   in the serif, boxed off from the card's own copy so it reads as the user's
   words rather than ours. */
.mkt-rcpcard__dir { font-family: var(--serif); font-style: italic; font-size: 14px; line-height: 1.5; color: var(--muted); background: var(--tan); border-radius: 10px; padding: 11px 13px; margin-bottom: 12px; }
.mkt-rcpcard__meta { margin-top: auto; font-size: 12.5px; color: var(--faint); }

/* Same filled block as the templates section's browse-all, full width here. */
.mkt-rcp__all { margin-top: 16px; }

/* ── 12. Pricing ─────────────────────────────────────────────────────────── */
.mkt-pricing__note { display: inline-block; font-size: 12px; color: var(--faint); background: #fff; border: var(--edge); border-radius: 999px; padding: 6px 14px; }
.mkt-tiers { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 18px; max-width: 840px; margin: 0 auto; }
/* One live plan: a single centered card, so "One plan" reads true. */
.mkt-tiers--single { max-width: 420px; }
/* Not currently rendered — the compact #pricing band moved to a single
   .prcp-band CTA (see landing.html.erb). Kept for a future tier that isn't
   purchasable yet and needs a teaser strip here; Scout used it until
   Connections shipped and it moved to a full live card on /pricing
   (joris/pricing.css .prcp-plan--pro carries the equivalent emphasis there). */
.mkt-tier { position: relative; background: #fff; border: var(--edge); border-radius: 20px; padding: 28px 26px; box-shadow: var(--sh-sm); }
.mkt-tier--pro { border-color: var(--green); box-shadow: 0 16px 48px rgba(50, 42, 28, .11); }
.mkt-tier__name { font-family: var(--serif); font-size: 22px; font-weight: 500; }
.mkt-tier__pitch { font-size: 12.5px; color: var(--faint); margin-bottom: 16px; min-height: 34px; }
.mkt-tier__price { display: flex; align-items: baseline; gap: 5px; margin-bottom: 20px; }
.mkt-tier__price b { font-family: var(--serif); font-size: 44px; font-weight: 500; line-height: 1; }
.mkt-tier__price span { font-size: 13px; color: var(--faint); }
.mkt-tier__flag { position: absolute; top: -11px; left: 26px; font: 700 9px var(--sans); letter-spacing: .6px; color: #fff; background: var(--green); border-radius: 999px; padding: 5px 12px; }
.mkt-tier__flag--soon { background: #b45b3e; }
.mkt-tier__feats { display: flex; flex-direction: column; gap: 11px; border-top: 1.5px solid var(--line-3); padding-top: 17px; }
/* What the trial actually is. Sits under the paid feature list, visibly a note
   about a different thing rather than a sixth feature of Standard. */
.mkt-tier__trial { margin-top: 20px; padding-top: 17px; border-top: 1.5px solid var(--line-3); font-size: 12.5px; line-height: 1.65; color: var(--faint); }
.mkt-tier__trialhead { display: block; font: 700 9px var(--sans); letter-spacing: .6px; text-transform: uppercase; color: var(--green); margin-bottom: 5px; }
.mkt-feat { display: flex; gap: 10px; align-items: flex-start; }
.mkt-feat__tick { width: 18px; height: 18px; flex: none; border-radius: 50%; background: var(--mint); color: var(--green); display: flex; align-items: center; justify-content: center; margin-top: 1px; }
.mkt-feat__tick svg { width: 11px; height: 11px; }
.mkt-feat span { font-size: var(--text-body-sm); line-height: 1.45; color: #3f3a30; }
.mkt-pricing__foot { text-align: center; margin-top: 22px; font-size: 12.5px; color: var(--faint); }

/* ── 13. Trust ───────────────────────────────────────────────────────────── */
.mkt-trust-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 16px 26px; }
.mkt-trust__item { display: flex; gap: 13px; align-items: flex-start; }
.mkt-trust__glyph { width: 34px; height: 34px; border-radius: 10px; }
.mkt-trust__glyph svg { width: 17px; height: 17px; }
.mkt-trust__title { font-size: var(--text-body); font-weight: 700; margin-bottom: 4px; }
.mkt-trust__body { font-size: var(--text-body-sm); line-height: 1.5; color: var(--muted); }

/* ── 14. Final CTA ───────────────────────────────────────────────────────── */
.mkt-cta__box { position: relative; overflow: hidden; background: var(--forest); border-radius: 24px; padding: 56px 40px; text-align: center; box-shadow: 0 16px 48px rgba(50, 42, 28, .16); }
.mkt-cta__box::before { content: ""; position: absolute; inset: 0; background: radial-gradient(90% 120% at 50% -10%, rgba(220, 235, 229, .14), transparent 60%); }
.mkt-cta__inner { position: relative; }
.mkt-cta__title { font-family: var(--serif); font-weight: 500; font-size: clamp(30px, 4vw, 44px); line-height: 1.08; color: #f4f1e9; margin-bottom: 14px; text-wrap: balance; }
.mkt-cta__lead { font-size: var(--text-lead); line-height: 1.6; color: #c3cec8; max-width: 520px; margin: 0 auto 28px; }
.mkt-cta__actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-bottom: 18px; }
.mkt-cta__fine { font-size: 12.5px; color: #9fb0a8; }

/* The Newsletter mock (Draft family) on the landing carousel. Like its sibling
   mocks, its type is NOT on the reading scale — these are miniature
   recreations of the real delivery, and scaling their type alone breaks the
   proportion that makes them read as screenshots. */
.mkt-nl__head { padding: 16px 18px; border-bottom: 1.5px solid var(--line-3); }
.mkt-nl__kicker { font: 700 9px var(--sans); letter-spacing: .5px; color: #a49d8d; margin-bottom: 6px; }
.mkt-nl__subject { font-family: var(--serif); font-size: 19px; font-weight: 500; line-height: 1.25; }
.mkt-nl__body { padding: 14px 16px 18px; display: flex; flex-direction: column; gap: 7px; }
.mkt-nl__row {
  border: 1.5px solid var(--line-3); border-radius: 9px; padding: 10px 12px;
  font-size: 12.5px; line-height: 1.5;
}
.mkt-nl__row--muted { color: var(--muted); }
.mkt-nl__tag { font: 700 9px var(--sans); letter-spacing: .5px; color: var(--green); }
.mkt-nl__foot {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  margin-top: 3px; font-size: 11px; color: var(--faint);
}
.mkt-nl__copy { font-weight: 600; color: var(--green); }

/* ── 15. Footer ──────────────────────────────────────────────────────────── */
/* Sits on --panel rather than the page. The footer used to end the page by
   simply running out of content, with one hairline doing all the work; giving
   it its own ground closes the page off. */
.mkt-footer { border-top: var(--edge); background: var(--panel); }
/* Five columns: who we are, then one per family. It was a single flat row
   until 2026-08-27, and named no vertical at all — eleven pages whose only
   inbound link was the hub. */
.mkt-footer__inner {
  max-width: 1080px; margin: 0 auto; padding: 36px 30px 22px;
  display: grid; grid-template-columns: 1.3fr repeat(4, 1fr); gap: 30px; align-items: start;
}
.mkt-footer__collabel { font: 700 10px var(--sans); letter-spacing: .8px; color: var(--faint); }
.mkt-footer__collinks { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; font-size: 12.5px; font-weight: 600; }
.mkt-footer__collinks a { color: var(--muted); }
.mkt-footer__collinks a:hover { color: var(--green); }
.mkt-footer__brand { display: flex; align-items: center; gap: 9px; }
.mkt-footer__brand img { width: 26px; height: 26px; border-radius: 7px; }
.mkt-footer__name { font-family: var(--serif); font-weight: 600; font-size: 18px; }
/* Capped and leaded so it wraps to two readable lines beside the mark instead
   of stretching into one thin ribbon across the whole row. */
.mkt-footer__tag { font-size: 12.5px; line-height: 1.5; color: var(--muted); max-width: 240px; margin: 12px 0 0; }
/* Wraps: six links plus the brand and tagline do not fit one row on a laptop. */
/* Stacked, like the family columns beside it — a wrapping row read as a
   different kind of thing to its own neighbours. */
.mkt-footer__links { display: flex; flex-direction: column; gap: 8px; margin-top: 16px; font-size: 12.5px; font-weight: 600; }
.mkt-footer__links a { color: var(--muted); }
/* The honesty line. Full width under the row so it reads as a statement rather
   than one more footer link, and now behind its own rule — against the panel it
   was reading as a fourth column of small print rather than a closing remark. */
/* The bottom bar: the honest note on the left, legal on the right. */
.mkt-footer__honest {
  max-width: 1080px; margin: 0 auto; padding: 16px 30px 30px;
  border-top: 1.5px solid var(--line-2);
  display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 12px 30px;
}
.mkt-footer__legal { display: flex; gap: 18px; font-size: 12px; font-weight: 600; }
.mkt-footer__legal a { color: var(--faint); }
.mkt-footer__legal a:hover { color: var(--green); }
/* The rule spans the footer, the sentence does not. They used to be the same
   element, so the line stopped where the text did — unnoticeable above a
   one-row footer and obviously wrong under five columns. */
.mkt-footer__honest p {
  max-width: 660px; margin: 0;
  font-size: 12px; line-height: 1.6; color: var(--muted);
}

/* ── 16. Animation ───────────────────────────────────────────────────────── */
@keyframes riseIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* Scroll reveal (reveal.js). Read the guard rail first:
   .mkt-reveal-on is set by an inline snippet in the layout and .mkt-rv by
   reveal.js itself, so BOTH have to be present before anything is hidden. With
   JS off, a stale cache, reduced motion, or reveal.js failing to parse, none of
   this matches and every page is plain visible HTML. Nothing on a marketing
   site should be one broken script away from being invisible.

   Kept to opacity and transform: both are compositor-only, so a long page of
   these costs no layout. */
.mkt-reveal-on .mkt-rv { opacity: 0; transform: translateY(14px); }
.mkt-reveal-on .mkt-rv.is-revealed {
  opacity: 1;
  transform: none;
  transition: opacity .55s cubic-bezier(.2, .6, .2, 1), transform .55s cubic-bezier(.2, .6, .2, 1);
}

/* The inline snippet already checks this; this is the belt to its braces, and
   covers the setting being changed after the page loaded. */
@media (prefers-reduced-motion: reduce) {
  .mkt-hero, .mkt-mock { animation: none; }
  .mkt-reveal-on .mkt-rv { opacity: 1; transform: none; }
  .mkt-reveal-on .mkt-rv.is-revealed { transition: none; }
}

/* ── 17. Responsive ──────────────────────────────────────────────────────── */
/* Stacks a step earlier than the other two-column blocks below. Three columns
   of prose plus a closer need ~300px each; by 940 the schedule pills are already
   wrapping to a second line and the measure is down to ~30 characters. Stacking
   into one panel of three rows — dividers turning with them, so it still reads
   as one object rather than three cards. */
@media (max-width: 940px) {
  .mkt-flow { grid-template-columns: 1fr; }
  .mkt-flow__step { border-left: none; border-top: 1.5px solid var(--line-3); }
  .mkt-flow__step:first-child { border-top: none; }
}
@media (max-width: 860px) {
  .mkt-hero { grid-template-columns: 1fr; gap: 30px; }
  .mkt-tplpanel { grid-template-columns: 1fr; gap: 22px; }
  /* Stacked, the browse-all block no longer needs to fill a column's height. */
  .mkt-tplrow { grid-template-columns: 1fr; }
  .mkt-tplall { padding: 20px 22px; }
}
@media (max-width: 720px) {
  .mkt-nav__links { display: none; }
}
@media (max-width: 900px) {
  /* Five columns to three, then to two: the family columns hold up to four
     links each and go ragged long before the page does. */
  .mkt-footer__inner { grid-template-columns: repeat(3, 1fr); gap: 26px; }
  .mkt-footer__about { grid-column: 1 / -1; }
  .mkt-footer__tag { max-width: 420px; }
}
@media (max-width: 520px) {
  .mkt-footer__inner { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .mkt-section,
  .mkt-wrap,
  .mkt-hero,
  .mkt-nav,
  .mkt-footer__inner { padding-left: 18px; padding-right: 18px; }
  .mkt-footer__honest { padding-left: 18px; padding-right: 18px; }
  .mkt-hero { padding-top: 40px; }
  .mkt-reader__badge { left: 4px; }
  .mkt-tplpanel { padding: 22px; }
  .mkt-flow__step { padding: 22px 20px 24px; }
  .mkt-rcp .mkt-wrap { padding-top: 44px; padding-bottom: 46px; }
  .mkt-assist .mkt-wrap { padding-top: 46px; padding-bottom: 50px; }
  /* The dashed run needs width to say "nothing happens here". At this size it
     collapses to a few pixels, so the label simply introduces the sentence. */
  .mkt-assist__footrule { display: none; }
}
@media (max-width: 640px) {
}

/* ── Legal pages (privacy, terms) ────────────────────────────────────────
   Long-form reading, so this deliberately breaks from the marketing page's
   wide layout: one narrow measure, generous line height, no decoration. */
.legal { max-width: 720px; margin: 0 auto; padding: 56px var(--page-gutter, 24px) 80px; }
.legal__head { padding-bottom: 26px; margin-bottom: 30px; border-bottom: 1.5px solid #e6e1d6; }
.legal__title { font-family: "Newsreader", Georgia, serif; font-weight: 500; font-size: 38px; line-height: 1.15; margin: 0 0 10px; color: #26221b; }
.legal__lede { font-size: 16px; line-height: 1.6; color: #6f6a5e; margin: 0 0 10px; }
.legal__updated { font-size: 12.5px; color: #9a9384; margin: 0; }

.legal__body { font-size: 15.5px; line-height: 1.72; color: #3a352c; }
.legal__body h2 { font-family: "Newsreader", Georgia, serif; font-weight: 600; font-size: 23px; line-height: 1.25; margin: 40px 0 12px; color: #26221b; }
.legal__body h3 { font-size: 15px; font-weight: 700; margin: 26px 0 8px; color: #26221b; }
.legal__body p { margin: 0 0 16px; }
.legal__body ul { margin: 0 0 16px; padding-left: 22px; }
.legal__body li { margin-bottom: 8px; }
.legal__body strong { color: #26221b; font-weight: 600; }
.legal__body a { color: #2f6d5b; text-decoration: underline; text-underline-offset: 2px; }
.legal__body a:hover { color: #28604f; }

/* Sub-processor table — the one place a table beats prose, and the one place
   people actually look. Scrolls inside itself so the page never does. */
.legal__table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 0 0 18px; }
.legal__table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: 14px; }
.legal__table th, .legal__table td { text-align: left; vertical-align: top; padding: 11px 14px; border-bottom: 1.5px solid #ece8df; }
.legal__table th { font-size: 11px; letter-spacing: .5px; text-transform: uppercase; color: #9a9384; font-weight: 700; }
.legal__table tbody tr:last-child td { border-bottom: none; }


@media (max-width: 720px) {
  .legal { padding-top: 34px; padding-bottom: 56px; }
  .legal__title { font-size: 30px; }
  .legal__body { font-size: 15px; }
  .legal__body h2 { font-size: 20px; margin-top: 32px; }
}

.legal__warn { border: 1.5px solid #e8d3c8; background: #fdf6f2; border-radius: 12px; padding: 14px 16px; margin: 0 0 26px; font-size: 14px; line-height: 1.6; color: #8a4a30; }
.legal__warn strong { color: #b45b3e; }
.legal__warn code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; background: #f6e2d8; padding: 1px 5px; border-radius: 4px; }

/* ── "Assist, don't interrupt" — the two assist moments (prompt coach + steering) ──
   The page's one dark band. This is the section whose argument is ABSENCE — the
   product speaks twice and is quiet the rest of the time — so the ground says it
   before the copy does, and the two white mocks read as the lights coming on.
   It also gives the page a real alternation: the recipes band above is light.

   Head, moments and closing row are all left-aligned here; a centred column
   fought the two cards sitting side by side under it. */
.mkt-assist { position: relative; overflow: hidden; background: var(--forest); }
/* The same top-glow as the final CTA box, so the two dark grounds on the page
   are lit the same way. */
.mkt-assist::before { content: ""; position: absolute; inset: 0; background: radial-gradient(80% 90% at 50% -20%, rgba(220, 235, 229, .12), transparent 62%); }
.mkt-assist .mkt-wrap { position: relative; padding-top: 66px; padding-bottom: 70px; }
.mkt-head--assist { max-width: 660px; margin-bottom: 34px; }
.mkt-head--assist .mkt-kicker { color: #8fb3a6; }
.mkt-head--assist .mkt-h2 { font-size: clamp(28px, 3.6vw, 40px); line-height: 1.08; color: #f4f1e9; margin: 8px 0 12px; }
.mkt-head--assist .mkt-lead { color: #c3cec8; }
.mkt-head--assist .mkt-em { color: #dcebe5; }

.mkt-moments { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 26px; max-width: 900px; margin: 8px auto 0; }
.mkt-moment { display: flex; flex-direction: column; }
.mkt-moment__step { display: inline-flex; align-items: center; gap: 9px; font: 700 10px var(--sans); letter-spacing: .7px; color: #8fb3a6; margin-bottom: 11px; }
.mkt-moment__n { display: inline-flex; align-items: center; justify-content: center; width: 19px; height: 19px; border-radius: 50%; background: rgba(220, 235, 229, .16); color: #dcebe5; font: 700 10px var(--sans); }
.mkt-moment__title { font-family: var(--serif); font-weight: 500; font-size: 21px; line-height: 1.2; margin: 0 0 16px; color: #f4f1e9; }
.mkt-mock--flush { max-width: 380px; }
.mkt-moment__cap { font-size: var(--text-fine); line-height: 1.55; color: #9db3aa; margin: 16px 2px 0; max-width: 340px; }

/* mock interiors — suggestive, not pixel-perfect replicas of the app.
   Scoped to .mkt-assist so the shared .mkt-mock__card used elsewhere is
   untouched. Borderless with a deep drop shadow: on the dark ground the card
   needs to float, and a hairline edge only muddies it. */
.mkt-assist .mkt-mock__card { padding: 17px 18px; text-align: left; border: none; box-shadow: 0 14px 40px rgba(12, 28, 22, .32); }
.mkt-coach__label { font: 700 9px var(--sans); letter-spacing: .6px; color: var(--faint); margin-bottom: 8px; }
.mkt-coach__prompt { font-family: var(--serif); font-size: 15.5px; line-height: 1.45; color: #3a352c; padding-bottom: 12px; border-bottom: 1.5px solid var(--line); margin-bottom: 12px; }
.mkt-coach__grade { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 14px; }
.mkt-coach__score { flex: none; font: 700 11px var(--sans); color: var(--green); background: var(--mint-soft); border-radius: 8px; padding: 5px 9px; }
.mkt-coach__tip { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.mkt-coach__cta svg { width: 14px; height: 14px; }

.mkt-steer__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 11px; }
.mkt-steer__note { font-size: var(--text-body-sm); line-height: 1.55; color: #3a352c; background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 11px 13px; margin-bottom: 14px; }

/* The quiet stretch, drawn: label, a long dashed run of nothing, the sentence. */
.mkt-assist__foot { display: flex; align-items: center; gap: 16px; margin-top: 38px; padding-top: 22px; border-top: 1px solid rgba(220, 235, 229, .16); }
.mkt-assist__footlbl { flex: none; font: 700 10px var(--sans); letter-spacing: .7px; color: #8fb3a6; }
.mkt-assist__footrule { flex: 1; height: 0; border-top: 1px dashed rgba(220, 235, 229, .26); }
.mkt-assist__foottxt { font-size: var(--text-body-sm); line-height: 1.55; color: #c3cec8; max-width: 460px; }

/* House-hunt preview mock (OUTPUT TEMPLATES 4th tab): vetting + what's-new. */
.mkt-hh__since { font: 700 10px var(--sans); letter-spacing: .3px; color: var(--green); background: var(--mint-soft); padding: 9px 14px; border-bottom: 1.5px solid var(--line-2); }
.mkt-hh__card { padding: 13px 15px; border-bottom: 1.5px solid var(--line-2); }
.mkt-hh__card--out { opacity: .62; }
.mkt-hh__card:last-child { border-bottom: none; }
.mkt-hh__row { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.mkt-hh__new { flex: none; font: 700 8.5px var(--sans); letter-spacing: .5px; color: #fff; background: var(--rust); border-radius: 999px; padding: 3px 7px; }
.mkt-hh__title { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.mkt-hh__title--out { text-decoration: line-through; color: var(--muted); }
.mkt-hh__price { margin-left: auto; font: 700 13px var(--mono); color: var(--ink); }
.mkt-hh__checks { display: flex; flex-wrap: wrap; gap: 5px 10px; }
.mkt-hh__ok { font: 600 11px var(--sans); color: var(--green); }
.mkt-hh__no { font: 600 11px var(--sans); color: var(--rust); }

/* ── 18. Use-case SEO pages (/use-cases/:slug) ────────────────────────────────
   Reuses the landing's chrome and CTA. What the retired catalog-driven layout
   needed — breadcrumb, problem list, output grid, related cards — went with it;
   what's left is shared with the designed pages: the template previews and the
   FAQ accordion. Page-specific rules live in section 19 (.ucp-*). */
/* Keep the preview card sized to its content — never stretched to the (taller)
   hero text column, which is what left an empty tail under the delivery. */

/* Real template previews rendered inside the reader chrome (see the mocks/*
   partials). Only the small additions the richer versions need. */
.mkt-wk__list > .mkt-wk__phase:first-child { margin-top: 0; }

/* Draft-family marketing previews (newsletter + social posts). */

.mkt-sp { padding: 16px; display: flex; flex-direction: column; gap: 12px; }

/* FAQ accordion — native <details>, styled. Also emits FAQPage JSON-LD. */
.mkt-faq { padding-top: 58px; padding-bottom: 58px; }
.mkt-faq__list { max-width: 760px; margin: 0 auto; display: grid; gap: 10px; }
.mkt-faq__item { border: var(--edge); border-radius: 14px; background: #fff; padding: 0 20px; overflow: hidden; }
.mkt-faq__item summary { display: flex; align-items: center; gap: 12px; justify-content: space-between; cursor: pointer; list-style: none; padding: 16px 0; font-family: var(--serif); font-size: var(--text-question); color: var(--ink); }
.mkt-faq__item summary::-webkit-details-marker { display: none; }
.mkt-faq__plus { flex: none; font: 400 20px var(--sans); color: var(--green); transition: transform .18s ease; line-height: 1; }
.mkt-faq__item[open] .mkt-faq__plus { transform: rotate(45deg); }
.mkt-faq__item p { margin: 0; padding: 0 0 18px; font-size: var(--text-body); line-height: 1.6; color: var(--muted); max-width: 640px; }

/* Contact page — a real form (server-emailed, bot-protected). */
.mkt-contact { padding-top: 56px; padding-bottom: 64px; }
.mkt-form { max-width: 560px; margin: 0 auto; }
.mkt-form__label { display: block; font: 700 11px var(--sans); letter-spacing: .3px; color: var(--muted); margin: 16px 0 6px; }
/* An explicit line-height because the <select> in this stack also carries this
   class: with the default `normal`, Chrome sizes an input to the font's
   ascent+descent and a select to its option box, so the two came out two
   pixels apart in a column of otherwise identical fields. */
.mkt-form__input { width: 100%; box-sizing: border-box; font: 400 var(--text-body)/1.35 var(--sans); color: var(--ink); background: #fff; border: var(--edge); border-radius: 11px; padding: 11px 13px; }
.mkt-form__input:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 3px rgba(47, 109, 91, .12); }
.mkt-form__textarea { resize: vertical; line-height: 1.5; }
.mkt-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.mkt-form__selectwrap { position: relative; }
/* Only the caret and the appearance reset come from the shared select rule —
   height comes from .mkt-form__input's own padding and line-height so this sits
   in a stack of fields at exactly their size. */
.mkt-form__selectwrap select {
  width: 100%; height: auto; padding: 11px 38px 11px 13px;
  font: 400 var(--text-body)/1.35 var(--sans); color: var(--ink); border: var(--edge);
  background: #fff var(--caret-down) no-repeat right 13px center;
}
.mkt-form__turnstile { margin-top: 18px; }
.mkt-form__submit { margin-top: 22px; }
.mkt-form__fine { margin-top: 12px; font-size: var(--text-fine); color: var(--faint); }
.mkt-form__err { background: #fbeee8; border: 1.5px solid #e8d3c8; color: #8a4a30; border-radius: 11px; padding: 11px 14px; font-size: var(--text-body-sm); line-height: 1.5; margin-bottom: 4px; }
/* Honeypot: off-screen, unfocusable, hidden from AT — only bots fill it. */
.mkt-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
/* Success state. */
.mkt-sent { max-width: 520px; margin: 20px auto 0; text-align: center; }
.mkt-sent__ico { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border-radius: 14px; background: var(--mint-2); color: var(--green); margin-bottom: 16px; }
.mkt-sent__ico svg { width: 22px; height: 22px; }
.mkt-sent .mkt-lead { margin: 10px auto 22px; max-width: 440px; }

/* "Tell us your use case" — the same form, embedded mid-page on the hub and on
   every template page. Boxed and on paper so it reads as a distinct invitation
   rather than more page copy, and centred at the form's own width. */

@media (max-width: 560px) { .mkt-form__row { grid-template-columns: 1fr; } }

@media (max-width: 700px) {
  .mkt-faq, .mkt-contact { padding-top: 44px; padding-bottom: 44px; }
  .mkt-faq__item summary { font-size: var(--text-lead); }
}

/* ── Mobile nav ───────────────────────────────────────────────────────────
   Below 720px .mkt-nav__links is hidden; this replaces it. Native <details>,
   so it needs no JavaScript and Esc closes it. Hidden on desktop. */
.mkt-menu { display: none; position: relative; }
.mkt-menu__button {
  list-style: none; display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 11px; border: 1.5px solid var(--line-2);
  background: #fff; cursor: pointer;
}
.mkt-menu__button::-webkit-details-marker { display: none; }
.mkt-menu__bars, .mkt-menu__bars::before, .mkt-menu__bars::after {
  display: block; width: 17px; height: 2px; border-radius: 2px; background: var(--ink); content: "";
}
.mkt-menu__bars { position: relative; }
.mkt-menu__bars::before { position: absolute; top: -6px; }
.mkt-menu__bars::after { position: absolute; top: 6px; }
.mkt-menu[open] .mkt-menu__button { border-color: var(--green); }
.mkt-menu__sheet {
  position: absolute; right: 0; top: calc(100% + 10px); z-index: 60;
  display: flex; flex-direction: column; min-width: 218px; padding: 8px;
  background: #fff; border: 1.5px solid var(--line-2); border-radius: 14px;
  box-shadow: 0 12px 32px rgba(50, 42, 28, .14);
}
.mkt-menu__sheet a {
  padding: 11px 12px; border-radius: 9px; font: 600 14.5px var(--sans);
  color: var(--ink); text-decoration: none;
}
.mkt-menu__sheet a:hover { background: var(--paper-warm, #faf8f3); color: var(--green); }
.mkt-menu__sheet a[aria-current="page"] { background: #dcebe5; color: var(--green); font-weight: 700; }
/* The verticals, grouped by family. A phone has no dropdown to hover, so this
   is the only route from any page to a use case — the sheet is scrollable
   because it now holds eleven of them plus the rest of the nav. */
.mkt-menu__sheet { max-height: min(72vh, 560px); overflow: hidden auto; }  /* Both axes named: overflow-y alone promotes overflow-x to `auto`. */
/* A column, like the sheet itself: the links are children of this div rather
   than of the sheet's flex container, so without it they lay out inline and
   run out the side of the panel. */
.mkt-menu__group { display: flex; flex-direction: column; padding: 6px 0; border-top: 1.5px solid var(--line-3); margin-top: 4px; }
.mkt-menu__group:first-of-type { border-top: none; margin-top: 0; }
.mkt-menu__label { font: 700 9.5px var(--sans); letter-spacing: .8px; color: var(--faint); padding: 6px 12px 2px; }
.mkt-menu__sheet a.mkt-menu__sub { padding: 8px 12px 8px 20px; font-size: 13.5px; font-weight: 500; color: var(--muted); white-space: nowrap; }
.mkt-menu__sheet a.mkt-menu__sub:hover { color: var(--green); }

@media (max-width: 720px) {
  .mkt-menu { display: block; }
  /* The brand name is the one thing that can push the row over on a phone. */
  .mkt-nav { gap: 10px; }
  .mkt-nav__name { font-size: 20px; }
}

/* ============================================================================
   18. Templates hub (/use-cases) — the .uch-* family
   ============================================================================
   Ported from Claude Design ("Use Cases.dc.html", 2026-07-26). The design ships
   as fully inline-styled HTML; per AGENTS.md every declaration lives here and the
   ERB carries semantic classes only.

   The page's argument: eleven templates, grouped by what you're asking for
   (coach / monitor / draft), each card ending in a miniature of its actual
   delivery. So most of what follows is (a) the family grid, with one wide
   "featured" card per section, and (b) a small set of mock primitives the eleven
   miniatures are all built from — one vocabulary rather than eleven bespoke
   card designs.
   ------------------------------------------------------------------------- */

/* ── Shared bits ─────────────────────────────────────────────────────────── */
.uch-kicker { font: 700 11px var(--sans); letter-spacing: .6px; color: var(--green); }
.uch-kicker--light { color: #a8cfc0; letter-spacing: .8px; }
.uch-spacer { flex: 1; }
.uch-muted { color: var(--muted); }
.uch-ink { color: var(--ink); }
.uch-eyebrow { font: 700 9px var(--sans); letter-spacing: 1px; color: #a49d8d; margin-bottom: 8px; }
.uch-eyebrow--green { color: var(--green); }
.uch-eyebrow--panel { margin-bottom: 10px; }
.uch-note { font-size: 10.5px; line-height: 1.4; color: var(--faint); }
.uch-note--center { text-align: center; margin-top: 9px; }
.uch-rule { display: block; height: 1px; background: var(--line-3); }
.uch-strong { font-size: 12px; font-weight: 600; line-height: 1.35; color: var(--ink); }
.uch-strong--sm { font-size: 11.5px; }
.uch-headline { font-family: var(--serif); font-weight: 500; font-size: 16px; line-height: 1.15; }
.uch-headline--sm { font-size: 14.5px; margin-bottom: 5px; }
.uch-dek { font-family: var(--serif); font-style: italic; font-size: 12px; line-height: 1.4; color: var(--muted); }

/* Tags: the small uppercase labels inside the mocks (PRICING, MOBILITY, RULE…). */
.uch-tag {
  display: inline-flex; align-items: center; font: 700 8px var(--sans); letter-spacing: .6px;
  padding: 2px 5px; border-radius: 4px; background: var(--tan); color: var(--muted); white-space: nowrap;
}
.uch-tag--mint { background: var(--mint-2); color: var(--green); }
.uch-tag--violet { background: var(--pro-bg); color: var(--pro); }
.uch-tag--rust { background: #fdf6f2; color: var(--rust); }
.uch-tag--slate { background: #eef1f6; color: #4a5b78; }

/* Chips: schedule / status pills on the cards themselves. */
.uch-chip { font: 600 11px var(--sans); padding: 4px 9px; border-radius: 999px; background: var(--tan); color: var(--muted); white-space: nowrap; }
.uch-chip--mint { background: var(--mint); color: var(--green); }

/* Emoji tile, tinted per template family so the grid isn't eleven green squares. */
.uch-tile {
  width: 32px; height: 32px; flex: none; border-radius: 10px;
  display: flex; align-items: center; justify-content: center; font-size: 16px;
}
.uch-tile--mint { background: var(--mint); }
.uch-tile--leaf { background: #f2f4e9; }
.uch-tile--slate { background: #eef1f6; }
.uch-tile--sand { background: #f6f0e8; }
.uch-tile--violet { background: var(--pro-bg); }
.uch-tile--paper { background: #f5f2ec; }

/* ── Hero ────────────────────────────────────────────────────────────────── */
/* Centred and column-shaped since 2026-08-27. It used to be a two-column grid
   with a fanned stack of delivery fragments beside the copy; the fan sold the
   OUTPUT, which the eleven cards below already do eleven times over, and it
   cost the hero the width it needed to lay the four families out as one
   countable row. */
.uch-hero { padding-top: 60px; padding-bottom: 8px; max-width: 900px; margin: 0 auto; text-align: center; }
.uch-hero__title {
  font-family: var(--serif); font-weight: 500; font-size: clamp(40px, 5.6vw, 64px);
  line-height: 1.05; letter-spacing: -.7px; margin: 13px 0 18px; text-wrap: balance;
}
/* The rotating verb. `inline-block` so the fade doesn't reflow the line, and
   the transition is on opacity alone — the JS swaps textContent at the bottom
   of the fade, so anything that moved would jump. */
.uch-rotate {
  display: inline-block; font-style: italic; color: var(--rust);
  opacity: 1; transition: opacity .26s ease;
}
.uch-rotate.is-out { opacity: 0; }
.uch-hero__lead { font-size: 16.5px; line-height: 1.65; color: var(--muted); max-width: 580px; margin: 0 auto 34px; }
.uch-hero__fine { font-size: 12px; color: var(--faint); margin-top: 14px; }

/* The four families as the page's table of contents: hairline-ruled cells in
   one row, so the count of them reads at a glance. */
.uch-families {
  display: flex; align-items: stretch;
  border-top: 1.5px solid var(--rule); border-bottom: 1.5px solid var(--rule);
}
.uch-families__item {
  flex: 1; display: flex; flex-direction: column; gap: 3px; align-items: center;
  padding: 18px 10px; color: inherit; text-decoration: none;
  transition: background .15s ease;
}
.uch-families__item + .uch-families__item { border-left: 1.5px solid var(--rule); }
.uch-families__item:hover { background: #f4f8f6; text-decoration: none; color: inherit; }
.uch-families__num { font: 700 10px var(--sans); letter-spacing: 1px; color: var(--faint); }
.uch-families__name { font-family: var(--serif); font-size: 24px; font-weight: 500; line-height: 1.1; }
.uch-families__count { font-size: 11.5px; color: var(--faint); }

/* ── Family sections ─────────────────────────────────────────────────────── */
.uch-family { padding-top: 56px; }
.uch-family__head {
  display: flex; align-items: flex-end; gap: 20px; flex-wrap: wrap;
  margin-bottom: 24px; padding-top: 38px; border-top: 1.5px solid var(--rule);
}
.uch-family__intro { max-width: 640px; }
/* The family name at display size, with the tagline as its subtitle. The
   tagline used to BE the h2 and read as a section of a magazine; the name is
   what the nav, the footer and the hero strip all call this group, and a
   heading that doesn't match its own navigation is a heading you scroll past
   looking for. */
.uch-family__title { font-family: var(--serif); font-weight: 500; font-size: clamp(40px, 6vw, 72px); line-height: 1; letter-spacing: -1px; margin: 5px 0 8px; }
.uch-family__tag { font-family: var(--serif); font-size: clamp(19px, 2.1vw, 22px); font-weight: 400; line-height: 1.35; color: var(--ink); margin: 0 0 11px; text-wrap: balance; }
.uch-family__lead { font-size: 14.5px; line-height: 1.6; color: var(--muted); }
.uch-family__lead em { font-style: italic; font-family: var(--serif); }
.uch-family__note { font-size: 12px; color: var(--faint); padding-bottom: 4px; }

.uch-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

/* ── Cards ───────────────────────────────────────────────────────────────── */
.uch-card {
  display: flex; flex-direction: column; background: #fff; border: var(--edge);
  border-radius: 18px; overflow: hidden; box-shadow: var(--sh-sm);
  text-decoration: none; color: inherit;
  transition: transform .18s cubic-bezier(.2, .6, .2, 1), box-shadow .18s ease, border-color .18s ease;
}
.uch-card:hover { border-color: var(--mint-br); box-shadow: 0 14px 38px rgba(50, 42, 28, .11); transform: translateY(-3px); text-decoration: none; }
.uch-card--feat { grid-column: span 2; }
.uch-card__inner { display: flex; flex-direction: column; height: 100%; }
.uch-card__split { display: grid; grid-template-columns: 1fr 1fr; height: 100%; }
.uch-card__copy { padding: 20px 22px 16px; }
.uch-card--feat .uch-card__copy { padding: 22px 24px; }
.uch-card__top { display: flex; align-items: center; gap: 10px; margin-bottom: 11px; }
.uch-card--feat .uch-card__top { margin-bottom: 12px; }
.uch-card--feat .uch-tile { width: 34px; height: 34px; font-size: 17px; }
.uch-card__label { font: 700 10px var(--sans); letter-spacing: .9px; color: var(--green); }
.uch-card__head { font-family: var(--serif); font-weight: 500; font-size: 21px; line-height: 1.13; margin-bottom: 9px; }
.uch-card--feat .uch-card__head { font-size: 25px; line-height: 1.1; margin-bottom: 10px; }
.uch-card__body { font-size: 13px; line-height: 1.55; color: var(--muted); margin-bottom: 12px; }
.uch-card--feat .uch-card__body { font-size: 13.5px; margin-bottom: 14px; }

/* The switching sentence. Boxed on a featured card, a marked aside on the rest. */
.uch-diff {
  display: flex; align-items: flex-start; gap: 8px; margin-bottom: 16px;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 12px; padding: 11px 13px;
  font-size: 12.5px; line-height: 1.5; color: var(--ink);
}
.uch-diff__mark { color: var(--green); font-size: 14px; line-height: 1.2; }
.uch-diff--inline {
  display: block; background: none; border: none; border-left: 2px solid var(--green);
  border-radius: 0; padding: 0 0 0 10px; margin-bottom: 0; font-size: 12px;
}
.uch-diff em { font-style: italic; }

.uch-card__foot { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
.uch-card--feat .uch-card__foot { margin-top: 2px; }
.uch-card__mockfoot { background: var(--panel); border-top: 1.5px solid var(--line-3); padding: 15px 18px; margin-top: auto; }
.uch-card__mockfoot .uch-card__foot { margin-top: 11px; }
.uch-card__panel {
  background: var(--panel); border-left: 1.5px solid var(--line-3);
  padding: 20px 22px; display: flex; flex-direction: column; justify-content: center;
}
.uch-card__go { font-weight: 600; font-size: 12.5px; color: var(--rust); }
.uch-card--feat .uch-card__go { margin-left: 4px; }

/* ── Mock primitives (used by app/views/marketing/hub_mocks/*) ───────────── */
.uch-mini { background: #fff; border: var(--edge); border-radius: 10px; overflow: hidden; }
.uch-card__panel .uch-mini { border-radius: 12px; }
.uch-mini + .uch-mini { margin-top: 7px; }
.uch-mini--dim { opacity: .72; }
.uch-mini--lift { border-color: var(--mint-br); }
.uch-mini__head { padding: 11px 13px; border-bottom: 1.5px solid var(--line-3); }
.uch-mini__head--paper { background: var(--panel); }
.uch-mini__title { font-family: var(--serif); font-size: 16px; font-weight: 500; }
.uch-mini__body { padding: 11px 13px; display: flex; flex-direction: column; gap: 6px; }

.uch-progress { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.uch-progress__track { flex: 1; height: 6px; border-radius: 999px; background: var(--line-3); overflow: hidden; }
.uch-progress__track i { display: block; height: 100%; width: 38%; background: var(--green); }
.uch-progress__count { font: 600 10px var(--sans); color: var(--faint); }

.uch-linehead { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.uch-linehead__name { font-size: 11.5px; font-weight: 600; color: var(--ink); }
.uch-sets { display: flex; gap: 5px; margin-top: 6px; }
.uch-set { flex: 1; text-align: center; font: 600 10.5px var(--sans); border-radius: 7px; padding: 6px 0; background: #f5f2ec; color: #a49d8d; }
.uch-set.is-done { background: var(--mint-2); color: var(--green); }
.uch-because { font-size: 11px; line-height: 1.5; color: var(--muted); }
.uch-because strong { color: var(--ink); }

/* Nutrition: the week strip. */
.uch-days { display: flex; gap: 5px; margin-bottom: 10px; }
.uch-day { flex: 1; text-align: center; border-radius: 8px; background: #fff; border: var(--edge); padding: 6px 0; }
.uch-day.is-on { background: var(--green); border-color: var(--green); }
.uch-day__dow { display: block; font: 700 8.5px var(--sans); letter-spacing: .6px; color: #a49d8d; }
.uch-day__n { display: block; font: 600 12px var(--sans); color: var(--muted); }
.uch-day.is-on .uch-day__dow { color: rgba(255, 255, 255, .8); }
.uch-day.is-on .uch-day__n { color: #fff; }
.uch-kv { display: flex; justify-content: space-between; font-size: 11.5px; }
.uch-kv--more { color: #a49d8d; }

/* Brief: the layout toggle. */
.uch-toggle { display: flex; gap: 6px; margin-bottom: 10px; }
.uch-toggle__opt {
  font: 700 9px var(--sans); letter-spacing: .7px; border-radius: 7px; padding: 5px 9px;
  background: #fff; border: var(--edge); color: var(--faint);
}
.uch-toggle__opt.is-on { background: var(--green); border-color: var(--green); color: #fff; }
.uch-numbered { display: flex; gap: 7px; font-size: 11.5px; line-height: 1.4; }
.uch-numbered__n { font-family: var(--serif); font-weight: 600; font-size: 12px; color: var(--green); }

/* House hunt: the three numbers, and the rejection reasons. */
.uch-kpis { display: flex; gap: 6px; margin-bottom: 10px; }
.uch-kpi { flex: 1; background: #fff; border: var(--edge); border-radius: 9px; padding: 8px 10px; }
.uch-kpi__v { display: block; font-family: var(--serif); font-size: 19px; font-weight: 500; line-height: 1; }
.uch-kpi__v--accent { color: var(--rust); }
.uch-kpi__l { display: block; font-size: 9.5px; line-height: 1.3; color: var(--faint); }
.uch-fails { display: flex; flex-wrap: wrap; gap: 4px; }
.uch-fail { font: 600 9.5px var(--sans); background: #fdf6f2; color: #b0553a; border: 1px solid #e8d3ca; border-radius: 999px; padding: 3px 7px; }
.uch-meta-pill { font: 600 9.5px var(--sans); background: #f5f2ec; color: var(--faint); border-radius: 999px; padding: 3px 7px; }
.uch-update { font: 600 9.5px var(--sans); color: var(--rust); }

/* Watch: signals, and the honest "quiet" card. */
.uch-signal { display: flex; gap: 6px; align-items: flex-start; font-size: 11px; line-height: 1.4; }
.uch-quiet {
  display: flex; align-items: center; gap: 8px; margin-top: 7px;
  background: #fff; border: 1.5px dashed var(--line); border-radius: 10px; padding: 9px 12px;
}
.uch-alert { background: #fdf6f2; border: 1.5px solid #e8d3ca; border-radius: 10px; padding: 10px 12px; }
.uch-alert__label { font: 700 8.5px var(--sans); letter-spacing: .8px; color: #b0553a; margin-bottom: 5px; }
/* Release Watch's lead card is news, not a warning — a date moving is neutral. */
.uch-alert--mint { background: var(--mint); border-color: var(--mint-br); }
.uch-alert__label--mint { color: var(--green); }
.uch-alert__text { font-size: 11.5px; line-height: 1.45; }
.uch-alert + .uch-mini { margin-top: 7px; }

/* Drafts: skeleton lines stand in for body copy nobody is meant to read. Ragged
   widths on purpose — three equal bars read as a loading state, not a page. */
.uch-skel { display: block; height: 6px; width: 100%; border-radius: 3px; background: var(--line-3); }
.uch-skel--mid { width: 94%; }
.uch-skel--short { width: 84%; }

/* News monitor: the merge diagram. */
.uch-merge__in { display: flex; flex-direction: column; gap: 4px; }
/* The three inbound headlines fade as they go — the eye should land on the merged
   line below them, not read all three. */
.uch-src { display: flex; align-items: center; gap: 7px; background: #fff; border: 1.5px solid var(--line-2); border-radius: 8px; padding: 6px 9px; }
.uch-merge__in .uch-src:nth-child(1) { opacity: .6; }
.uch-merge__in .uch-src:nth-child(2) { opacity: .48; }
.uch-merge__in .uch-src:nth-child(3) { opacity: .36; }
.uch-src__name { font: 700 8.5px var(--sans); color: var(--muted); width: 52px; flex: none; }
.uch-src__line { font-size: 10.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.uch-merge__arrow { display: flex; justify-content: center; margin: 10px 0; }
.uch-merge__out {
  display: flex; gap: 8px; align-items: flex-start;
  background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 11px; padding: 12px 13px;
}
.uch-merge__n { font-family: var(--serif); font-weight: 600; font-size: 13px; color: var(--green); }
.uch-merge__text { font-size: 12px; line-height: 1.45; }

/* ── "Not on the list?" spike + the site's one enquiry form ──────────────── */
.uch-spike { margin-top: 64px; background: var(--green); color: #fff; }
.uch-spike--slim { margin-top: 60px; }
.uch-spike__inner {
  max-width: 1080px; margin: 0 auto; padding: 52px 30px 56px;
  display: grid; grid-template-columns: 1fr 1fr; gap: 40px; align-items: start;
}
.uch-spike__inner--slim { display: flex; flex-wrap: wrap; gap: 30px; align-items: center; padding: 44px 30px 46px; }
.uch-spike__pitch { flex: 1; min-width: 300px; }
.uch-spike__title {
  font-family: var(--serif); font-weight: 500; font-size: clamp(28px, 3.6vw, 42px);
  line-height: 1.06; margin: 9px 0 14px; text-wrap: balance; color: #fff;
}
.uch-spike__title--slim { font-size: clamp(24px, 3vw, 34px); line-height: 1.08; margin-bottom: 10px; }
.uch-spike__lead { font-size: 15.5px; line-height: 1.62; color: #d6e6df; max-width: 560px; }
.uch-spike__inner:not(.uch-spike__inner--slim) .uch-spike__lead { margin-bottom: 18px; }
.uch-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; max-width: 480px; }
.uch-steps li { display: flex; gap: 10px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; color: #e6f0eb; }
.uch-steps__n { color: #a8cfc0; font-size: 13px; flex: none; }
.uch-spike__actions { display: flex; flex-wrap: wrap; gap: 11px; }
.uch-btn {
  display: inline-flex; align-items: center; gap: 8px; font-weight: 600; font-size: 14.5px;
  border-radius: 12px; padding: 14px 22px; text-decoration: none;
}
.uch-btn:hover { text-decoration: none; }
.uch-btn--cream { color: var(--green); background: #fff; }
.uch-btn--cream:hover { background: #f4f1e9; }
.uch-btn--outline { color: #fff; background: rgba(255, 255, 255, .14); border: 1.5px solid rgba(255, 255, 255, .35); }
.uch-btn--outline:hover { background: rgba(255, 255, 255, .22); }

.uch-ask { background: #fff; border-radius: 18px; padding: 24px 24px 22px; box-shadow: 0 16px 48px rgba(20, 40, 33, .25); }
.uch-ask__title { font-family: var(--serif); font-weight: 500; font-size: 20px; color: var(--ink); margin-bottom: 4px; }
.uch-ask__sub { font-size: 12.5px; color: var(--faint); margin-bottom: 16px; }
.uch-ask__from { font-size: 12px; line-height: 1.5; color: var(--green); background: var(--mint); border-radius: 9px; padding: 8px 10px; margin-bottom: 14px; }
.uch-ask__label { display: block; font: 700 10px var(--sans); letter-spacing: .8px; color: var(--muted); margin-bottom: 6px; }
.uch-ask__input {
  width: 100%; box-sizing: border-box; font-family: var(--sans); font-size: 13.5px; line-height: 1.55;
  color: var(--ink); background: var(--panel); border: var(--edge); border-radius: 12px;
  padding: 12px 13px; margin-bottom: 14px; outline: none;
}
.uch-ask__input:focus { border-color: var(--green); box-shadow: 0 0 0 3px rgba(47, 109, 91, .15); }
.uch-ask__textarea { min-height: 104px; resize: vertical; }
.uch-ask__submit {
  display: flex; width: 100%; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--sans); font-weight: 600; font-size: 14.5px; color: #fff; background: var(--green);
  border: none; border-radius: 12px; padding: 14px 20px; margin-top: 2px; cursor: pointer;
  box-shadow: 0 3px 10px rgba(47, 109, 91, .25);
}
.uch-ask__submit:hover { background: var(--green-d); }
.uch-ask__fine { font-size: 11.5px; color: #a49d8d; text-align: center; margin-top: 11px; }
.uch-ask__ico {
  display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  border-radius: 12px; background: var(--mint-2); color: var(--green); margin-bottom: 12px;
}
.uch-ask__ico svg { width: 20px; height: 20px; }
.uch-ask__sent { font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.uch-ask .mkt-form__err { margin-bottom: 14px; }

/* ── Closing CTA ─────────────────────────────────────────────────────────── */
.uch-close { padding-top: 52px; padding-bottom: 60px; text-align: center; }
.uch-close__title { font-family: var(--serif); font-weight: 500; font-size: clamp(26px, 3.4vw, 36px); line-height: 1.08; margin-bottom: 12px; text-wrap: balance; }
.uch-close__lead { font-size: var(--text-lead); line-height: 1.6; color: var(--muted); max-width: 520px; margin: 0 auto 22px; }
.uch-close__fine { font-size: 12.5px; color: var(--faint); margin-top: 14px; }

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 980px) {
  .uch-grid { grid-template-columns: repeat(2, 1fr); }
  .uch-spike__inner { grid-template-columns: 1fr; gap: 28px; }
  /* The dropdown is four columns of eleven links; below this it would run off
     the right edge of the viewport rather than off the edge of the nav. */
  .mkt-drop__sheet { grid-template-columns: repeat(2, minmax(140px, 1fr)); }
}
@media (max-width: 680px) {
  /* iOS Safari zooms the whole page when a focused input is under 16px, which on
     the one form we have reads as the layout jumping away from you mid-sentence.
     The visual size only matters on desktop; on a phone, 16px is the price of the
     page staying still. */
  .uch-ask__input, .mkt-form__input { font-size: 16px; }
  .uch-grid { grid-template-columns: 1fr; }
  .uch-card--feat { grid-column: span 1; }
  .uch-card__split { grid-template-columns: 1fr; }
  .uch-card__panel { border-left: none; border-top: 1.5px solid var(--line-3); }
  .uch-family { padding-top: 44px; }
  .uch-hero { padding-top: 34px; }
  /* Four cells in a row become 2×2 — a strip you have to scroll is not a table
     of contents. */
  .uch-families { flex-wrap: wrap; }
  .uch-families__item { flex: 1 0 50%; }
  .uch-families__item:nth-child(2n) { border-left: 1.5px solid var(--rule); }
  .uch-families__item:nth-child(odd) { border-left: none; }
  .uch-families__item:nth-child(n + 3) { border-top: 1.5px solid var(--rule); }
}

/* ============================================================================
   19. Template page, v2 (/use-cases/:slug) — the .ucp-* family
   ============================================================================
   Ported from Claude Design ("Use Case - Personal Trainer.dc.html" and
   "Use Case - News Monitor.dc.html", 2026-07-26).

   The shared skeleton lives in use_case_v2.html.erb; the middle of each page is
   its own partial under app/views/marketing/uc/. So this section holds (a) the
   page furniture every v2 page uses — crumb, hero, section heads, FAQ, related,
   week strip — and (b) the delivery-card and diagram pieces the individual pages
   build their argument out of. Anything genuinely single-page is grouped and
   labelled as such at the end.
   ------------------------------------------------------------------------- */

/* ── Furniture ───────────────────────────────────────────────────────────── */
.ucp-crumb {
  max-width: 1080px; margin: 0 auto; padding: 14px 30px 0;
  display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--faint);
}
.ucp-crumb a { color: var(--faint); font-weight: 600; }
.ucp-crumb__here { color: var(--muted); font-weight: 600; }

.ucp-section { padding-top: 58px; }
.ucp-head { max-width: 660px; margin-bottom: 24px; }
.ucp-head--wide { max-width: 680px; margin-bottom: 32px; }
.ucp-h1 {
  font-family: var(--serif); font-weight: 500; font-size: clamp(33px, 4.6vw, 54px);
  line-height: 1.03; letter-spacing: -.5px; margin-bottom: 18px; text-wrap: balance;
}
.ucp-h2 {
  font-family: var(--serif); font-weight: 500; font-size: clamp(28px, 3.6vw, 42px);
  line-height: 1.07; margin: 8px 0 12px; text-wrap: balance;
}
.ucp-h2--sm { font-size: clamp(26px, 3.2vw, 38px); line-height: 1.08; }
.ucp-lead { font-size: 15px; line-height: 1.62; color: var(--muted); }
/* The paragraph that says what the thing above it is NOT. Set apart with a rule
   rather than shrunk, because a limit in small print reads as one being hidden. */
.ucp-lead--note { border-left: 2px solid var(--line); padding-left: 14px; }
.ucp-eyebrow { font: 700 9.5px var(--sans); letter-spacing: 1px; color: #a49d8d; margin-bottom: 7px; }
.ucp-eyebrow--green { color: var(--green); }

/* Hero. Centred for a page whose delivery card is the real hero; the two-column
   variant is on the pages that put the delivery beside the pitch. */
.ucp-hero { max-width: 820px; margin: 0 auto; padding: 30px 30px 0; }
.ucp-hero--centred { text-align: center; }
.ucp-hero--split { max-width: 1080px; }
.ucp-hero__grid { display: grid; grid-template-columns: 1.02fr .98fr; gap: 44px; align-items: center; }
.ucp-pill {
  display: inline-flex; align-items: center; gap: 8px; margin-bottom: 18px;
  background: #fff; border: var(--edge); border-radius: 999px; padding: 6px 13px;
}
.ucp-pill__emoji { font-size: 14px; }
.ucp-pill__text { font: 700 10.5px var(--sans); letter-spacing: .8px; color: var(--muted); }
.ucp-hero__lead { font-size: 16.5px; line-height: 1.6; color: var(--muted); margin: 0 auto 22px; max-width: 560px; }
.ucp-hero--split .ucp-hero__lead { margin-left: 0; max-width: 500px; margin-bottom: 14px; }
.ucp-hero__lead2 { font-size: var(--text-body); line-height: 1.6; color: var(--ink); max-width: 500px; margin-bottom: 24px; }
.ucp-hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; }
.ucp-hero--centred .ucp-hero__actions { justify-content: center; }
.ucp-proof { font-size: 12px; color: var(--faint); }
.ucp-proof--row { display: flex; flex-wrap: wrap; gap: 16px; }

/* ── The delivery card ───────────────────────────────────────────────────── */
.ucp-delivery { max-width: 760px; margin: 0 auto; padding: 34px 30px 0; position: relative; }
.ucp-glow {
  position: absolute; inset: 10px 6px -14px; pointer-events: none;
  background: radial-gradient(55% 50% at 50% 25%, rgba(47, 109, 91, .11), transparent 72%);
}
.ucp-card { position: relative; border: var(--edge); border-radius: 20px; background: #fff; overflow: hidden; box-shadow: 0 16px 48px rgba(50, 42, 28, .12); }
.ucp-card__bar {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  padding: 12px 18px; border-bottom: 1.5px solid var(--line-2); background: var(--panel);
}
.ucp-card__ver { font-size: 11px; color: #b6afa0; }
.ucp-card__head { padding: 22px 24px 12px; }
.ucp-card__title { font-family: var(--serif); font-weight: 500; font-size: 28px; line-height: 1.08; margin-bottom: 11px; }
.ucp-card__lead { font-size: var(--text-body-sm); line-height: 1.6; color: var(--muted); margin-bottom: 16px; }
.ucp-card__foot {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 15px 24px; background: var(--panel); border-top: 1.5px solid var(--line-3);
}
.ucp-card__next { font-size: 12.5px; color: var(--muted); }
.ucp-card__next strong { color: var(--ink); }
.ucp-feedback { display: flex; gap: 6px; flex-wrap: wrap; }
.ucp-feedback__chip { font: 600 11px var(--sans); background: #fff; border: var(--edge); border-radius: 999px; padding: 5px 11px; color: var(--muted); }

.ucp-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 18px; }
.ucp-stat { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 11px 12px; }
.ucp-stat__v { display: block; font-family: var(--serif); font-size: 22px; font-weight: 500; line-height: 1; }
.ucp-stat__v--accent { color: var(--rust); }
.ucp-stat__l { display: block; font-size: 10.5px; line-height: 1.3; color: var(--faint); margin-top: 3px; }

.ucp-progress { display: flex; align-items: center; gap: 10px; }
.ucp-progress__track { flex: 1; height: 7px; border-radius: 999px; background: var(--line-3); overflow: hidden; }
.ucp-progress__track i { display: block; height: 100%; width: 38%; background: var(--green); }
.ucp-progress__count { font: 600 11px var(--sans); color: var(--faint); white-space: nowrap; }

/* Blocks: done (collapsed), live (the only one open), upcoming (one line). */
.ucp-blocks { padding: 6px 24px 22px; display: flex; flex-direction: column; gap: 11px; }
.ucp-block { border: 1.5px solid var(--line-2); border-radius: 14px; padding: 14px 16px; }
.ucp-block--done { background: var(--panel); opacity: .72; }
.ucp-block--live { background: #fff; border-color: var(--mint-br); box-shadow: 0 3px 10px rgba(47, 109, 91, .09); padding: 16px 17px; }
.ucp-block--next { display: flex; align-items: center; gap: 10px; padding: 13px 16px; }
.ucp-block__head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-bottom: 8px; }
.ucp-block__name { font-size: var(--text-body-sm); font-weight: 600; }
.ucp-block__meta { font-size: 11.5px; color: var(--faint); }
.ucp-tick {
  width: 20px; height: 20px; flex: none; border-radius: 6px; background: var(--green); color: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 11px;
}
.ucp-moves { display: flex; flex-wrap: wrap; gap: 14px; padding-left: 29px; font-size: 12.5px; color: var(--muted); }
.ucp-moves strong { color: var(--ink); }
.ucp-lift { font-family: var(--serif); font-size: 20px; font-weight: 500; margin: 6px 0 3px; }
.ucp-lift__sub { font-size: 12.5px; color: var(--muted); margin-bottom: 13px; }
.ucp-setgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 7px; margin-bottom: 12px; }
.ucp-setcell { text-align: center; border-radius: 10px; padding: 10px 0; background: var(--panel); border: 1.5px dashed #d9d3c6; }
.ucp-setcell.is-done { background: var(--mint-2); border: 1.5px solid var(--mint-br); }
.ucp-setcell__n { display: block; font: 700 8.5px var(--sans); letter-spacing: .6px; color: #a49d8d; }
.ucp-setcell.is-done .ucp-setcell__n { color: var(--green); opacity: .7; }
.ucp-setcell__v { display: block; font: 600 14px var(--sans); color: #a49d8d; margin-top: 2px; }
.ucp-setcell.is-done .ucp-setcell__v { color: var(--green); }
.ucp-cues { display: flex; flex-direction: column; gap: 6px; padding-top: 12px; border-top: 1px solid var(--line-3); }
.ucp-cue { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.ucp-cue__mark { color: var(--green); font-size: 11px; line-height: 1.5; }
.ucp-fallback {
  display: flex; gap: 8px; align-items: flex-start; margin-top: 3px;
  background: var(--panel); border-radius: 9px; padding: 9px 11px; font-size: 12.5px; line-height: 1.45;
}

/* ── The mechanic band (logged → adapts → arrived) ───────────────────────── */
.ucp-band { margin-top: 66px; background: var(--panel); border-top: var(--edge); border-bottom: var(--edge); padding: 52px 0 56px; }
.ucp-diff { display: grid; grid-template-columns: 1fr 74px 1fr; align-items: center; }
.ucp-diff__card { background: #fff; border: var(--edge); border-radius: 18px; padding: 20px 22px; box-shadow: 0 4px 14px rgba(50, 42, 28, .06); }
.ucp-diff__card--out { border-color: var(--mint-br); box-shadow: 0 10px 30px rgba(47, 109, 91, .12); }
.ucp-diff__title { font-family: var(--serif); font-size: 19px; font-weight: 500; margin-bottom: 12px; }
.ucp-diff__arrow { display: flex; flex-direction: column; align-items: center; gap: 7px; padding: 18px 0; }
.ucp-diff__line { width: 1.5px; height: 26px; background: linear-gradient(var(--line), var(--mint-br)); }
.ucp-diff__foot { font-size: 11.5px; color: #a49d8d; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-3); }
.ucp-logged { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; }
.ucp-logrow { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.ucp-logrow__name { font-size: 12.5px; font-weight: 600; flex: 1; }
.ucp-chip--miss { font: 600 11px var(--sans); background: #fdf6f2; color: #b0553a; border-radius: 999px; padding: 4px 9px; }
.ucp-quote { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 12px 13px; }
.ucp-quote p { font-family: var(--serif); font-style: italic; font-size: var(--text-body-sm); line-height: 1.45; }
.ucp-changes { display: flex; flex-direction: column; gap: 9px; }
.ucp-change { display: flex; gap: 9px; align-items: flex-start; font-size: 13px; line-height: 1.45; }
.ucp-change__mark { color: var(--green); font-weight: 700; font-size: 12px; line-height: 1.5; }

/* ── Anatomy: numbered list + phone ──────────────────────────────────────── */
.ucp-anat { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; align-items: start; }
.ucp-numbers { list-style: none; margin: 20px 0 0; padding: 0; display: flex; flex-direction: column; gap: 13px; }
.ucp-numbers li { display: flex; gap: 12px; align-items: flex-start; }
.ucp-numbers__n {
  width: 26px; height: 26px; flex: none; border-radius: 8px; background: var(--mint); color: var(--green);
  display: flex; align-items: center; justify-content: center; font: 700 11px var(--sans);
}
.ucp-numbers__t { font-size: var(--text-body-sm); font-weight: 600; margin-bottom: 3px; }
.ucp-numbers__b { font-size: 13px; line-height: 1.5; color: var(--muted); }
.ucp-numbers__b em { font-style: italic; }

.ucp-phone { max-width: 330px; margin: 0 auto; background: var(--ink); border-radius: 34px; padding: 9px; box-shadow: 0 20px 54px rgba(50, 42, 28, .22); }
.ucp-phone__screen { background: var(--cream); border-radius: 27px; overflow: hidden; }
.ucp-phone__status { display: flex; align-items: center; justify-content: space-between; padding: 11px 18px 7px; font: 600 10.5px var(--sans); color: var(--muted); }
.ucp-phone__body { padding: 6px 14px 18px; }
.ucp-phone__card { background: #fff; border: var(--edge); border-radius: 16px; overflow: hidden; }
.ucp-phone__head { padding: 13px 15px; border-bottom: 1.5px solid var(--line-3); }
.ucp-phone__lift { font-family: var(--serif); font-size: 17px; font-weight: 500; }
.ucp-phone__now { padding: 15px; text-align: center; }
.ucp-phone__load { font-family: var(--serif); font-size: 44px; font-weight: 500; line-height: 1; color: var(--green); }
.ucp-phone__load span { font-size: 20px; }
.ucp-phone__reps { font-size: 13px; color: var(--muted); margin-top: 5px; }
.ucp-phone__actions { display: flex; gap: 8px; margin-top: 15px; }
.ucp-phone__done { flex: 1; text-align: center; font-weight: 600; font-size: var(--text-body-sm); color: #fff; background: var(--green); border-radius: 12px; padding: 14px 0; }
.ucp-phone__adjust { flex: none; font-weight: 600; font-size: var(--text-body-sm); color: var(--muted); background: var(--panel); border: var(--edge); border-radius: 12px; padding: 14px 16px; }
.ucp-phone__rest { font-size: 11.5px; color: #a49d8d; margin-top: 11px; }
.ucp-phone__cue { padding: 12px 15px; background: var(--panel); border-top: 1.5px solid var(--line-3); font-size: 12px; line-height: 1.45; color: var(--muted); }
.ucp-phonewrap__cap { text-align: center; font-size: 12px; color: var(--faint); margin-top: 14px; }

/* ── The week strip ──────────────────────────────────────────────────────── */
.ucp-week { display: grid; grid-template-columns: repeat(5, 1fr); gap: 11px; }
.ucp-daycard { background: #fff; border: var(--edge); border-radius: 14px; padding: 14px 15px; }
.ucp-daycard--missed { background: var(--panel); border-style: dashed; border-color: #d9d3c6; }
.ucp-daycard--today { border-color: var(--mint-br); box-shadow: 0 3px 10px rgba(47, 109, 91, .1); }
.ucp-daycard__dow { font: 700 9px var(--sans); letter-spacing: .9px; color: #a49d8d; margin-bottom: 7px; }
.ucp-daycard__dow--today { color: var(--green); }
.ucp-daycard__what { font-size: 13.5px; font-weight: 600; margin-bottom: 6px; }
.ucp-daycard--missed .ucp-daycard__what { color: var(--faint); }
.ucp-daytag { font: 600 10px var(--sans); background: var(--tan); color: var(--muted); border-radius: 999px; padding: 3px 8px; }
.ucp-daytag--ok { background: var(--mint-2); color: var(--green); }
.ucp-daytag--flag { background: #fdf6f2; color: #b0553a; }

/* ── Shared page pieces ──────────────────────────────────────────────────────
   Promoted out of individual pages the moment a second one needed them (the rule
   at the top of 19b). Every template page argues its case with some combination
   of: a white panel, a two-column split, a before/after flow, a set of soft
   chips, a row of scores, a rail of cards, and a list of changes. */

/* A white panel to hold a diagram. */
.ucp-box { background: #fff; border: var(--edge); border-radius: 20px; padding: 26px 28px; box-shadow: var(--sh-md); }
.ucp-box--wide { padding: 28px 30px; }
.ucp-two { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; align-items: start; }
.ucp-two--wide { gap: 40px; }
.ucp-two--tight { gap: 20px; }
.ucp-gap { margin-top: 16px; }

/* The flow: inputs on the left, a labelled connector, the result on the right.
   Same shape whether it's five headlines merging into one line, four plates
   rolling up into a shopping list, or twelve listings collapsing to one match. */
.ucp-flow { display: grid; grid-template-columns: 1fr 90px 1fr; align-items: center; }
.ucp-flow--top { align-items: start; }
.ucp-flow__in { display: flex; flex-direction: column; gap: 7px; }
.ucp-flow__tag {
  font: 700 9px var(--sans); letter-spacing: .9px; color: var(--green);
  background: var(--mint-2); border-radius: 999px; padding: 5px 11px; white-space: nowrap;
}

/* Constraint chips — "say it once and it holds": 1,900 kcal, no shellfish, EU
   remote only, two wire services. */
.ucp-chipsbox { background: #fff; border: var(--edge); border-radius: 14px; padding: 16px 18px; margin-top: 20px; }
.ucp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.ucp-chip-soft {
  font: 600 11.5px var(--sans); background: var(--panel); border: 1.5px solid var(--line-2);
  border-radius: 999px; padding: 5px 11px; color: var(--muted);
}

/* Scores: the two or three numbers a mechanic earns. */
.ucp-scores { display: flex; gap: 12px; margin-top: 14px; }
.ucp-score { flex: 1; text-align: center; background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 12px 8px; }
.ucp-score__v { display: block; font-family: var(--serif); font-size: 24px; font-weight: 500; line-height: 1; }
.ucp-score__v--green { color: var(--green); }
.ucp-score__v--sm { font-size: 22px; }
.ucp-score__l { display: block; font-size: 10.5px; color: var(--faint); margin-top: 4px; }

/* A rail of cards: a week, a night, a pipeline. --4 / --5 / --7 set the columns. */
.ucp-rail { display: grid; gap: 12px; }
.ucp-rail--3 { grid-template-columns: repeat(3, 1fr); }
.ucp-rail--4 { grid-template-columns: repeat(4, 1fr); }
.ucp-rail--5 { grid-template-columns: repeat(5, 1fr); }
.ucp-rail--7 { grid-template-columns: repeat(7, 1fr); gap: 9px; }
.ucp-railcard { background: #fff; border: var(--edge); border-radius: 14px; padding: 17px 18px; }
.ucp-rail--7 .ucp-railcard { border-radius: 13px; padding: 12px 13px; }
.ucp-railcard--now { border-color: var(--mint-br); }
.ucp-railcard--done { background: var(--green); border-color: var(--green); color: #fff; }
.ucp-railcard--quiet { background: var(--panel); border-style: dashed; border-color: #d9d3c6; }
.ucp-railcard__t { font: 700 10px var(--sans); letter-spacing: .8px; color: #a49d8d; margin-bottom: 8px; }
.ucp-rail--7 .ucp-railcard__t { font-size: 9px; letter-spacing: .9px; margin-bottom: 6px; }
.ucp-railcard__t--green { color: var(--green); }
.ucp-railcard__t--light { color: #a8cfc0; }
.ucp-railcard__h { font-family: var(--serif); font-size: 17px; font-weight: 500; margin-bottom: 6px; }
.ucp-railcard__b { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.ucp-railcard--done .ucp-railcard__b { color: #d6e6df; }
/* The compact rail says what, not why: a line and a tag. */
.ucp-railcard__what { font-size: 12.5px; font-weight: 600; line-height: 1.3; margin-bottom: 6px; }
.ucp-railcard--quiet .ucp-railcard__what { color: var(--faint); }

/* What changed after a note — the steering payoff, on every template that has one. */
.ucp-changes { display: flex; flex-direction: column; gap: 8px; }
.ucp-change {
  display: flex; gap: 10px; align-items: flex-start; font-size: 13px; line-height: 1.45;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 12px 13px;
}
.ucp-change--up { background: var(--mint); border-color: var(--mint-br); }
.ucp-change--down { background: #fdf6f2; border-color: #e8d3ca; }
.ucp-change__mark { color: var(--green); font-weight: 700; font-size: 13px; line-height: 1.4; }
.ucp-change__mark--down { color: #b0553a; }
.ucp-changes__foot { font-size: 11.5px; color: #a49d8d; margin-top: 12px; }

/* A listed panel: a titled header, rows, an optional footer. Whatever the rows
   are — watched sources, your must-haves, a reject pile — the shape is the same:
   a marker, a name with a note under it, and a status on the right. */
.ucp-panel { background: #fff; border: var(--edge); border-radius: 18px; overflow: hidden; box-shadow: var(--sh-md); }
.ucp-panel__head { display: flex; align-items: center; gap: 9px; padding: 14px 17px; background: var(--panel); border-bottom: 1.5px solid var(--line-3); }
.ucp-panel__title { font: 700 10px var(--sans); letter-spacing: .8px; color: var(--muted); }
.ucp-panel__meta { font-size: 11px; color: #a49d8d; }
.ucp-panel__rows { padding: 6px 0; }
.ucp-panel__foot { display: flex; align-items: center; gap: 8px; padding: 13px 17px; background: var(--panel); border-top: 1.5px solid var(--line-3); }
/* A panel foot holding a SENTENCE rather than a row of chips. The flex row is
   for "MUTED · crypto"; a sentence needs to be a block at note size, or it sits
   in the foot at body size looking like unstyled copy. Job Hunt and Competitor
   Watch each had their own identical copy of this before it was promoted. */
.ucp-panel__foot--note { display: block; font-size: 12px; line-height: 1.5; color: var(--muted); }
.ucp-panel__foot--note strong { color: var(--ink); }
.ucp-panelrow { display: flex; align-items: center; gap: 11px; padding: 12px 17px; border-bottom: 1px solid #f4f0e8; }
.ucp-panelrow--top { align-items: flex-start; }
.ucp-panelrow--last { border-bottom: none; }
.ucp-panelrow__main { flex: 1; min-width: 0; }
.ucp-panelrow__name { font-size: 13px; font-weight: 600; }
.ucp-panelrow--top .ucp-panelrow__name { font-size: 13.5px; margin-bottom: 2px; }
.ucp-panelrow__note { font-size: 11px; color: var(--faint); }
.ucp-panelrow--top .ucp-panelrow__note { font-size: 11.5px; }
.ucp-role { font: 600 10px var(--sans); background: var(--tan); color: var(--muted); border-radius: 999px; padding: 3px 8px; white-space: nowrap; }
.ucp-role--primary { background: var(--mint-2); color: var(--green); }

/* A numbered finding: the serif numeral is the delivery's own voice. */
.ucp-item { display: flex; gap: 9px; align-items: flex-start; font-size: 13.5px; line-height: 1.45; }
.ucp-item__n { font-family: var(--serif); font-weight: 600; font-size: var(--text-body-sm); color: var(--green); }
.ucp-item--lg { font-size: var(--text-body-sm); line-height: 1.5; gap: 10px; margin-bottom: 12px; }
.ucp-item__n--lg { font-size: 16px; }

/* A delivery's own metadata line, and the note it signs off with. */
.ucp-meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 11.5px; color: var(--faint); margin-bottom: 9px; }
.ucp-meta__dot { color: #cbc4b6; }
.ucp-foot { margin-top: 16px; padding-top: 13px; border-top: 1.5px solid var(--line-3); font-size: 11.5px; color: #a49d8d; }

/* A labelled rule: "THE REST, BY SOURCE", "ALSO, BRIEFLY". */
.ucp-divider { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; }
.ucp-divider__label { font: 700 9px var(--sans); letter-spacing: 1px; color: var(--faint); }
.ucp-divider__rule { flex: 1; height: 1.5px; background: #e2ddd0; }

/* Key/value rows inside a mock (ingredient → quantity, field → value). */
.ucp-kv { display: flex; justify-content: space-between; align-items: baseline; font-size: 12px; }
.ucp-kv__note { font-size: 11px; color: var(--muted); }
.ucp-hair { height: 1px; background: var(--mint-br); }

.ucp-h2--xs { font-size: clamp(24px, 2.9vw, 32px); line-height: 1.09; }

/* ── FAQ + related ───────────────────────────────────────────────────────── */
.ucp-faq { display: flex; flex-direction: column; gap: 10px; max-width: 820px; }
.ucp-faq__item { background: #fff; border: var(--edge); border-radius: 13px; }
/* The padding lives on the summary, not the card: with it on the card the tap
   target was the 19px text line and the surrounding whitespace did nothing —
   which on a phone reads as a question that won't open. */
.ucp-faq__item summary {
  padding: 15px 18px; font-size: 14.5px; font-weight: 600; cursor: pointer; list-style: none;
}
.ucp-faq__item summary::-webkit-details-marker { display: none; }
.ucp-faq__item p { padding: 0 18px 15px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

.ucp-rel { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ucp-rel__card {
  display: block; background: #fff; border: var(--edge); border-radius: 16px; padding: 18px 20px;
  text-decoration: none; color: inherit;
  transition: transform .15s cubic-bezier(.2, .6, .2, 1), box-shadow .15s ease, border-color .15s ease;
}
.ucp-rel__card:hover { border-color: var(--mint-br); box-shadow: 0 10px 28px rgba(50, 42, 28, .1); transform: translateY(-2px); text-decoration: none; }
.ucp-rel__top { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
.ucp-rel__emoji { font-size: 16px; }
.ucp-rel__head { font-family: var(--serif); font-size: 19px; font-weight: 500; margin-bottom: 7px; }
.ucp-rel__body { font-size: 13px; line-height: 1.55; color: var(--muted); margin-bottom: 10px; }

/* ── Responsive ──────────────────────────────────────────────────────────── */
@media (max-width: 940px) {
  .ucp-flow { grid-template-columns: 1fr; }
  .ucp-flow .ucp-diff__arrow { padding: 12px 0 14px; }
  .ucp-two, .ucp-two--wide { grid-template-columns: 1fr; gap: 26px; }
  .ucp-rail--3, .ucp-rail--4, .ucp-rail--7 { grid-template-columns: 1fr 1fr; }
  .ucp-diff { grid-template-columns: 1fr; gap: 12px; }
  /* Stacked, the connector becomes a horizontal rule between the two cards —
     centred, and with room to read as a step rather than a stray label. */
  .ucp-diff__arrow { flex-direction: row; justify-content: center; padding: 6px 0 10px; }
  .ucp-diff__line { width: 26px; height: 1.5px; background: linear-gradient(90deg, var(--line), var(--mint-br)); }
  .ucp-anat { grid-template-columns: 1fr; gap: 24px; }
  .ucp-week { grid-template-columns: 1fr 1fr; }
  .ucp-rel { grid-template-columns: 1fr; }
  .ucp-hero__grid { grid-template-columns: 1fr; gap: 26px; }
}
@media (max-width: 620px) {
  .ucp-rail--3, .ucp-rail--4 { grid-template-columns: 1fr; }
  .ucp-box { padding: 20px 18px; }
  .ucp-scores { flex-wrap: wrap; }
  .ucp-stats { grid-template-columns: 1fr 1fr; }
  .ucp-week { grid-template-columns: 1fr; }
  .ucp-card__head, .ucp-blocks { padding-left: 18px; padding-right: 18px; }
  .ucp-card__foot { padding-left: 18px; padding-right: 18px; }
  .ucp-section { padding-top: 44px; }
}

/* ── 19b. News Monitor page only (.nm-*) ─────────────────────────────────────
   Kept apart from the shared .ucp-* furniture on purpose: these are the pieces
   of ONE page's argument (an inbound/outbound merge diagram, a watchlist, an
   overnight timeline). If a second page needs one of them, promote it up into
   .ucp-* rather than aliasing it here. */

/* Hero mock: the delivery, beside the pitch. */
.ucp-heromock { position: relative; }
.ucp-card__head--tight { padding: 20px 22px 22px; }
.ucp-card__title--sm { font-size: 25px; line-height: 1.1; margin-bottom: 16px; }

.nm-top3 { background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 14px; padding: 15px 16px; margin-bottom: 18px; }
.nm-top3 .ucp-eyebrow { margin-bottom: 11px; letter-spacing: .8px; font-size: 10px; }
.nm-top3__list { display: flex; flex-direction: column; gap: 10px; }
.nm-rest { display: flex; flex-direction: column; gap: 9px; }
.nm-rest__row { display: flex; gap: 10px; align-items: flex-start; }
.nm-rest__row--dim { opacity: .7; }
.nm-rest__line { font-size: 13px; line-height: 1.4; flex: 1; }
.nm-src { font: 700 9px var(--sans); letter-spacing: .6px; color: var(--muted); background: var(--tan); border-radius: 4px; padding: 3px 6px; white-space: nowrap; margin-top: 1px; }
.nm-src--mine { color: var(--green); background: var(--mint-2); }
.nm-chev { color: var(--rust); }

/* The merge diagram: what landed → MERGE → what you read. */
.nm-inbound { display: flex; flex-direction: column; gap: 7px; }
.nm-in {
  display: flex; align-items: center; gap: 9px;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 10px; padding: 10px 12px;
}
.nm-in--dup { opacity: .55; }
.nm-in__src { font: 700 9px var(--sans); color: var(--muted); width: 60px; flex: none; }
.nm-in__src--primary { color: var(--ink); }
.nm-in__line { font-size: 12.5px; line-height: 1.35; flex: 1; color: var(--muted); }
.nm-in:first-child .nm-in__line { color: var(--ink); }
.nm-out { background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 14px; padding: 16px 17px; }
.nm-credits { display: flex; flex-wrap: wrap; gap: 6px; }
.nm-credit { font: 600 10.5px var(--sans); background: #fff; border: 1.5px solid var(--mint-br); color: var(--green); border-radius: 999px; padding: 4px 9px; }
.nm-credit--muted { border-color: var(--line); color: var(--faint); }

.nm-avatar {
  width: 30px; height: 30px; flex: none; border-radius: 8px; background: var(--tan);
  display: flex; align-items: center; justify-content: center; font: 700 9px var(--sans); color: var(--muted);
}
.nm-avatar--mine { background: var(--mint-2); color: var(--green); }
.nm-muted-tag { font: 700 9px var(--sans); letter-spacing: .7px; color: #b0553a; background: #fdf6f2; border: 1px solid #e8d3ca; border-radius: 4px; padding: 3px 7px; }
.nm-mutedtext { font-size: 11.5px; color: var(--muted); }

/* ── 19c. Nutrition page only (.nup-*) ────────────────────────────────────── */
.nup-days { display: flex; flex-direction: column; gap: 9px; margin-bottom: 16px; }
/* Today's plate is open; the rest of the week is one line each. */
.nup-day {
  display: flex; align-items: center; gap: 9px;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 12px; padding: 11px 13px;
}
.nup-day--open { display: block; background: var(--mint); border-color: var(--mint-br); padding: 12px 13px; }
.nup-day__what { font-size: 12.5px; flex: 1; }
.nup-day__kcal { font: 600 10px var(--sans); color: var(--faint); }
.nup-meals { display: flex; flex-direction: column; gap: 5px; }
.nup-meal { display: flex; gap: 8px; font-size: 12.5px; line-height: 1.4; }
.nup-meal__slot { color: var(--faint); width: 52px; flex: none; }
.nup-time { font: 600 9.5px var(--sans); background: #fff; border: 1px solid var(--mint-br); color: var(--green); border-radius: 999px; padding: 2px 6px; }

.nup-list { border: var(--edge); border-radius: 12px; overflow: hidden; }
.nup-list__head { display: flex; align-items: center; gap: 8px; padding: 10px 13px; background: var(--panel); border-bottom: 1.5px solid var(--line-3); }
.nup-list__title { font: 700 9px var(--sans); letter-spacing: .9px; color: var(--green); }
.nup-list__meta { font-size: 11px; color: #a49d8d; }
.nup-list__body { padding: 11px 13px; display: flex; flex-direction: column; gap: 6px; }
.nup-list__body .ucp-eyebrow { margin-bottom: 0; font-size: 8.5px; letter-spacing: .9px; }
.nup-aisle { margin-top: 4px; }
.nup-qty { color: var(--faint); }

/* The derivation: plates on the left, each ingredient tagged with its quantity. */
.nup-plate { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 11px; padding: 11px 13px; }
.nup-plate__name { font-size: 13px; font-weight: 600; margin-bottom: 5px; }
.nup-ing { display: flex; flex-wrap: wrap; gap: 5px; }
.nup-ing__item { font-size: 10.5px; background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 3px 8px; color: var(--muted); }
/* A carried-over ingredient is the point of the leftover — mark it as owned. */
.nup-ing__item--carry { background: var(--mint-2); border-color: var(--mint-br); color: var(--green); }

.nup-rollup { background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 14px; padding: 15px 16px; display: flex; flex-direction: column; gap: 8px; }
.nup-rollup__name { font-size: 13px; font-weight: 600; }
.nup-rollup__qty { font-size: 12px; color: var(--green); }

/* ── 19d. Daily Brief page only (.dbp-*) ─────────────────────────────────────
   `dbp` = daily-brief PAGE. Not `.db-*`: the in-app brief reader owns that
   prefix in delivery_template.css, which is loaded on every page including
   marketing — so `.db-tldr` here silently inherited the reader's mint panel and
   `.db-paper` its bordered card. Same-prefix collisions across two stylesheets
   that are both always loaded are invisible until they aren't. */
.dbp-layouts { padding-top: 44px; }
.ucp-head--centred { text-align: center; max-width: 620px; margin-left: auto; margin-right: auto; margin-bottom: 26px; }
.ucp-hero__lead2--centred { margin-left: auto; margin-right: auto; max-width: 540px; }

.dbp-layout { border: var(--edge); border-radius: 18px; background: #fff; overflow: hidden; box-shadow: 0 12px 36px rgba(50, 42, 28, .1); }
/* Layout A is the recommended one, so it carries the green edge. */
.dbp-layout--a { border-color: var(--mint-br); }
.dbp-layout__bar { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; padding: 13px 17px; border-bottom: 1.5px solid var(--line-2); background: var(--mint); }
.dbp-layout__bar--b { background: var(--panel); }
.dbp-layout__name { font: 700 10px var(--sans); letter-spacing: .9px; color: var(--green); }
.dbp-layout__name--b { color: var(--muted); }
.dbp-layout__meta { font-size: 11px; color: var(--muted); }
.dbp-layout__body { padding: 19px 20px 20px; }
.dbp-layout__title { font-family: var(--serif); font-weight: 500; font-size: 21px; line-height: 1.12; margin-bottom: 14px; }
.dbp-tldr { display: flex; flex-direction: column; gap: 10px; margin-bottom: 15px; }
.dbp-also { display: flex; flex-direction: column; gap: 7px; }
.dbp-also__row { display: flex; gap: 8px; align-items: flex-start; font-size: 12.5px; line-height: 1.4; }

/* The front page: a masthead, a real lead column, a side column of shorts. */
.dbp-masthead { text-align: center; padding-bottom: 11px; border-bottom: 2.5px solid var(--ink); margin-bottom: 14px; }
.dbp-masthead__name { font-family: var(--serif); font-weight: 600; font-size: 20px; letter-spacing: .5px; }
.dbp-masthead__date { font-size: 9.5px; color: var(--faint); margin-top: 4px; letter-spacing: .5px; }
.dbp-paper { display: grid; grid-template-columns: 1.25fr .75fr; gap: 18px; }
.dbp-paper__lead { border-right: 1.5px solid var(--line-3); padding-right: 18px; }
.dbp-paper__side { display: flex; flex-direction: column; gap: 12px; }
.dbp-kicker { font: 700 8.5px var(--sans); letter-spacing: 1px; color: var(--rust); margin-bottom: 6px; }
.dbp-headline { font-family: var(--serif); font-weight: 600; font-size: 22px; line-height: 1.08; margin-bottom: 8px; }
.dbp-standfirst { font-family: var(--serif); font-style: italic; font-size: 12.5px; line-height: 1.45; color: var(--muted); margin-bottom: 10px; }
.dbp-body { font-size: 12px; line-height: 1.6; color: var(--ink); margin-bottom: 8px; }
.dbp-body--muted { color: var(--muted); margin-bottom: 0; }
.dbp-sidelabel { font: 700 8.5px var(--sans); letter-spacing: .9px; color: var(--faint); margin-bottom: 5px; }
.dbp-sidehead { font-family: var(--serif); font-weight: 500; font-size: var(--text-body-sm); line-height: 1.2; margin-bottom: 4px; }
.dbp-sidebody { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.dbp-hair { background: var(--line-3); }
.dbp-switch { text-align: center; font-size: 13px; color: var(--muted); margin-top: 18px; }
.dbp-switch__quote { font-family: var(--serif); font-style: italic; }

@media (max-width: 700px) {
  .dbp-paper { grid-template-columns: 1fr; }
  .dbp-paper__lead { border-right: none; padding-right: 0; border-bottom: 1.5px solid var(--line-3); padding-bottom: 14px; }
}

/* ── 19e. House Hunt page only (.hhp-*) ──────────────────────────────────────
   `hhp` = house-hunt PAGE; `.hh-*` belongs to the in-app house-hunt reader. */
.hhp-title { margin-bottom: 5px; }
.hhp-since { font-size: 12.5px; color: var(--faint); margin-bottom: 15px; }

/* The top match: everything checked, and the one thing the listing didn't say. */
.hhp-match { background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 13px; padding: 14px 15px; margin-bottom: 9px; }
.hhp-match__head { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 9px; }
.hhp-match__main { flex: 1; min-width: 0; }
.hhp-match__tags { display: flex; align-items: center; gap: 7px; margin-bottom: 5px; }
.hhp-match__name { font-family: var(--serif); font-size: 17px; font-weight: 500; line-height: 1.15; }
.hhp-match__price { text-align: right; flex: none; }
.hhp-price { font-size: var(--text-body-sm); font-weight: 500; }
.hhp-permsq { font-size: 10.5px; color: var(--muted); }
.hhp-new { font: 600 9.5px var(--sans); color: var(--rust); }
.hhp-verdict { font-size: 12px; line-height: 1.5; color: var(--ink); background: #fff; border-radius: 9px; padding: 9px 11px; }

.hhp-checks { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 9px; }
.hhp-match .hhp-checks:last-of-type { margin-bottom: 9px; }
.hhp-second .hhp-checks { margin-bottom: 0; }
.hhp-check { font: 600 10px var(--sans); background: #fff; border: 1px solid var(--mint-br); color: var(--green); border-radius: 999px; padding: 3px 8px; }
/* Amber = the listing is silent on a must-have. Not a pass, not a rejection —
   a question for the agent. */
.hhp-check--amber { background: #fdf6f2; border-color: #e8d3ca; color: #b0553a; }
.hhp-check--plain { border-color: var(--line); color: var(--faint); }

.hhp-second { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 13px; padding: 12px 14px; margin-bottom: 14px; }
.hhp-second__head { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; }
.hhp-second__name { font-size: 13.5px; font-weight: 600; flex: 1; }
.hhp-second__price { font-size: 12.5px; }

.hhp-rejects { display: flex; flex-direction: column; gap: 6px; }
.hhp-reject { display: flex; align-items: center; gap: 9px; opacity: .68; }
.hhp-reject__name { font-size: 12px; flex: 1; }

/* The funnel: 13 scanned → 8 in band → 2 pass. The bars are fixed illustrative
   proportions, so they live here rather than as inline widths. */
.hhp-panel { background: #fff; border: var(--edge); border-radius: 18px; padding: 20px 22px; box-shadow: 0 4px 14px rgba(50, 42, 28, .06); }
.hhp-panel .ucp-eyebrow { margin-bottom: 14px; }
.hhp-funnel { display: flex; flex-direction: column; gap: 11px; }
.hhp-funnel__row { display: flex; align-items: baseline; gap: 8px; margin-bottom: 5px; }
.hhp-funnel__n { font-size: 19px; font-weight: 500; }
.hhp-funnel__n--pass { color: var(--green); }
.hhp-funnel__l { font-size: 12.5px; color: var(--muted); }
.hhp-bar { height: 9px; border-radius: 999px; background: var(--tan); overflow: hidden; }
.hhp-bar__fill { display: block; height: 100%; }
.hhp-bar__fill--all { width: 100%; background: #d9d3c6; }
.hhp-bar__fill--band { width: 62%; background: #c3bcaa; }
.hhp-bar__fill--pass { width: 16%; background: var(--green); }
.hhp-panel__foot { margin-top: 16px; padding-top: 14px; border-top: 1.5px solid var(--line-3); font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.hhp-em { font-family: var(--serif); font-style: italic; }

.hhp-pile { display: flex; flex-direction: column; gap: 7px; }
.hhp-pilerow {
  display: flex; align-items: center; gap: 10px;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 10px; padding: 10px 12px;
}
.hhp-pilerow__price { font-size: 10.5px; color: var(--faint); }

/* ── 19f. Job Hunt page only (.jhp-*) ────────────────────────────────────── */
.jhp-role { font-family: var(--serif); font-size: 18px; font-weight: 500; line-height: 1.15; margin-bottom: 4px; }
.jhp-role__meta { font-size: 12.5px; color: var(--muted); margin-bottom: 10px; }
.jhp-role__meta--tight { font-size: 12px; margin-bottom: 7px; }
/* The filtered-out counts: the reason, not the postings. */
.jhp-count { font: 600 10px var(--sans); background: #fff; border: 1px solid var(--line); color: var(--faint); border-radius: 999px; padding: 4px 9px; }

/* The ledger: one role's history as four steps, so "reposted twice, held back"
   is visible as a decision the routine made on your behalf. */
.jhp-ledger__head { display: flex; align-items: center; gap: 11px; flex-wrap: wrap; margin-bottom: 6px; }
.jhp-ledger__title { font-family: var(--serif); font-size: 20px; font-weight: 500; }
.jhp-ledger__sub { font-size: 13px; color: var(--muted); margin-bottom: 22px; }
.jhp-ledger { display: grid; grid-template-columns: repeat(4, 1fr); }
.jhp-step { border-left: 2.5px solid var(--line); padding: 0 16px 0 14px; }
/* A green spine marks the two moments it actually spoke to you. */
.jhp-step--on { border-left-color: var(--green); }
.jhp-step--last { padding-right: 0; }
.jhp-step__date { font-size: 10.5px; color: var(--faint); margin-bottom: 6px; }
.jhp-step__date--on { color: var(--green); }
.jhp-step__title { font-size: 13.5px; font-weight: 600; margin-bottom: 6px; }
.jhp-step__body { font-size: 12px; line-height: 1.5; color: var(--muted); margin-bottom: 8px; }
.jhp-tally { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; padding-top: 18px; border-top: 1.5px solid var(--line-3); }
.jhp-tally .ucp-score { min-width: 150px; margin-top: 0; }

/* How one posting was read, requirement by requirement. */
.jhp-mark {
  width: 22px; height: 22px; flex: none; border-radius: 6px; font-size: 12px;
  display: flex; align-items: center; justify-content: center;
}
.jhp-mark--pass { background: var(--mint-2); color: var(--green); }
.jhp-mark--flag { background: #fdf6f2; color: #b0553a; }

@media (max-width: 940px) { .jhp-ledger { grid-template-columns: 1fr 1fr; gap: 18px 0; } }
@media (max-width: 620px) { .jhp-ledger { grid-template-columns: 1fr; gap: 16px; } }

/* ── 19g. Competitor Watch page only (.cwp-*) ────────────────────────────── */
.cwp-delivery { max-width: 1080px; margin: 0 auto; padding: 38px 30px 0; }
.cwp-counts { font-size: 11.5px; color: var(--faint); }
.cwp-summary { font-size: 13px; color: var(--muted); margin-bottom: 18px; }

/* The board: one column per watched company, so "who moved" is spatial. */
.cwp-board { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: start; }
.cwp-co { border: var(--edge); border-radius: 14px; overflow: hidden; }
.cwp-co--moved { border-color: var(--mint-br); }
/* Dashed = still. The card exists precisely to report an absence. */
.cwp-co--quiet { border-style: dashed; border-color: #d9d3c6; background: var(--panel); }
.cwp-co__head { display: flex; align-items: center; gap: 8px; padding: 12px 14px; background: var(--mint); border-bottom: 1.5px solid var(--mint-br); }
.cwp-co__head--plain { background: var(--panel); border-bottom-color: var(--line-3); }
.cwp-co__head--quiet { background: none; border-bottom: 1.5px dashed var(--line); }
.cwp-co__name { font-size: var(--text-body-sm); font-weight: 600; flex: 1; }
.cwp-co__name--quiet { color: var(--muted); }
.cwp-co__badge { font: 700 9px var(--sans); letter-spacing: .6px; background: var(--tan); color: var(--faint); border-radius: 999px; padding: 3px 8px; }
.cwp-co__badge--on { background: var(--green); color: #fff; }
.cwp-co__body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.cwp-move__tags { display: flex; align-items: center; gap: 6px; margin-bottom: 5px; }
.cwp-move__what { font-size: 12.5px; font-weight: 600; line-height: 1.35; margin-bottom: 4px; }
.cwp-move__why { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.cwp-move__why--lg { font-size: 12px; line-height: 1.55; margin-bottom: 9px; }
.cwp-move__src { font-size: 10.5px; color: #a49d8d; margin-top: 5px; }
.cwp-hair { background: var(--line-3); }
.cwp-quietnote { font-size: 11px; color: #a49d8d; line-height: 1.5; }
.cwp-discard { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 18px; padding-top: 15px; border-top: 1.5px solid var(--line-3); }
.cwp-tag--product { background: #f6f0e8; color: #8a6a3a; }

/* Kept vs discarded, side by side — the discarded column is dimmed but present. */
.cwp-panel--kept { border-color: var(--mint-br); box-shadow: 0 10px 30px rgba(47, 109, 91, .1); }
.cwp-panel__head--kept { background: var(--mint); border-bottom-color: var(--mint-br); }
.cwp-panel__title--kept { color: var(--green); }
.cwp-panel__title--dropped { color: var(--faint); }
.cwp-panel__note { font-size: 11px; color: var(--green); }
.cwp-dropped { opacity: .7; }
.cwp-panel--dropped { box-shadow: none; }

/* Quiet is an answer — the one green section on the page. */
.cwp-green { background: var(--green); border-radius: 20px; padding: 34px 34px 32px; color: #fff; }
.cwp-h2--light { color: #fff; }
.cwp-lead--light { font-size: var(--text-body); line-height: 1.62; color: #d6e6df; }
.cwp-meeting { background: rgba(255, 255, 255, .1); border: 1.5px solid rgba(255, 255, 255, .22); border-radius: 16px; padding: 20px 21px; }
.cwp-meeting__label { font: 700 9.5px var(--sans); letter-spacing: .9px; color: #a8cfc0; margin-bottom: 14px; }
.cwp-meeting__list { display: flex; flex-direction: column; gap: 13px; }
.cwp-say { display: flex; gap: 11px; align-items: flex-start; font-size: 13.5px; line-height: 1.5; }
.cwp-say__n { color: #a8cfc0; font-size: 13px; line-height: 1.4; flex: none; }
.cwp-meeting__foot { font-size: 11.5px; color: #a8cfc0; margin-top: 16px; padding-top: 14px; border-top: 1px solid rgba(255, 255, 255, .18); }

@media (max-width: 940px) { .cwp-board { grid-template-columns: 1fr; } }
@media (max-width: 620px) { .cwp-green { padding: 24px 20px; } }

/* ── 19h. Release Watch page only (.rwp-*) ───────────────────────────────────
   `rwp` was the Regulatory Watch page, which this replaced; the classes carried
   over because the shapes did — a lead alert, tagged changes, a clock of dates
   and a provenance chain. The mint variants below are the difference: a release
   date moving is good news or neutral, where a compliance deadline was not. */
.rwp-alert { background: #fdf6f2; border: 1.5px solid #e8d3ca; border-radius: 13px; padding: 14px 15px; margin-bottom: 11px; }
.rwp-alert__head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.rwp-flag { font: 700 8.5px var(--sans); letter-spacing: .8px; background: #b0553a; color: #fff; border-radius: 4px; padding: 3px 7px; }
.rwp-alert__days { font-size: 12px; font-weight: 500; color: #b0553a; }
.rwp-alert__title { font-family: var(--serif); font-size: 17px; font-weight: 500; line-height: 1.15; margin-bottom: 6px; }
.rwp-alert__body { font-size: 12.5px; line-height: 1.5; color: var(--ink); margin-bottom: 9px; }
.rwp-doclink { font: 600 10px var(--sans); background: #fff; border: 1px solid #e8d3ca; color: #b0553a; border-radius: 999px; padding: 4px 9px; }
.rwp-affects { font: 600 9px var(--sans); color: var(--rust); }

.rwp-changes { border: var(--edge); border-radius: 13px; overflow: hidden; margin-bottom: 11px; }
.rwp-change { padding: 11px 13px; border-bottom: 1px solid #f4f0e8; }
.rwp-change--last { border-bottom: none; }
.rwp-change__what { font-size: 13px; font-weight: 600; line-height: 1.35; margin-bottom: 4px; }

/* The clock: every obligation as days-to-go, including the ones that moved and
   the ones already closed (kept for the audit trail). */
.rwp-clock__label { margin-bottom: 18px; }
.rwp-clock { display: flex; flex-direction: column; gap: 11px; }
.rwp-row {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 13px; padding: 14px 16px;
}
.rwp-row--now { background: #fdf6f2; border-color: #e8d3ca; }
.rwp-row--moved { background: var(--mint); border-color: var(--mint-br); }
.rwp-row--done { border-style: dashed; border-color: #d9d3c6; opacity: .75; }
.rwp-count { flex: none; width: 74px; text-align: center; }
.rwp-count__n { display: block; font-size: 22px; font-weight: 500; line-height: 1; }
.rwp-count__n--now { color: #b0553a; }
.rwp-count__n--moved { color: var(--green); }
.rwp-count__n--done { color: var(--faint); }
.rwp-count__l { display: block; font: 700 8.5px var(--sans); letter-spacing: .7px; color: var(--faint); }
.rwp-count__l--now { color: #b0553a; }
.rwp-count__l--moved { color: var(--green); }
.rwp-rule { width: 1.5px; height: 38px; background: var(--line); flex: none; }
.rwp-rule--now { background: #e8d3ca; }
.rwp-rule--moved { background: var(--mint-br); }
.rwp-row__main { flex: 1; min-width: 220px; }
.rwp-row__what { font-size: var(--text-body-sm); font-weight: 600; margin-bottom: 3px; }
.rwp-row__note { font-size: 12px; color: var(--muted); }
.rwp-state { font: 700 9px var(--sans); letter-spacing: .6px; background: var(--tan); color: var(--muted); border-radius: 999px; padding: 4px 9px; flex: none; }
.rwp-state--now { background: #b0553a; color: #fff; }
.rwp-state--moved { background: var(--green); color: #fff; }

/* The provenance chain: document → clause → what it means, in that order, with
   the interpretation visibly separated from the quoted law. */
.rwp-chainbox { padding: 24px 26px; }
.rwp-chain { display: grid; grid-template-columns: repeat(3, 1fr); }
.rwp-chain__step { font: 700 9px var(--sans); letter-spacing: .9px; color: #a49d8d; margin-bottom: 8px; }
.rwp-chain__step--on { color: var(--green); }
.rwp-chain__head { font-family: var(--serif); font-size: 18px; font-weight: 500; line-height: 1.15; margin-bottom: 8px; }
.rwp-chain__body { font-size: 12.5px; line-height: 1.55; color: var(--muted); margin-bottom: 9px; }
.rwp-cite { display: inline-block; font-size: 10.5px; background: var(--panel); border: 1px solid var(--line-2); border-radius: 6px; padding: 4px 8px; color: var(--muted); }
.rwp-caveat { display: inline-block; font: 600 10px var(--sans); background: #fdf6f2; border: 1px solid #e8d3ca; color: #b0553a; border-radius: 999px; padding: 4px 9px; }
.rwp-kind { font-size: 9.5px; background: var(--tan); color: var(--muted); border-radius: 6px; padding: 4px 7px; flex: none; }
.rwp-kind--on { background: var(--mint-2); color: var(--green); }

/* Release Watch's lighter palette: the lead card is an update, not a warning. */
.rwp-alert--mint { background: var(--mint); border-color: var(--mint-br); }
.rwp-flag--mint { background: var(--green); }
.rwp-alert__days--mint { color: var(--green); }
.rwp-doclink--mint { border-color: var(--mint-br); color: var(--green); }
.rwp-caveat--mint { background: var(--mint-2); border-color: var(--mint-br); color: var(--green); }

@media (max-width: 940px) { .rwp-chain { grid-template-columns: 1fr; gap: 18px 0; } }

/* ── 19i. Article page only (.arp-*) ─────────────────────────────────────── */
.arp-hero { max-width: 780px; }
/* The post and its publish drawer, side by side: the drawer is half the
   delivery, not a footnote, so it gets real width. */
.arp-split { display: grid; grid-template-columns: 1.35fr .65fr; }
.arp-post { padding: 26px 30px 28px; }
.arp-title { font-family: var(--serif); font-weight: 600; font-size: 30px; line-height: 1.08; margin: 12px 0 10px; letter-spacing: -.3px; }
.arp-standfirst { font-family: var(--serif); font-style: italic; font-size: 16px; line-height: 1.5; color: var(--muted); margin-bottom: 16px; }
.arp-meta { padding-bottom: 16px; border-bottom: 1.5px solid var(--line-3); margin-bottom: 16px; }
.arp-para { font-family: var(--serif); font-size: 15.5px; line-height: 1.65; margin-bottom: 13px; }
.arp-para--muted { color: var(--muted); }
.arp-h3 { font-family: var(--serif); font-weight: 600; font-size: 19px; line-height: 1.2; margin-bottom: 8px; }
.arp-pull {
  font-family: var(--serif); font-style: italic; font-size: var(--text-body); line-height: 1.55; color: var(--ink);
  border-left: 2.5px solid var(--mint-br); padding: 2px 0 2px 15px; margin-bottom: 13px;
}
.arp-sources { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-top: 18px; padding-top: 14px; border-top: 1.5px solid var(--line-3); }
.arp-source { font: 600 10.5px var(--sans); background: var(--panel); border: 1px solid var(--line-2); color: var(--muted); border-radius: 999px; padding: 4px 9px; }

.arp-drawer { background: var(--panel); border-left: 1.5px solid var(--line-3); padding: 22px 24px; }
.arp-drawer__label { font: 700 9.5px var(--sans); letter-spacing: 1px; color: var(--green); margin-bottom: 6px; }
.arp-drawer__note { font-size: 11.5px; line-height: 1.5; color: var(--faint); margin-bottom: 16px; }
.arp-fields { display: flex; flex-direction: column; gap: 12px; }
.arp-field__label { font: 700 8.5px var(--sans); letter-spacing: .8px; color: #a49d8d; margin-bottom: 5px; }
.arp-field { background: #fff; border: var(--edge); border-radius: 9px; padding: 9px 11px; font-size: 12.5px; }
.arp-field--strong { font-weight: 600; }
.arp-field--mono { font-size: 11.5px; color: var(--muted); }
.arp-field--small { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.arp-cat { font: 600 10.5px var(--sans); background: var(--mint-2); color: var(--green); border-radius: 999px; padding: 4px 9px; }
.arp-tag { font: 600 10.5px var(--sans); background: #fff; border: 1px solid var(--line); color: var(--muted); border-radius: 999px; padding: 4px 9px; }
.arp-hair { display: block; height: 1px; background: var(--line); }
.arp-checks { display: flex; flex-direction: column; gap: 6px; }
.arp-checkrow { display: flex; align-items: center; gap: 8px; font-size: 11.5px; }
.arp-tick { color: var(--green); }
.arp-tick--warn { color: #b0553a; }
/* Not a link — the export lives in the app, and a marketing mock must not
   pretend to be clickable. */
.arp-copy {
  display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 18px;
  font-weight: 600; font-size: 13px; color: #fff; background: var(--green); border-radius: 11px; padding: 12px 16px;
}
.arp-copy__note { font-size: 11px; color: #a49d8d; text-align: center; margin-top: 9px; }

.arp-brief { background: #fff; border: var(--edge); border-radius: 16px; padding: 20px 21px; display: flex; flex-direction: column; gap: 13px; }
.arp-brief__k { font-size: 12.5px; font-weight: 600; margin-bottom: 3px; }
.arp-brief__v { font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.arp-brief__hair { background: var(--line-3); }
.arp-brief__foot { font-size: 12px; line-height: 1.55; color: var(--muted); margin-top: 13px; }

.arp-times { display: flex; flex-direction: column; gap: 9px; }
.arp-time { display: flex; align-items: center; gap: 13px; background: #fff; border: var(--edge); border-radius: 13px; padding: 14px 16px; font-size: 12.5px; line-height: 1.5; }
.arp-time--key { border-color: var(--mint-br); }
.arp-time--left { background: var(--green); border-color: var(--green); color: #fff; }
.arp-time__n { font-size: 17px; font-weight: 500; color: var(--green); width: 52px; flex: none; }
.arp-time__n--light { color: #a8cfc0; }
.arp-proof__cta { margin-top: 18px; margin-bottom: 0; }
.arp-routine { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 16px; padding: 19px 20px; }
.arp-routine__rows { display: flex; flex-direction: column; gap: 9px; }
.arp-routine__row {
  display: flex; align-items: flex-start; gap: 9px; font-size: 12px; line-height: 1.45;
  background: #fff; border: var(--edge); border-radius: 10px; padding: 10px 12px;
}

@media (max-width: 940px) {
  .arp-split { grid-template-columns: 1fr; }
  .arp-drawer { border-left: none; border-top: 1.5px solid var(--line-3); }
}
@media (max-width: 620px) { .arp-post { padding: 20px 18px 22px; } .arp-drawer { padding: 18px; } }

/* ── 19j. Newsletter page only (.nlp-*) ──────────────────────────────────── */
/* The inbox: your issue between two it has to beat. */
.nlp-mail { display: flex; gap: 12px; padding: 14px 17px; border-bottom: 1px solid #f4f0e8; }
.nlp-mail--other { opacity: .42; }
.nlp-mail--yours { background: var(--mint); border-left: 2.5px solid var(--green); }
.nlp-mail--last { border-bottom: none; }
.nlp-avatar { width: 30px; height: 30px; border-radius: 8px; background: var(--tan); flex: none; }
.nlp-avatar--yours {
  background: var(--green); color: #fff; font: 700 11px var(--sans);
  display: flex; align-items: center; justify-content: center;
}
.nlp-mail__fromrow { display: flex; align-items: center; gap: 6px; margin-bottom: 2px; }
.nlp-mail__from { font-size: 12.5px; font-weight: 600; margin-bottom: 2px; }
.nlp-mail__fromrow .nlp-mail__from { margin-bottom: 0; }
.nlp-mail__subject { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nlp-mail__subject--yours { font-size: 12.5px; font-weight: 600; line-height: 1.35; color: var(--ink); white-space: normal; margin-bottom: 3px; }
.nlp-mail__preview { font-size: 11px; color: #a49d8d; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nlp-mail__preview--yours { color: var(--muted); line-height: 1.4; white-space: normal; }
.nlp-drafted { font: 700 8px var(--sans); letter-spacing: .6px; background: var(--mint-2); color: var(--green); border-radius: 3px; padding: 2px 5px; }

/* One routine, two formats, side by side. The STRUCTURE line sits above each
   shape because it is the only thing that differs between them — the page's
   whole argument is that the line, not the layout, decides the issue. */
.nlp-shape { padding: 18px 20px 20px; }
.nlp-shape__title { font-family: var(--serif); font-weight: 600; font-size: 20px; line-height: 1.18; margin-bottom: 12px; }
/* The line breaks are deliberate — it's meant to look like something you typed
   — so the block scrolls inside itself rather than pushing the page sideways on
   a phone (SEO.md invariant 8). */
.nlp-structline {
  font-size: 11px; line-height: 1.6; color: var(--green);
  background: var(--mint); border: 1.5px solid var(--mint-br); border-radius: 10px;
  padding: 9px 11px; margin-bottom: 15px; overflow-x: auto;
}
.nlp-structline--big { font-size: 11.5px; line-height: 1.7; margin-bottom: 12px; }

/* A lead in the tiered shape: heading in the sans, so it reads as a tier rather
   than a chapter of the essay beside it. */
.nlp-lead { margin-bottom: 13px; }
.nlp-lead__h { font: 700 11.5px var(--sans); letter-spacing: .2px; color: var(--ink); margin-bottom: 4px; }

/* The tail. Deliberately compact, and the third row carries no blurb — that is
   a format people ask for, so the page has to show it as intentional. */
.nlp-brieflist { list-style: none; margin: 0; padding: 0; }
.nlp-briefrow { padding: 8px 0; border-bottom: 1px solid var(--line-3); }
.nlp-briefrow:last-child { border-bottom: none; }
.nlp-briefrow__t { display: block; font-size: 12.5px; line-height: 1.4; color: var(--ink); }
.nlp-briefrow__b { display: block; font-size: 11.5px; line-height: 1.45; color: var(--muted); margin-top: 2px; }
.nlp-briefrow--more { font-size: 11px; color: var(--faint); }

.nlp-shapefoot {
  max-width: 760px; margin: 22px auto 0; text-align: center;
  font-size: var(--text-body-sm); line-height: 1.6; color: var(--muted);
}

/* The vocabulary list — what a format may contain, in the words you'd type. */
.nlp-askrow { display: grid; grid-template-columns: 96px 1fr; gap: 12px; padding: 12px 17px; border-bottom: 1px solid var(--line-3); }
.nlp-askrow--last { border-bottom: none; }
.nlp-askrow__k { font: 700 11px var(--sans); letter-spacing: .3px; color: var(--green); padding-top: 2px; }
.nlp-askrow__v { font-size: 12.5px; line-height: 1.55; color: var(--muted); }

.nlp-structcard { background: #fff; border: var(--edge); border-radius: 16px; padding: 18px 20px; }
.nlp-structcard--rules { margin-top: 13px; }
.nlp-structcard__note { font-size: 11.5px; line-height: 1.55; color: var(--muted); }
.arp-para--tight { margin-bottom: 8px; }
.nlp-sectionlabel { color: var(--green); }
.nlp-cite { margin-bottom: 16px; }
.nlp-signoff { margin-top: 20px; padding-top: 15px; border-top: 1.5px solid var(--line-3); font-family: var(--serif); font-style: italic; font-size: var(--text-body-sm); line-height: 1.55; color: var(--muted); }
.nlp-structure { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }
.nlp-slot { display: flex; align-items: center; gap: 9px; background: #fff; border: var(--edge); border-radius: 10px; padding: 9px 11px; }
.nlp-slot__n { font-size: 10px; color: var(--faint); width: 14px; flex: none; }
.nlp-slot__name { font-size: 12px; flex: 1; }
.nlp-slot__len { font-size: 10.5px; color: #a49d8d; }
.nlp-rules { margin: 7px 0 16px; }

@media (max-width: 620px) {
  .nlp-shape { padding: 16px 17px 18px; }
  .nlp-askrow { grid-template-columns: 1fr; gap: 4px; }
  .nlp-structline, .nlp-structline--big { font-size: 10px; }
}

/* ── 19k. Social posts page only (.spp-*) ────────────────────────────────── */
.spp-hero { max-width: 800px; }
.spp-body { padding: 20px 22px 14px; }
.spp-idea { background: var(--panel); border: 1.5px solid var(--line-2); border-radius: 13px; padding: 14px 16px; margin-bottom: 18px; }
.spp-idea__what { font-family: var(--serif); font-size: 19px; font-weight: 500; line-height: 1.2; margin-bottom: 6px; }
.spp-idea__why { font-size: 12.5px; line-height: 1.55; color: var(--muted); }

/* Three drafts side by side, each in its platform's own colour, because the
   point is that they are not the same text. */
.spp-set { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; align-items: start; }
.spp-post { border: var(--edge); border-radius: 14px; overflow: hidden; }
.spp-post--lead { border-color: var(--mint-br); box-shadow: 0 3px 12px rgba(47, 109, 91, .08); }
.spp-post__bar { display: flex; align-items: center; gap: 8px; padding: 11px 14px; border-bottom: var(--edge); }
.spp-post__bar--li { background: #eef1f6; border-bottom-color: #dde3ee; }
.spp-post__bar--x { background: var(--tan); border-bottom-color: var(--line); }
.spp-post__bar--ig { background: var(--pro-bg); border-bottom-color: #e3d9ea; }
.spp-platform { font: 700 9.5px var(--sans); letter-spacing: .7px; color: var(--ink); }
.spp-platform--li { color: #4a5b78; }
.spp-platform--ig { color: var(--pro); }
.spp-platform--tag { border-radius: 4px; padding: 3px 7px; background: var(--tan); }
.spp-platform--tag.spp-platform--li { background: #eef1f6; }
.spp-platform--tag.spp-platform--ig { background: var(--pro-bg); }
.spp-count { font-size: 10.5px; color: var(--muted); }
.spp-count--li { color: #4a5b78; }
.spp-count--ig { color: var(--pro); }
.spp-post__body { padding: 14px 15px; }
.spp-hook { font-size: 13px; font-weight: 600; line-height: 1.4; margin-bottom: 9px; }
.spp-para { font-size: 12px; line-height: 1.6; color: var(--ink); margin-bottom: 8px; }
.spp-para--x { font-size: 12.5px; margin-bottom: 9px; }
.spp-para--muted { color: var(--muted); }
.spp-post__body .spp-para:last-of-type { margin-bottom: 0; }
.spp-notes { display: flex; flex-wrap: wrap; gap: 5px; align-items: center; margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--line-3); }
.spp-imagebrief { background: var(--panel); border: 1.5px dashed #d9d3c6; border-radius: 10px; padding: 20px 12px; text-align: center; margin-bottom: 11px; }
.spp-imagebrief__label { font: 700 9px var(--sans); letter-spacing: .8px; color: #a49d8d; margin-bottom: 4px; }
.spp-imagebrief__text { font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.spp-copy { font: 600 12px var(--sans); color: #fff; background: var(--green); border-radius: 10px; padding: 9px 15px; }

.spp-natives { display: flex; flex-direction: column; gap: 9px; }
.spp-native { background: #fff; border: var(--edge); border-radius: 13px; padding: 14px 16px; }
.spp-native__head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.spp-native__what { font-size: 12.5px; font-weight: 600; }
.spp-native__why { font-size: 12px; line-height: 1.55; color: var(--muted); }

.spp-sources { background: #fff; border: var(--edge); border-radius: 16px; padding: 19px 20px; margin-bottom: 13px; }
.spp-sources__lead { font-size: 13.5px; line-height: 1.6; color: var(--ink); margin-bottom: 12px; }
.spp-sources__list { display: flex; flex-direction: column; gap: 8px; }
.spp-sources__list .ucp-cue { font-size: 12.5px; color: var(--ink); }
/* The refusals, in the attention palette: this is a promise about taste. */
.spp-wont { background: #fdf6f2; border: 1.5px solid #e8d3ca; border-radius: 16px; padding: 17px 19px; }
.spp-wont__label { font: 700 9px var(--sans); letter-spacing: .8px; color: #b0553a; margin-bottom: 7px; }
.spp-wont__body { font-size: 12.5px; line-height: 1.55; color: var(--ink); }

@media (max-width: 940px) { .spp-set { grid-template-columns: 1fr; } }
@media (max-width: 620px) { .spp-body { padding: 18px; } }
/* New-routine wizard — two-step skill browser + configure, inside the app shell. */
/* The 56px is .app-topbar, which lives inside .app-main on desktop, so the
   wizard has to discount it to fill the rest. dvh for the reason in
   app_shell.css. On mobile both halves of that are wrong — see below. */
.nrw { display: flex; flex-direction: column; min-height: calc(100vh - 56px); min-height: calc(100dvh - 56px); }
.nrw-step { display: none; flex: 1; min-height: 0; }
.nrw-step.is-active { display: flex; align-items: stretch; }

/* ── Rail mode (≥901px): viewport-bounded, columns scroll independently ── */
/* Scoped to .nrw--wizard (/routines/new only): edit.html.erb reuses
   .nrw/.nrw-compose for its full-width form and must keep document scroll.
   Fixing the wizard at exactly the space under the top bar makes .app-main's
   content (56px .app-topbar + this) add up to exactly .app-main's own 100dvh,
   so the page-level scroller never moves and each column scrolls by itself.
   The two columns' heights stop depending on each other: the rail is always
   exactly viewport-tall no matter how tall the browse panel's content is, so
   its door (margin-top: auto) sits at the visible foot — and the rail scrolls
   internally if the template list ever outgrows it (once content overflows,
   the door's auto margin resolves to 0 and it simply follows the list).
   Step 2 gets the same treatment via .nrw-compose/.nrw-example so switching
   steps can't reintroduce page scroll.
   Known gap, shared with the min-height above: the admin-only impersonation
   banner adds height above the top bar, so .app-main scrolls by the banner's
   height while impersonating.
   Everything in this block is inert at ≤900px: the rail and browse column are
   display:none there, and compose/example stack in the normal document flow. */
@media (min-width: 901px) {
  .nrw--wizard { height: calc(100vh - 56px); height: calc(100dvh - 56px); overflow: hidden; }
  .nrw--wizard .nrw-rail,
  .nrw--wizard .nrw-browse,
  .nrw--wizard .nrw-compose,
  .nrw--wizard .nrw-example { overflow-y: auto; }
}

/* ---------------- STEP 1: pick ---------------- */
/* Rail width: was a fixed 248px, which truncated most template names/blurbs.
   clamp() widens it only where the row can afford it: 248px stays the floor so
   the tightest rail-mode viewports (just above the 900px cutover) are unchanged,
   28vw reaches ~287px at 1024px, and 300px is the ceiling from ~1072px up.
   Must not exceed 300px: .nrw-browse takes the remainder (viewport minus the
   62px spine minus the rail), and the preview panel's 88px of inner padding
   still needs to leave the example window comfortably wider than its 340px
   URL pill — at 1024px that remainder is 1024−62−287−88 = 587px. */
.nrw-rail { width: clamp(248px, 28vw, 300px); flex: none; border-right: 1.5px solid #e6e1d6; background: #faf8f3; padding: 26px 14px 40px; display: flex; flex-direction: column; }
.nrw-rail__step { font-size: 11px; color: #9a9384; margin-bottom: 2px; }
.nrw-rail__title { font-family: "Newsreader", serif; font-size: 19px; font-weight: 500; margin-bottom: 18px; line-height: 1.2; }
/* Negative top margin tucks the intro under the title (same trick as
   .nrw-hint--field) instead of shrinking the title's own margin. */
.nrw-rail__intro { font-size: 11.5px; line-height: 1.5; color: #9a9384; margin: -12px 0 14px; }
.nrw-rail__label {
   font: 700 10px "Hanken Grotesk";
   letter-spacing: .5px;
   color: #2f6d5b;
   margin: 0 0 9px 4px;
   text-transform: uppercase;
   border-bottom: 1px solid #2f6d5b1f;
   padding-bottom: 8px;
}
.nrw-rail__list { display: flex; flex-direction: column; gap: 3px; }
/* One group per family. The label is the same .nrw-rail__label the whole list
   used to carry once — it moved down a level rather than gaining a twin. */
.nrw-rail__fam { display: flex; flex-direction: column; gap: 3px; }
.nrw-rail__fam + .nrw-rail__fam { margin-top: 11px; }
.nrw-railrow { display: flex; align-items: center; gap: 10px; padding: 8px 9px; border-radius: 10px; cursor: pointer; background: none; border: none; text-align: left; width: 100%; }
.nrw-railrow:hover { background: #f1ede4; }
.nrw-railrow.is-active { background: #eef3f1; box-shadow: inset 0 0 0 1.5px #cfe0d9; }
.nrw-railrow__tile { width: 30px; height: 30px; flex: none; border-radius: 9px; background: #eef4f1; display: flex; align-items: center; justify-content: center; font-size: 15px; }
.nrw-railrow__tile--muted { background: #efece4; color: #9a9384; }
.nrw-railrow__text { min-width: 0; }
.nrw-railrow__name { display: block; font-weight: 600; font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nrw-railrow__short { display: block; font-size: 10.5px; color: #9a9384; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nrw-rail__div { height: 1.5px; background: #ece8df; margin: 14px 4px; }

/* Mobile-only card grid (≤900px) — see the @media block below. Hidden on
   desktop, where the rail + one-at-a-time preview take over instead. */
.nrw-mobile-pick { display: none; padding: 22px 20px 8px; }
.nrw-mobile-pick__step { font-size: 11px; color: #9a9384; margin-bottom: 2px; }
.nrw-mobile-pick__title { font-family: "Newsreader", serif; font-size: 21px; font-weight: 500; margin: 0 0 16px; line-height: 1.2; }
.nrw-mobile-pick__intro { font-size: 12.5px; line-height: 1.5; color: #9a9384; margin: -10px 0 14px; }
/* Same kicker treatment as the rail's label, sitting between the door and
   the grid. */
.nrw-mobile-pick__label { font: 700 10px "Hanken Grotesk"; letter-spacing: .5px; color: #2f6d5b; margin: 0 0 10px; }
.nrw-mobile-pick__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.nrw-mobile-pick__grid + .nrw-mobile-pick__label { margin-top: 22px; }
.nrw-mobile-card { display: flex; flex-direction: column; align-items: flex-start; text-align: left; gap: 4px; padding: 18px; }
.nrw-mobile-card__icon { width: 44px; height: 44px; border-radius: var(--radius-md); background: var(--primary-tint); border: 1.5px solid var(--primary-border); display: flex; align-items: center; justify-content: center; font-size: 21px; margin-bottom: 8px; }
.nrw-mobile-card__name { font-weight: 600; font-size: 14px; color: #26221b; line-height: 1.3; }
.nrw-mobile-card__desc { font-size: 12px; color: #857f70; line-height: 1.45; }
.nrw-mobile-pick__blank { display: block; width: 100%; text-align: center; margin-top: 14px; background: none; border: none; font: 600 12.5px "Hanken Grotesk"; color: var(--accent); cursor: pointer; padding: 8px; }

/* ---------------- the door to the recipes library ---------------- */
/* One card (rendered by _wizard_door.html.erb) at the BOTTOM of both Step 1
   layouts, after the Custom/blank entry, whole thing a link to /recipes.
   Always present — no recipe count involved anywhere, so nothing here can go
   stale. Hover lift matches .nrw-recipes__card so the two recipe surfaces
   read as one family. In the rail, margin-top:auto pins it to the rail's
   foot (the slot "More templates soon" used to occupy). */
.nrw-door {
  display: flex; align-items: center; gap: 11px; padding: 13px 14px;
  background: #fff; border: 1.5px solid #e6e1d6; border-radius: 14px;
  box-shadow: 0 1px 3px rgba(50,42,28,.05); text-decoration: none;
  margin-top: 16px;
  transition: transform var(--dur-fast), box-shadow var(--dur-fast), border-color var(--dur-fast);
}
/* The door sits at the FOOT of the rail, on the free space left under the list.
   That works right up until there is no free space: the family headings made the
   list taller, `auto` resolved to 0, and the card butted straight up against
   Custom. The floor below is a margin `auto` cannot eat — Custom is the rail's
   only direct .nrw-railrow child (every other row lives inside .nrw-rail__fam),
   so this reaches it without a class of its own. */
.nrw-rail .nrw-door { margin-top: auto; }
.nrw-rail > .nrw-railrow { margin-bottom: 20px; }
.nrw-door:hover { transform: translateY(-2px); border-color: #cfe0d9; box-shadow: 0 4px 16px rgba(50,42,28,.08); text-decoration: none; }
.nrw-door__tile { width: 34px; height: 34px; flex: none; border-radius: 10px; background: #f6efe7; display: flex; align-items: center; justify-content: center; font-size: 16px; }
.nrw-door__text { flex: 1; min-width: 0; }
.nrw-door__title { display: block; font-family: "Newsreader", serif; font-size: 15px; font-weight: 500; line-height: 1.25; color: #26221b; }
.nrw-door__sub { display: block; font-size: 11px; line-height: 1.45; color: #9a9384; margin-top: 3px; }
.nrw-door__arrow { flex: none; font: 600 15px "Hanken Grotesk"; color: var(--accent); }

.nrw-browse { flex: 1; min-width: 0; background: #fbfaf7; display: flex; flex-direction: column; }
.nrw-panel { display: none; flex: 1; min-width: 0; flex-direction: column; }
.nrw-panel.is-active { display: flex; }
.nrw-panel__inner { flex: 1; display: flex; flex-direction: column; padding: 40px 44px 28px; max-width: 760px; width: 100%; margin: 0 auto; }
.nrw-panel__head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.nrw-panel__tile { width: 52px; height: 52px; flex: none; border-radius: 14px; background: #eef4f1; display: flex; align-items: center; justify-content: center; font-size: 26px; }
.nrw-panel__cat { font-size: 12px; color: #9a9384; margin-bottom: 2px; }
.nrw-panel__name { font-family: "Newsreader", serif; font-weight: 500; font-size: 28px; margin: 0; line-height: 1.1; }
.nrw-panel__desc { font-size: 14px; line-height: 1.6; color: #3a352c; margin: 0 0 8px; }
.nrw-panel__get { border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 12px; padding: 11px 14px; margin-bottom: 20px; font-size: 12.5px; line-height: 1.5; color: #2f6d5b; }
.nrw-panel__get strong { font-weight: 700; }

.nrw-window { flex: 1; border: 1.5px solid #d9d3c7; border-radius: 14px; background: #fff; overflow: hidden; display: flex; flex-direction: column; box-shadow: 0 12px 34px rgba(50,42,28,.12); }
.nrw-window__chrome { display: flex; align-items: center; gap: 10px; padding: 9px 13px; border-bottom: 1.5px solid #ece8df; background: #f1ede4; }
.nrw-window__dots { display: flex; gap: 6px; flex: none; }
.nrw-window__dots i { width: 11px; height: 11px; border-radius: 50%; }
.nrw-window__dots i:nth-child(1) { background: #e5a19a; }
.nrw-window__dots i:nth-child(2) { background: #e6cf9a; }
.nrw-window__dots i:nth-child(3) { background: #a9cbb2; }
.nrw-window__url { flex: 1; text-align: center; max-width: 340px; margin: 0 auto; background: #fff; border: 1.5px solid #e6e1d6; border-radius: 8px; padding: 4px 11px; font: 600 10.5px "Hanken Grotesk"; color: #9a9384; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nrw-window__badge { font: 700 8.5px "Hanken Grotesk"; letter-spacing: .4px; color: #9a9384; flex: none; background: #e6e1d6; padding: 3px 7px; border-radius: 5px; }
.nrw-window__doc { padding: 22px 24px; flex: 1; overflow: auto; }

.nrw-actionbar { border-top: 1.5px solid #e6e1d6; background: #fbfaf7; padding: 15px 44px; display: flex; align-items: center; gap: 14px; }
/* On any reasonably tall window, keep the "Use …" action pinned to the bottom so
   it's always visible however tall the preview grows. Skipped on short windows. */
@media (min-height: 620px) {
  .nrw-actionbar { position: sticky; bottom: 0; z-index: 5; box-shadow: 0 -7px 20px rgba(50,42,28,.07); }
}
.nrw-use { padding: 12px 22px; border: none; border-radius: 11px; background: #2f6d5b; color: #fff; font: 600 13.5px "Hanken Grotesk"; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.nrw-use:hover { background: #28604f; }
.nrw-actionbar__spacer { flex: 1; }
.nrw-actionbar__pos { font-size: 12px; color: #9a9384; }
.nrw-arrow { width: 36px; height: 36px; border-radius: 10px; border: 1.5px solid #e6e1d6; background: #fff; display: flex; align-items: center; justify-content: center; color: #6f6a5e; cursor: pointer; font-size: 18px; }
.nrw-arrow:hover { border-color: #cfe0d9; }

/* ---------------- recipes for the template in view ---------------- */
/* Under the example window: up to two published recipes for the panel's skill,
   each one whole link into the ?recipe= prefill. When a skill has none the
   section is absent entirely (see _wizard_recipes.html.erb) — no empty state
   to style. */
.nrw-recipes { margin-top: 24px; }
.nrw-recipes__head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 7px; }
.nrw-recipes__kicker { font: 700 10px "Hanken Grotesk"; letter-spacing: .5px; color: #2f6d5b; }
.nrw-recipes__all { margin-left: auto; font: 600 12px "Hanken Grotesk"; color: var(--accent); text-decoration: none; white-space: nowrap; }
.nrw-recipes__all:hover { text-decoration: underline; }
.nrw-recipes__intro { font-size: 12px; line-height: 1.5; color: #9a9384; margin: 0 0 12px; }
/* auto-fit so the pair sits side by side in the 760px panel and stacks on its
   own when the panel narrows — no breakpoint to keep in sync with the rail's. */
.nrw-recipes__grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.nrw-recipes__card {
  display: flex; flex-direction: column; gap: 7px; padding: 15px 16px;
  background: #fff; border: 1.5px solid #e6e1d6; border-radius: 13px;
  box-shadow: 0 1px 3px rgba(50,42,28,.05); text-decoration: none;
  transition: transform var(--dur-fast), box-shadow var(--dur-fast), border-color var(--dur-fast);
}
.nrw-recipes__card:hover { transform: translateY(-2px); border-color: #cfe0d9; box-shadow: 0 4px 16px rgba(50,42,28,.08); text-decoration: none; }
.nrw-recipes__title { font-family: "Newsreader", serif; font-size: 15.5px; font-weight: 500; line-height: 1.25; color: #26221b; }
.nrw-recipes__quote { font-family: "Newsreader", serif; font-style: italic; font-size: 12.5px; line-height: 1.55; color: #6f6a5e; }
.nrw-recipes__meta { font: 600 11px "Hanken Grotesk"; color: #9a9384; margin-top: auto; }

/* ---------------- shared sample doc ---------------- */
.nrw-doc { display: flex; flex-direction: column; gap: 13px; }
.nrw-doc__meta { font: 600 10.5px "Hanken Grotesk"; letter-spacing: .3px; color: #a49d8d; }
.nrw-doc__title { font-family: "Newsreader", serif; font-size: 22px; font-weight: 500; line-height: 1.15; margin-top: -4px; }
.nrw-doc__lead { font-size: 13px; line-height: 1.55; color: #6f6a5e; }
.nrw-doc__stats { display: flex; gap: 9px; }
.nrw-doc__stat { flex: 1; border: 1.5px solid #f0ece3; border-radius: 10px; padding: 10px 12px; background: #faf8f3; }
.nrw-doc__statv { font-family: "Newsreader", serif; font-size: 22px; font-weight: 500; color: #2f6d5b; line-height: 1; }
.nrw-doc__statl { font-size: 10.5px; color: #9a9384; margin-top: 4px; line-height: 1.35; }
.nrw-doc__rule { height: 1px; background: #f0ece3; }
.nrw-doc__row { display: flex; align-items: flex-start; gap: 11px; }
.nrw-doc__k { width: 20px; height: 20px; flex: none; border-radius: 6px; background: #eef4f1; color: #2f6d5b; display: flex; align-items: center; justify-content: center; font: 700 10px "Hanken Grotesk"; margin-top: 1px; }
.nrw-doc__rmain { flex: 1; min-width: 0; }
.nrw-doc__t { font-weight: 600; font-size: 13px; color: #26221b; }
.nrw-doc__s { font-size: 12px; color: #6f6a5e; line-height: 1.5; margin-top: 2px; }
.nrw-doc__m { font: 600 12.5px "Hanken Grotesk"; color: #26221b; flex: none; }
.nrw-doc__foot { border-top: 1.5px solid #f0ece3; padding-top: 11px; font-size: 12px; line-height: 1.5; color: #6f6a5e; }
.nrw-doc__foot strong { color: #3a352c; font-weight: 600; }

/* ---------------- STEP 2: config ---------------- */
.nrw-step--config.is-active { align-items: stretch; }
.nrw-config { display: flex; flex: 1; min-width: 0; width: 100%; }
.nrw-compose { flex: 1; min-width: 0; background: #f4f1ea; padding: 30px 34px 60px; display: flex; flex-direction: column; }
.nrw-back { align-self: flex-start; background: none; border: none; cursor: pointer; font: 600 12px "Hanken Grotesk"; color: #6f6a5e; margin-bottom: 18px; padding: 0; }
.nrw-back:hover { color: #2f6d5b; }
.nrw-compose__head { display: flex; align-items: center; gap: 13px; margin-bottom: 14px; }
.nrw-compose__tile { width: 44px; height: 44px; flex: none; border-radius: 12px; background: #eef4f1; display: flex; align-items: center; justify-content: center; font-size: 22px; }
.nrw-compose__cat { font-size: 12px; color: #9a9384; }
.nrw-compose__name { font-family: "Newsreader", serif; font-weight: 500; font-size: 24px; margin: 1px 0 0; }

/* Edit reuses the compose column full-width (no example pane, no picker). */
.nrw-compose--full { margin: 0 auto; width: 100%; max-width: 720px; padding-top: 34px; }
.nrw-compose__headtext { flex: 1; min-width: 0; }
.nrw-runbtn { flex: none; background: #fff; border: 1.5px solid #e6e1d6; border-radius: 10px; padding: 9px 13px; font: 600 12.5px "Hanken Grotesk"; color: #2f6d5b; cursor: pointer; }
.nrw-runbtn:hover { border-color: #cfe0d9; background: #f4f8f6; }
.nrw-headactions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 22px; }
.nrw-runbtn--resume { color: #fff; background: #2f6d5b; border-color: #2f6d5b; }
.nrw-runbtn--resume:hover { color: #fff; background: #28604f; border-color: #28604f; }
/* Transparent status right in the edit header. */
.nrw-status { display: inline-flex; align-items: center; gap: 5px; font-weight: 700; }
.nrw-status__dot { width: 7px; height: 7px; border-radius: 50%; }
.nrw-status--active { color: #2f6d5b; }
.nrw-status--active .nrw-status__dot { background: #2f6d5b; }
.nrw-status--paused { color: #b08a2e; }
.nrw-status--paused .nrw-status__dot { background: #d4a53a; }
/* Block, not flex: the note is one flowing sentence with inline <strong>s and
   a link — flex turned every text node into its own column (the "banner looks
   bad" bug, 2026-08-06). */
.nrw-pausednote { display: block; background: #fdf7ea; border: 1.5px solid #ecdcae; border-radius: 12px; padding: 11px 14px; font-size: 13px; line-height: 1.5; color: #6f5b2e; margin: -8px 0 22px; }
.nrw-pausednote strong { color: #5a4a24; }
/* base.css strips link affordance app-wide (color:inherit, no underline), so
   the note's "See plans"/"Subscribe" read as plain text — the one action in
   the banner must look clickable. */
.nrw-pausednote a { color: var(--accent); font-weight: 600; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
.nrw-pausednote a:hover { color: #8f3f28; }
/* Same amber as the paused note — it is the same kind of message (this will
   not run yet, and here is what to do about it), said before the work
   instead of after it. */
.nrw-capnote { background: #fdf7ea; border: 1.5px solid #ecdcae; border-radius: 12px; padding: 11px 14px; font-size: 13px; line-height: 1.55; color: #6f5b2e; margin: 0 0 20px; }
.nrw-capnote strong { display: block; color: #5a4a24; margin-bottom: 2px; }
.nrw-capnote a { color: #8a6420; font-weight: 600; }
/* Opt-in delivery-email checkbox. */
.nrw-check { display: flex; align-items: flex-start; gap: 11px; margin: 4px 0 28px; cursor: pointer; }
.nrw-check input[type="checkbox"] { width: 18px; height: 18px; margin: 1px 0 0; flex: none; accent-color: #2f6d5b; cursor: pointer; }
.nrw-check__text { font-size: 13.5px; color: #3a352c; line-height: 1.4; }
.nrw-check__sub { display: block; font-size: 12px; color: #9a9384; margin-top: 2px; }

/* "Where deliveries go" — the channel list (design: Webhooks Flow §2). The
   rows sit tighter than a lone checkbox did, because they are now a list. */
.nrw-check + .nrw-check { margin-top: -20px; }
.nrw-check__sub .mono { font-size: 11.5px; }

/* A paused webhook. Disabled AND explained: it unticks itself and says why,
   with a link that fixes it, rather than silently stopping. */
.nrw-check--off { opacity: .62; cursor: default; }
.nrw-check--off input[type="checkbox"] { cursor: default; }

/* The locked row on Personal. A <button>, not a checkbox — a checkbox that
   refuses to tick is a bug the user has to test to discover. */
.nrw-check--locked {
  width: 100%; text-align: left; background: none; border: none; padding: 0;
  font: inherit; cursor: pointer;
}
.nrw-check__lock { flex: none; font-size: 13px; line-height: 1.4; margin-top: 1px; }
.nrw-check--locked .nrw-check__text { color: #6f6a5e; }
.nrw-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 560px) { .nrw-grid2 { grid-template-columns: 1fr; } }

/* "What joris remembers" — folded-in feedback, each removable. */
.nrw-mem { margin-top: 34px; padding-top: 26px; border-top: 1.5px solid #e6e1d6; }
.nrw-mem__head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 12px; }
.nrw-mem__note { font-size: 11.5px; color: #9a9384; }
.nrw-mem__list { display: flex; flex-direction: column; gap: 8px; margin-bottom: 12px; }
.nrw-mem__item { display: flex; align-items: flex-start; gap: 10px; padding: 11px 13px; border: 1.5px solid #e6e1d6; border-radius: 12px; background: #fbfaf7; }
.nrw-mem__ver { flex: none; font: 600 10.5px "Hanken Grotesk"; letter-spacing: .3px; color: #6f6a5e; background: #f1ede4; border-radius: 6px; padding: 3px 7px; margin-top: 1px; }
.nrw-mem__text { flex: 1; min-width: 0; font-size: 12.5px; line-height: 1.55; color: #3a352c; white-space: pre-wrap; word-break: break-word; }
.nrw-mem__rm { flex: none; background: none; border: none; cursor: pointer; font: 600 11.5px "Hanken Grotesk"; color: #b45b3e; padding: 0; }
.nrw-mem__rm:hover { text-decoration: underline; }
.nrw-mem__empty { font-size: 12.5px; line-height: 1.6; color: #9a9384; margin: 0; }

/* Danger zone. Tinted rather than shouting: the confirm dialog is what actually
   stops a misclick, so this only has to read as "different from everything
   above it" — matching the account-closure block in settings.css. */
.nrw-danger {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  margin-top: 26px; padding: 16px 18px;
  border: 1.5px solid var(--danger-border); border-radius: 14px;
  background: var(--danger-tint);
}
.nrw-danger__main { flex: 1; min-width: 220px; }
.nrw-danger__title { font-size: 13px; font-weight: 600; color: var(--danger-press); margin-bottom: 3px; }
.nrw-danger__sub { font-size: 12px; line-height: 1.55; color: #6f6a5e; }
.nrw-danger__btn { flex: none; }

.nrw-lbl { display: block; font-size: 12px; font-weight: 600; color: #6f6a5e; margin: 0 0 7px; }
.nrw-lbl--inline { margin: 0; }
.nrw-input, .nrw-textarea { width: 100%; padding: 12px 14px; border: 1.5px solid #e6e1d6; border-radius: 12px; font: 400 13px/1.65 "Hanken Grotesk"; color: #3a352c; outline: none; background: #fff; box-shadow: 0 1px 3px rgba(50,42,28,.05); margin-bottom: 6px; }
.nrw-input:focus, .nrw-textarea:focus { border-color: #cfe0d9; }
.nrw-input { margin-bottom: 18px; }
.nrw-textarea { min-height: 220px; resize: vertical; white-space: pre-wrap; }
.nrw-hint { font-size: 11.5px; color: #9a9384; margin-bottom: 18px; line-height: 1.5; }
/* base.css makes every anchor inherit its colour with no underline, so a link
   inside a hint ("change it in your profile", "Fix it") read as plain text. */
.nrw-hint a, .nrw-check__sub a { color: #2f6d5b; border-bottom: 1px solid #cfe0d9; }
.nrw-hint a:hover, .nrw-check__sub a:hover { color: #b45b3e; border-bottom-color: #b45b3e; }
/* Sits between a label and its field, so it is read before writing rather
   than after. Tighter than the standalone hint, and it must not push the
   field away from its label. */
.nrw-hint--field { margin: -3px 0 8px; }

/* Character counter, created by char_count.js next to any textarea carrying
   data-maxlen (the Direction, every feedback box). Hidden until close to the
   limit — a ceiling nobody is near is noise. */
.charcount { font-size: 11.5px; color: #9a9384; margin: -8px 0 12px; text-align: right; }
.charcount.is-over { color: #a3564c; font-weight: 600; }

.nrw-toolshead { display: flex; align-items: baseline; gap: 8px; margin-bottom: 9px; }
.nrw-toolshead__note { font-size: 11.5px; color: #9a9384; }
.nrw-tools { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }
.nrw-tool { display: inline-flex; align-items: center; gap: 8px; padding: 9px 12px; border-radius: 11px; border: 1.5px solid #e6e1d6; background: #fff; cursor: pointer; }
.nrw-tool__icon { font-size: 13px; }
.nrw-tool__label { font-weight: 600; font-size: 12.5px; }
.nrw-tool__check { width: 20px; height: 20px; border-radius: 6px; background: #f1ede4; color: #9a9384; display: flex; align-items: center; justify-content: center; font: 700 11px "Hanken Grotesk"; }
.nrw-tool.is-on { border-color: #cfe0d9; background: #f4f8f6; }
.nrw-tool.is-on .nrw-tool__check { background: #2f6d5b; color: #fff; }
.nrw-tool--soon { cursor: default; opacity: .75; }
.nrw-tool__pro { font: 700 9px "Hanken Grotesk"; letter-spacing: .3px; color: #9a9384; background: #f1ede4; padding: 2px 6px; border-radius: 5px; }

.nrw-select { position: relative; margin-bottom: 22px; }
.nrw-select select { width: 100%; }

/* Rich schedule editor (shared partial). */
.sch [data-sch-row] { margin-bottom: 2px; }
.sch .nrw-input.mono { font-family: "IBM Plex Mono", ui-monospace, Menlo, Consolas, monospace; font-size: 12.5px; letter-spacing: .2px; }
.sch-trans { margin: -12px 0 18px; font-size: 12px; line-height: 1.5; color: #9a9384; }
.sch-trans--ok { color: #2f6d5b; font-weight: 600; }
.sch-trans--bad { color: #b45b3e; }

.nrw-static { padding: 11px 13px; border: 1.5px solid #e6e1d6; border-radius: 11px; font-size: 12.5px; line-height: 1.5; color: #6f6a5e; background: #faf8f3; margin-bottom: 22px; }
.nrw-static strong { color: #2f6d5b; font-weight: 700; }
.nrw-schedule { display: flex; align-items: center; gap: 8px; padding: 11px 13px; border: 1.5px solid #e6e1d6; border-radius: 11px; font-size: 13px; color: #26221b; background: #fff; margin-bottom: 24px; }
.nrw-schedule__spacer { flex: 1; }
.nrw-schedule__change { font-size: 11.5px; color: #2f6d5b; font-weight: 600; }

.nrw-submit { width: 100%; padding: 14px; border: none; border-radius: 12px; background: #2f6d5b; color: #fff; font: 600 14px "Hanken Grotesk"; cursor: pointer; box-shadow: 0 3px 10px rgba(47,109,91,.25); }
.nrw-submit:hover { background: #28604f; }
.nrw-errors { margin-bottom: 14px; }

.nrw-example { flex: 1; min-width: 0; background: #fbfaf7; border-left: 1.5px solid #e6e1d6; padding: 30px 34px 60px; display: flex; flex-direction: column; gap: 16px; }
.nrw-example__get { border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 12px; padding: 11px 14px; font-size: 12.5px; line-height: 1.5; color: #2f6d5b; }
.nrw-example__get strong { font-weight: 700; }
.nrw-example__card { border: 1.5px solid #e6e1d6; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 16px rgba(50,42,28,.05); background: #fff; }
.nrw-example__head { display: flex; align-items: center; gap: 10px; padding: 11px 15px; background: #faf8f3; border-bottom: 1.5px solid #f0ece3; }
.nrw-example__titles { flex: 1; }
.nrw-example__t { font-weight: 600; font-size: 12.5px; }
.nrw-example__s { font-size: 11px; color: #9a9384; }
.nrw-example__badge { font: 600 9.5px "Hanken Grotesk"; letter-spacing: .4px; padding: 3px 8px; border-radius: 6px; background: #f1ede4; color: #9a9384; }
.nrw-example__doc { display: none; }
.nrw-example__doc.is-active { display: block; }

/* Live template previews: render the real partial, scaled to fit the surface. */
.nrw-preview { zoom: .8; }
.nrw-preview .tr, .nrw-preview .nu, .nrw-preview .db, .nrw-preview .hh { max-width: none; margin: 0; }
.nrw-preview .hh-layout { display: block; }   /* drop the sticky side-nav column */
.nrw-preview .hh-nav { display: none; }
.nrw-window__doc .nrw-preview { padding: 4px; }
.nrw-example__doc .nrw-preview { padding: 18px 20px; }
.nrw-example__doc .nrw-doc { padding: 18px 20px; } /* Custom (no template) fallback */
@supports not (zoom: 1) { .nrw-preview { transform: scale(.8); transform-origin: top left; width: 125%; } }

@media (max-width: 720px) {
  /* .app-topbar is hidden at this width and the bar that replaces it
     (.mobile-topbar) sits OUTSIDE .app-main, so .app-main is already the
     right height — discounting another 56px here made the wizard overflow
     it and the page scrolled ~56px with nothing to show for it. Just fill
     the parent. */
  .nrw { min-height: 100%; }

  /* 34px each side is a desktop gutter. On a 390px phone it spent 68px — 17%
     of the screen — on empty margin, and the editor's fields sat noticeably
     narrower than every other page in the app. --page-gutter (16px here) is
     what Routines, History, Settings and the reader already use. */
  .nrw-compose { padding-left: var(--page-gutter); padding-right: var(--page-gutter); }

  /* btn--sm is 31px tall, which is under a thumb's worth on a phone. Being a
     destructive action is not a reason to leave it hard to hit — the confirm
     dialog is what stops a misclick, and an undersized control just makes you
     tap twice. Not full-width: that would read as the page's primary action. */
  .nrw-danger__btn { min-height: 42px; padding: 11px 18px; }
}

@media (max-width: 900px) {
  .nrw-rail { display: none; }
  .nrw-browse { display: none; }
  /* It's a flex item of .nrw-step, so `display: block` alone leaves it
     shrink-to-fit — the card list ends up ~220px wide on a 390px phone. */
  .nrw-mobile-pick { display: block; flex: 1; min-width: 0; }
  .nrw-config { flex-direction: column; }
  .nrw-example { border-left: none; border-top: 1.5px solid #e6e1d6; }
}
/* One per row on phones. Stacked cards waste most of the width on a tall
   empty column, so lay each one out as an icon-left row instead — same
   treatment as the Help & support cards. */
@media (max-width: 560px) {
  .nrw-mobile-pick__grid { grid-template-columns: 1fr; gap: 10px; }
  .nrw-mobile-card {
    display: grid; grid-template-columns: auto 1fr;
    column-gap: 13px; row-gap: 2px; align-items: center; padding: 14px 15px;
  }
  .nrw-mobile-card__icon { grid-row: 1 / span 2; margin-bottom: 0; }
  .nrw-mobile-card__name { align-self: end; }
  .nrw-mobile-card__desc { align-self: start; }
}

/* Pro-gated (web) starting points for free users. */
.nrw-prolock { font: 700 8.5px "Hanken Grotesk"; letter-spacing: .3px; margin-left: 6px; padding: 2px 6px; border-radius: 5px; background: #efe9f2; color: #6a4c86; vertical-align: middle; }
.nrw-use--lock { background: #efe9f2; color: #6a4c86; box-shadow: none; text-decoration: none; }
.nrw-use--lock:hover { background: #e5ddf0; text-decoration: none; }
.nrw-actionbar__note { font-size: 11.5px; color: #9a9384; margin-left: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   CONNECTIONS IN THE TOOLS ROW — design §1 (the gate), §2 (unlocked), §7 (break)
   ───────────────────────────────────────────────────────────────────────────
   Four chip variants sit alongside the shipped 🌐 Web research chip, and the
   chip's border is the whole status system:

     .nrw-tool--locked    grey + 🔒   not on this plan, opens the gate
     .nrw-tool--conn      white       connected, not ticked for this routine
     .nrw-tool--conn.is-on green      ticked, carries the account identity
     .nrw-tool--broken    gold        access ended; stays ticked, stays visible
     .nrw-tool--connect   dashed      "+ Connect a service"

   Geometry (padding, radius, the 20px check box) is inherited from .nrw-tool
   above so the new chips are the same object as the one already shipping —
   only colour and content differ.
   ═══════════════════════════════════════════════════════════════════════════ */

/* The head gains a right-aligned link, so the note has to stop being the last
   thing on the line. */
.nrw-toolshead__link { margin-left: auto; font: 600 12px "Hanken Grotesk"; color: #2f6d5b; }
.nrw-toolshead__link:hover { text-decoration: underline; }

/* The row now has a note (and often a summary block) under it, so it gives up
   its own bottom margin to them. */
.nrw-tools--conn { margin-bottom: 10px; }

/* One explanatory line under the whole row — never one per chip. */
.nrw-toolsnote { font-size: 12.5px; line-height: 1.55; color: #8f8877; margin: 0 0 18px; }
.nrw-toolsnote a { color: #2f6d5b; font-weight: 600; text-decoration: underline; text-underline-offset: 2px; }

/* Locked (§1). Never hidden: a chip you cannot use yet is the clearest upgrade
   argument in the product, and clicking it always answers. */
.nrw-tool--locked {
  border-color: #e2ddd0; background: #f6f4ef; color: #8f8877;
  font: 600 12.5px "Hanken Grotesk"; gap: 7px;
}
.nrw-tool--locked:hover { border-color: #d8d1bf; background: #f1eee6; }

/* The tick itself. Visually hidden rather than display:none so the chip stays
   reachable and operable from the keyboard — the focus ring below is what
   makes that visible. */
.nrw-tool__input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.nrw-tool:has(.nrw-tool__input:focus-visible) { outline: 2px solid #2f6d5b; outline-offset: 2px; }

/* Connected but not ticked for this routine. */
.nrw-tool--conn { border-color: #ddd6c9; background: #fff; color: #6f6a5e; }
/* Ticked. Stronger than the generic .is-on above: this chip is a grant, and it
   should read as one at a glance across a row of five. */
.nrw-tool--conn.is-on { border-color: #2f6d5b; background: #eaf1ee; color: #245a4a; }
.nrw-tool--conn.is-on .nrw-tool__check { background: #2f6d5b; color: #fff; }

/* The account identity, inline and in regular weight — on an account with two
   Gmails, the routine says which one it reads. */
.nrw-tool__ident { font-weight: 400; font-size: 12.5px; color: #5d7f74; }

/* Access ended (§7). Gold beats ticked deliberately: the state that needs
   attention is the one the chip should be showing. It is never auto-unticked —
   that would silently change the brief. */
.nrw-tool--broken,
.nrw-tool--broken.is-on { border-color: #e0c48f; background: #fdf7e9; color: #6f5a2c; }
.nrw-tool--broken.is-on .nrw-tool__check { background: #c9a24a; color: #2b2109; }
.nrw-tool__note { font-weight: 400; font-size: 12.5px; color: #8a6b33; }

/* "+ Connect a service" — the advanced affordance idiom, dashed and quiet. */
.nrw-tool--connect { border-style: dashed; border-color: #ddd6c9; background: none; color: #8f8877; }
.nrw-tool--connect:hover { border-color: #cfc7b6; color: #6f6a5e; }

/* The chooser is a <details> disclosure, so it costs no JS to open — only the
   click-outside close is scripted. */
.nrw-connect { position: relative; display: inline-block; }
.nrw-connect > summary { list-style: none; }
.nrw-connect > summary::-webkit-details-marker { display: none; }
.nrw-connect__menu {
  position: absolute; z-index: 20; top: calc(100% + 6px); left: 0;
  min-width: 230px; padding: 6px;
  background: #fff; border: 1.5px solid #e6e1d6; border-radius: 12px;
  box-shadow: 0 10px 30px rgba(50, 42, 28, .08);
}
.nrw-connect__item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 9px 11px; border: 0; border-radius: 8px; background: none;
  font: 600 12.5px "Hanken Grotesk"; color: #3a352c;
}
.nrw-connect__item:hover { background: #f4f8f6; color: #245a4a; }
.nrw-connect__link {
  display: block; padding: 9px 11px; margin-top: 4px;
  border-top: 1.5px solid #efe9dc;
  font: 600 12px "Hanken Grotesk"; color: #2f6d5b;
}

/* The derived summary (§2). Every line is generated from the ticked chips —
   both here and in routine_tools.js — so there is no second copy of this
   sentence to fall out of date with the row above it. */
.nrw-toolsum {
  padding: 14px 16px; margin: 0 0 22px;
  border: 1.5px solid #dbe8e2; border-radius: 12px; background: #f4f8f6;
}
.nrw-toolsum[hidden] { display: none; }
.nrw-toolsum__label { font: 700 10px "Hanken Grotesk"; letter-spacing: .6px; color: #2f6d5b; margin-bottom: 8px; }
.nrw-toolsum__lines { display: grid; gap: 6px; font-size: 13.5px; line-height: 1.5; color: #3a352c; }
.nrw-toolsum__line { display: flex; gap: 8px; }
.nrw-toolsum__mark { flex: none; color: #2f6d5b; }
/* A ticked tool that cannot run is not a failure state — it is a fact with a
   fix, so it is gold rather than red. */
.nrw-toolsum__line--warn { color: #8a6b33; }
.nrw-toolsum__line--warn .nrw-toolsum__mark { color: #8a6b33; }

/* §7's Reconnect, in the paused banner. Gold on gold: the action belongs to
   the break it sits inside, not to the page's green primary. */
.nrw-pausednote__btn {
  display: inline-block; margin-top: 10px; cursor: pointer;
  padding: 8px 13px; border: 0; border-radius: 9px;
  background: #c9a24a; color: #2b2109;
  font: 600 12.5px "Hanken Grotesk"; text-decoration: none;
}
.nrw-pausednote__btn:hover { background: #bd9440; color: #2b2109; text-decoration: none; }

/* ── The gate dialog (§1) ──
   A second variant of .capgate (joris/dialog.css), not a new component — only
   what differs lives here. */
.capgate--plan .capgate__title { font-weight: 600; line-height: 1.2; }
.capgate--plan .capgate__feats li strong { font-weight: 600; color: #26221b; }
/* "Keep Standard" is a form (method="dialog") rather than a bare button, so the
   auto margin that right-aligns the link has to move up one level. */
.capgate--plan .capgate__keep { margin-left: auto; }
.capgate--plan .capgate__keep .capgate__footlink {
  border: 0; background: none; cursor: pointer; padding: 0; margin-left: 0;
  font: 600 12.5px "Hanken Grotesk"; color: #8f8877;
}
.capgate--plan .capgate__keep .capgate__footlink:hover { color: #6f6a5e; }
.capgate--plan .capgate__altbody { color: #6f6a5e; }

/* ── Responsive ──
   The chip row already wraps. What does not survive a narrow column is the
   absolutely-positioned chooser, which would hang off the right edge. */
@media (max-width: 560px) {
  .nrw-connect { position: static; }
  .nrw-connect__menu { left: var(--page-gutter, 16px); right: var(--page-gutter, 16px); min-width: 0; }
  .nrw-toolshead__link { margin-left: 0; }
  /* Long identities (a work address) would otherwise force a chip wider than
     the screen, since chips are nowrap by inheritance from the row. */
  .nrw-tool--conn { max-width: 100%; }
  .nrw-tool__ident { overflow: hidden; text-overflow: ellipsis; }
}
/* ============================================================================
   /pricing — page-scoped `prcp-` family (docs/growth/SEO.md §1.2: page families
   never collide with the app's or another page's). Extracted from the Claude
   Design handoff claude-design/Pricing.dc.html (2026-08 reframe) per AGENTS.md
   "Claude Design → code": the ERB carries structure and semantic classes only,
   every value lives here, and the responsive behaviour is real media queries.

   Shared furniture (nav, footer, kicker, buttons) stays in the mkt-* family and
   is not restated here. Colors reuse the marketing tokens declared on body.mkt
   (--line, --green, --panel, --serif…); only the handful of shades this page
   introduces get prcp- tokens of their own.

     1. Tokens
     2. Page furniture (banner, wrappers, shared bits)
     3. Hero
     4. The plans card (headers + comparison table)
     5. Connecting your tools (split panel)
     6. The trial
     7. What's a web run (split panel)
     8. FAQ
     9. Teams and heavy use
    10. Closing band
    11. Landing's compact #pricing band (not this page — see landing.html.erb)
    12. Responsive — 900 / 820 / 700 / 560, mirroring the design
   ============================================================================ */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */
.prcp {
  --prcp-copy: #4a453b;          /* panel body copy — one step darker than --muted */
  --prcp-cell: #3a352c;          /* a comparison cell's value */
  --prcp-answer: #5f5a4f;        /* FAQ answers */
  --prcp-meta: #8f8877;          /* row hints, "/mo + VAT", the em-dash cells */
  --prcp-col-a: #f7faf8;         /* the Personal column's wash, header to footer */
  --prcp-badge-a-bg: #e4efe9;
  --prcp-soon: #b45b3e;          /* the "Soon" chip — the one warm alarm on the page */
  --prcp-badge-b: #8a6b33;       /* Business's badge reads warm, not green */
  --prcp-badge-b-bg: #f7edd6;
  --prcp-talk-bg: #f7f4ec;
  --prcp-end-lead: #c5d8d0;
  --prcp-card-shadow: 0 14px 40px rgba(50, 42, 28, .09);
}

/* ── 2. Page furniture ───────────────────────────────────────────────────── */
.prcp-banner { background: var(--forest); color: var(--mint-2); text-align: center; padding: 9px 20px; font-size: 12.5px; }
.prcp-banner strong { color: #fff; font-weight: 700; }

/* One wrapper, four widths. The design's blocks differ in max-width (960 hero,
   1060 body, 900 FAQ) and in their top gap; both live on the modifier so the
   ERB never carries a spacing decision. */
.prcp-pad { max-width: 1060px; margin: 0 auto; padding: 22px 30px 0; }
.prcp-pad--hero { max-width: 960px; padding: 56px 30px 12px; }
.prcp-pad--faq { max-width: 900px; padding: 34px 30px 0; }
.prcp-pad--talk { padding-top: 26px; }
.prcp-pad--end { padding: 26px 30px 60px; }
.prcp-plans { padding-top: 34px; }

.prcp-h2 { font-family: var(--serif); font-weight: 500; font-size: 26px; line-height: 1.15; }
.prcp-label { font: 700 10px var(--sans); letter-spacing: .8px; color: var(--faint); margin-bottom: 10px; }
/* A second label inside the same column needs air above it, or it reads as a
   caption on the paragraph it follows rather than a heading for the next. */
.prcp-label--spaced { margin-top: 20px; }
/* The white panels behind everything below the plans card. */
.prcp-panel { background: #fff; border: 1.5px solid var(--line); border-radius: 18px; overflow: hidden; }

/* ── 3. Hero ─────────────────────────────────────────────────────────────── */
.prcp-hero { text-align: center; }
/* clamp rather than the design's flat 48px: at 375px a fixed 48px serif line
   pushes the page into horizontal scroll (invariant 9). The ceiling is the
   design's own size. */
.prcp-hero__title { font-family: var(--serif); font-weight: 500; font-size: clamp(32px, 4.6vw, 48px); line-height: 1.04; letter-spacing: -.6px; margin: 12px 0 16px; text-wrap: balance; }
.prcp-hero__lead { max-width: 620px; margin: 0 auto; font-size: 17.5px; line-height: 1.6; color: var(--prcp-copy); }

/* ── 4. The plans card ────────────────────────────────────────────────────────
   One card holds both plan headers AND the comparison table, so a column reads
   top to bottom as a single plan. Every row is a .prcp-row with
   `display: contents` — it groups the three cells for the markup and the specs
   without adding a box between them and the grid. */
.prcp-table { border: 1.5px solid var(--line); border-radius: 20px; background: #fff; overflow: hidden; box-shadow: var(--prcp-card-shadow); }
.prcp-grid { display: grid; grid-template-columns: 1.15fr 1fr 1fr; }
.prcp-row { display: contents; }

.prcp-rowlabel { padding: 16px 26px; border-bottom: 1.5px solid var(--tan); }
.prcp-rowlabel--head { padding: 26px; border-bottom: 1.5px solid var(--line-2); display: flex; flex-direction: column; justify-content: flex-end; }
.prcp-rowlabel__lead { font-size: 13.5px; line-height: 1.55; color: var(--muted); }
.prcp-rowlabel__name { font-weight: 600; font-size: 14px; margin-bottom: 2px; }
.prcp-rowlabel__hint { font-size: 12.5px; line-height: 1.5; color: var(--prcp-meta); }

.prcp-cell { padding: 16px 24px; border-left: 1.5px solid var(--line-2); border-bottom: 1.5px solid var(--tan); }
.prcp-cell--a { background: var(--prcp-col-a); }
.prcp-cell__v { font-size: 13.5px; line-height: 1.5; color: var(--prcp-cell); }
.prcp-tick { color: var(--green); margin-right: 5px; }
.prcp-dash { color: var(--prcp-meta); }
/* Reprinted row label, so a column still reads on its own once the label
   column is gone. Hidden above 820px (§12). */
.prcp-cell__mob { display: none; font-size: 11px; font-weight: 700; letter-spacing: .4px; text-transform: uppercase; color: var(--faint); margin-bottom: 5px; }
/* …and the plan's own name, which only matters once the two columns stack. */
.prcp-cell__plan { display: none; }

.prcp-row:last-child .prcp-cell,
.prcp-row:last-child .prcp-rowlabel { border-bottom: none; }

/* The plan headers — the first row of the same grid. */
.prcp-head { padding: 26px 24px 22px; border-bottom: 1.5px solid var(--line-2); }
/* Name and state on one line. Soon used to sit above the heading, beside a
   badge that no longer exists — alone up there it cost the column a whole line
   and pushed the price, the pitch and the button down past its neighbour. */
.prcp-head__nameline { display: flex; align-items: center; gap: 9px; margin-bottom: 7px; }
.prcp-head__name { font-family: var(--serif); font-size: 22px; font-weight: 500; margin: 0; }
/* Optically centred on the name rather than the line box: the serif's cap
   height sits above the middle, so a flex-centred pill reads a shade low. */
.prcp-head__soon { flex: none; position: relative; top: 1px; font: 700 10px var(--sans); letter-spacing: .7px; text-transform: uppercase; color: var(--prcp-soon); border: 1px solid var(--prcp-soon); padding: 3px 8px; border-radius: 999px; }
.prcp-head__pricerow { display: flex; align-items: baseline; gap: 5px; flex-wrap: wrap; }
/* The price is still shown — withholding it would make "soon" read as "we
   haven't decided", which is a worse answer than the real one. Dimmed so it
   does not read as an offer you can take today. */
.prcp-head--soon .prcp-head__price, .prcp-head--soon .prcp-head__per { color: var(--prcp-meta); }
.prcp-head__price { font-family: var(--serif); font-size: 44px; font-weight: 500; line-height: 1; letter-spacing: -1px; }
.prcp-head__per { font-size: 12.5px; color: var(--prcp-meta); white-space: nowrap; }
.prcp-head__pitch { margin: 10px 0 16px; font-size: 13px; line-height: 1.55; color: var(--muted); }

.prcp-cta { display: block; text-align: center; font: 600 13.5px var(--sans); padding: 12px; border-radius: 11px; background: var(--green); color: #fff; box-shadow: 0 3px 10px rgba(47, 109, 91, .22); border: 1.5px solid transparent; }
.prcp-cta:hover { background: var(--green-d); text-decoration: none; }
.prcp-cta--ghost { background: #fff; color: var(--green); border-color: var(--green); box-shadow: none; }
.prcp-cta--ghost:hover { background: var(--mint-soft); }

/* Read-only, said where the money is. */
.prcp-promise { padding: 15px 26px; border-top: 1.5px solid var(--line-2); background: var(--panel); font-size: 12.5px; line-height: 1.6; color: var(--muted); }

/* ── 5. Connecting your tools ────────────────────────────────────────────── */
.prcp-split { display: grid; grid-template-columns: 1fr 1fr; }
.prcp-split__left { padding: 28px 30px; border-right: 1.5px solid var(--line-2); }
.prcp-split__left .prcp-h2 { margin-bottom: 12px; }
.prcp-split__right { padding: 28px 30px; background: var(--panel); }
.prcp-split__body { font-size: 14.5px; line-height: 1.62; color: var(--prcp-copy); margin-bottom: 12px; }
.prcp-split__note { font-size: 13px; line-height: 1.6; color: var(--muted); }
.prcp-split__foot { padding-top: 14px; border-top: 1.5px solid var(--line-2); font-size: 13px; line-height: 1.6; color: var(--muted); }
.prcp-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.prcp-chip { font: 600 12.5px var(--sans); padding: 7px 12px; border-radius: 999px; background: #fff; border: 1.5px solid var(--line); color: var(--prcp-cell); }
.prcp-chips__note { margin: 10px 0 16px; font-size: 12.5px; line-height: 1.5; color: var(--faint); }

/* ── 6. The trial ────────────────────────────────────────────────────────── */
.prcp-card { padding: 26px 30px; }
.prcp-card__head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 18px; }
.prcp-card__sub { font-size: 13px; color: var(--muted); }
.prcp-trial { display: grid; grid-template-columns: repeat(4, 1fr); border: 1.5px solid var(--line-2); border-radius: 14px; overflow: hidden; }
.prcp-trial__cell { padding: 18px 20px; border-right: 1.5px solid var(--line-2); }
.prcp-trial__cell:last-child { border-right: none; }
.prcp-trial__n { font-family: var(--serif); font-size: 31px; font-weight: 500; line-height: 1; margin-bottom: 7px; }
.prcp-trial__label { font-size: 12.5px; line-height: 1.5; color: var(--muted); }
.prcp-card__foot { margin-top: 18px; font-size: 13.5px; line-height: 1.62; color: var(--prcp-copy); }

/* ── 7. What's a web run ─────────────────────────────────────────────────── */
.prcp-runs { display: grid; grid-template-columns: 1fr 1.05fr; }
.prcp-runs__left { padding: 28px 30px; background: var(--panel); border-right: 1.5px solid var(--line-2); }
.prcp-runs__left .prcp-h2 { margin-bottom: 10px; }
.prcp-runs__body { font-size: 14px; line-height: 1.6; color: var(--prcp-copy); margin-bottom: 12px; }
.prcp-runs__note { font-size: 13px; line-height: 1.6; color: var(--muted); }
.prcp-runs__right { padding: 22px 26px; }
.prcp-run { display: flex; align-items: center; gap: 12px; padding: 11px 0; border-bottom: 1.5px solid var(--tan); }
.prcp-run:last-child { border-bottom: none; }
.prcp-run__tag { font: 700 9.5px var(--sans); letter-spacing: .6px; border-radius: 6px; padding: 4px 8px; flex: none; }
.prcp-run__tag--web { color: var(--green); background: var(--prcp-badge-a-bg); }
.prcp-run__tag--free { color: var(--prcp-meta); background: var(--tan); }
.prcp-run__text { font-size: 13.5px; color: var(--prcp-cell); }

/* ── 8. FAQ ──────────────────────────────────────────────────────────────── */
.prcp-faq__title { font-size: 30px; margin-bottom: 16px; }
.prcp-faq { display: flex; flex-direction: column; gap: 10px; }
.prcp-qa { background: #fff; border: 1.5px solid var(--line); border-radius: 14px; padding: 16px 20px; }
.prcp-qa summary { display: flex; align-items: center; gap: 12px; font-size: 15px; font-weight: 600; cursor: pointer; list-style: none; }
.prcp-qa summary::-webkit-details-marker { display: none; }
.prcp-qa__q { flex: 1; }
.prcp-plus { color: var(--green); font-size: 19px; line-height: 1; transition: transform .18s; }
.prcp-qa[open] .prcp-plus { transform: rotate(45deg); color: var(--prcp-meta); }
.prcp-qa__a { font-size: 14px; line-height: 1.65; color: var(--prcp-answer); margin-top: 11px; }

/* ── 9. Teams and heavy use ──────────────────────────────────────────────── */
.prcp-talk { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; background: var(--prcp-talk-bg); border: 1.5px solid var(--line); border-radius: 16px; padding: 20px 26px; }
.prcp-talk__badge { font: 700 9.5px var(--sans); letter-spacing: .6px; color: var(--prcp-meta); background: #fff; border: 1.5px solid var(--line); padding: 6px 11px; border-radius: 8px; flex: none; }
.prcp-talk__text { flex: 1 1 320px; min-width: 280px; font-size: 13.5px; line-height: 1.55; color: var(--prcp-copy); }
.prcp-talk__text strong { font-weight: 600; color: var(--ink); }
.prcp-talk__link { font: 600 13px var(--sans); color: var(--rust); white-space: nowrap; }

/* ── 10. Closing band ────────────────────────────────────────────────────── */
.prcp-end { background: var(--forest); border-radius: 20px; padding: 44px 40px; text-align: center; }
.prcp-end__title { font-family: var(--serif); font-weight: 500; font-size: 34px; line-height: 1.12; color: #fff; margin-bottom: 12px; text-wrap: balance; }
.prcp-end__lead { max-width: 520px; margin: 0 auto 22px; font-size: 15.5px; line-height: 1.6; color: var(--prcp-end-lead); }
.prcp-end__ctas { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; }
.prcp-endbtn { font: 600 14.5px var(--sans); color: var(--forest); background: #fff; border: 1.5px solid transparent; border-radius: 12px; padding: 13px 24px; }
.prcp-endbtn:hover { text-decoration: none; }
.prcp-endbtn--ghost { color: var(--mint-2); background: transparent; border-color: rgba(220, 235, 229, .4); }
.prcp-endbtn--ghost:hover { background: rgba(220, 235, 229, .1); }

/* ── 11. Landing's compact #pricing band ─────────────────────────────────────
   Screen 2 of the original handoff. It lives on the LANDING page, not here —
   left in this file because it is pricing furniture, and still referenced by
   app/views/marketing/landing.html.erb. */
.prcp-band { background: #fff; border: 1.5px solid #2f6d5b; border-radius: 20px; padding: 28px 30px; display: flex; align-items: center; gap: 30px; flex-wrap: wrap; box-shadow: 0 14px 40px rgba(47, 109, 91, .12); }
.prcp-band__copy { flex: 1; min-width: 300px; }
.prcp-band__title { font-family: "Newsreader", serif; font-weight: 500; font-size: 32px; line-height: 1.1; margin: 7px 0 9px; }
.prcp-band__lead { font-size: 14.5px; line-height: 1.6; color: #4a453b; max-width: 440px; }
.prcp-band__ctas { display: flex; flex-direction: column; gap: 9px; min-width: 210px; }
.prcp-band__more { text-align: center; font-weight: 600; font-size: 13.5px; color: #9c4526; text-decoration: none; }
.prcp-band__more:hover { color: #8f3f28; }

/* ── 12. Responsive ──────────────────────────────────────────────────────────
   The design's four breakpoints, unchanged. Invariant 9: no horizontal scroll
   at 375px. */
@media (max-width: 900px) {
  .prcp-split, .prcp-runs { grid-template-columns: 1fr; }
  .prcp-split__left, .prcp-runs__left { border-right: none; border-bottom: 1.5px solid var(--line-2); }
}

/* The comparison table becomes two stacked plan columns: the label column drops
   out and each cell reprints its own row label. */
@media (max-width: 820px) {
  .prcp-grid { grid-template-columns: 1fr 1fr; }
  .prcp-rowlabel { display: none; }
  .prcp-cell__mob { display: block; }
  .prcp-cell { border-left: none; }
  .prcp-cell--b { border-left: 1.5px solid var(--line-2); }
}

@media (max-width: 700px) {
  .prcp-trial { grid-template-columns: 1fr 1fr; }
  .prcp-trial__cell:nth-child(2n) { border-right: none; }
  .prcp-trial__cell:nth-child(-n+2) { border-bottom: 1.5px solid var(--line-2); }
  .prcp-pad { padding-left: 18px; padding-right: 18px; }
  .prcp-card, .prcp-split__left, .prcp-split__right, .prcp-runs__left { padding-left: 22px; padding-right: 22px; }
  .prcp-end { padding: 34px 24px; }
  .prcp-band__ctas { width: 100%; }
}

/* One column: the two plans now alternate row by row, so each cell has to say
   whose number it is as well as which row. */
@media (max-width: 560px) {
  .prcp-grid { grid-template-columns: 1fr; }
  .prcp-cell--b { border-left: none; border-top: 1.5px solid var(--line-2); }
  .prcp-cell__plan { display: inline; }
}
/* "✨ Let joris analyse your Direction" — prompt coach widget (new + edit). */
.pc { margin: 0 0 18px; }
/* Several children below set their own `display: flex`, which otherwise beats
   the `hidden` attribute's UA-stylesheet `display: none` in the cascade. */
.pc [hidden] { display: none !important; }
.pc__bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.pc__btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border: 1.5px solid #cfe0d9; border-radius: 11px;
  background: #f4f8f6; color: #2f6d5b; cursor: pointer;
  font: 600 12.5px "Hanken Grotesk";
}
.pc__btn:hover { background: #eaf2ee; }
.pc__btn:disabled { cursor: default; opacity: .7; }
.pc__spark { font-size: 13px; }
.pc.is-busy .pc__spark { animation: pc-pulse 1s ease-in-out infinite; }
@keyframes pc-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .35; } }

.pc__score { display: flex; align-items: center; gap: 9px; flex: 1; min-width: 140px; }
.pc__meter { flex: 1; height: 7px; border-radius: 999px; background: #e6e1d6; overflow: hidden; }
.pc__fill { display: block; height: 100%; width: 0; border-radius: 999px; background: #2f6d5b; transition: width .5s ease; }
.pc__num { flex: none; font: 700 13px "Hanken Grotesk"; color: #2f6d5b; min-width: 22px; text-align: right; }

.pc__panel { margin-top: 12px; padding: 14px 16px; border: 1.5px solid #e6e1d6; border-radius: 13px; background: #fbfaf7; }
.pc__verdict { margin: 0 0 10px; font-size: 13px; line-height: 1.5; color: #3a352c; font-weight: 600; }
.pc__verdict:empty { display: none; }

.pc__loading { display: flex; align-items: center; gap: 11px; padding: 2px 0; }
.pc__spinner {
  width: 16px; height: 16px; flex: none; border-radius: 50%;
  border: 2px solid #dbe6e0; border-top-color: #2f6d5b;
  animation: pc-spin .7s linear infinite;
}
.pc__loading-text { font-size: 12.5px; line-height: 1.5; color: #6f6a5e; }
@keyframes pc-spin { to { transform: rotate(360deg); } }

.pc__sugg { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.pc__item { font-size: 12.5px; line-height: 1.5; color: #3a352c; padding-left: 15px; position: relative; }
.pc__item::before { content: "→"; position: absolute; left: 0; color: #9a9384; }
.pc__item--none { color: #6f6a5e; }
.pc__issue { font-weight: 600; color: #b45b3e; margin-right: 6px; }
.pc__fix { color: #3a352c; }

.pc__apply-row { display: flex; align-items: center; gap: 10px; margin-top: 13px; }
.pc__apply {
  padding: 8px 14px; border: none; border-radius: 10px;
  background: #2f6d5b; color: #fff; cursor: pointer; font: 600 12.5px "Hanken Grotesk";
}
.pc__apply:hover { background: #28604f; }
.pc__undo { background: none; border: none; cursor: pointer; font: 600 12px "Hanken Grotesk"; color: #6f6a5e; padding: 0; }
.pc__undo:hover { color: #2f6d5b; }

.pc__err { margin: 10px 0 0; font-size: 12px; color: #b45b3e; }

/* Async lifecycle: cancel while running, and a warning when the Direction has
   moved on since the review was made. */
.pc__cancel {
  margin-left: auto; flex: none;
  font: 600 11.5px var(--font-sans, inherit); padding: 5px 11px; border-radius: 8px;
  border: 1.5px solid #ddd6c9; background: #fff; color: #8f8877; cursor: pointer;
}
.pc__cancel:hover { border-color: #c9bfae; color: #6f6a5e; }

.pc__stale {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 12px; padding: 9px 12px; border-radius: 9px;
  background: #fdf8ec; border: 1.5px solid #e0cd9a; color: #6f5a1f; font-size: 12.5px;
}
.pc__restale {
  font: 600 11.5px var(--font-sans, inherit); padding: 5px 11px; border-radius: 8px;
  border: 1.5px solid #ddc98f; background: #fff; color: #7a6224; cursor: pointer;
}
.pc__restale:hover { background: #fbf3e0; }

/* ── Connection advisory (§3) — the Direction asks for the user's own
   accounts. Two registers: an offer (green, plan has Connections) and an
   answer (neutral, plan doesn't — deliberately calmer, not a sales moment). */
.pc-conn { display: flex; gap: 10px; border-radius: 13px; padding: 13px 15px; margin-bottom: 12px; }
.pc-conn--offer { border: var(--hairline) solid var(--primary-border); background: var(--primary-tint-2, #f4f8f6); }
.pc-conn--plan { border: var(--hairline) solid var(--border-strong); background: var(--surface-raised); }
.pc-conn__avatar {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  background: var(--primary); color: #fff; font: 700 13px/26px var(--font-sans);
  text-align: center;
}
.pc-conn__avatar--muted { background: var(--ink-faint); }
.pc-conn__title { display: block; font: 600 13.5px/1.35 var(--font-sans); color: var(--ink); }
.pc-conn__text { margin: 4px 0 0; font: 400 13px/1.55 var(--font-sans); color: var(--ink-soft); }
.pc-conn__row { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
.pc-conn__cta {
  display: inline-block; padding: 8px 14px; border-radius: 10px;
  background: var(--primary); color: #fff; font: 600 12.5px var(--font-sans);
  text-decoration: none;
}
.pc-conn__cta:hover { background: var(--primary-press); }
.pc-conn__link { font: 600 12.5px var(--font-sans); color: var(--primary); text-decoration: none; }
.pc-conn__dismiss {
  border: var(--hairline) solid var(--border-strong); background: transparent;
  border-radius: 10px; padding: 7px 13px; font: 600 12.5px var(--font-sans);
  color: var(--ink-soft); cursor: pointer;
}
/* /recipes + /recipes/<slug> — page-scoped `rcp-` family (never collides with
   marketing.css or another page's family; see marketing_css_isolation_spec).
   Ported 2026-08-05 from the Claude Design pair:
     claude-design/Recipes Index.dc.html            → recipes/index.html.erb
     claude-design/Recipe Detail v1 (linear).dc.html → recipes/show.html.erb
   Shared furniture (nav, footer, .mkt-btn, .mkt-section) stays in marketing.css;
   tokens (--serif, --green, --line…) come from body.mkt. The design breaks at
   760px; everything here reads at 390px. */

/* ── hero (index) ── */
/* Centred, like the use-cases hub's — this page is a list with a switcher over
   it, so the hero is a masthead rather than the start of a left-hand column.
   The measures stay capped and are centred with auto margins. */
.rcp-hero { padding-top: 26px; text-align: center; }
.rcp-hero__title { font-family: var(--serif); font-weight: 500; font-size: clamp(32px, 5.5vw, 64px); line-height: 1.05; letter-spacing: -.4px; margin: 8px auto 14px; max-width: 900px; text-wrap: balance; }
/* The one flourish on the page, and the only italic: it lands on the two words
   that carry the argument — the direction is published whole, not summarised.
   The full stop stays in ink, so the accent reads as emphasis, not as a colour
   change that ran on to the end of the sentence. */
.rcp-hero__accent { font-style: italic; color: var(--rust); }
.rcp-hero__lead { font-size: 16px; line-height: 1.6; color: #4a453b; max-width: 600px; margin-inline: auto; }

/* Both pages' small green section eyebrow (the index hero's "RECIPES", the
   detail's "HUNTS · JOB HUNT TEMPLATE"). Own name, not .uch-kicker — one class
   in two families is a collision the isolation spec rejects. */
.rcp-kicker { font: 700 11px var(--sans); letter-spacing: .7px; color: var(--green); }

/* ── the switcher (index) ──
   Sticks under the nav, offset by the nav's published height rather than a
   hardcoded number (see --mkt-nav-h in marketing.css). The list below it is
   flat, so the switcher is the only thing telling you where you are in it —
   which is exactly why it has to stay on screen. */
/* No bottom rule and no band of its own. .mkt-page's ground is a radial
   GRADIENT, not a flat colour, so a sticky bar cannot simply paint the page
   colour behind itself — it would read as a patch. A translucent wash plus a
   blur reads as nothing at rest (the gradient here, near the top, is within a
   shade of it) and still masks the cards that pass under it once stuck. The
   1.5px rule that used to sit under it was what actually drew the eye and made
   the whole row look like a band the design does not have. */
/* padding-top/bottom, NOT the `padding` shorthand: .mkt-section supplies the
   30px horizontal padding every other section on the page uses, and a
   shorthand here silently zeroed it — which put the capsule 30px left of the
   cards and the note 30px right of them. The backdrop still spans the full
   section width; only the contents inset, so the row lines up with the grid. */
.rcp-filterwrap { padding-top: 22px; padding-bottom: 18px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 18px; }
/* Sticky is added by marketing.js, not declared here, and the backdrop only
   appears once the row is actually stuck. At rest the design has no band at
   all — and a bar that is sticky in CSS but transparent would let cards scroll
   visibly through it for anyone without JS. This way no-JS gets the design's
   plain row, and the wash exists exactly when it has something to mask. */
.rcp-filterwrap.is-sticky { position: sticky; top: var(--mkt-nav-h); z-index: 30; }
.rcp-filterwrap.is-stuck { background: rgba(245, 242, 236, .88); backdrop-filter: blur(10px); }

/* A segmented control, not a row of outlined chips: one capsule holding all
   five, the selected one lifted out of it in white. The chips it replaced were
   individually bordered with a solid-green active state — the inverse of the
   design, and the giveaway that this row was inherited rather than ported. */
.rcp-filter { display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 4px; background: rgba(255, 255, 255, .5); border: 1px solid var(--line-2); border-radius: 999px; }
.rcp-filter__chip { font: 600 13px var(--sans); border: 0; border-radius: 999px; padding: 7px 14px; cursor: pointer; background: transparent; color: var(--muted); }
.rcp-filter__chip:hover { background: rgba(255, 255, 255, .6); color: var(--ink); }
.rcp-filter__chip.is-on { background: #fff; color: var(--green); box-shadow: 0 1px 3px rgba(50, 42, 28, .09); }
.rcp-filter__chip.is-on:hover { background: #fff; color: var(--green); }
/* The count rides inside the chip, dimmed — it labels the control, it is not
   a second word in it. */
.rcp-filter__n { margin-left: 6px; font-size: 11.5px; color: var(--faint); font-weight: 500; }
.rcp-filter__chip.is-on .rcp-filter__n { color: var(--green); opacity: .55; }
.rcp-filter__note { font: 400 12.5px var(--sans); color: #8b8474; }

/* ── card grid (index) ──
   One flat grid, no per-family sections: the hub already groups by family and
   repeating that treatment here made the two pages read as copies (founder,
   "Recipes Index (1c)"). Each card wears its family instead. */
/* scroll-margin-top is what the switcher's scrollIntoView lands against: the
   nav plus the sticky bar, both measured by marketing.js, so the list top comes
   to rest just below the bar instead of under it. The fallback keeps a no-JS /
   pre-measurement landing sane. */
.rcp-list { padding-top: 24px; scroll-margin-top: calc(var(--mkt-nav-h, 70px) + var(--rcp-bar-h, 74px) + 8px); }
.rcp-grid { display: grid; grid-template-columns: 1fr; gap: 12px; }
.rcp-card[hidden] { display: none; }

.rcp-card { display: flex; flex-direction: column; padding: 17px; background: #fff; border: var(--edge); border-radius: 16px; color: inherit; box-shadow: 0 2px 5px rgba(50, 42, 28, .05); transition: .16s cubic-bezier(.2, .6, .2, 1); }
.rcp-card:hover { border-color: var(--mint-br); box-shadow: 0 12px 30px rgba(50, 42, 28, .1); transform: translateY(-2px); text-decoration: none; }
.rcp-card__top { display: flex; align-items: center; gap: 9px; margin-bottom: 9px; }
/* The family tag. Reads as a label rather than a control — it is not a link
   and not a filter; the switcher above is both. */
.rcp-card__fam { font: 600 10.5px var(--sans); letter-spacing: .2px; color: var(--green); background: var(--mint-2); border-radius: 999px; padding: 3px 9px; }
.rcp-card__label { font: 700 10px var(--sans); letter-spacing: .9px; color: #8b8474; }
.rcp-card__title { display: block; font-family: var(--serif); font-weight: 600; font-size: 21px; line-height: 1.14; letter-spacing: -.2px; margin-bottom: 11px; color: var(--ink); }
.rcp-card__dir { display: block; border-left: 2px solid var(--mint-2); padding-left: 13px; margin-bottom: 14px; }
.rcp-card__dirlbl { display: block; font: 700 9px var(--sans); letter-spacing: .9px; color: #a49d8d; margin-bottom: 6px; }
.rcp-card__excerpt { display: block; font-family: var(--serif); font-size: 16.5px; line-height: 1.55; color: #3f3a30; }
.rcp-card__meta { display: flex; align-items: center; gap: 8px; margin-top: auto; flex-wrap: wrap; }
.rcp-card__go { font: 600 12.5px var(--sans); color: var(--rust); margin-left: auto; }

/* Cadence chip is neutral; the run-kind chip goes mint only when the recipe
   actually reads the web ("thinking" stays neutral, as in the design). */
.rcp-chip { font: 600 11px var(--sans); padding: 4px 9px; border-radius: 999px; background: var(--tan); color: var(--muted); }
.rcp-chip--web { background: var(--mint); color: var(--green); }

/* ── empty index ── */
.rcp-empty { padding-top: 34px; }
.rcp-empty__line { font-size: 15px; line-height: 1.6; color: var(--muted); max-width: 560px; }

/* ── closing band (index): panel card, copy left, CTA right ── */
.rcp-band { padding-top: 40px; padding-bottom: 44px; }
.rcp-band__card { background: var(--panel); border: var(--edge); border-radius: 16px; padding: 22px 20px; display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.rcp-band__copy { min-width: 260px; flex: 1; }
.rcp-band__title { font-family: var(--serif); font-weight: 500; font-size: 23px; line-height: 1.15; margin-bottom: 6px; }
.rcp-band__lead { font-size: 13.5px; line-height: 1.55; color: var(--muted); max-width: 520px; }

/* ══ detail page ══ */
/* The detail column is narrower than .mkt-section's 1080 — the design reads at
   820. recipes.css loads after marketing.css (require_tree is alphabetical),
   so the same-specificity override wins. */
.rcp-crumb, .rcp-head, .rcp-sec { max-width: 820px; margin: 0 auto; }

/* breadcrumb (replaces the design's "← All recipes"; the three-step crumb is
   the SEO-enforced shape — visible text mirrors the BreadcrumbList JSON) */
.rcp-crumb { padding: 24px 30px 0; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.rcp-crumb a { color: var(--muted); }
.rcp-crumb a:hover { color: var(--ink); }
.rcp-crumb__sep { margin: 0 7px; color: #a49d8d; }
.rcp-crumb__here { color: #8b8474; font-weight: 600; }

/* ── title block ── */
.rcp-head { padding-top: 16px; }
.rcp-head__eyebrow { display: flex; align-items: center; gap: 11px; margin: 0 0 12px; }
.rcp-head__glyph { width: 38px; height: 38px; border-radius: 11px; background: var(--mint); display: flex; align-items: center; justify-content: center; font-size: 19px; }
.rcp-head__eyebrow .rcp-kicker { font-size: 10.5px; letter-spacing: .9px; }
.rcp-head__title { font-family: var(--serif); font-weight: 500; font-size: clamp(29px, 5.2vw, 44px); line-height: 1.06; letter-spacing: -.4px; margin-bottom: 14px; text-wrap: balance; }
.rcp-head__pitch { font-size: 16.5px; line-height: 1.6; color: #4a453b; max-width: 620px; }
.rcp-head__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 22px 0 6px; }
.rcp-head__meta { display: flex; flex-wrap: wrap; gap: 6px; }
.rcp-head__meta .rcp-chip { font-size: 11.5px; padding: 5px 10px; }
.rcp-head__fine { font-size: 13px; color: #8b8474; max-width: 420px; }
.rcp-head__credit { font-size: 13px; color: #8b8474; margin-top: 6px; }

/* ── shared section furniture: kicker-style h2 + hairline header ── */
.rcp-sec { padding-top: 38px; }
.rcp-sec__head { padding-bottom: 14px; border-bottom: 1.5px solid #e2ddd0; }
.rcp-sec__head--row { display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap; }
.rcp-sec__lead { flex: 1; min-width: 220px; }
.rcp-h2 { font: 700 11px var(--sans); letter-spacing: .8px; color: var(--green); text-transform: uppercase; }
.rcp-note { font-size: 13.5px; line-height: 1.55; color: var(--muted); margin-top: 5px; max-width: 540px; }

/* ── the direction document ── */
.rcp-copybtn { font: 600 12.5px var(--sans); display: inline-flex; align-items: center; gap: 7px; background: #fff; color: var(--green); border: 1.5px solid var(--mint-br); border-radius: 10px; padding: 9px 14px; cursor: pointer; }
.rcp-copybtn:hover { background: var(--mint); }
.rcp-direction__doc { background: #fff; border: var(--edge); border-radius: 18px; padding: 26px 22px; margin-top: 16px; box-shadow: 0 3px 10px rgba(50, 42, 28, .06); }
.rcp-direction__doc p { font-family: var(--serif); font-size: 17px; line-height: 1.62; color: #3f3a30; margin: 0 0 14px; }
.rcp-direction__doc p:first-child { font-size: 19px; line-height: 1.55; color: var(--ink); margin-bottom: 16px; }
.rcp-direction__doc p:last-child { margin-bottom: 0; }

/* ── sample delivery frame (chrome only — the body inside is the REAL delivery
     template partial, styled by its own delivery_*.css family) ── */
.rcp-sample__frame { position: relative; background: var(--cream); border: 1.5px solid #e0dacd; border-radius: 18px; margin-top: 16px; overflow: hidden; box-shadow: 0 10px 34px rgba(50, 42, 28, .09); }
.rcp-sample__bar { display: flex; align-items: center; gap: 9px; padding: 10px 18px; background: var(--panel); border-bottom: var(--edge); }
.rcp-sample__dot { width: 6px; height: 6px; border-radius: 999px; background: #a49d8d; }
.rcp-sample__tag { font: 700 10px var(--sans); letter-spacing: 1px; color: #8b8474; }
.rcp-sample__doc { padding: 26px 20px 28px; max-width: 720px; margin: 0 auto; }

/* ── how it runs ── */
.rcp-how__grid { display: grid; grid-template-columns: 1fr; gap: 14px; margin: 16px 0 0; }
.rcp-how__cell { background: #fff; border: var(--edge); border-radius: 16px; padding: 18px 19px; }
.rcp-how__k { font: 700 10px var(--sans); letter-spacing: .9px; color: #8b8474; margin-bottom: 11px; }
.rcp-how__v { margin: 0; }
.rcp-how__big { display: block; font-family: var(--serif); font-size: 21px; font-weight: 500; margin-bottom: 7px; }
.rcp-how__sub { display: block; font-size: 13.5px; line-height: 1.6; color: var(--muted); }

/* ── trial timeline (replaces the first-two-weeks band): the visitor's first
     fourteen days if they started this recipe today. One vertical axis down
     the left, three dot styles — hollow for today, filled green for
     deliveries, dashed terracotta for the trial's end — and quiet-gap notes
     riding the line where nothing runs. Row spacing lives INSIDE the entry
     cells (padding-bottom), never on the <li>: grid cells stretch to row
     height, which is what keeps the axis unbroken. ── */
.rcp-tl { background: var(--panel); border: var(--edge); border-radius: 16px; padding: 20px 19px; margin-top: 14px; }
.rcp-tl__head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 12px; margin-bottom: 18px; }
.rcp-tl__kicker { font: 700 10px var(--sans); letter-spacing: .9px; color: #8b8474; }
.rcp-tl__rule { flex: 1 1 24px; align-self: center; border-top: 1.5px solid #e2ddd0; }
.rcp-tl__range { font-family: var(--serif); font-size: 15px; color: var(--ink); white-space: nowrap; }

.rcp-tl__list { list-style: none; margin: 0; padding: 0; }
.rcp-tl__item, .rcp-tl__note { display: grid; grid-template-columns: 52px 20px 1fr; column-gap: 8px; }
.rcp-tl__when { text-align: right; padding-top: 1px; }
.rcp-tl__date { display: block; font-family: var(--serif); font-size: 15px; line-height: 1.2; color: var(--ink); white-space: nowrap; }
.rcp-tl__time { display: block; font: 500 11px var(--sans); color: #a49d8d; margin-top: 2px; }

/* the axis: every row's mark cell draws the line; only items add a dot */
.rcp-tl__mark { position: relative; }
.rcp-tl__mark::before { content: ""; position: absolute; left: 50%; top: 0; bottom: 0; width: 1.5px; transform: translateX(-50%); background: #ddd7c8; }
.rcp-tl__item:first-child .rcp-tl__mark::before { top: 7px; }
.rcp-tl__item--end .rcp-tl__mark::before { bottom: auto; height: 7px; }
.rcp-tl__item .rcp-tl__mark::after { content: ""; position: absolute; left: 50%; top: 4px; transform: translateX(-50%); width: 11px; height: 11px; border-radius: 999px; background: var(--panel); border: 2px solid #a49d8d; }
.rcp-tl__item .rcp-tl__mark--run::after { background: var(--green); border-color: var(--green); }
.rcp-tl__item .rcp-tl__mark--end::after { background: var(--panel); border: 2px dashed var(--rust); }

.rcp-tl__entry { min-width: 0; padding-bottom: 18px; }
.rcp-tl__item--end .rcp-tl__entry { padding-bottom: 0; }
.rcp-tl__k { display: block; font: 700 10px var(--sans); letter-spacing: .9px; color: var(--green); margin-bottom: 4px; }
.rcp-tl__title { display: block; font-family: var(--serif); font-size: 16px; font-weight: 600; line-height: 1.25; margin-bottom: 4px; }
.rcp-tl__title--end { color: var(--rust); }
.rcp-tl__body { font-size: 13px; line-height: 1.55; color: #3f3a30; max-width: 560px; }
.rcp-tl__count { font-family: var(--mono); font-size: 12px; color: var(--green); }
.rcp-tl__quiet { font-family: var(--serif); font-style: italic; font-size: 13px; color: #8b8474; padding: 1px 0 16px; }
.rcp-tl__fine { font-size: 12.5px; color: #8b8474; margin-top: 14px; }

/* ── repeat CTA (detail) ── */
.rcp-close__card { background: #fff; border: var(--edge); border-radius: 18px; padding: 26px 22px; text-align: center; box-shadow: 0 3px 10px rgba(50, 42, 28, .06); }
.rcp-close__title { font-family: var(--serif); font-weight: 500; font-size: clamp(22px, 3.4vw, 29px); line-height: 1.15; margin-bottom: 10px; text-wrap: balance; }
.rcp-close__lead { font-size: 14.5px; line-height: 1.6; color: var(--muted); max-width: 460px; margin: 0 auto 18px; }
.rcp-close__fine { font-size: 12.5px; color: #8b8474; margin-top: 12px; }
.rcp-close__browse { text-align: center; padding: 22px 0 44px; font-size: 13.5px; font-weight: 600; }

/* ── responsive: the design's single 760px break (plus the crumb following
     .mkt-section's 18px gutters below 700px) ── */
@media (max-width: 700px) {
  .rcp-crumb { padding-left: 18px; padding-right: 18px; }

  /* The switcher stays ONE row on a phone. Five chips plus the note wrap to
     three rows otherwise, and since the bar is sticky that is ~110px of a
     ~900px screen permanently spent on a control — on top of the nav above it.
     The chips scroll sideways in their own overflow container instead, so the
     page body never scrolls with them. */
  .rcp-filter { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
  .rcp-filter::-webkit-scrollbar { display: none; }
  .rcp-filter__chip { flex: none; }
  /* The note KEEPS its row. It repeats the count that is already on the "All"
     chip, which is why hiding it looked free — but it is also the only place
     /recipes still says a person reviewed these, the hero lead having been cut
     when this note took the claim over. Hidden here, the page made no claim of
     review at all on a phone, which is most of its readers. Twenty pixels of
     sticky height is the cheaper thing to spend. */
  .rcp-filter__note { width: 100%; padding-bottom: 12px; font-size: 12px; }
}

@media (min-width: 760px) {
  .rcp-hero { padding-top: 44px; }
  .rcp-grid { grid-template-columns: 1fr 1fr; gap: 16px; }
  .rcp-card { padding: 20px 21px; }
  .rcp-card__title { font-size: 23px; }
  .rcp-crumb { padding-top: 40px; }
  .rcp-sample__doc { padding: 32px 30px 34px; }
  .rcp-how__grid { grid-template-columns: 1fr 1fr; gap: 18px; }
  .rcp-tl { padding: 24px 26px; }
  .rcp-tl__item, .rcp-tl__note { grid-template-columns: 72px 24px 1fr; column-gap: 12px; }
}
/* Routines → "Share as a recipe" — the `shr-` family, ported 2026-08-05 from
   claude-design/Share as a Recipe.dc.html. The design draws a bottom sheet over
   the routine; the shipped thing is a standalone PAGE
   (routines/share_recipe.html.erb), so the sheet's card sits centered on the
   app background instead — same surface, border, radii and type, no scrim and
   no sheet animation. Must read at 390px. */

/* No overflow:hidden here — it would make the card the sticky header's
   containing block and the header would never stick; the header clips its own
   top corners instead. */
.shr { width: min(520px, calc(100% - 32px)); margin: 10px auto 40px; background: #f5f2ec; border: 1.5px solid #e0dacd; border-radius: 20px; box-shadow: 0 12px 44px rgba(30, 25, 16, .14); }

/* header: title + the routine it forks from, sticky like the sheet's. Sticks
   below the app bars: .app-topbar is 56px in the scrolling pane; on phones the
   document scrolls under the 52px .mobile-topbar instead. */
.shr-head { position: sticky; top: 56px; z-index: 2; padding: 13px 18px; background: #f5f2ec; border-bottom: 1.5px solid #e6e1d6; border-radius: 19px 19px 0 0; }
.shr-head__title { font-family: "Newsreader", serif; font-size: 19px; font-weight: 500; line-height: 1.2; margin: 0; }
.shr-head__from { font-size: 12px; color: #8b8474; margin: 2px 0 0; }

.shr-error { margin: 18px 18px 0; font-size: 13px; line-height: 1.5; color: #a03d23; background: #fdf6f2; border: 1.5px solid #e8d3ca; border-radius: 12px; padding: 11px 13px; }

.shr-intro { font-size: 13.5px; line-height: 1.6; color: #4a453b; margin: 18px 18px 0; }

.shr-form { padding: 20px 18px 22px; display: flex; flex-direction: column; gap: 20px; }
.shr-field { margin: 0; padding: 0; border: none; }
.shr-lbl { display: block; font: 700 10.5px "Hanken Grotesk", system-ui, sans-serif; letter-spacing: .9px; color: #6f6a5e; margin-bottom: 7px; }

/* the direction fork */
.shr-textarea { width: 100%; min-height: 184px; resize: vertical; box-sizing: border-box; font-family: "Newsreader", serif; font-size: 16px; line-height: 1.55; color: #26221b; background: #fff; border: 1.5px solid #e0dacd; border-radius: 14px; padding: 14px 15px; outline: none; }
.shr-textarea:focus { border-color: #2f6d5b; box-shadow: 0 0 0 3px rgba(47, 109, 91, .14); }

/* becomes-public warning */
.shr-warn { display: flex; align-items: flex-start; gap: 9px; background: #fdf6f2; border: 1.5px solid #e8d3ca; border-radius: 12px; padding: 11px 13px; margin-top: 9px; }
.shr-warn__mark { color: #b0553a; font-size: 13px; line-height: 1.4; flex: none; }
.shr-warn__body { font-size: 12.5px; line-height: 1.55; color: #3f3a30; margin: 0; }

.shr-hint { font-size: 12.5px; line-height: 1.5; color: #8b8474; margin: -3px 0 9px; }

/* radio option cards (sample picker + credit choice) */
.shr-samples, .shr-credit { display: flex; flex-direction: column; gap: 7px; }
.shr-samples .shr-lbl { margin-bottom: 0; }
.shr-samples .shr-hint { margin-bottom: 0; }
.shr-credit .shr-lbl { margin-bottom: 2px; }
.shr-radio { display: flex; align-items: flex-start; gap: 11px; background: #fff; border: 1.5px solid #e0dacd; border-radius: 12px; padding: 12px 13px; cursor: pointer; }
.shr-radio--none { align-items: center; border-style: dashed; border-color: #d8d2c4; }
.shr-radio input[type="radio"] { accent-color: #2f6d5b; width: 17px; height: 17px; margin: 0; flex: none; margin-top: 1px; }
.shr-radio__text { flex: 1; }
.shr-radio__name { display: block; font-size: 13.5px; font-weight: 600; }
.shr-radio--none .shr-radio__name { font-weight: 400; color: #6f6a5e; }
.shr-radio__sub { display: block; font-size: 12px; color: #8b8474; margin-top: 2px; }

/* submit */
.shr-foot { display: flex; flex-direction: column; gap: 10px; padding-top: 2px; }
.shr-submit { width: 100%; font: 600 15px "Hanken Grotesk", system-ui, sans-serif; color: #fff; background: #2f6d5b; border: none; border-radius: 13px; padding: 15px 20px; cursor: pointer; box-shadow: 0 3px 10px rgba(47, 109, 91, .25); }
.shr-submit:hover { background: #28604f; }
.shr-foot__note { font-size: 12.5px; color: #8b8474; text-align: center; margin: 0; }

@media (max-width: 720px) {
  .shr-head { top: 52px; }
}
@media (max-width: 560px) {
  .shr { width: calc(100% - 24px); margin: 8px auto 28px; border-radius: 16px; }
  .shr-head { border-radius: 15px 15px 0 0; }
}
/* User-facing Help & support (ticketing). Standard page frame (matches Routines/History). */
.sup { max-width: 880px; margin: 0 auto; padding: var(--page-top) var(--page-gutter) 90px; }
.sup__intro { font-size: 12.5px; color: #9a9384; margin-bottom: 5px; }
.sup__h1 { font-family: "Newsreader", serif; font-weight: 500; font-size: 30px; line-height: 1.1; margin: 0 0 22px; }
.sup__h1--sm { font-size: 26px; margin-bottom: 6px; }
.sup__lead { font-size: 13px; color: #6f6a5e; margin: 0 0 22px; }
.sup-back { display: inline-flex; align-items: center; gap: 6px; font: 600 12px "Hanken Grotesk"; color: #6f6a5e; margin-bottom: 16px; }
.sup-back:hover { color: #2f6d5b; text-decoration: none; }

/* quick-help cards */
.sup-quick { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; margin-bottom: 14px; }
.sup-quick__card {
  border: 1.5px solid #e6e1d6; border-radius: 13px; background: #fff; padding: 15px 16px;
  display: flex; gap: 12px; align-items: center; color: inherit;
  transition: transform .12s ease, box-shadow .12s ease, border-color .12s ease;
}
.sup-quick__card:hover { border-color: #cfe0d9; background: #fcfbf7; text-decoration: none; transform: translateY(-1px); box-shadow: 0 4px 14px rgba(50,42,28,.06); }
.sup-quick__card:active { transform: translateY(0) scale(.98); }
.sup-quick__icon {
  width: 38px; height: 38px; flex: none; border-radius: var(--radius-md);
  background: var(--primary-tint); border: 1.5px solid var(--primary-border);
  display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.sup-quick__title { font-weight: 600; font-size: 13px; margin-bottom: 2px; color: #26221b; }
.sup-quick__sub { font-size: 11.5px; color: #9a9384; line-height: 1.4; }
.sup-quick__chev { flex: none; margin-left: auto; color: #c2bbac; font-size: 16px; }

/* Two columns squeezes each card to ~150px of text on a phone, so every
   title wraps to three lines and the rows go ragged. Stack them. */
@media (max-width: 560px) {
  .sup-quick { grid-template-columns: 1fr; }
  .sup-quick__card { padding: 14px 15px; }
}

.sup-open { display: flex; align-items: center; gap: 12px; border: 1.5px dashed #cbc4b6; border-radius: 13px; padding: 15px 17px; margin-bottom: 30px; color: inherit; }
.sup-open:hover { border-color: #2f6d5b; background: #f4f8f6; text-decoration: none; }
.sup-open__plus { width: 34px; height: 34px; flex: none; border-radius: 9px; background: #2f6d5b; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 20px; }
.sup-open__text { flex: 1; }
.sup-open__title { font-weight: 600; font-size: 13.5px; }
.sup-open__sub { font-size: 12px; color: #9a9384; }
.sup-open__chev { color: #9a9384; font-size: 18px; }

.sup-divider { display: flex; align-items: baseline; gap: 9px; margin-bottom: 12px; }
.sup-divider span:first-child { font: 700 10px "Hanken Grotesk"; letter-spacing: .6px; color: #9a9384; }
.sup-divider__rule { flex: 1; height: 1.5px; background: #e2ddd0; }

.sup-list { display: flex; flex-direction: column; gap: 9px; }
.sup-row { display: flex; align-items: center; gap: 13px; border: 1.5px solid #e6e1d6; border-radius: 13px; background: #fff; padding: 14px 16px; color: inherit; }
.sup-row:hover { border-color: #cfe0d9; text-decoration: none; }
.sup-row__main { flex: 1; min-width: 0; }
.sup-row__top { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.sup-row__subject { font-weight: 600; font-size: 13.5px; }
.sup-row__dot { width: 7px; height: 7px; border-radius: 50%; background: #2f6d5b; }
.sup-row__meta { font-size: 11.5px; color: #9a9384; }
.sup-row__chev { color: #c2bbac; font-size: 16px; }
.sup-empty { padding: 22px; text-align: center; color: #9a9384; font-size: 12.5px; border: 1.5px solid #f0ece3; border-radius: 13px; }

/* new-ticket form */
.sup--article { max-width: 620px; }
.sup-qa { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
.sup-qa__item { border: 1.5px solid #e6e1d6; border-radius: 13px; background: #fff; padding: 15px 17px; }
.sup-qa__q { font-weight: 600; font-size: 13.5px; margin-bottom: 6px; color: #26221b; }
.sup-qa__a { font-size: 12.5px; line-height: 1.6; color: #6f6a5e; }

.sup--form { max-width: 620px; }
.sup-errors { background: #fbf3f0; border: 1.5px solid #e5c3ba; color: #b45b3e; border-radius: 11px; padding: 11px 14px; font-size: 12.5px; margin-bottom: 16px; }
.sup-lbl { display: block; font-size: 12px; font-weight: 600; color: #6f6a5e; margin: 0 0 9px; }
.sup-cats { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 20px; }
.sup-cat { font: 600 12px "Hanken Grotesk"; padding: 8px 14px; border-radius: 999px; cursor: pointer; border: 1.5px solid #e6e1d6; background: #fff; color: #6f6a5e; }
.sup-cat:has(.sup-cat__input:checked), .sup-cat.is-on { border-color: #2f6d5b; background: #eef4f1; color: #2f6d5b; }
.sup-cat__input { position: absolute; opacity: 0; pointer-events: none; }
.sup-input, .sup-textarea { width: 100%; border: 1.5px solid #e6e1d6; border-radius: 11px; background: #fff; padding: 11px 14px; font: 400 13.5px "Hanken Grotesk"; color: #3a352c; outline: none; margin-bottom: 16px; }
.sup-textarea { font: 400 13px/1.6 "Hanken Grotesk"; resize: vertical; }
.sup-input:focus, .sup-textarea:focus { border-color: #cfe0d9; }
.sup-context { display: flex; gap: 10px; border: 1.5px solid #cfe0d9; background: #f4f8f6; border-radius: 11px; padding: 12px 15px; margin-bottom: 22px; font-size: 12px; line-height: 1.5; color: #2f5f52; }
.sup-context input { margin-top: 2px; accent-color: #2f6d5b; }
.sup-formfoot { display: flex; align-items: center; gap: 14px; }
.sup-formfoot__note { font-size: 12px; color: #9a9384; }
.sup-formfoot__spacer { flex: 1; }

/* thread + messages (shared with admin) */
.sup--thread { max-width: 680px; }
.sup-thread__head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 20px; }
.sup-thread__subject { font-family: "Newsreader", serif; font-weight: 500; font-size: 23px; line-height: 1.2; margin: 0; }
.sup-thread__meta { font-size: 11.5px; color: #9a9384; margin-top: 4px; }
.sup-messages { display: flex; flex-direction: column; gap: 12px; margin-bottom: 20px; }
.sup-msg { display: flex; }
.sup-msg--admin { justify-content: flex-end; }
.sup-bubble { max-width: 80%; border: 1.5px solid #e6e1d6; background: #fff; border-radius: 14px; padding: 12px 15px; }
.sup-msg--admin .sup-bubble { border-color: #cfe0d9; background: #f4f8f6; }
.sup-bubble__head { display: flex; align-items: center; gap: 7px; margin-bottom: 6px; }
.sup-bubble__who { font: 700 9px "Hanken Grotesk"; letter-spacing: .4px; padding: 2px 7px; border-radius: 5px; background: #ece7db; color: #6f6a5e; }
.sup-msg--admin .sup-bubble__who { background: #dcebe5; color: #2f6d5b; }
.sup-bubble__time { font-size: 10.5px; color: #9a9384; }
.sup-bubble__text { font-size: 13px; line-height: 1.6; color: #3a352c; }
.sup-bubble__text p { margin: 0 0 6px; }
.sup-bubble__text p:last-child { margin-bottom: 0; }

.sup-reply { border: 1.5px solid #cfe0d9; border-radius: 14px; background: #fff; overflow: hidden; }
.sup-reply__input { display: block; width: 100%; border: none; outline: none; padding: 13px 15px; font: 400 13px/1.6 "Hanken Grotesk"; color: #3a352c; resize: vertical; }
.sup-reply__foot { display: flex; align-items: center; gap: 10px; padding: 11px 14px; border-top: 1.5px solid #f0ece3; background: #faf8f3; }
.sup-reply__note { font-size: 11.5px; color: #9a9384; }
.sup-reply__spacer { flex: 1; }
/* A plain note above the reopen box — it used to be a panel WRAPPING the
   reply form, which boxed a box and left the button floating inside it. */
.sup-resolved { font-size: 12.5px; color: #9a9384; margin: 0 2px 10px; }
/* "Sorted it yourself?" — the owner closing their own ticket. */
.sup-resolve { margin: 12px 2px 0; font-size: 12.5px; color: #9a9384; }
.sup-resolve__form { display: inline; }
.sup-resolve__link { border: none; background: none; padding: 0; font: inherit; color: #2f6d5b; text-decoration: underline; cursor: pointer; }
.sup-resolve__link:hover { color: #28604f; }
.sup-reply--reopen { margin-top: 10px; }

/* ---------------------------------------------------------------
   Replay the tour — Getting started only.

   Deliberately built to .sup-open's proportions rather than as a button: this
   article is a single column of full-width rows, and the first attempt (a small
   left-aligned pill) read as an element that had fallen in — 42px of air above
   it and none below, at a width nothing else on the page shared.
   --------------------------------------------------------------- */

.sup-replay {
  display: flex; align-items: center; gap: 12px; width: 100%; text-align: left;
  border: 1.5px solid var(--border-default); border-radius: 13px;
  background: var(--paper); padding: 15px 17px; margin-bottom: 10px;
  color: inherit; cursor: pointer; font-family: inherit;
}
.sup-replay:hover { border-color: var(--primary-border); background: var(--primary-tint-2); }
.sup-replay__glyph {
  width: 34px; height: 34px; flex: none; border-radius: 9px;
  background: var(--primary-tint); color: var(--primary);
  display: flex; align-items: center; justify-content: center; font-size: 17px;
}
.sup-replay__text { flex: 1; }
.sup-replay__title { display: block; font-weight: 600; font-size: 13.5px; }
.sup-replay__sub { display: block; font-size: 12px; color: var(--text-faint); }
.sup-replay__chev { color: var(--text-faint); font-size: 18px; }
/* Flash toasts — bottom-right stack, calm slide-in. */
.toast-stack {
  position: fixed; right: 20px; bottom: 20px; z-index: 60;
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  display: flex; align-items: center; gap: 11px;
  max-width: 380px; padding: 12px 14px;
  border-radius: 13px; border: 1.5px solid #e6e1d6; background: #fff;
  box-shadow: 0 12px 34px rgba(50, 42, 28, .16);
  font: 500 13px "Hanken Grotesk", system-ui, sans-serif; color: #26221b;
  opacity: 0; transform: translateY(10px); transition: opacity .26s ease, transform .26s ease;
}
.toast.is-in { opacity: 1; transform: translateY(0); }
.toast.is-leaving { opacity: 0; transform: translateY(10px); }

.toast__icon {
  width: 22px; height: 22px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font: 700 12px "Hanken Grotesk"; color: #fff;
}
.toast--good { border-color: #cfe0d9; }
.toast--good .toast__icon { background: #2f6d5b; }
.toast--bad { border-color: #e7cabf; }
.toast--bad .toast__icon { background: #b45b3e; }

.toast__msg { flex: 1; min-width: 0; line-height: 1.45; }
.toast__x {
  flex: none; background: none; border: none; cursor: pointer;
  color: #b7b0a1; font-size: 12px; padding: 2px 4px; line-height: 1;
}
.toast__x:hover { color: #6f6a5e; }

@media (max-width: 560px) {
  .toast-stack { right: 12px; left: 12px; bottom: 12px; align-items: stretch; }
  .toast { max-width: none; }
}
/* ---------------------------------------------------------------
   joris — Settings › Webhooks (design: Settings - Webhooks.dc.html
   and Settings - Webhook Destinations.dc.html)

   The outbound mirror of Connections, and deliberately the same
   idiom: one list, a 4px left edge for status, the same gold for
   "this needs you". A technical user reading both pages should
   learn one pattern.

   The difference is what the rows carry. A connection row is about
   PERMISSIONS — what joris may touch. A webhook row is about
   RELIABILITY — did it arrive, and will I know if it stops. So the
   numbers lead here where the permission sentence leads there.

   Every colour is a token or one of the connections page's gold
   family; nothing new is invented.
   --------------------------------------------------------------- */

.wh-page .prof-divider { margin: 26px 0 10px; align-items: center; }
.wh-page .prof-divider:first-of-type { margin-top: 0; }

/* Tabs moved to components.css (.tabs / .tab) when the admin LLMs screen
   needed the same Activity/Destinations split — one definition, two screens. */

/* ── Outcome pills + dropdowns ───────────────────────────────────── */
.wh-headline__bad { color: var(--accent); }

/* Outcome pills moved to components.css (.filters / .filter) — the admin
   LLMs screen filters its list the same way. */

.wh-filters {
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  padding-bottom: 18px; margin-bottom: 10px;
  border-bottom: var(--hairline) solid var(--border-divider);
}
/* The caret is a background image because a styled <select> loses the native
   one the moment appearance is reset, and an overlaid SVG would swallow the
   click on the control it sits on. */
.wh-select {
  height: 44px; padding: 0 38px 0 14px;
  border: var(--hairline) solid var(--border); border-radius: var(--radius-md);
  font: 400 var(--text-sm) var(--font-sans); color: var(--ink);
  background-color: var(--paper); cursor: pointer; outline: none;
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='m4 6 4 4 4-4' fill='none' stroke='%239a9384' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
  max-width: 100%;
}
.wh-select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px rgba(47, 109, 91, .35); }

/* ── Pager ───────────────────────────────────────────────────────── */
.wh-pager {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; margin-top: 12px;
}
.wh-pager__count { font: 400 11.5px var(--font-sans); color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.wh-pager__nav { display: flex; gap: 16px; }
.wh-pager__link { font: var(--weight-semibold) 11.5px var(--font-sans); color: var(--primary); }

/* ── The paused banner — a task, with its fix attached ───────────── */
.wh-banner {
  display: flex; gap: 13px; align-items: flex-start;
  padding: 15px 17px; margin: 0 0 18px;
  border: var(--hairline) solid var(--conx-gold-border);
  border-left: 4px solid var(--conx-gold);
  border-radius: var(--radius-xl);
  background: var(--conx-gold-tint);
}
.wh-banner__ic { font-size: 15px; line-height: 1.4; color: var(--conx-gold-ink); flex: none; }
.wh-banner__body { flex: 1; min-width: 0; }
.wh-banner__title {
  font: var(--weight-semibold) var(--text-ui)/1.3 var(--font-sans);
  color: var(--conx-gold-ink-strong); margin-bottom: 3px;
}
.wh-banner__text { margin: 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--conx-gold-ink); }
.wh-banner__text strong { font-weight: var(--weight-semibold); color: var(--conx-gold-ink-strong); }
.wh-banner__act { flex: none; align-self: center; }

/* ── The activity log ────────────────────────────────────────────── */
.wh-log {
  border: var(--hairline) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--paper);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.wh-log > * + * { border-top: var(--hairline) solid var(--border-divider); }

.wh-send { border-left: 4px solid var(--primary); }
.wh-send--failed { border-left-color: var(--accent); }
.wh-send--pending { border-left-color: var(--conx-edge-muted); }

.wh-send__summary {
  display: flex; align-items: center; gap: 14px;
  padding: 11px 16px; cursor: pointer; list-style: none;
}
.wh-send__summary::-webkit-details-marker { display: none; }
.wh-send__caret {
  flex: none; width: 22px; height: 22px; border-radius: 7px;
  background: #e9e5db; color: var(--primary);
  font-size: 12px; line-height: 22px; text-align: center;
  transition: transform .14s, background .12s;
}
.wh-send[open] .wh-send__caret { transform: rotate(180deg); background: var(--primary-chip); }
.wh-send__summary:hover .wh-send__caret { background: var(--primary-chip); }
/* Fixed, so the column reads as a column when you scan down sixty of them. */
.wh-send__when {
  flex: none; width: 104px;
  font: 400 12.5px var(--font-sans); color: #57513f; font-variant-numeric: tabular-nums;
}
.wh-send__main {
  flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 7px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.wh-send__name { font: var(--weight-semibold) var(--text-ui) var(--font-sans); color: var(--ink); }
.wh-send__v { font: var(--weight-semibold) 12px var(--font-sans); color: #57513f; }
.wh-send__dest {
  font: 400 12.5px var(--font-sans); color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis;
}
/* A test ping is not a delivery, and the row says so before you read it. */
.wh-send--test { background: var(--paper-warm); }
.wh-send--test .wh-send__name { color: var(--ink-soft); }

.wh-send__body { padding: 0 17px 17px 52px; }
.wh-send__target { font-size: 12px; color: var(--ink-soft); margin-bottom: 9px; }

.wh-attempts { list-style: none; margin: 0 0 11px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.wh-attempt {
  display: flex; align-items: baseline; gap: 10px;
  font: 400 var(--text-sm) var(--font-sans); color: var(--ink-soft);
}
.wh-attempt__at { flex: none; font-size: 12px; font-variant-numeric: tabular-nums; }
.wh-attempt__n { flex: none; }
.wh-attempt--bad .wh-attempt__out { color: var(--accent); }
.wh-attempt__last { color: var(--ink-faint); }

.wh-send__note {
  margin: 0 0 11px; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--ink-soft);
}
.wh-send__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.wh-send__acts form { display: inline; }

/* ── The body we posted, in place ────────────────────────────────── */
.wh-payload {
  margin: 0 0 11px; border: var(--hairline) solid var(--border);
  border-radius: var(--radius-lg); background: var(--paper-warm); overflow: hidden;
}
.wh-payload__summary {
  display: flex; align-items: baseline; gap: 8px; padding: 10px 13px;
  cursor: pointer; list-style: none;
  font: var(--weight-semibold) var(--text-sm) var(--font-sans); color: var(--primary);
}
.wh-payload__summary::-webkit-details-marker { display: none; }
.wh-payload__caret { flex: none; font-size: 10px; transition: transform .14s; }
.wh-payload[open] .wh-payload__caret { transform: rotate(180deg); }
.wh-payload__hint {
  flex: 1; min-width: 0; font-weight: var(--weight-regular); color: var(--ink-faint);
  font-size: var(--text-xs);
}
.wh-payload__body { padding: 0 13px 13px; }
.wh-payload__label {
  margin: 11px 0 5px;
  font: var(--weight-semibold) 10px var(--font-sans); letter-spacing: .6px;
  text-transform: uppercase; color: var(--ink-faint);
}
/* Wide content scrolls inside its own box — a long URL in the JSON must never
   make the page itself scroll sideways on a phone. */
.wh-payload__json,
.wh-payload__headers {
  margin: 0; padding: 12px 13px; border-radius: var(--radius-sm);
  font-size: 11.5px; line-height: 1.7;
  overflow-x: auto; white-space: pre;
}
/* Dark: it is code, and it should read as code rather than as another
   paragraph on a warm page. Also the ground the syntax colours need. */
.wh-payload__code { position: relative; }
.wh-payload__json {
  max-height: 340px; overflow-y: auto;
  background: #26221b; color: #d8d2c4; border: none;
  padding-right: 46px;
}
.wh-payload__json .tok-key { color: #a9cabd; }
.wh-payload__json .tok-str { color: #e0c48f; }
.wh-payload__json .tok-num { color: #c9a24a; }
.wh-payload__json .tok-lit { color: #c9a24a; }
/* The headers stay light — reference text you read, not code you lift. */
.wh-payload__headers {
  background: var(--paper); border: var(--hairline) solid var(--border);
  color: var(--ink-soft);
}

.wh-payload__copy {
  position: absolute; top: 8px; right: 8px; z-index: 1;
  width: 30px; height: 30px; display: flex; align-items: center; justify-content: center;
  border-radius: 8px; cursor: pointer;
  border: 1px solid rgba(216, 210, 196, .22); background: rgba(216, 210, 196, .1);
  color: #d8d2c4; transition: background .12s, color .12s, border-color .12s;
}
.wh-payload__copy:hover:not(:disabled) { background: rgba(216, 210, 196, .2); color: #fff; }
.wh-payload__copy:disabled { opacity: .35; cursor: default; }
.wh-payload__copy svg { width: 15px; height: 15px; display: block; }
.wh-payload__copy .wh-payload__copy-ok,
.wh-payload__copy.is-copied .wh-payload__copy-i { display: none; }
.wh-payload__copy.is-copied {
  color: #a9cabd; border-color: rgba(169, 202, 189, .5); background: rgba(169, 202, 189, .16);
}
.wh-payload__copy.is-copied .wh-payload__copy-ok { display: block; }
.wh-payload__note {
  margin: 9px 0 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--ink-soft);
}
.wh-payload__note a { color: var(--primary); border-bottom: 1px solid var(--primary-border); }
.wh-payload__note a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* Inline prose links. base.css sets `a { color: inherit; text-decoration:
   none }` globally, so a link inside a sentence is invisible as a link — and
   these pages lean on them more than most ("read it here", "Fix it"). Same
   underline treatment .wt-change__text already uses. */
.wh-send__note a,
.wh-row__note a,
.wh-foot a {
  color: var(--primary); border-bottom: 1px solid var(--primary-border);
}
.wh-send__note a:hover,
.wh-row__note a:hover,
.wh-foot a:hover { color: var(--accent); border-bottom-color: var(--accent); }

/* ── Destination rows ────────────────────────────────────────────── */
.wh-list {
  border: var(--hairline) solid var(--border);
  border-radius: var(--radius-xl);
  background: var(--paper);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.wh-list > * + * { border-top: var(--hairline) solid var(--border-divider); }

.wh-row {
  display: block; padding: 17px 18px;
  border-left: 4px solid var(--primary);
}
/* Saved and inert: nothing real will go here until a test answers, so the edge
   is the muted one rather than the green that means "carrying traffic". */
.wh-row--pending { border-left-color: var(--conx-edge-muted); }
.wh-row--paused { border-left-color: var(--conx-gold); background: var(--conx-gold-wash); }
/* Still sending, but losing deliveries — not paused, and not healthy either. */
.wh-row--failing { border-left-color: var(--accent); }
.wh-row__main { min-width: 0; }
.wh-row__head { display: flex; align-items: center; gap: 9px; margin-bottom: 4px; }
.wh-row__name { font: var(--weight-semibold) var(--text-ui)/1.3 var(--font-sans); color: var(--ink); }
.wh-row__url {
  font-size: 12px; color: var(--ink-soft); margin-bottom: 5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.wh-row__note { margin: 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--ink-soft); }
.wh-row__note strong { font-weight: var(--weight-semibold); color: var(--ink); }
/* Text links under the facts, not a column of buttons beside them: a
   destination row is read far more often than it is acted on. A paused row is
   the exception — those two actions are a task, so they stay buttons. */
.wh-row__acts { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-top: 11px; }
.wh-row__acts form { display: inline; }
.wh-row--paused .wh-row__acts { gap: 9px; }
.wh-act {
  padding: 0; border: none; background: none; cursor: pointer;
  font: var(--weight-semibold) 12.5px var(--font-sans); color: var(--primary);
  text-decoration: none;
}
.wh-act:hover { color: var(--primary-press); text-decoration: underline; }
.wh-act--quiet { color: var(--ink-soft); }
.wh-act--quiet:hover { color: var(--accent); }

/* ── Pills ───────────────────────────────────────────────────────── */
.wh-pill {
  flex: none; padding: 3px 9px; border-radius: var(--radius-pill);
  font: var(--weight-semibold) 11px var(--font-sans); letter-spacing: .2px;
}
.wh-pill--ok      { color: var(--primary);            background: var(--primary-tint); }
.wh-pill--pending { color: var(--ink-soft);           background: var(--paper-warm); }
.wh-pill--paused,
.wh-pill--warn    { color: var(--conx-gold-ink);      background: var(--conx-gold-pill); }
.wh-pill--test    { color: var(--ink-soft);           background: var(--border-divider); }
.wh-pill--bad     { color: var(--accent);             background: var(--danger-tint); }

/* ── Buttons ─────────────────────────────────────────────────────── */
.wh-btn {
  display: inline-flex; align-items: center; justify-content: center;
  padding: 8px 14px; border-radius: var(--radius-md);
  font: var(--weight-semibold) var(--text-sm)/1 var(--font-sans);
  border: var(--hairline) solid transparent; cursor: pointer; text-decoration: none;
  transition: background .12s, border-color .12s, color .12s;
}
.wh-btn:hover { text-decoration: none; }
.wh-btn--primary { background: var(--primary); color: #fff; }
.wh-btn--primary:hover { background: var(--primary-press); color: #fff; }
.wh-btn--ghost { background: var(--paper); color: var(--primary); border-color: var(--border); }
.wh-btn--ghost:hover { border-color: var(--primary-border); color: var(--primary); }
.wh-btn--gold { background: var(--conx-gold); color: var(--conx-gold-on); }
.wh-btn--gold:hover { background: #b8913f; color: var(--conx-gold-on); }
.wh-btn--danger { background: var(--paper); color: var(--accent); border-color: var(--border); }
.wh-btn--danger:hover { border-color: var(--accent); color: var(--accent); }

/* ── The secret, shown once ──────────────────────────────────────── */
.wh-secret {
  padding: 16px 18px; margin: 0 0 20px;
  border: var(--hairline) solid var(--conx-gold-border);
  border-left: 4px solid var(--conx-gold);
  border-radius: var(--radius-xl);
  background: var(--conx-gold-tint);
}
.wh-secret__label {
  font: var(--weight-semibold) 11px var(--font-sans); letter-spacing: .6px;
  text-transform: uppercase; color: var(--conx-gold-ink); margin-bottom: 7px;
}
.wh-secret__row { display: flex; align-items: stretch; gap: 8px; }
.wh-secret__value {
  flex: 1; min-width: 0;
  font-size: 14px; color: var(--conx-gold-ink-strong); word-break: break-all;
  padding: 9px 11px; border-radius: var(--radius-sm); background: var(--paper);
  border: var(--hairline) solid var(--conx-gold-border);
}
.wh-secret__copy { flex: none; }
.wh-secret__copy.is-copied { background: var(--primary); color: #fff; }
@media (max-width: 520px) {
  .wh-secret__row { flex-direction: column; }
}
.wh-secret__note { margin: 8px 0 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--conx-gold-ink); }

/* ── The secret panel's bits inside the shared form dialog ───────── */
/* The dialog itself is .fdlg in dialog.css — Connections uses the same one.
   Only what is specific to the secret panel stays here. */
.fdlg__actions--split .wh-secret__lost {
  flex: 1; min-width: 0; margin: 0; text-align: left;
  font: 400 var(--text-sm)/1.5 var(--font-sans); color: var(--ink-soft);
}
.wh-secret__notes {
  margin: 12px 0 0; padding-left: 18px;
  font: 400 var(--text-sm)/1.6 var(--font-sans); color: var(--ink-soft);
}
.wh-secret__notes li + li { margin-top: 4px; }
.fdlg--wide .wh-secret__label { margin: 16px 0 6px; }

/* ── Empty + foot ────────────────────────────────────────────────── */
.wh-empty {
  padding: 26px 22px; border: var(--hairline) solid var(--border);
  border-radius: var(--radius-xl); background: var(--paper);
}
.wh-empty__title { margin: 0 0 7px; font: var(--weight-semibold) 17px var(--font-display); color: var(--ink); }
.wh-empty__lead { margin: 0 0 14px; font: 400 var(--text-ui)/1.6 var(--font-sans); color: var(--ink-soft); max-width: 62ch; }
.wh-foot { margin: 18px 0 0; font: 400 var(--text-sm)/1.6 var(--font-sans); color: var(--ink-soft); max-width: 70ch; }

/* ── Preview (Personal) ──────────────────────────────────────────── */
.wh-preview__rows {
  border: var(--hairline) solid var(--border); border-radius: var(--radius-xl);
  background: var(--paper); overflow: hidden; box-shadow: var(--shadow-sm);
}
.wh-preview__rows > * + * { border-top: var(--hairline) solid var(--border-divider); }
.wh-preview__row { display: flex; gap: 12px; padding: 15px 18px; align-items: flex-start; }
.wh-preview__tick { flex: none; color: var(--primary); font-size: 14px; line-height: 1.5; }
.wh-preview__title { font: var(--weight-semibold) var(--text-ui)/1.4 var(--font-sans); color: var(--ink); }
.wh-preview__body { margin: 2px 0 0; font: 400 var(--text-sm)/1.55 var(--font-sans); color: var(--ink-soft); }

/* ── Responsive ──────────────────────────────────────────────────── */
@media (max-width: 720px) {
  .wh-row__acts { gap: 14px; }
  /* The destination is the first thing to go: the row already carries the
     routine and the outcome, and 390px has no room for all three. */
  .wh-send__dest { display: none; }
  .wh-send__when { width: 88px; font-size: 12px; }
  .wh-send__summary { gap: 10px; padding: 11px 13px; }
  .wh-send__body { padding-left: 18px; }
  .wh-select { flex: 1 1 100%; }
}
/*
















 */

