/* =========================================================================
   FELIX · CLICKPOST
   Felix wears the ClickPost dashboard's design language: white panels floating
   on a cool grey page, one interactive blue, 12–16px radii, hairline borders,
   sentence-case bold headings and outline icons. No newsprint, no tracked-out
   uppercase display type, no grain — Felix should read as another surface of
   the ClickPost product, not as a separate publication.

   Reference: ClickPost Control Tower / Smart Alerts / Incidents screens.
   ========================================================================= */

:root {
  /* ---- surfaces ---- */
  --page:       #fafafa;   /* app background + sidebar: the dashboard's own grey */
  --surface:    #ffffff;   /* panels, cards */
  --surface-2:  #f8fafd;   /* table headers, quiet fills, hover rows */
  --panel:      #f5f8fe;   /* tinted sidebar nav panel */

  /* ---- ink ---- */
  --ink:        #0f172a;   /* headings */
  --ink-2:      #1e293b;   /* body */
  --ink-3:      #334155;   /* nav labels, table cells */
  /* Both greys are a step darker than the dashboard's slate-500/400: at Felix's
     text sizes those tested thin against white, and answers are the product. */
  --muted:      #56637a;   /* secondary copy — carries real prose, so AA at 13px */
  --muted-2:    #8a97ab;   /* placeholders and decorative marks only */

  /* ---- lines ---- */
  --border:     #e5e9f2;
  --border-2:   #d6dee9;

  /* ---- ClickPost interactive blue ---- */
  --blue:        #3b76f6;
  --blue-hover:  #2c62dd;
  --blue-ink:    #1d4ed8;
  --blue-tint:   #eef4ff;
  --blue-tint-2: #dfe9ff;

  /* ---- status ---- */
  --good:        #15803d;
  --good-tint:   #edfcf2;
  --good-border: #bbe9c9;
  --bad:         #dc2626;
  --bad-tint:    #fef3f2;
  --bad-border:  #fbd2ce;
  --amber:       #b45309;

  /* Kept as aliases so older rules and any inline styles still resolve. */
  --signal:      var(--blue);
  --signal-deep: var(--blue-hover);
  --signal-soft: var(--blue-tint);
  --rule:        var(--border);
  --rule-2:      var(--border-2);
  --paper:       var(--surface);
  --paper-2:     var(--surface-2);
  --paper-3:     var(--blue-tint);

  --font-body:    "Plus Jakarta Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --font-display: var(--font-body);
  --font-label:   var(--font-body);
  --font-mono:    "JetBrains Mono", ui-monospace, SFMono-Regular, monospace;

  --rail: 232px;   /* puts the content panel where the dashboard's starts */

  /* ClickPost shape language: soft, consistent, never sharp. */
  --radius-sm:  8px;    /* pills, small chips */
  --radius:     10px;   /* buttons, inputs */
  --radius-lg:  12px;   /* cards, popovers */
  --radius-xl:  16px;   /* the floating panels themselves */

  --shadow-sm:   0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-card: 0 1px 3px rgba(15, 23, 42, 0.05), 0 1px 2px rgba(15, 23, 42, 0.03);
  --shadow-pop:  0 16px 40px -8px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.06);
  --ring:        0 0 0 3px rgba(59, 118, 246, 0.16);
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  background: var(--page);
  color: var(--ink-2);
  font-family: var(--font-body);
  font-size: 14.5px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow: hidden;
}

button, input, textarea, select { font: inherit; color: inherit; }

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

/* ---------- outline icon system (Lucide-ish, 1.7 stroke) ---------- */
.i {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- small labels ----------
   ClickPost labels sections with quiet bold caps, not wide-tracked eyebrows. */
.eyebrow {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.section-label {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  margin: 4px 0 10px;
}

/* ---------- card scaffolding ---------- */
.card-head { margin-bottom: 18px; }
.card-title {
  font-size: 15.5px;
  font-weight: 700;
  color: var(--ink);
  margin: 0;
  letter-spacing: -0.005em;
}
.card-sub {
  font-size: 12.5px;
  color: var(--muted);
  margin: 4px 0 0;
}

/* =========================================================================
   BUTTONS
   Primary = filled blue. Secondary = white with a blue outline. Ghost =
   neutral outline. Quiet = borderless. All rounded, sentence case, 13.5px.
   ========================================================================= */

.btn-primary,
.btn-secondary,
.btn-ghost,
.btn-quiet,
.btn-new-chat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 9px 16px;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  border-radius: var(--radius);
  border: 1px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: background 130ms ease, border-color 130ms ease,
              color 130ms ease, box-shadow 130ms ease;
}
.btn-block { width: 100%; }

.btn-primary {
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
}
.btn-primary:hover { background: var(--blue-hover); border-color: var(--blue-hover); }
.btn-primary:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-primary:disabled { opacity: 0.55; cursor: default; }

.btn-secondary {
  background: var(--surface);
  border-color: var(--blue);
  color: var(--blue);
}
.btn-secondary:hover { background: var(--blue-tint); color: var(--blue-ink); }
.btn-secondary:focus-visible { outline: none; box-shadow: var(--ring); }

.btn-ghost {
  background: var(--surface);
  border-color: var(--border-2);
  color: var(--ink-3);
}
.btn-ghost:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.btn-ghost:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-ghost.danger { color: var(--bad); border-color: var(--bad-border); }
.btn-ghost.danger:hover { border-color: var(--bad); color: var(--bad); background: var(--bad-tint); }

.btn-quiet {
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  font-weight: 600;
  padding: 8px 10px;
  width: 100%;
  justify-content: flex-start;
}
.btn-quiet:hover { background: var(--surface-2); color: var(--ink); }
.btn-quiet:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-quiet .i { width: 17px; height: 17px; color: var(--muted-2); }
.btn-quiet:hover .i { color: var(--blue); }

/* Pill = the ClickPost sidenav's "Explore Felix AI" button: fully rounded,
   white, a pink-to-blue gradient hairline, ink label. The gradient is a second
   background clipped to the border box, since border-image can't follow a
   radius. `.btn-pill-plain` keeps the shape with a neutral border, for a pill
   that is navigation rather than the screen's main action. */
.btn-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 7px 16px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--ink);
  border: 1.5px solid transparent;
  border-radius: 999px;
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(100deg, #f0a6d8, #b58cf4 45%, #7aa2fb) border-box;
  cursor: pointer;
  white-space: nowrap;
  transition: box-shadow 130ms ease, background 130ms ease, color 130ms ease;
}
.btn-pill .i { width: 17px; height: 17px; color: #7c5cf0; }
.btn-pill:hover {
  background:
    linear-gradient(#faf7ff, #faf7ff) padding-box,
    linear-gradient(100deg, #e98bcb, #a173ef 45%, #5f8ff9) border-box;
  color: var(--ink);
}
.btn-pill:focus-visible { outline: none; box-shadow: var(--ring); }
.btn-pill-plain {
  background:
    linear-gradient(var(--surface), var(--surface)) padding-box,
    linear-gradient(var(--border-2), var(--border-2)) border-box;
  color: var(--ink-3);
}
.btn-pill-plain .i { color: var(--muted); }
.btn-pill-plain:hover {
  background:
    linear-gradient(var(--blue-tint), var(--blue-tint)) padding-box,
    linear-gradient(var(--blue), var(--blue)) border-box;
  color: var(--blue-ink);
}
.btn-pill-plain:hover .i { color: var(--blue); }

/* =========================================================================
   FORM CONTROLS
   Bordered boxes with a soft radius and a blue focus ring — the ClickPost
   input, not an editorial underline.
   ========================================================================= */

.field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: 18px;
}
.field label,
.schedule-form label {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-3);
}
.field input[type="password"],
.field input[type="text"],
.field input[type="email"],
.schedule-form input[type="email"],
.schedule-form select,
.schedule-form textarea {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 10px 13px;
  font-family: var(--font-body);
  font-size: 14px;
  color: var(--ink);
  outline: none;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.field input::placeholder,
.schedule-form input::placeholder,
.schedule-form textarea::placeholder { color: var(--muted-2); }
.field input:focus,
.schedule-form input:focus,
.schedule-form select:focus,
.schedule-form textarea:focus {
  border-color: var(--blue);
  box-shadow: var(--ring);
}
.field .hint,
.schedule-form .hint {
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
}
.field .hint code {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 5px;
}

.alert {
  background: var(--bad-tint);
  border: 1px solid var(--bad-border);
  border-radius: var(--radius);
  padding: 11px 14px;
  font-size: 13px;
  color: #9f1239;
  margin-bottom: 20px;
}

/* =========================================================================
   BRAND LOCKUP
   The ClickPost wordmark with the product name beneath it — the same
   "CLICKPOST / Prism" construction the dashboard uses for its sub-products.
   ========================================================================= */

.brand-masthead {
  display: flex;
  align-items: center;
  gap: 11px;
}
.brand-tile {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 9px;
  /* The mark's ink ground. Uses the palette token rather than a literal so it
     cannot drift from the rest of the blue; the favicons and the mark's own
     knockout halo carry the same value written out, since an SVG in a favicon
     can't read a custom property (see scripts/build_brand_mark.py). */
  background: var(--blue);
  color: #f5f8ff;        /* fallback for any currentColor use inside the tile */
  display: flex;
  align-items: center;
  justify-content: center;
}
.brand-tile svg { width: 100%; height: 100%; }
.brand-lockup { display: flex; flex-direction: column; min-width: 0; }
.brand-wordmark {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--blue);
  line-height: 1.2;
}
.brand-wordmark b { font-weight: 800; color: var(--ink); }
.brand-product {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--ink);
}

/* =========================================================================
   LOGIN
   Blue brand panel + white form pane. Light, product-like, no newsprint.
   ========================================================================= */

.login-shell {
  display: grid;
  grid-template-columns: 1.02fr 0.98fr;
  min-height: 100vh;
  background: var(--surface);
}
html:has(.login-shell), body:has(.login-shell) { overflow: auto; height: auto; }

.login-brand {
  position: relative;
  overflow: hidden;
  padding: 48px 56px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 48px;
  min-height: 100vh;
  color: #fff;
  background:
    radial-gradient(120% 90% at 100% 0%, rgba(255, 255, 255, 0.18), transparent 60%),
    linear-gradient(158deg, #4a80f7 0%, #2c62dd 42%, #1a3fa8 100%);
}
/* A faint dot grid for texture — the ClickPost marketing surfaces do this
   instead of paper grain. */
.login-brand::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: radial-gradient(rgba(255, 255, 255, 0.16) 1px, transparent 1px);
  background-size: 22px 22px;
  mask-image: linear-gradient(to bottom right, rgba(0, 0, 0, 0.9), transparent 70%);
  -webkit-mask-image: linear-gradient(to bottom right, rgba(0, 0, 0, 0.9), transparent 70%);
  pointer-events: none;
}
.login-brand > * { position: relative; }

/* Keeps the ink ground on the blue panel too — a translucent-white tile would
   swallow the near-white monogram. A hairline lifts it off the gradient. */
.login-brand .brand-tile {
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.22);
}
.login-brand .brand-wordmark { color: rgba(255, 255, 255, 0.82); }
.login-brand .brand-wordmark b { color: #fff; }
.login-brand .brand-product { color: #fff; }

.brand-statement { max-width: 470px; }
.brand-statement h1 {
  font-size: clamp(32px, 3.4vw, 44px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.03em;
  margin: 0 0 16px;
  color: #fff;
}
.brand-statement p {
  font-size: 15px;
  line-height: 1.62;
  color: rgba(255, 255, 255, 0.82);
  margin: 0;
}
.brand-points {
  list-style: none;
  margin: 30px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 13px;
}
.brand-points li {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  font-size: 13.5px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.9);
}
.brand-points .i {
  margin-top: 1px;
  color: rgba(255, 255, 255, 0.72);
}

.brand-footer {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 20px;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.6);
}

.login-form-pane {
  background: var(--surface);
  padding: 56px 64px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.login-card { width: 100%; max-width: 400px; }
.login-card .eyebrow { margin-bottom: 12px; color: var(--blue); }
.login-card h2 {
  font-size: 29px;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.15;
  margin: 0 0 10px;
  color: var(--ink);
}
.login-card .lede {
  font-size: 14px;
  color: var(--muted);
  margin: 0 0 30px;
}
.login-altlink {
  margin-top: 24px;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  color: var(--muted);
}

@media (max-width: 900px) {
  .login-shell { grid-template-columns: 1fr; }
  .login-brand { min-height: auto; padding: 36px 28px; gap: 32px; }
  .brand-points { display: none; }
  .login-form-pane { padding: 40px 28px 56px; }
}

/* =========================================================================
   APP SHELL
   Floating white panels on the cool grey page — the ClickPost dashboard frame.
   ========================================================================= */

.app {
  display: grid;
  grid-template-columns: var(--rail) 1fr;
  gap: 14px;
  padding: 14px;
  height: 100vh;
  height: 100dvh;   /* 100vh can exceed the visible area and clip the composer */
  background: var(--page);
}

/* The rail sits straight on the page, not in a card — the ClickPost dashboard
   floats only its content panel. */
.rail {
  background: transparent;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 10px 4px 4px;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: thin;
}
.rail::-webkit-scrollbar { width: 8px; }
.rail::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }
.rail::-webkit-scrollbar-track { background: transparent; }

.rail-brand {
  display: flex;
  align-items: baseline;
  gap: 9px;
  padding: 2px 8px 0;
}
/* The official ClickPost wordmark (webapp/static/clickpost-logo.png, sized
   down from the brand file at 4x for sharp high-density screens). */
.rail-logo { display: block; height: 17px; width: auto; }
.rail .brand-product {
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0;
  line-height: 1;
  color: var(--ink-3);
}
.rail-primary { padding: 0 2px; }

/* ---- navigation: a bold group row with its pages on a guide line ----
   Geometry: the group icon's centre sits 19px in; the guide line runs down
   from under it and each page row gets a short tick off the line, as in the
   dashboard's Analytics group. */
.rail-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.nav-group {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 10px;
  font-size: 15px;
  font-weight: 700;
  /* Blue because it holds the page you are on, as the dashboard colours the
     group of its current page. */
  color: var(--blue-ink);
}
.nav-group .i { width: 19px; height: 19px; color: var(--blue); }
.nav-tree {
  position: relative;
  display: flex;
  flex-direction: column;
  margin-left: 19px;
  padding-left: 0;
  border-left: 1px solid var(--border-2);
}
.nav-item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 11px;
  /* The row starts after its tick, so the current page's tint sits clear of
     the guide line the way the dashboard's does. */
  margin-left: 16px;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  font-size: 14.5px;
  font-weight: 500;
  color: var(--ink-3);
  cursor: pointer;
  transition: color 130ms ease, background 130ms ease;
}
.nav-item::before {
  content: "";
  position: absolute;
  left: -16px;
  top: 50%;
  width: 12px;
  border-top: 1px solid var(--border-2);
}
/* Pages in the tree are text-only, like the dashboard's; their icons exist for
   the icon-only phone rail below. */
.nav-item .i { display: none; }
.nav-item:hover { color: var(--blue); }
.nav-item.is-active {
  background: var(--blue-tint);
  color: var(--blue-ink);
  font-weight: 700;
  cursor: default;
}
.nav-item.is-active::before { border-top-color: var(--blue); }
.nav-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---- rail sections ---- */
.rail-block {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 0 8px;
}
.rail-block .eyebrow { margin-bottom: 2px; }
.rail .spacer { flex: 1 1 auto; min-height: 8px; }
.rail form { margin: 0; }

/* ---- past-chats history list ----
   The list takes ALL the rail's leftover height rather than a fixed 32vh slice,
   so its scroll region ends where the account card begins instead of stopping
   short with dead space under it. It outweighs `.spacer` 100:1, so on a screen
   with no history the spacer still pushes the footer down; with history, the
   list gets essentially everything. */
.rail-history { flex: 100 1 auto; min-height: 0; }
.history-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  margin: 0 -4px;
  padding-bottom: 4px;
}
.history-list::-webkit-scrollbar { width: 6px; }
.history-list::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }
.history-item {
  display: flex;
  align-items: stretch;
  gap: 2px;
  border-radius: var(--radius-sm);
  transition: background 120ms ease;
}
.history-item:hover { background: var(--surface); }
.history-item.active { background: var(--blue-tint); }
.history-open {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: transparent;
  border: 0;
  padding: 7px 8px;
  cursor: pointer;
  text-align: left;
  border-radius: var(--radius-sm);
}
.history-title {
  font-size: 13px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color 120ms ease;
}
.history-item.active .history-title { color: var(--blue-ink); font-weight: 600; }
.history-open:hover .history-title { color: var(--blue); }
.history-time { font-size: 11px; color: var(--muted-2); }
.history-del {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: 0;
  color: var(--muted-2);
  width: 24px;
  height: 24px;
  padding: 0;
  margin-right: 2px;
  cursor: pointer;
  border-radius: 6px;
  opacity: 0;
  transition: opacity 120ms ease, color 120ms ease;
}
/* Same reason as the chip's close control: an SVG cross centres on its geometry,
   a "×" glyph centres on a line box whose ink sits high within it. */
.history-del svg { width: 11px; height: 11px; display: block; }
.history-item:hover .history-del { opacity: 1; }
.history-del:hover { color: var(--bad); }

/* ---- footer: account switcher + session ---- */
.rail-foot {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.rail-account {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 4px 6px;
}
.rail-account-avatar {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--blue-ink);
  color: #fff;
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.rail-account-info { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.rail-account-name {
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rail-account-org {
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rail-session { display: flex; flex-direction: column; }

/* =========================================================================
   CONTENT PANEL
   ========================================================================= */

.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  position: relative;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-card);
}

.main-head {
  padding: 14px 28px 13px;
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}
.head-text { min-width: 0; }
.crumbs {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 12px;
  font-weight: 500;
  margin-bottom: 2px;
}
.crumbs a { color: var(--blue); }
.crumbs a:hover { text-decoration: underline; text-underline-offset: 2px; }
.crumb-sep { color: var(--muted-2); }
.crumb-current { color: var(--ink); font-weight: 700; }
.main-head h1 {
  font-size: 21px;
  font-weight: 800;
  letter-spacing: -0.025em;
  line-height: 1.25;
  margin: 0;
  color: var(--ink);
}
.head-title { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.plan-badge {
  padding: 2px 9px; border-radius: 999px;
  background: var(--blue); color: #fff;
  font-size: 11.5px; font-weight: 700; letter-spacing: 0.02em; line-height: 1.5;
}
.plan-badge[hidden] { display: none; }
/* Free: a quiet neutral chip that is also the way to Pro. */
.plan-badge-free {
  border: 1px solid var(--border-2);
  background: var(--surface-2); color: var(--ink-3);
  font-family: inherit; cursor: pointer;
  transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}
.plan-badge-free:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.plan-badge-free:focus-visible { outline: none; box-shadow: var(--ring); }
.head-sub {
  font-size: 12.5px;
  color: var(--muted);
  margin: 2px 0 0;
  max-width: 620px;
}
.head-actions {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

/* Live status, in the ClickPost "last refreshed" slot. */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 11px 5px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 600;
  color: var(--ink-3);
}
.status-pill .status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--good);
}
.main.is-busy .status-pill { color: var(--blue-ink); border-color: var(--blue-tint-2); background: var(--blue-tint); }
.main.is-busy .status-pill .status-dot { background: var(--blue); animation: pulse-dot 1.1s infinite ease-in-out; }

/* ---------- thread ---------- */
.thread {
  flex: 1;
  overflow-y: auto;
  padding: 28px 32px 20px;
  scroll-behavior: smooth;
  scrollbar-width: thin;
}
.thread::-webkit-scrollbar { width: 10px; }
.thread::-webkit-scrollbar-thumb { background: var(--border-2); border-radius: 99px; }
.thread::-webkit-scrollbar-track { background: transparent; }
/* With only the empty state present, centre it in the available height. */
.thread:has(> #empty-state) {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 24px 32px;
}

.empty-state {
  max-width: 680px;
  width: 100%;
  margin: 0 auto;
}
.empty-state .stamp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 11px 4px 9px;
  margin-bottom: 14px;
  border: 1px solid var(--blue-tint-2);
  border-radius: 999px;
  background: var(--blue-tint);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--blue-ink);
}
.empty-state .stamp .i { width: 14px; height: 14px; stroke: none; }
.empty-state h2 {
  font-size: clamp(24px, 2.7vw, 32px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  margin: 0 0 10px;
  color: var(--ink);
}
.empty-state p {
  font-size: 15px;
  color: var(--muted);
  max-width: 540px;
  margin: 0 0 22px;
}
.empty-state p em { font-style: normal; font-weight: 600; color: var(--ink-3); }

/* ---------- starter cards ---------- */
.suggestion-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  max-width: 680px;
}
@media (max-width: 620px) { .suggestion-grid { grid-template-columns: 1fr; } }
.suggestion-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 14px 40px 15px 15px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
  position: relative;
  box-shadow: var(--shadow-sm);
  transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease, transform 140ms ease;
}
.suggestion-card:hover {
  border-color: var(--blue);
  background: var(--blue-tint);
  box-shadow: var(--shadow-card);
  transform: translateY(-1px);
}
.suggestion-card:focus-visible { outline: none; border-color: var(--blue); box-shadow: var(--ring); }
.suggestion-card .suggestion-tag {
  display: inline-flex;
  align-self: flex-start;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  transition: background 140ms ease, color 140ms ease, border-color 140ms ease;
}
.suggestion-card:hover .suggestion-tag {
  background: #fff;
  border-color: var(--blue-tint-2);
  color: var(--blue-ink);
}
/* Regular weight, not semibold: these are questions the reader might ask, and
   four bold blocks side by side read as four headings competing with the page
   title above them. The tag pill carries the emphasis. */
.suggestion-card .suggestion-text {
  font-size: 15px;
  font-weight: 400;
  line-height: 1.4;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.suggestion-card .suggestion-text em { font-style: normal; }
.suggestion-card .suggestion-arrow {
  position: absolute;
  right: 14px;
  bottom: 13px;
  font-size: 15px;
  color: var(--muted-2);
  transition: color 140ms ease, transform 140ms ease;
}
.suggestion-card:hover .suggestion-arrow { color: var(--blue); transform: translateX(2px); }

/* =========================================================================
   SUGGESTION / FOLLOW-UP CHIP RAIL (above the composer)
   ========================================================================= */

.composer-suggestions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  margin: 0 auto 9px;
}
/* Data-driven eyebrow: "Try" with starters, "Ask next" with follow-ups. */
.composer-suggestions::before {
  content: attr(data-label);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted-2);
  align-self: center;
  margin-right: 3px;
  white-space: nowrap;
  transition: color 200ms ease;
}
.composer-suggestions.followup-mode::before { color: var(--blue); }
.composer-suggestions.is-empty { display: none; }
/* First paint only: the starters arrive on a fetch, and collapsing the rail
   until they land would bounce the composer up and back down under the cursor.
   Hold the row's height (one chip + its border) and hide the eyebrow, so the
   space is reserved and nothing is announced before there's anything to read.
   Dropped once the fetch resolves — a failed fetch collapses like any empty rail. */
.composer-suggestions.is-pending { min-height: 29px; }
.composer-suggestions.is-pending::before { visibility: hidden; }
@media (max-width: 640px) {
  .composer-suggestions {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    scroll-padding-left: 34px;
  }
  .composer-suggestions::-webkit-scrollbar { display: none; }
  .composer-suggestions::before {
    position: sticky;
    left: 0;
    background: var(--surface);
    padding-right: 6px;
    z-index: 1;
  }
  .composer-suggestions > * { flex: 0 0 auto; }
}
/* One-shot cue when follow-up chips arrive: the eyebrow brightens, nothing
   loops and nothing moves the layout. */
.composer-suggestions.just-arrived::before { animation: rail-cue 1.1s ease-out; }
@keyframes rail-cue {
  0%   { color: var(--blue); }
  18%  { color: var(--blue-ink); }
  100% { color: var(--blue); }
}

/* ClickPost pill: full radius, hairline border, tint on hover. */
.chip {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 12px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--muted);
  cursor: pointer;
  text-align: left;
  transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}
.chip:hover { background: var(--blue-tint); border-color: var(--blue-tint-2); color: var(--blue-ink); }
.chip:focus-visible {
  outline: none;
  background: var(--blue-tint);
  border-color: var(--blue);
  color: var(--blue-ink);
  box-shadow: var(--ring);
}

/* ---------- follow-up chips ("Ask next") ----------
   Two-part pill: the text sends, the pencil loads it into the composer to edit
   first. It must always read as ONE object, so the whole pill tints and only the
   control actually under the cursor changes its own colour. */
.followup-chip {
  display: inline-flex;
  align-items: stretch;
  max-width: 100%;
  /* Deliberately the same shape and metrics as the `.chip` starters that share
     this row — the two sets swap in and out, so a different radius would make
     the handover look like a different widget. */
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
  opacity: 1;
  /* `backwards`, NOT `forwards`: a forwards-filled animation keeps asserting its
     final transform, which outranks normal declarations and would kill hover. */
  animation: chip-in 240ms cubic-bezier(0.22, 0.61, 0.36, 1) backwards;
  transition: background 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}
@keyframes chip-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.followup-chip:hover,
.followup-chip:focus-within { background: var(--blue-tint); border-color: var(--blue-tint-2); }
.followup-chip:focus-within { border-color: var(--blue); box-shadow: var(--ring); }

.followup-chip .fu-send,
.followup-chip .fu-edit {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--ink-3);
  transition: color 130ms ease;
}
/* Scoped to the half actually under the cursor — darkening the text while the
   pencil is hovered would point at the wrong action. */
.followup-chip .fu-send:hover,
.followup-chip .fu-send:focus-visible { color: var(--blue-ink); }
.followup-chip .fu-send:focus-visible,
.followup-chip .fu-edit:focus-visible { outline: none; }
.followup-chip .fu-send {
  padding: 5px 7px 5px 12px;
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.35;
  text-align: left;
  min-width: 0;
}
/* The pencil stays quiet at rest — four always-lit icons make the row busy, and
   sending is the primary action. It brightens whenever the chip is engaged. */
.followup-chip .fu-edit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 27px;
  flex: 0 0 27px;
  color: var(--border-2);
  border-left: 1px solid var(--border);
}
.followup-chip .fu-edit svg {
  width: 12px;
  height: 12px;
  display: block;
  transition: transform 130ms ease;
}
.followup-chip:hover .fu-edit,
.followup-chip:focus-within .fu-edit { color: var(--muted-2); border-left-color: var(--blue-tint-2); }
.followup-chip .fu-edit:hover,
.followup-chip .fu-edit:focus-visible { color: var(--blue-ink); }
.followup-chip .fu-edit:hover svg { transform: rotate(-8deg) scale(1.06); }
.followup-chip .fu-edit:active svg { transform: rotate(-8deg) scale(0.94); }

@media (prefers-reduced-motion: reduce) {
  .followup-chip { animation-duration: 1ms; }
  .followup-chip .fu-edit:hover svg,
  .followup-chip .fu-edit:active svg { transform: none; }
  .composer-suggestions.just-arrived::before { animation: none; }
  .suggestion-card:hover { transform: none; }
}

/* =========================================================================
   MESSAGES
   ========================================================================= */

.msg-row {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 28px;
  max-width: 820px;
}
/* Tight row gap so the timestamp hugs the bubble it belongs to rather than
   drifting in the whitespace beneath it. */
.msg-row.user { align-items: flex-end; margin-left: auto; max-width: 720px; gap: 3px; }

/* The reader's question as a tinted ClickPost bubble. */
.msg-user {
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  background: var(--blue-tint);
  border: 1px solid var(--blue-tint-2);
  border-radius: var(--radius-lg) var(--radius-lg) 4px var(--radius-lg);
  padding: 10px 15px 11px;
  max-width: 100%;
  white-space: pre-wrap;
}
.msg-user::before {
  content: "You";
  display: block;
  margin-bottom: 3px;
  font-size: 11px;
  font-weight: 700;
  color: var(--blue-ink);
  opacity: 0.75;
}

.assistant-block {
  display: flex;
  flex-direction: column;
  gap: 10px;
  position: relative;
}

/* When a turn was asked / answered. Small, grey, and out of the reading column's
   way — it's provenance, not content, and it matters most on a reopened chat
   where "last week's numbers" needs a date to mean anything. */
.msg-time {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--muted-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.msg-row.user .msg-time { padding-right: 2px; }
/* The answer's stamp sits at the foot of the block, under the content. */
.assistant-block > .msg-time { align-self: flex-start; margin-top: -2px; }

/* Felix's byline, mirroring the ClickPost activity-timeline entry header. */
.assistant-byline {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}
.assistant-byline .byline-tile {
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: var(--blue);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}
.assistant-byline .byline-tile svg { width: 100%; height: 100%; }
.assistant-byline .byline-org {
  font-size: 11px;
  font-weight: 600;
  color: var(--muted-2);
}

.tools-container {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tools-container:empty { display: none; }

/* ---------- assistant markdown ---------- */
.msg-assistant {
  color: var(--ink-2);
  font-size: 15.5px;
  line-height: 1.7;
  /* Declared on the BASE (not only on .thinking) so the graduation out of
     thinking animates too. */
  transition: color 0.18s ease, padding-left 0.18s ease;
}
.msg-assistant > *:first-child { margin-top: 0; }
.msg-assistant > *:last-child { margin-bottom: 0; }

.msg-assistant h1,
.msg-assistant h2,
.msg-assistant h3 {
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 22px 0 8px;
  line-height: 1.25;
}
.msg-assistant h1 { font-size: 20px; }
.msg-assistant h2 { font-size: 17.5px; }
.msg-assistant h3 { font-size: 15.5px; }
.msg-assistant p { margin: 10px 0; }
.msg-assistant strong { font-weight: 700; color: var(--ink); }
.msg-assistant em { font-style: italic; }
.msg-assistant ul, .msg-assistant ol { margin: 10px 0; padding-left: 20px; }
.msg-assistant li { margin: 4px 0; }
/* Ink, not blue: a list marker isn't interactive, and answers already carry blue in
   links, code and the caveat rule. */
.msg-assistant li::marker { color: var(--ink-3); }
.msg-assistant hr { border: 0; border-top: 1px solid var(--border); margin: 20px 0; }

.msg-assistant code {
  font-family: var(--font-mono);
  font-size: 0.86em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 1px 5px;
  color: var(--ink);
}
.msg-assistant pre {
  background: #0f172a;
  color: #e2e8f0;
  padding: 14px 16px;
  border-radius: var(--radius-lg);
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.6;
  overflow-x: auto;
  margin: 14px 0;
}
.msg-assistant pre code { background: transparent; border: 0; color: inherit; padding: 0; }

/* ClickPost data table: shaded header, hairline grid, rounded card edge. */
.msg-assistant table {
  border-collapse: separate;   /* `collapse` would ignore border-radius */
  border-spacing: 0;
  margin: 16px 0;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.msg-assistant thead th { background: var(--surface-2); }
.msg-assistant th {
  text-align: left;
  padding: 10px 12px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}
.msg-assistant td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  color: var(--ink-2);
}
.msg-assistant th + th,
.msg-assistant td + td { border-left: 1px solid var(--border); }
.msg-assistant tbody tr:last-child td { border-bottom: 0; }
/* Honour markdown column alignment (marked.js emits align="..."). */
.msg-assistant th[align="right"],  .msg-assistant td[align="right"]  { text-align: right; }
.msg-assistant th[align="center"], .msg-assistant td[align="center"] { text-align: center; }
.msg-assistant th[align="left"],   .msg-assistant td[align="left"]   { text-align: left;  }
.msg-assistant tbody tr:hover td { background: var(--surface-2); }
/* While streaming, lock column widths so each new row doesn't re-wrap the whole
   table (the visible "jumping"). The finished table reverts to natural widths. */
.msg-assistant.streaming table { table-layout: fixed; }
.msg-assistant.streaming th,
.msg-assistant.streaming td { overflow-wrap: anywhere; }

.msg-assistant blockquote {
  border-left: 3px solid var(--blue-tint-2);
  background: var(--surface-2);
  border-radius: 0 var(--radius) var(--radius) 0;
  padding: 10px 14px;
  color: var(--ink-3);
  margin: 14px 0;
}
.msg-assistant a { color: var(--blue); }
.msg-assistant a:hover { text-decoration: underline; text-underline-offset: 2px; }

/* THINKING state: while streaming, text renders muted with a pulsing dot, so it
   reads as Felix thinking out loud — never as the committed answer. */
.msg-assistant.thinking {
  position: relative;
  padding-left: 20px;
  color: var(--muted);
}
.msg-assistant.thinking::before {
  content: "";
  position: absolute;
  left: 1px;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted-2);
  animation: pulse-dot 1.1s infinite ease-in-out;
}
/* Caret while an answer streams. The live answer renders append-only (smd), so
   the caret hangs off the container and trails the last rendered node. */
.msg-assistant.streaming::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 1.05em;
  margin-left: 2px;
  border-radius: 1px;
  background: var(--blue);
  vertical-align: text-bottom;
  animation: caret-blink 1s steps(1, end) infinite;
}
@keyframes caret-blink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.3; transform: scale(0.62); }
}

/* ---------- single "working" indicator ---------- */
.work-indicator {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  background: var(--blue-tint);
  border: 1px solid var(--blue-tint-2);
  border-radius: 999px;
  padding: 5px 13px 5px 11px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  animation: work-in 0.2s ease both;
}
.work-indicator .work-square {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--blue);
  flex-shrink: 0;
  animation: pulse-dot 1.1s infinite ease-in-out;
}
.work-indicator .work-label { color: var(--blue-ink); font-weight: 700; }
.work-indicator .work-dots { display: inline-flex; gap: 3px; }
.work-indicator .work-dots i {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--muted-2);
  animation: work-bounce 1.2s infinite ease-in-out;
}
.work-indicator .work-dots i:nth-child(2) { animation-delay: 0.16s; }
.work-indicator .work-dots i:nth-child(3) { animation-delay: 0.32s; }
@keyframes work-bounce {
  0%, 80%, 100% { opacity: 0.25; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-3px); }
}
@keyframes work-in {
  from { opacity: 0; transform: translateY(2px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* ---------- feedback ---------- */
.feedback-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  opacity: 0;
  animation: work-in 0.3s ease 0.1s forwards;
}
.feedback-bar .fb-label { margin-right: 2px; }
.feedback-bar .fb-btn {
  width: 28px;
  height: 26px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-sm);
  transition: color 0.12s ease, border-color 0.12s ease, background 0.12s ease;
}
.feedback-bar .fb-btn .i { width: 14px; height: 14px; }
/* Up is green, down is red — a rating reads faster as its own semantic colour
   than as the product's interactive blue, which says "clickable", not "good". */
.feedback-bar .fb-btn[data-v="1"]:hover {
  color: var(--good);
  border-color: var(--good-border);
  background: var(--good-tint);
}
.feedback-bar .fb-btn[data-v="1"].selected {
  background: var(--good);
  border-color: var(--good);
  color: #fff;
}
.feedback-bar .fb-btn[data-v="-1"]:hover {
  color: var(--bad);
  border-color: var(--bad-border);
  background: var(--bad-tint);
}
.feedback-bar .fb-btn[data-v="-1"].selected {
  background: var(--bad);
  border-color: var(--bad);
  color: #fff;
}

.fb-note {
  display: flex;
  flex-direction: column;
  gap: 8px;
  opacity: 0;
  animation: work-in 0.3s ease forwards;
}
/* `display: flex` above beats the UA [hidden] rule, so re-assert it. */
.fb-note[hidden] { display: none; }
.fb-note .fb-note-input {
  width: 100%;
  resize: vertical;
  padding: 9px 11px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  line-height: 1.5;
}
.fb-note .fb-note-input:focus { outline: none; border-color: var(--blue); box-shadow: var(--ring); }
.fb-note .fb-note-row { display: flex; align-items: center; gap: 9px; }
.fb-note .fb-note-send {
  border: 1px solid var(--blue);
  background: var(--surface);
  color: var(--blue);
  font-size: 12.5px;
  font-weight: 600;
  padding: 6px 14px;
  cursor: pointer;
  border-radius: var(--radius);
  transition: background 0.12s ease, color 0.12s ease;
}
.fb-note .fb-note-send:hover { background: var(--blue-tint); color: var(--blue-ink); }
.fb-note .fb-note-status { font-size: 12px; color: var(--muted); }

/* ---------- stopped note ---------- */
.stopped-note {
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
}
.stopped-note::before {
  content: "";
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: var(--muted-2);
}

/* =========================================================================
   BANNERS, USAGE, LIMITS
   ========================================================================= */

.error-banner {
  background: var(--bad-tint);
  border: 1px solid var(--bad-border);
  border-radius: var(--radius-lg);
  color: #9f1239;
  padding: 12px 15px;
  font-size: 13px;
  margin: 8px 0;
}
/* Usage-limit banner: informational blue, not error red. */
.error-banner.limit-banner {
  background: var(--blue-tint);
  border-color: var(--blue-tint-2);
  color: var(--ink-2);
}
.limit-banner .limit-msg { margin-bottom: 10px; }

.limit-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.limit-cta {
  border: 1px solid var(--blue);
  background: var(--blue);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  padding: 7px 14px;
  cursor: pointer;
  border-radius: var(--radius);
  transition: background 0.13s ease;
}
.limit-cta:hover { background: var(--blue-hover); }
.limit-cta:disabled { opacity: 0.55; cursor: default; }
.limit-status { font-size: 12px; color: var(--muted); }
/* Mobile number asked for just before the paid checkout. */
.limit-phone {
  font: inherit;
  font-size: 12.5px;
  padding: 6px 10px;
  width: 15.5em;
  max-width: 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
}
.limit-phone:focus { outline: 2px solid var(--blue); outline-offset: 1px; }
/* ---- standalone upgrade page (/upgrade) — the dialog's panel on a page ---- */
.upgrade-page {
  min-height: 100vh; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 32px 16px; background: var(--page); font-family: var(--font-body);
}
.upgrade-page-card {
  width: min(452px, 100%); box-sizing: border-box;
  padding: 28px 28px 22px; border: 1px solid var(--border); border-radius: 16px;
  background: var(--surface); color: var(--ink-2);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 32px rgba(15, 23, 42, 0.08);
}
.upgrade-page-loading { margin: 0; color: var(--muted); font-size: 13.5px; }
.upgrade-page-foot { margin: 16px 0 0; font-size: 13px; }
.upgrade-page-foot a { color: var(--blue-ink); font-weight: 600; text-decoration: none; }
.upgrade-page-foot a:hover { text-decoration: underline; }
.upgrade-page .upgrade-head { padding-right: 0; }
.upgrade-returned { margin: 0 0 18px; }
.upgrade-link { text-align: center; text-decoration: none; box-sizing: border-box; }
.upgrade-request { margin-top: 20px; }
/* "Open Felix" under a primary action is the way out, not the thing to do. */
.upgrade-next + .upgrade-link-quiet {
  margin-top: 10px; background: transparent; color: var(--ink-2); border-color: var(--border);
}
@media (max-width: 480px) {
  .upgrade-page { justify-content: flex-start; padding-top: 16px; }
  .upgrade-page-card { padding: 22px 18px 18px; }
}
.flash .flash-upgrade { margin-left: 6px; font-weight: 700; color: var(--blue-ink); white-space: nowrap; }
.usage-card.billing-return { font-size: 13.5px; color: var(--ink-2); }

/* ---- upgrade dialog (Free vs Pro, price, mobile number) ----
   One loud thing: the Pro column, outlined in the interactive blue with a solid
   head, so the comparison reads as the plan being chosen. Everything else stays
   in the dashboard's quiet panel language. */
.upgrade-dialog {
  width: min(452px, calc(100vw - 32px));
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  padding: 28px 28px 22px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  color: var(--ink-2);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.06), 0 20px 48px rgba(15, 23, 42, 0.18);
  font-family: var(--font-body);
}
.upgrade-dialog::backdrop { background: rgba(15, 23, 42, 0.42); }
.upgrade-dialog[open] { animation: upgrade-in 0.16s ease-out; }
@keyframes upgrade-in { from { opacity: 0; transform: translateY(6px); } }
@media (prefers-reduced-motion: reduce) { .upgrade-dialog[open] { animation: none; } }
.upgrade-close {
  position: absolute; top: 16px; right: 16px;
  width: 32px; height: 32px; border: 0; border-radius: 8px;
  background: transparent; color: var(--muted);
  display: grid; place-items: center; padding: 0; cursor: pointer;
}
.upgrade-close svg { width: 16px; height: 16px; display: block; }
.upgrade-close:hover { background: var(--surface-2); color: var(--ink); }
.upgrade-close:focus-visible,
.upgrade-go:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
.upgrade-head { padding-right: 32px; }
.upgrade-head h2 { margin: 0 0 6px; font-size: 21px; line-height: 1.25; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }
.upgrade-head p { margin: 0; font-size: 13.5px; color: var(--muted); line-height: 1.5; }

.upgrade-compare { margin: 22px 0 0; font-variant-numeric: tabular-nums; }
.upgrade-row {
  display: grid; grid-template-columns: 1fr 88px 132px; align-items: stretch;
  font-size: 13.5px;
}
.upgrade-row > div { padding: 12px 12px; display: flex; align-items: center; }
.upgrade-row:not(.upgrade-row-head) > .upgrade-label,
.upgrade-row:not(.upgrade-row-head) > .upgrade-free { border-top: 1px solid var(--border); }
.upgrade-label { color: var(--ink-3); padding-left: 0 !important; }
.upgrade-free { color: var(--muted); justify-content: flex-end; }
.upgrade-row-head > div { white-space: nowrap; font-size: 12.5px; font-weight: 600; padding-top: 8px; padding-bottom: 8px; }
.upgrade-row-head .upgrade-free { color: var(--muted); }
/* The Pro column: a blue frame running head to foot. */
.upgrade-pro {
  justify-content: flex-end; gap: 8px;
  font-weight: 700; font-size: 15px; color: var(--ink);
  background: var(--blue-tint);
  border-left: 2px solid var(--blue); border-right: 2px solid var(--blue);
}
.upgrade-row:not(.upgrade-row-head) > .upgrade-pro { border-top: 1px solid var(--blue-tint-2); }
.upgrade-row-head .upgrade-pro {
  background: var(--blue); color: #fff; font-size: 13px;
  border-radius: 10px 10px 0 0; justify-content: center;
}
.upgrade-row:last-child .upgrade-pro { border-bottom: 2px solid var(--blue); border-radius: 0 0 10px 10px; }
.upgrade-gain {
  font-size: 11px; font-weight: 700; color: var(--blue-ink);
  background: var(--surface); border: 1px solid var(--blue-tint-2);
  border-radius: 999px; padding: 1px 7px;
}

.upgrade-price { display: flex; align-items: baseline; flex-wrap: wrap; column-gap: 12px; row-gap: 2px; margin: 24px 0 4px; }
.upgrade-amount { font-size: 26px; font-weight: 800; color: var(--ink); letter-spacing: -0.02em; }
.upgrade-amount small { font-size: 14px; font-weight: 600; color: var(--muted); letter-spacing: 0; margin-left: 2px; }
.upgrade-intro {
  align-self: center; padding: 3px 10px; border-radius: 999px;
  background: var(--blue); color: #fff; font-size: 12px; font-weight: 700; letter-spacing: 0.01em;
}
.upgrade-terms { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.5; max-width: 38em; }
.upgrade-form { display: flex; gap: 6px; flex-wrap: wrap; margin: 18px 0 0; }
.upgrade-phone-label { flex: 1 1 100%; font-size: 12.5px; font-weight: 600; color: var(--ink-3); margin-bottom: -1px; }
.upgrade-form .limit-phone { flex: 1 1 12em; width: auto; font-size: 14px; padding: 10px 12px; border-color: var(--border-2); }
.upgrade-go { font-size: 14px; padding: 10px 18px; }
/* Step 2 stacks: label, field, label, field, then the full-width pay button. */
.upgrade-form .upgrade-field { flex: 1 1 100%; margin-bottom: 8px; }
/* The country code sits inside the mobile field's left edge, divided from the digits. */
.upgrade-prefixed {
  display: flex; align-items: stretch; box-sizing: border-box;
  border: 1px solid var(--border-2); border-radius: var(--radius);
  background: var(--surface);
}
.upgrade-prefixed:focus-within { outline: 2px solid var(--blue); outline-offset: 1px; }
.upgrade-prefix {
  display: flex; align-items: center; padding: 0 10px 0 12px;
  border-right: 1px solid var(--border); background: var(--surface-2);
  border-radius: var(--radius) 0 0 var(--radius);
  font-size: 14px; font-weight: 600; color: var(--ink-3);
}
/* The country-code button: just "+91" and a caret; it opens the search panel. */
.upgrade-country {
  gap: 6px; padding-right: 10px;
  border-top: 0; border-bottom: 0; border-left: 0;
  font-family: inherit; cursor: pointer;
}
.upgrade-country:hover { background: var(--blue-tint); }
.upgrade-country:disabled { cursor: default; color: var(--muted); background: var(--surface-2); }
.upgrade-country::after {
  content: ""; width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 5px solid var(--muted);
}
.upgrade-country[aria-expanded="true"]::after { border-top: 0; border-bottom: 5px solid var(--muted); }
/* Opens inside the form under the mobile field, so the dialog never clips it. */
.upgrade-country-panel {
  flex: 1 1 100%; margin: -2px 0 8px; overflow: hidden;
  border: 1px solid var(--border-2); border-radius: var(--radius);
  background: var(--surface); box-shadow: 0 8px 24px rgba(15, 23, 42, 0.10);
}
.upgrade-country-panel:focus-within { outline: 2px solid var(--blue); outline-offset: 1px; }
.upgrade-country-search {
  display: block; width: 100%; box-sizing: border-box;
  border: 0; border-bottom: 1px solid var(--border); outline: 0;
  padding: 10px 12px; font: inherit; font-size: 14px; color: var(--ink); background: transparent;
}
.upgrade-country-search::placeholder { color: var(--muted-2); }
.upgrade-country-list { list-style: none; margin: 0; padding: 4px; max-height: 216px; overflow-y: auto; }
.upgrade-country-list li {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 8px 10px; border-radius: var(--radius-sm);
  font-size: 13.5px; color: var(--ink-2); cursor: pointer;
}
.upgrade-country-list li.is-active { background: var(--blue-tint); }
.upgrade-country-list li[aria-selected="true"] { font-weight: 600; color: var(--blue-ink); }
.upgrade-country-dial { color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.upgrade-country-empty { margin: 0; padding: 10px 12px; font-size: 13px; color: var(--muted); }
.upgrade-prefixed-input {
  flex: 1; min-width: 0; border: 0; outline: 0; background: transparent;
  font: inherit; font-size: 14px; padding: 10px 12px; color: var(--ink);
}
.upgrade-prefixed-input:disabled { color: var(--muted); }
.upgrade-form .upgrade-pay { flex: 1 1 100%; margin-top: 4px; }
.upgrade-next { display: block; width: 100%; margin-top: 22px; }
.upgrade-step[hidden] { display: none; }
.upgrade-back {
  border: 0; background: none; padding: 4px 0; margin: -6px 0 12px;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--blue-ink); cursor: pointer;
}
.upgrade-back:hover { text-decoration: underline; }
.upgrade-back:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 4px; }
.upgrade-summary {
  margin: 18px 0 0; padding: 10px 12px; border-radius: 10px;
  background: var(--blue-tint); color: var(--ink-2); font-size: 13px; font-weight: 600;
}
.upgrade-status { margin: 8px 0 0; min-height: 1em; }
@media (max-width: 480px) {
  .upgrade-dialog { padding: 24px 18px 18px; }
  .upgrade-row { grid-template-columns: 1fr 74px 112px; font-size: 13px; }
  .upgrade-row > div { padding: 11px 8px; }
  .upgrade-go { flex: 1 1 100%; }
}

/* ---- /usage card ---- */
.usage-card {
  max-width: 480px;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  padding: 18px 20px 20px;
}
.usage-card .usage-head {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  margin-bottom: 16px;
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border);
}
.usage-row + .usage-row { margin-top: 16px; }
.usage-row-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}
.usage-row .usage-label { font-size: 13.5px; font-weight: 600; color: var(--ink); }
.usage-row .usage-count { font-size: 13px; font-weight: 600; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.usage-row .usage-count.over { color: var(--bad); }
.usage-bar {
  position: relative;
  height: 6px;
  border-radius: 99px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  margin: 8px 0 5px;
  overflow: hidden;
}
.usage-bar > span {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  border-radius: 99px;
  background: var(--blue);
  transition: width 220ms ease;
}
.usage-bar > span.over { background: var(--bad); }
.usage-row .usage-reset { font-size: 11.5px; color: var(--muted-2); }
.usage-card .usage-note { margin-top: 14px; font-size: 12.5px; color: var(--muted); }
/* Why the rows above look fine yet nothing sends: the organization's cap. */
.usage-card .usage-note-blocked {
  padding: 10px 12px;
  border: 1px solid var(--bad-border);
  border-radius: var(--radius);
  background: var(--bad-tint);
  color: var(--ink-2);
}
.usage-card .limit-actions { margin-top: 16px; }
/* A second section (organisation, then the reader's own) starts clear of the rows above. */
.usage-card .usage-row + .usage-head { margin-top: 20px; }
.usage-card .usage-plan .limit-actions { margin-top: 10px; }
/* Secondary action (cancel): outlined, so it never competes with the primary CTA. */
.limit-cta.limit-cta-quiet { background: transparent; color: var(--ink-2); border-color: var(--border); }
.limit-cta.limit-cta-quiet:hover { background: var(--surface-2); }

/* ---- exhausted-cap strip on the composer ----
   Raised by chat.js when the caller's cap is already spent, so the limit is
   known before a question is typed. A strip, not a panel: the workspace is the
   box below it. */
.limit-notice {
  position: relative;
  isolation: isolate;   /* keeps the ::after wash's negative z-index inside */
  margin: 0 auto 10px;
  display: flex;
  align-items: baseline;
  column-gap: 0;        /* the action follows the message by one word space */
  row-gap: 4px;
  flex-wrap: wrap;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--muted);
}
.limit-notice[hidden] { display: none; }
.limit-notice::before {
  content: "";
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--bad);
  transform: translateY(-2px);
  margin-right: 8px;
}
/* While capped, every canned question is a dead end, so both places that offer
   them stand down. (Follow-ups are also dropped in JS — see showFollowups.) */
.main.is-limited .composer-suggestions,
.main.is-limited .empty-state .suggestion-grid { display: none; }
.limit-notice-msg { flex: 0 1 auto; min-width: 0; color: var(--ink-2); }
/* The action reads as text: at this size a filled button would outweigh the
   composer it sits on. */
.limit-notice .limit-cta {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  padding: 0;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--blue);
  cursor: pointer;
}
.limit-notice .limit-cta:hover { background: transparent; color: var(--blue-hover); }
.limit-notice .limit-cta:disabled { opacity: 0.55; cursor: default; }
.limit-notice .limit-actions { flex: 0 0 auto; gap: 5px; margin-left: 4px; }
.limit-notice .limit-status { font-size: 12.5px; }
/* Re-assert the notice when a capped reader sends anyway (flashLimitNotice).
   One soft wash behind the text, then it settles — flipping the text red twice
   was a literal <blink>. The wash is a pseudo-element so nothing reflows. */
@keyframes limit-wash {
  0%, 35% { opacity: 1; }
  100%    { opacity: 0; }
}
.limit-notice::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: -6px -10px;
  border-radius: var(--radius);
  background: rgba(220, 38, 38, 0.09);
  opacity: 0;
  pointer-events: none;
}
.limit-notice.nudge::after { animation: limit-wash 0.75s ease-out; }
@media (prefers-reduced-motion: reduce) {
  .limit-notice.nudge::after { animation: none; }
}

/* =========================================================================
   COMPOSER
   One bordered, rounded field with the send button inside it — the ClickPost
   search/input treatment, scaled up.
   ========================================================================= */

.composer-wrap {
  border-top: 1px solid var(--border);
  background: var(--surface);
  padding: 16px 32px 20px;
}
.composer-wrap > * { max-width: 980px; margin-left: auto; margin-right: auto; }

.composer {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 10px;
  max-width: 980px;
  margin: 0 auto;
  position: relative;
  padding: 8px 8px 8px 16px;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  transition: border-color 140ms ease, box-shadow 140ms ease;
}
/* Deliberately quieter than a form input's focus ring. The composer is
   autofocused on load, so a full-strength blue border + 3px ring was lit the
   entire time the page sat idle and became the loudest thing on screen. A
   slate-blue edge and a whisper of a halo still read as "this is where you
   type" without framing the whole pane. */
.composer:focus-within {
  border-color: #aec6ee;
  box-shadow: 0 0 0 3px rgba(59, 118, 246, 0.07);
}

#input {
  width: 100%;
  resize: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 9px 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.55;
  color: var(--ink);
  outline: none;
  min-height: 42px;
  max-height: 200px;
}
#input::placeholder { color: var(--muted-2); }

#send-btn {
  background: var(--blue);
  color: #fff;
  border: 0;
  padding: 10px 16px;
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  border-radius: var(--radius);
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  transition: background 130ms ease;
}
#send-btn:hover { background: var(--blue-hover); }
#send-btn:disabled { background: var(--muted-2); cursor: wait; }
#send-btn.stop { background: var(--ink-2); }
#send-btn.stop:hover { background: var(--ink); }
/* One glyph at a time: arrow while idle, square while a run is in flight. */
#send-btn .glyph-stop,
#send-btn.stop .glyph-send { display: none; }
#send-btn.stop .glyph-stop { display: block; }

/* Capped: the textarea stays usable (slash commands are free), so only Send is
   visibly stood down. */
.main.is-limited #send-btn { opacity: 0.45; }
.main.is-limited .composer { border-color: var(--border); }

/* ---------- slash-command palette ---------- */
.slash-menu {
  position: absolute;
  left: 0;
  bottom: calc(100% + 10px);
  width: min(400px, 100%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
  z-index: 20;
  display: flex;
  flex-direction: column;
  padding: 5px;
}
/* `display: flex` above would otherwise beat the `hidden` attribute. */
.slash-menu[hidden] { display: none; }
.slash-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 8px 10px;
  background: transparent;
  border: 0;
  border-radius: var(--radius-sm);
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.slash-item.active,
.slash-item:hover { background: var(--blue-tint); }
.slash-item .slash-name { font-size: 13px; font-weight: 600; color: var(--ink); }
.slash-item.active .slash-name { color: var(--blue-ink); }
.slash-item .slash-desc { font-size: 12.5px; color: var(--muted); }

/* ---------- first-render reveal ---------- */
.app, .login-shell { animation: pageIn 320ms ease both; }
@keyframes pageIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* =========================================================================
   SCHEDULE PAGE
   ========================================================================= */

/* The chat layout locks html/body overflow so its inner panes scroll. The
   schedule page is a normal scrolling document — undo that. */
html:has(.schedule-shell),
body:has(.schedule-shell) { overflow: auto; height: auto; }

.schedule-shell {
  position: relative;
  min-height: 100vh;
  padding: 14px;
  /* No animation here on purpose — pageIn uses transform, which would make this
     a containing block and break the rail's position: fixed. */
}
.schedule-shell .rail {
  position: fixed;
  left: 14px;
  top: 14px;
  width: var(--rail);
  height: calc(100vh - 28px);
  z-index: 1;
}
/* The schedule page is the same single white panel as the chat, filling the
   same area right of the rail, so moving between the two screens doesn't
   change the frame. It scrolls as a document rather than in inner panes; its
   sections are divided by hairlines inside the panel, with the form held to a
   readable width. */
.schedule-main {
  margin-left: calc(var(--rail) + 14px);
  padding: 0 0 12px;
  /* Override .main's flex/overflow so this page scrolls naturally. */
  display: block;
  overflow: visible;
  height: auto;
  min-height: calc(100vh - 28px);
}

.schedule-card {
  padding: 22px 28px 24px;
  border-bottom: 1px solid var(--border);
}
.schedule-card:last-child { border-bottom: 0; }
.schedule-card > * { max-width: 880px; }
.schedule-main > .flash { margin: 16px 28px 0; max-width: 880px; }

.schedule-form .field { gap: 7px; margin-bottom: 18px; }
/* `display: flex` beats the UA [hidden] rule, so re-assert it: a field toggled
   off by the frequency selector must hide. */
.schedule-form .field[hidden] { display: none; }
.hint-inline { text-transform: none; letter-spacing: 0; color: var(--muted); }
/* Custom dropdown chevron — the native arrow ignores padding-right. */
.schedule-form select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%2364748b' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}
.schedule-form textarea { resize: vertical; min-height: 96px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }

/* Multi-select pills for the guided focus question. (Distinct from the chat
   `.chip` class — named `focus-chip` to avoid the collision.) */
.focus-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.focus-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1px solid var(--border-2);
  border-radius: 999px;
  background: var(--surface);
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-3);
  cursor: pointer;
  transition: border-color 130ms ease, background 130ms ease, color 130ms ease;
  user-select: none;
}
.focus-chip:hover { border-color: var(--blue); color: var(--blue-ink); }
.focus-chip input { margin: 0; accent-color: var(--blue); }
.focus-chip:has(input:checked) {
  border-color: var(--blue);
  background: var(--blue-tint);
  color: var(--blue-ink);
  font-weight: 600;
}

/* ---- recipients chip input ----
   Looks like one form control: the box owns the border and the focus ring, the
   chips and the typing field live inside it. Enhanced from a plain comma-separated
   input by the script in schedule.html. */
.chip-input {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  width: 100%;
  min-height: 44px;
  padding: 7px 9px;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  cursor: text;
  transition: border-color 130ms ease, box-shadow 130ms ease;
}
.chip-input:focus-within { border-color: var(--blue); box-shadow: var(--ring); }
.chip-input-chip {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  max-width: 100%;
  padding: 3px 4px 3px 10px;
  border: 1px solid var(--blue-tint-2);
  border-radius: 999px;
  background: var(--blue-tint);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--blue-ink);
}
/* A typo is shown, not swallowed — and submit is blocked until it's gone. */
.chip-input-chip.is-invalid {
  border-color: var(--bad-border);
  background: var(--bad-tint);
  color: #9f1239;
}
.chip-input-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.chip-input-x {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  padding: 0;
  background: transparent;
  color: inherit;
  opacity: 0.55;
  cursor: pointer;
  transition: opacity 120ms ease, background 120ms ease;
}
/* An SVG cross rather than a "×" glyph: the character's ink sits above its line
   box's centre, so flex centring rendered it a pixel or two low inside the chip. */
.chip-input-x svg { width: 10px; height: 10px; display: block; }
.chip-input-x:hover { opacity: 1; background: rgba(15, 23, 42, 0.08); }
.chip-input-x:focus-visible { outline: none; opacity: 1; background: rgba(15, 23, 42, 0.12); }
/* The field claims the rest of the line and never shrinks below a readable width,
   so it wraps to its own row rather than being squeezed to nothing by chips. */
.chip-input-field {
  flex: 1 1 12ch;
  min-width: 12ch;
  border: 0 !important;
  outline: none;
  padding: 3px 2px !important;
  background: transparent !important;
  box-shadow: none !important;
  font-size: 14px;
  color: var(--ink);
}
.chip-input-error {
  margin: 6px 0 0;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--bad);
}
.chip-input-error[hidden] { display: none; }

.link-btn {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--blue);
  cursor: pointer;
}
.link-btn:hover { text-decoration: underline; text-underline-offset: 3px; }

.optional-tag {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted-2);
}
.optional-tag::before { content: "("; }
.optional-tag::after { content: ")"; }

/* Guided "tailor the digest" carousel — one question per slide. */
.tailor-carousel {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  background: var(--surface-2);
  margin-bottom: 20px;
}
.tailor-slide { display: flex; flex-direction: column; gap: 9px; }
.tailor-slide[hidden] { display: none; }
.tailor-dots { display: flex; gap: 6px; margin-bottom: 14px; }
.tailor-dots [data-dot] {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--border-2);
  transition: background 130ms ease;
}
.tailor-dots [data-dot].is-active { background: var(--blue); }
.tailor-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
}
.tailor-nav-right { display: inline-flex; align-items: center; gap: 10px; }
.btn-step {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border-radius: var(--radius);
  padding: 8px 15px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
  border: 1px solid var(--blue);
  background: var(--blue);
  color: #fff;
  transition: background 130ms ease, border-color 130ms ease, color 130ms ease;
}
.btn-step:hover { background: var(--blue-hover); border-color: var(--blue-hover); }
.btn-step.ghost {
  background: var(--surface);
  color: var(--ink-3);
  border-color: var(--border-2);
}
.btn-step.ghost:hover { border-color: var(--blue); color: var(--blue); background: var(--blue-tint); }
.btn-step.muted {
  background: transparent;
  color: var(--muted);
  border-color: transparent;
}
.btn-step.muted:hover { color: var(--ink); background: var(--surface); border-color: var(--border); }

.subscription-list { list-style: none; margin: 0; padding: 0; }
.subscription-item {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  padding: 14px 0;
  border-bottom: 1px solid var(--border);
}
.subscription-item:first-child { padding-top: 0; }
.subscription-item:last-child { border-bottom: none; padding-bottom: 0; }
.sub-meta { flex: 1; min-width: 0; }
.sub-line { font-size: 13.5px; line-height: 1.5; color: var(--ink-2); }
.sub-line strong { font-weight: 700; color: var(--ink); }
/* Recipients as chips: a subscription can carry several addresses, and one long
   comma-run reads as a single unbroken string — you can't tell at a glance how
   many people are on it or spot the wrong one. */
.sub-emails { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 5px; }
.email-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  padding: 3px 10px 3px 7px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-2);
}
.email-chip .i { width: 13px; height: 13px; color: var(--muted-2); }
.email-chip span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sub-when { color: var(--blue-ink); font-weight: 600; }
.sub-notes { color: var(--muted); margin-top: 3px; }
.sub-meta-small { font-size: 12px; color: var(--muted-2); margin-top: 4px; }
.sub-meta-small .err { color: var(--bad); }
.sub-actions { display: flex; gap: 8px; flex-shrink: 0; align-items: center; }
.sub-actions button[disabled] { opacity: 0.55; cursor: progress; }
/* Inline spinner inside the Send-test button, revealed by .is-loading. */
.sub-actions .spinner {
  display: none;
  width: 12px;
  height: 12px;
  margin-left: 6px;
  border: 2px solid var(--blue-tint-2);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: schedule-spin 0.7s linear infinite;
}
.sub-actions button.is-loading .spinner { display: inline-block; }
.sub-actions button.is-loading .btn-label { color: var(--muted); }
@keyframes schedule-spin { to { transform: rotate(360deg); } }

/* Full-page busy overlay shown while the test send is running. */
.busy-overlay {
  position: fixed;
  inset: 0;
  background: rgba(244, 247, 252, 0.8);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 50;
  animation: fadeIn 160ms ease both;
}
.busy-overlay[hidden] { display: none; }
.busy-card {
  display: flex;
  align-items: center;
  gap: 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 26px;
  max-width: 460px;
  box-shadow: var(--shadow-pop);
}
.busy-spinner {
  width: 28px;
  height: 28px;
  border: 3px solid var(--blue-tint-2);
  border-top-color: var(--blue);
  border-radius: 50%;
  animation: schedule-spin 0.8s linear infinite;
  flex-shrink: 0;
}
.busy-title { font-size: 15px; font-weight: 700; color: var(--ink); margin-bottom: 3px; }
.busy-sub { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

.flash {
  padding: 12px 15px;
  border-radius: var(--radius-lg);
  font-size: 13.5px;
  border: 1px solid var(--good-border);
  background: var(--good-tint);
  color: #14532d;
}
.flash-err {
  border-color: var(--bad-border);
  background: var(--bad-tint);
  color: #9f1239;
}

/* =========================================================================
   RESPONSIVE
   ========================================================================= */

@media (max-width: 1000px) {
  :root { --rail: 220px; }
}
@media (max-width: 880px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr;
    padding: 10px;
    gap: 10px;
  }
  .rail {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    overflow-x: auto;
    padding: 10px 12px;
  }
  .rail-brand { padding: 0; flex: 0 0 auto; }
  .rail-logo { height: 18px; }
  .rail .brand-product { display: none; }
  /* The tree flattens to a row of page icons: no group heading, no guide line. */
  .rail-nav { flex-direction: row; flex: 0 0 auto; }
  .nav-group { display: none; }
  .nav-tree { flex-direction: row; gap: 2px; margin-left: 0; border-left: 0; }
  .nav-item::before { display: none; }
  .nav-tree .nav-item { margin-left: 0; }
  .nav-item .i { display: block; color: var(--muted); }
  .nav-item.is-active { background: var(--blue-tint); }
  .nav-item.is-active .i { color: var(--blue); }
  .rail .rail-block,
  .rail .spacer { display: none; }
  .rail-foot { border-top: 0; padding-top: 0; flex-direction: row; align-items: center; margin-left: auto; }
  .rail-session { flex: 0 0 auto; }
  /* Collapse every label in the horizontal rail to its icon so the whole row
     fits a phone without becoming a scroller with the account off-screen. */
  .btn-quiet span:not(.i),
  .nav-item .nav-label,
  .rail-account-info { display: none; }
  .btn-quiet { width: auto; padding: 8px; }
  .nav-item { padding: 9px; }
  .rail-account { padding: 5px; }
  .rail-primary { flex: 0 0 auto; }
}
@media (max-width: 560px) {
  /* Only the icon survives on the narrowest phones; the button keeps its
     accessible name from the visually hidden label. */
  .rail-primary .btn-pill span:not(.i) { display: none; }
  .rail-primary .btn-pill { padding: 9px 11px; }
  /* Smaller logo and tighter gaps so the account stays on screen at 390px. */
  .rail { gap: 8px; }
  .rail-logo { height: 14px; }
}
@media (max-width: 720px) {
  .main-head { padding: 18px 20px 16px; }
  .thread { padding: 20px 20px 14px; }
  .thread:has(> #empty-state) { padding: 20px; }
  .composer-wrap { padding: 12px 20px 16px; }
  .schedule-shell { padding: 10px; }
  .schedule-shell .rail {
    position: static;
    width: 100%;
    height: auto;
    left: auto;
    top: auto;
  }
  .schedule-main {
    margin-left: 0;
    min-height: 0;
    margin-top: 10px;
  }
  .schedule-main .main-head { padding: 18px 18px 15px; }
  .schedule-card { padding: 18px 18px 20px; }
  .schedule-main > .flash { margin: 14px 18px 0; }
  .field-row { grid-template-columns: 1fr; }
  .msg-row.user { max-width: 100%; }
  /* A wide answer table can't shrink below its content, so let it scroll inside
     itself rather than pushing the panel sideways. */
  .msg-assistant table { display: block; overflow-x: auto; white-space: nowrap; }
}
@media (max-width: 560px) {
  /* Stack the composer: a side-by-side Send button leaves the textarea too
     narrow to read the question being typed. */
  .composer { grid-template-columns: 1fr; padding: 10px 12px 10px 14px; }
  #send-btn { justify-self: end; }
  /* Room for the placeholder's second wrapped line, so the prompt isn't clipped
     before anything has been typed. */
  #input { min-height: 58px; }
}

/* Email digests: the organisation digest, personal digests' on/off switch and
   their inline edit form. */
.btn-primary.btn-compact { padding: 7px 14px; font-size: 13px; }
.subscription-item.is-off .sub-when,
.subscription-item.is-off .sub-notes { color: var(--muted-2); }
.org-recipients { margin-top: 6px; }
.sub-edit-row { list-style: none; padding: 0 0 12px; border-bottom: 1px solid var(--border); margin-top: -8px; }
.sub-edit > summary {
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  color: var(--blue-ink);
  margin-top: 10px;
}
.sub-edit > summary:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 4px; }
.sub-edit[open] > summary { margin-bottom: 12px; }
.switch {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 4px 6px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink-2);
  cursor: pointer;
}
.switch:focus-visible { outline: none; box-shadow: var(--ring); border-radius: 999px; }
.switch[disabled] { cursor: not-allowed; opacity: 0.55; }
.switch-track {
  position: relative;
  width: 32px;
  height: 18px;
  border-radius: 999px;
  background: var(--border-2);
  transition: background 130ms ease;
}
.switch-knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--surface);
  transition: transform 130ms ease;
}
.switch[aria-checked="true"] .switch-track { background: var(--good); }
.switch[aria-checked="true"] .switch-knob { transform: translateX(14px); }
@media (prefers-reduced-motion: reduce) {
  .switch-track, .switch-knob { transition: none; }
}
@media (max-width: 640px) {
  .subscription-item { flex-direction: column; }
  .sub-actions { flex-wrap: wrap; }
}

/* Frequency, day and time on one row, the time-zone note right under it. */
.field-row.timing-row { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.schedule-form .timing-row .field { margin-bottom: 0; }
.schedule-form .timing-zone { margin: 6px 0 12px; }
.sub-edit .schedule-form { padding: 4px 0 6px; }
.form-foot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.form-foot .hint { margin: 0; }
@media (max-width: 640px) {
  .field-row.timing-row { grid-template-columns: 1fr; }
}
