:root {
  color-scheme: dark;
  /* Modern dark theme: deep cool-charcoal surfaces, a layered elevation step
     from page -> card, and a vibrant indigo accent. */
  --bg: #14151a;
  --card: #1d1f25;
  --text: #ecedf1;
  --muted: #8b929e;
  --border: #23262f;
  --border-strong: #353a45;
  --accent: #7c7dff;
  --accent-press: #9b9cff;
  --ok: #4ade80;
  --err: #fb7185;
  --radius: 9px;
  --label-col: 8.5rem;
  --row-gap: 1.25rem;
}

* { box-sizing: border-box; }

html { scrollbar-gutter: stable; }

body {
  margin: 0;
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 1.5rem;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color: var(--text);
  background: var(--bg);
}

/* Wraps the card + the under-card nav, and sets the shared width. */
.page {
  width: 75rem;
  max-width: 90vw;
  display: grid;
  gap: 0.85rem;
}

.card {
  width: 100%;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.75rem 2rem;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.45);
}

/* "Back to dashboard" link at the top of the standalone insight page. */
.insight-back {
  display: inline-block;
  margin-bottom: 1rem;
  font-size: 0.875rem;
  color: var(--muted);
  text-decoration: none;
}
.insight-back:hover { color: var(--accent); }

/* Prev / next navigation, sitting under the card. */
.page-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
}

/* Save row at the bottom of the card: status on the left, button on the right. */
.card-footer {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 1.25rem;
}

.card-footer #status { flex: 1; }

/* Top dashboard bar: status text fills the row so Rerun sits at the right.
   Sits at the very top, so drop the footer's top margin. */
#dashboard-actions { margin-top: 0; margin-bottom: 1rem; }
#dashboard-actions #pipeline-status { flex: 1; margin: 0; }

header { margin-bottom: 1.5rem; }

/* Header with a title block on the left and a user bar on the right. */
/* Top row holds the app title and the floated-right actions (spend badge +
   menu); the business switcher sits on the row below (.page-header-main). */
.page-header {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.page-header-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* Spend badge + hamburger menu, kept together at the top-right. */
.header-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}

.page-header-main {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
}

/* Header hamburger menu. */
.menu { position: relative; flex: none; }

.hamburger {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 4px;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  cursor: pointer;
}

.hamburger:hover { background: transparent; border-color: var(--accent); }
.hamburger span {
  display: block;
  width: 1.05rem;
  height: 1.5px;
  margin: 0 auto;
  background: var(--text);
  border-radius: 1px;
}

/* Dropdown panel, anchored to the right edge of the header. */
.menu-panel {
  position: absolute;
  top: calc(100% + 0.4rem);
  right: 0;
  z-index: 20;
  min-width: 11rem;
  display: flex;
  flex-direction: column;
  padding: 0.3rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.menu-panel[hidden] { display: none; }

/* Full-width text rows; no primary-button fill. */
.menu-item {
  font-size: 0.85rem;
  font-weight: 500;
  text-align: left;
  padding: 0.5rem 0.6rem;
  background: transparent;
  color: var(--text);
  border: 0;
  border-radius: calc(var(--radius) - 3px);
}

.menu-item:hover { background: var(--border); }
.menu-item:disabled { opacity: 0.45; cursor: not-allowed; }
.menu-item:disabled:hover { background: transparent; }

/* Rerun menu items: shown on every page now that the toolbar is shared (see
   toolbar.js). Admin-only "Rerun pipeline" is hidden via the `hidden`
   attribute (set in toolbar.js), which the UA stylesheet already turns into
   `display: none` — no override needed. */

h1 {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.subtitle {
  margin: 0.2rem 0 0;
  font-size: 0.8rem;
  color: var(--muted);
}

/* Explanatory line under the profile page's back link (a plain page-content
   subtitle, not the header's — that one stays reserved for the intake empty
   state). */
.profile-intro { margin: 0 0 1.25rem; }

form { display: grid; gap: 0.55rem; }

/* Label to the side of its control. */
label {
  display: grid;
  grid-template-columns: var(--label-col) 1fr;
  align-items: center;
  gap: var(--row-gap);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}

/* Multi-line controls: top-align the label. */
label:has(textarea) { align-items: start; }
label:has(textarea) > :first-child { padding-top: 0.3rem; }


/* App name / brand — the main header title, sits above the business name. */
.app-brand {
  /* Own row above the switcher; align-self keeps it from stretching full width
     so only the logo + name are clickable. */
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 1.7rem;
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--text);
  text-decoration: none;
}
.app-brand img { border-radius: 6px; display: block; }

/* Business name — a secondary label under the app title (the switcher trigger),
   so the app title stays the most prominent element in the header. */
.page-heading { margin: 0; }
#page-title {
  font-size: 1.2rem;
  font-weight: 650;
  color: var(--text);
}

/* Under the title: the business's own website, and a link to its Company
   profile page ("Overview"). Both hidden until set (see toolbar.js). */
.header-links {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 0.2rem 0 0;
}

/* The business name doubles as the switcher trigger. The button is invisible
   chrome — it inherits the heading's type — and becomes interactive (caret
   + pointer) whenever a business is selected, since the picker always offers
   "New business" (`has-switcher`). */
.switcher { position: relative; display: inline-block; }
.switcher-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  cursor: default;
  text-align: left;
}
.switcher-caret { display: none; font-size: 0.7em; color: var(--muted); }
.switcher-trigger.has-switcher { cursor: pointer; }
.switcher-trigger.has-switcher .switcher-caret { display: inline; }

/* Dropdown menu of businesses, anchored under the name. */
.switcher-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 20;
  margin-top: 0.35rem;
  min-width: 12rem;
  max-width: 20rem;
  padding: 0.3rem;
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.switcher-item {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: 0;
  border-radius: calc(var(--radius) - 2px);
  background: none;
  color: var(--text);
  font-size: 0.9rem;
  text-align: left;
  cursor: pointer;
}
.switcher-item:hover { background: var(--bg); }
.switcher-item[aria-current="true"] { color: var(--accent); font-weight: 650; }
/* "New business" action, pinned to the bottom of the picker and set off from
   the business list above it. */
.switcher-item-new {
  margin-top: 0.3rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  border-radius: 0 0 calc(var(--radius) - 2px) calc(var(--radius) - 2px);
  color: var(--accent);
  font-weight: 600;
}

/* Site favicon (derived from the business's website via Google's favicon
   service), shown beside the name in the header title and switcher dropdown.
   Fixed box so a tall/wide source icon can't disturb the row. */
.favicon {
  flex: none;
  object-fit: contain;
  background: #fff;
  border-radius: 50%;
  padding: 2px;
}
.title-favicon { width: 20px; height: 20px; }


/* New-business intake dialog. */
.dialog {
  width: 30rem;
  max-width: 92vw;
  padding: 1.5rem 1.75rem;
  color: var(--text);
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 12px 32px rgba(0, 0, 0, 0.5);
}
.dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.dialog-title {
  margin: 0 0 1.1rem;
  font-size: 1rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}
/* Optional explanatory line under a dialog title. */
.dialog-subtitle {
  margin: -0.7rem 0 1.2rem;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--muted);
}
/* Status text takes the slack so Cancel / Create sit at the right. */
.dialog .card-footer p { flex: 1; margin: 0; }

/* Admin-only header badge: running spend total for the selected company.
   A button — clicking it opens the same breakdown dialog as the menu item. */
.spend-badge {
  align-self: center;
  margin-left: auto;
  padding: 0.3rem 0.7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.spend-badge:hover { border-color: var(--accent, #888); }

/* Admin spend dialog: token/cost breakdown table. */
#spend-dialog { width: 34rem; max-width: 95vw; }
.spend-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}
.spend-table th,
.spend-table td {
  padding: 0.4rem 0.6rem;
  text-align: right;
  border-bottom: 1px solid var(--border);
}
.spend-table th:first-child,
.spend-table td:first-child {
  text-align: left;
}
.spend-table tfoot td {
  font-weight: 600;
  border-bottom: none;
}
.spend-note { margin-top: 0.75rem; font-size: 0.8rem; }

/* Confirm-details summary list. */
.confirm-fields {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.35rem 1rem;
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
}
.confirm-fields dt { color: var(--muted); white-space: nowrap; }
.confirm-fields dd { margin: 0; word-break: break-all; }

/* Onboarding goal checklist. */
.goal-options {
  display: grid;
  gap: 0.45rem;
  margin: 0;
  padding: 0.85rem 1rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
}
.goal-options legend {
  padding: 0 0.4rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}
/* A checkbox row — override the global two-column label grid. */
.check {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text);
  cursor: pointer;
}
.check input[type="checkbox"] {
  width: auto;
  margin: 0;
  border: 0;
  box-shadow: none;
  accent-color: var(--accent);
  cursor: pointer;
}
/* Dim the options disabled once three are picked. */
.check:has(input:disabled) { opacity: 0.4; cursor: not-allowed; }

/* Free-text box revealed by the "Other" goal checkbox. */
.goal-other-text { margin-left: 1.65rem; }
.goal-other-text:disabled { opacity: 0.4; }

/* Minimal underline inputs — no box, no horizontal padding. */
input,
textarea,
select {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--text);
  background: transparent;
  width: 100%;
  padding: 0.3rem 0;
  border: 0;
  border-bottom: 1px solid var(--border-strong);
  border-radius: 0;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input::placeholder,
textarea::placeholder { color: var(--muted); }

input:focus,
textarea:focus,
select:focus {
  outline: none;
  border-bottom-color: var(--accent);
  box-shadow: inset 0 -1px 0 0 var(--accent); /* thickens the underline */
}

/* Read-only fields (e.g. company/website) read as static text, not inputs. */
input[readonly] {
  color: var(--muted);
  border-bottom-color: transparent;
  cursor: default;
}
input[readonly]:focus {
  border-bottom-color: transparent;
  box-shadow: none;
}

/* A transparent select lets the native option list fall back to a light system
   surface (light text on light bg). Pin both the control and its options to the
   dark theme so the dropdown stays readable. */
select { background-color: var(--card); }
select option {
  background-color: var(--card);
  color: var(--text);
}

textarea {
  min-height: 2.5rem;
  /* Grow to fit the content (no scrollbar, no manual resize handle). */
  field-sizing: content;
  resize: none;
  overflow: hidden;
  line-height: 1.45;
}

.actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.75rem;
  padding-left: calc(var(--label-col) + var(--row-gap));
}

button {
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.45rem 1rem;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  transition: background 0.15s ease, opacity 0.15s ease;
}

button:disabled { opacity: 0.55; cursor: not-allowed; }

.btn-secondary {
  font-size: 0.875rem;
  font-weight: 600;
  padding: 0.45rem 1rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--text);
  text-decoration: none;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.btn-secondary:hover {
  border-color: var(--accent);
  color: var(--accent);
}

/* A <button> with the secondary look: strip the primary fill. */
button.btn-secondary,
button.btn-secondary:hover {
  background: transparent;
}

.insights {
  margin: 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.5rem;
  font-size: 0.875rem;
  line-height: 1.45;
}

.muted { color: var(--muted); }

/* ---- SPA: drop the centered card, fill the viewport ---- */

body.app {
  display: block;
  place-items: initial;
  padding: 1.75rem 2.5rem 3.5rem;
}

body.app .page {
  width: 100%;
  max-width: 100%;
  gap: 1.25rem;
}

body.app .card {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

/* Dashboard only (scoped to html.view-dashboard — profile.html
   also uses body.app but never gets this class, so it keeps the normal
   scrolling-document layout above untouched): pin the whole shell to exactly
   the viewport height and hand it down as a flex chain, so anything that
   needs to "fill remaining height" (the insight chat panel, ultimately) can
   just say flex: 1; min-height: 0 and let the browser do the subtraction —
   no calc() anywhere, and it stays correct if the header/status line above
   it ever changes height. */
html.view-dashboard body.app {
  height: 100vh;
  display: flex;
  flex-direction: column;
}
html.view-dashboard body.app .page {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
html.view-dashboard body.app .card {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ---- SPA dashboard: collapsible sections ---- */

/* Exactly one view is shown; the choice is made before first paint by the
   inline script in the page head (and updated by spa.js on navigation). */
#view-intake, #view-dashboard { display: none; }
html.view-intake #view-intake { display: block; }
html.view-dashboard #view-dashboard {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

#pipeline-status {
  margin: 0 0 0.75rem;
  font-size: 0.8rem;
  font-weight: 500;
  min-height: 1rem;
}
/* Usually empty now (only shown on failure/action errors) — collapse it so it
   leaves no gap at the top of the dashboard. */
#pipeline-status:empty { display: none; }
#dashboard-actions:has(#pipeline-status:empty) { margin-bottom: 0; }

/* Dashboard first-load state. While `#view-dashboard` carries `.is-loading`
   (set in spa.js on entering the dashboard, cleared once company data is in),
   the spinner is shown and every other section is hidden — so the sections
   never flash empty before the first render. The id + two classes here outrank
   `.panel.active` etc., so nothing leaks through. */
.dashboard-loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.85rem;
  min-height: 40vh;
  padding: 3rem 1rem;
}
#view-dashboard:not(.is-loading) .dashboard-loading { display: none; }
#view-dashboard.is-loading > :not(.dashboard-loading) { display: none; }

/* Profile page: while the card carries `.is-loading` (profile.js clears it on
   success/error), only the spinner shows in the content area — the toolbar
   stays put with the cached business name, so just the content sits behind the
   spinner. */
.card.is-loading > :not(#app-toolbar):not(#profile-root) { display: none; }

.spinner {
  width: 2rem;
  height: 2rem;
  border: 3px solid var(--border);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation-duration: 2.4s; }
}

/* Content heading below the toolbar on the standalone pages (e.g. "Profile",
   "Dashboard") — names the page's content, distinct from the app title. */
.content-title {
  margin: 0.25rem 0 0.5rem;
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}

/* Only the active panel is shown. Insights is the app's main view; the tab bar
   was removed and showPanel() (spa.js) toggles `.active`. Fills the rest of
   #view-dashboard's height (see the flex chain above) and is the fallback
   scroll boundary if a panel's own content ever runs taller than that —
   normally nothing scrolls here directly, since insights carves out its own
   internal scroll regions further down (list column, chat, ...). */
.panel { display: none; }
.panel.active {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.section-body {
  padding: 0.25rem 0 1.1rem;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}

.insights-toolbar {
  display: none;
  align-items: center;
  gap: 0.7rem;
  padding: 0.55rem 0.8rem;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

.insights-hint {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--muted);
}

/* Feedback-mode toggle: a pill switch + label, top of the insights list. */
.feedback-toggle {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  cursor: pointer;
  user-select: none;
  flex: none;
}

.feedback-toggle input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.feedback-toggle-track {
  position: relative;
  width: 2rem;
  height: 1.15rem;
  background: var(--border-strong);
  border-radius: 999px;
  transition: background 0.15s;
  flex: none;
}

.feedback-toggle-thumb {
  position: absolute;
  top: 0.15rem;
  left: 0.15rem;
  width: 0.85rem;
  height: 0.85rem;
  background: var(--muted);
  border-radius: 50%;
  transition: transform 0.15s, background 0.15s;
}

.feedback-toggle input:checked + .feedback-toggle-track {
  background: var(--accent);
}
.feedback-toggle input:checked + .feedback-toggle-track .feedback-toggle-thumb {
  transform: translateX(0.85rem);
  background: #fff;
}

.feedback-toggle-label {
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
  white-space: nowrap;
}

.section-summary { margin: 0 0 0.75rem; font-size: 0.875rem; line-height: 1.5; }

.section-body h3 {
  font-size: 0.8rem;
  font-weight: 650;
  margin: 1.1rem 0 0.4rem;
}

.section-body > .field { padding: 0.35rem 0; }

/* Detail cards (insights actions + marketing allocations): a responsive grid.
   Columns auto-fit to the available width (min ~17rem each) and collapse to a
   single column on narrow screens. */
.card-grid {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  max-width: 700px;
  margin-bottom: 0.4rem;
}

.detail-card {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem;
  background: var(--bg);
  display: grid;
  gap: 0.7rem;
  align-content: start;
}

.detail-card-head {
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: 0.45rem;
}

/* Insights: a master-detail layout — a flush-left list of rows on the left,
   a detail panel on the right showing whichever row was last clicked (that
   panel is itself split horizontally into content + chat — see
   .insight-detail-split below). On mobile (see the @media block after
   .insight-row below) this becomes a tiered list -> detail -> chat flow
   instead, one screen at a time. Fills the rest of .section-body's height
   (see the flex chain further up) and stretches both columns to match it —
   each column scrolls its own content internally rather than growing the
   page, which is also what lets the chat panel below fill real, available
   height with no calc(): every ancestor down to it is either flex: 1 (grow
   to fill) or min-height: 0 (allow shrinking below content), so the browser
   works out how tall it can be instead of us computing it. */
.insights-layout {
  display: flex;
  gap: 1.75rem;
  align-items: stretch;
  flex: 1;
  min-height: 0;
}

.insights-list-col {
  flex: 0 0 380px;
  min-width: 0;
  overflow-y: auto;
}

.insights-detail-col {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* Within the detail column: content card + chat, side by side. The detail
   card wraps to its own content height (align-items: start — it shouldn't
   stretch to match a tall chat panel); the chat panel is the one that fills
   the row (align-self: stretch below), since an open chat should use all
   the available height regardless of how short the detail card's text is.
   On wide screens the two columns are always reserved at equal width,
   whether or not chat is actually open — .insight-action-chat (in the
   like/dislike/remind row) only toggles the chat pane's own visibility
   within its column, never the grid, so the detail card never jumps from
   full-width to half-width or back; the chat column just sits empty while
   closed. On narrow screens there's no room for two columns at all (see the
   max-width block further down), so there it's real tiered navigation
   instead — opening chat there hides the detail card and collapses to one
   column. */
.insight-detail-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1.25rem;
  align-items: start;
  flex: 1;
  min-height: 0;
}

/* Still a safety net in case a detail card's content is ever taller than the
   row: max-height caps it at the row's stretched height (grid's default
   align-content) rather than overflowing past it, scrolling internally
   instead. Harmless — and usually a no-op — when content is shorter, since
   align-items: start above already keeps the box sized to its content. */
.insight-detail-split .insight-card-detail {
  max-height: 100%;
  overflow-y: auto;
}

.insight-detail-split .insight-chat {
  display: none;
  align-self: stretch;
}

.insights-layout[data-insight-view="chat"] .insight-detail-split .insight-chat {
  display: flex;
}

/* Defensive floor only — normally the flex/grid chain above already gives
   this its full real height. */
.insight-detail-split .insight-chat {
  min-height: 20rem;
}

/* The detail panel's card: same box look as other detail cards. */
.insight-card {
  padding: 0.8rem 1rem;
}

.insight-card-body {
  display: grid;
  gap: 0.7rem;
}

/* The list itself: flush-left rows separated by a divider instead of a gap
   between boxed cards. */
.insights-list {
  gap: 0;
}

.insight-row {
  border: none;
  border-radius: 0;
  background: transparent;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
}

.insight-row:last-child { border-bottom: none; }

.insight-row:hover { background: var(--card); }

.insight-row--selected { background: var(--card); }
.insight-row--selected .detail-card-title { color: var(--accent); }

/* Back control above the detail panel — mobile only (desktop has no separate
   list/detail tier to back out of; the chat toggle below is all it needs). */
.insights-mobile-nav {
  display: none;
  align-items: center;
  margin-bottom: 0.75rem;
}

.insights-mobile-back {
  font-size: 0.85rem;
  padding: 0.4rem 0.85rem;
}

/* Chat button inline with like/dislike/remind (.insight-actions) — always
   visible, on every viewport (opens the chat tier on mobile, toggles the
   chat panel open/closed on desktop). Right-aligned via margin-left: auto so
   it sits apart from the like/dislike/remind cluster (present or not —
   archived insights skip those but still get this). Reuses
   .insight-action-remind's box (built with both classes — see
   makeInsightActionsBar); the compound selector here outranks a bare
   .insight-action-remind on specificity so the accent color always wins
   regardless of which rule comes first in the sheet. */
.insight-action-remind.insight-action-chat {
  margin-left: auto;
  color: var(--accent);
  border-color: currentColor;
}
.insight-action-remind.insight-action-chat:hover {
  color: var(--accent);
  background: var(--card);
}

/* Mobile: tiered navigation (list -> detail -> chat) instead of one long
   scrolling stack — full-screen tiers picked by [data-insight-view]
   (insight-cards.js's setInsightPanelView). Desktop uses that same attribute
   only for the narrower chat-panel toggle above (.insight-detail-split). */
@media (max-width: 50rem) {
  .insights-layout { flex-direction: column; }
  /* flex: 1 (not the desktop 320px basis) so whichever single tier is
     visible — list or detail-col, the other is display: none below — fills
     the full height instead of sitting at its natural content size. */
  .insights-list-col { flex: 1; width: 100%; }
  .insights-detail-col { width: 100%; }
  .insight-detail-split { grid-template-columns: 1fr; }

  .insights-mobile-nav { display: flex; }

  .insights-layout[data-insight-view="list"] .insights-detail-col { display: none; }
  .insights-layout:not([data-insight-view="list"]) .insights-list-col { display: none; }
  .insights-layout[data-insight-view="chat"] .insight-detail-split .insight-card-detail { display: none; }
}

/* Highlight popover -------------------------------------------------------- */
.feedback-highlight-mark {
  background: var(--accent);
  color: #fff;
  border-radius: 2px;
}

.feedback-highlight-mark--queued {
  background: rgba(124, 125, 255, 0.28);
  color: inherit;
  cursor: pointer;
  /* box-shadow instead of border-bottom: paints an underline without adding
     to the box, so it can't nudge line-height/spacing of surrounding text. */
  box-shadow: inset 0 -2px 0 0 var(--accent);
}
.feedback-highlight-mark--queued:hover {
  background: rgba(124, 125, 255, 0.42);
}

.highlight-popover {
  z-index: 100;
  background: var(--card);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 0.6rem;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 240px;
}

.highlight-popover-quote {
  font-size: 0.75rem;
  color: var(--muted);
  font-style: italic;
  line-height: 1.4;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-clamp: 2;
}

.highlight-popover-input {
  font-size: 0.82rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  padding: 0.35rem 0.5rem;
  resize: none;
  line-height: 1.4;
}

.highlight-popover-btns {
  display: flex;
  gap: 0.35rem;
  justify-content: flex-end;
}

.highlight-popover-cancel {
  padding: 0.25rem 0.6rem;
  font-size: 0.75rem;
  background: transparent;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
}
.highlight-popover-cancel:hover { color: var(--text); background: transparent; }

.highlight-popover-remove {
  margin-right: auto;
}
.highlight-popover-remove:hover { color: var(--err); background: transparent; }

.highlight-popover-add {
  padding: 0.25rem 0.7rem;
  font-size: 0.75rem;
  background: var(--accent);
  color: #fff;
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}
.highlight-popover-add:hover { background: var(--accent-press); }

.detail-card-title {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 650;
  line-height: 1.35;
  color: var(--text);
}

/* One or more pills, shown in a row under the card title. */
.card-badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

/* Header pill. Color comes from a modifier; the border tracks the text color. */
.card-badge {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  border: 1px solid currentColor;
  white-space: nowrap;
}

.badge-accent { color: var(--accent); }

/* Like/dislike + "remind me later" row at the top of an insight's detail card. */
.insight-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.1rem;
}

.insight-action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.9rem;
  height: 1.9rem;
  padding: 0;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
}
.insight-action-btn:hover { color: var(--text); background: var(--card); }

.insight-action-btn--active.insight-action-like { color: var(--ok); border-color: currentColor; }
.insight-action-btn--active.insight-action-dislike { color: var(--err); border-color: currentColor; }

.insight-action-remind {
  padding: 0.3rem 0.65rem;
  font-size: 0.78rem;
  font-weight: 600;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  margin-left: 0.15rem;
}
.insight-action-remind:hover { color: var(--text); background: var(--card); }
.insight-action-remind--active {
  color: var(--accent);
  border-color: currentColor;
}

.insight-card-pending-icon {
  display: none;
  color: #f59e0b;
  margin-left: 0.35rem;
  vertical-align: -0.1em;
}

.insight-card--needs-revision .insight-card-pending-icon {
  display: inline-flex;
}

/* Archived insight status badges + greyed cards ---------------------------- */
.badge-status { border-color: currentColor; }
.badge-status--completed { color: var(--ok); }
.badge-status--dismissed { color: var(--muted); }

.insight-card--inactive { opacity: 0.6; }
.insight-card--inactive:hover { opacity: 0.8; }

/* Collapsed "Archived (N)" section below the active insights grid */
.insights-archive { max-width: 700px; margin-top: 1rem; }
.insights-archive-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  width: 100%;
  padding: 0.4rem 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 650;
  letter-spacing: 0.02em;
  cursor: pointer;
}
.insights-archive-toggle:hover { color: var(--text); }
.insights-archive-caret { display: inline-block; transition: transform 0.15s; }
.insights-archive-toggle--open .insights-archive-caret { transform: rotate(90deg); }
.insights-archive-grid { margin-top: 0.5rem; }

/* Insights skeleton, shown in place of the master-detail layout while
   insights_report is still generating (see renderInsightsSkeleton in
   renderers.js and the skeleton* builders in insight-cards.js). Every wrapper
   reuses the real layout's classes (.insight-row, .detail-card, ...) so this
   block is byte-for-byte the same box model as the real content — only these
   shimmer bars are skeleton-only, and swapping them out for real
   text/badges/blocks moves nothing else on the page. The chat panel has no
   skeleton (the .insight-detail-split grid still reserves its column). */
.skeleton-bar {
  display: inline-block;
  height: 0.8em;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--border) 25%, var(--border-strong) 37%, var(--border) 63%);
  background-size: 400% 100%;
  animation: skeleton-shimmer 1.4s ease infinite;
  vertical-align: middle;
}
@keyframes skeleton-shimmer {
  0% { background-position: 100% 50%; }
  100% { background-position: 0 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .skeleton-bar { animation: none; }
}

.skeleton-title { width: 60%; }
.skeleton-badge { width: 3.5rem; height: 1.1rem; border-radius: 999px; }
.skeleton-label { width: 5rem; height: 0.7em; }
.skeleton-line { display: block; width: 100%; height: 0.7em; margin: 0.4em 0; }
.skeleton-line--short { width: 65%; }

/* "View previous version" history inside a revised insight card */
.insight-history { border-top: 1px dashed var(--border-strong); padding-top: 0.6rem; }
.insight-history-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}
.insight-history-toggle::before { content: "\21a9"; }
.insight-history-toggle:hover { color: var(--accent); }
.insight-history-list { margin-top: 0.55rem; display: grid; gap: 0.7rem; }
.insight-history-item {
  border-left: 2px solid var(--border-strong);
  padding-left: 0.7rem;
  opacity: 0.85;
}
.insight-history-item-title { font-size: 0.8rem; font-weight: 650; margin-bottom: 0.35rem; }

/* Floating pills (revise / pending feedback) stacked above the chat launcher */
.floating-actions {
  position: fixed;
  right: 1.5rem;
  bottom: calc(1.5rem + 3.25rem + 0.75rem);
  z-index: 40;
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 0.6rem;
}
html.view-intake .floating-actions { display: none; }

.floating-pill-btn {
  padding: 0.45rem 1rem;
  font-size: 0.82rem;
  font-weight: 600;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.4);
  transition: background 0.15s;
}
.floating-pill-btn:disabled { opacity: 0.5; cursor: default; }

.revise-btn {
  background: #2a2208;
  color: #f59e0b;
  border: 1px solid #f59e0b;
}
.revise-btn:hover { background: #3a2e0a; }

.feedback-queue-btn {
  background: #0d2a3a;
  color: #38bdf8;
  border: 1px solid #38bdf8;
}
.feedback-queue-btn:hover { background: #123a4f; }

.detail-block { display: grid; gap: 0.2rem; }

.detail-label {
  font-size: 0.7rem;
  font-weight: 650;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--muted);
}

.detail-text {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--text);
}

/* Per-insight checklist (subtasks). */
.subtask-list {
  list-style: none;
  margin: 0.1rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.3rem;
}

/* Override the global two-column grid `label` rule: these are simple checkbox
   rows, not form field labels. */
.subtask-label {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.875rem;
  font-weight: 400;
  line-height: 1.4;
  color: var(--text);
  cursor: pointer;
}

/* Reset the global underline-`input` styling (width:100%, padding, border) that
   otherwise stretches the checkbox full-width — same reset as `.check`'s. */
.subtask-check {
  width: auto;
  flex: none;
  margin: 0.15rem 0 0;
  padding: 0;
  border: 0;
  box-shadow: none;
  accent-color: var(--accent);
  cursor: pointer;
}

.subtask-check:disabled { cursor: default; }

.subtask-text { flex: 1; }

.subtask-item--done .subtask-text {
  text-decoration: line-through;
  color: var(--muted);
}

/* A wrapping row of tag chips (e.g. media types, ad themes). */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.chip {
  font-size: 0.75rem;
  line-height: 1.3;
  padding: 12px;
  border-radius: 10px;
  background: var(--border);
  color: var(--text);
}

#plan h2 {
  font-size: 0.8rem;
  font-weight: 650;
  margin: 1.1rem 0 0.4rem;
}

#plan > p { margin: 0 0 0.25rem; font-size: 0.9rem; line-height: 1.5; }

#plan ul,
#plan ol {
  margin: 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.45rem;
  font-size: 0.875rem;
  line-height: 1.45;
}

#allocations {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0;
}

#allocations > li {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
  display: grid;
  gap: 0.45rem;
}

#allocations > li:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

/* Read-only two-column row — mirrors the label grid without a form control. */
.field {
  display: grid;
  grid-template-columns: var(--label-col) 1fr;
  align-items: start;
  gap: var(--row-gap);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--muted);
}

.website-link {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--accent);
  word-break: break-all;
}
.website-link:hover { text-decoration: underline; }

.field-value {
  font-size: 0.875rem;
  font-weight: 400;
  color: var(--text);
}

.field-value ul { margin: 0; }

#report h2,
#copy h2 {
  font-size: 0.8rem;
  font-weight: 650;
  margin: 1.1rem 0 0.4rem;
}

#copy .field { padding: 0.35rem 0; }

#report > p { margin: 0 0 0.75rem; font-size: 0.875rem; line-height: 1.5; }

#actions ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0;
}

#actions li {
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
  display: grid;
  gap: 0.45rem;
}

#actions li:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

#status {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 500;
  min-height: 1rem;
}

.ok { color: var(--ok); }
.err { color: var(--err); }

#created {
  margin: 0.5rem 0 0;
  padding-left: calc(var(--label-col) + var(--row-gap));
  font-size: 0.72rem;
  color: var(--muted);
}

/* Stack labels on top on narrow screens. */
@media (max-width: 34rem) {
  .card { padding: 1.25rem; }
  label { grid-template-columns: 1fr; gap: 0.25rem; }
  label:has(textarea) > :first-child { padding-top: 0; }
  .actions,
  #created { padding-left: 0; }
}

/* ===========================================================================
   Feedback chat widget (floating icon + panel)
   =========================================================================== */

/* Floating launcher, pinned to the bottom-right. Currently hidden in the UI
   (feedback goes through the per-insight chat instead — see the `hidden`
   attribute on the button in intake.html). This rule's own `display: grid`
   is author CSS and would outrank the browser's default `[hidden]` styling
   regardless of specificity, so — same as .chat-panel[hidden] below —
   .chat-toggle[hidden] spells out the override explicitly. */
.chat-toggle {
  position: fixed;
  right: 1.5rem;
  bottom: 1.5rem;
  z-index: 40;
  width: 3.25rem;
  height: 3.25rem;
  padding: 0;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
}
.chat-toggle[hidden] { display: none; }
.chat-toggle:hover { background: var(--accent-press); }
html.view-intake .chat-toggle,
html.view-intake .chat-panel { display: none; }

/* The panel floats just above the launcher. */
.chat-panel {
  position: fixed;
  right: 1.5rem;
  bottom: 5.25rem;
  z-index: 40;
  width: 26rem;
  max-width: calc(100vw - 3rem);
  height: 34rem;
  max-height: calc(100vh - 8rem);
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
  overflow: hidden;
}
.chat-panel[hidden] { display: none; }

.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
  font-weight: 650;
}

.chat-close {
  width: 1.6rem;
  height: 1.6rem;
  padding: 0;
  display: grid;
  place-items: center;
  font-size: 1.2rem;
  line-height: 1;
  background: transparent;
  color: var(--muted);
  border-radius: var(--radius);
}
.chat-close:hover { background: var(--border); color: var(--text); }

.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 0.85rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* A single message bubble; user messages align right, replies left. */
.chat-bubble {
  max-width: 80%;
  padding: 0.45rem 0.7rem;
  border-radius: 12px;
  font-size: 0.85rem;
  line-height: 1.4;
  white-space: pre-wrap;
  word-break: break-word;
}
.chat-user {
  align-self: flex-end;
  background: var(--accent);
  color: #fff;
  border-bottom-right-radius: 4px;
}
.chat-bot {
  align-self: flex-start;
  background: var(--border);
  color: var(--text);
  border-bottom-left-radius: 4px;
}

/* Tappable quick-reply chips between the messages and the input. Empty by
   default (no padding/border), so it's invisible until suggestions arrive. */
.chat-suggestions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
}
.chat-suggestions:not(:empty) {
  padding: 0.5rem 0.75rem 0;
}
.chat-suggestion {
  flex: none;
  width: auto;
  padding: 0.3rem 0.7rem;
  font-size: 0.8rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease;
}
.chat-suggestion:hover {
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border-color: var(--accent);
}

.chat-form {
  display: flex;
  /* Keep Send pinned to the bottom as the textarea grows taller. */
  align-items: flex-end;
  gap: 0.5rem;
  padding: 0.75rem;
  border-top: 1px solid var(--border);
}
.chat-form textarea {
  flex: 1;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  /* Grow with the content (one line by default), then scroll once it's tall. */
  field-sizing: content;
  min-height: 0;
  max-height: 7.5rem;
  overflow-y: auto;
  line-height: 1.4;
}
.chat-form textarea:focus { box-shadow: none; }
.chat-form button { flex: none; padding: 0.45rem 0.9rem; }

/* Dedicated insight page layout: detail + chat stacked on narrow screens, side
   by side (chat sticky on the right) once there's room. */
.insight-layout {
  display: grid;
  gap: 1.5rem;
  align-items: start;
}
@media (min-width: 60rem) {
  .insight-layout {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  }
  .insight-side {
    position: sticky;
    top: 1rem;
  }
}

/* Inline per-insight chat: a static (non-floating) bordered box (title +
   scrolling messages + form) reused in two places that size it differently —
   this shared rule only carries the box's own look, not its height. */
.insight-chat {
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Dedicated insight page: no bounded-height ancestor chain to stretch into
   (the page is a normal scrolling document), so this one spot still sizes
   itself directly off the viewport. 100vh minus everything else stacked in
   the viewport above/below this box: body.app's own top+bottom padding
   (1.75rem + 3.5rem) plus the "Back to dashboard" link's height + margin
   above it (~2.3rem). */
.insight-side .insight-chat {
  height: calc(100vh - 8rem);
}
.insight-chat-title {
  margin: 0;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
  font-weight: 650;
}
/* Fill the space between the title and the form; scroll internally. min-height:0
   lets this flex child shrink below its content so overflow-y actually kicks in. */
.insight-chat .chat-messages {
  flex: 1;
  min-height: 0;
}
.insight-chat .chat-empty {
  margin: auto;
  color: var(--muted);
  font-size: 0.85rem;
}

/* Markdown-rendered bubbles (assistant replies): normal whitespace (overriding
   the plain bubble's pre-wrap) and tidy block spacing. */
.chat-bubble--md { white-space: normal; }
.chat-bubble--md > :first-child { margin-top: 0; }
.chat-bubble--md > :last-child { margin-bottom: 0; }
.chat-bubble--md p { margin: 0 0 0.5em; }
.chat-bubble--md ul,
.chat-bubble--md ol { margin: 0 0 0.5em; padding-left: 1.2em; }
.chat-bubble--md li { margin: 0.15em 0; }
.chat-bubble--md h1,
.chat-bubble--md h2,
.chat-bubble--md h3,
.chat-bubble--md h4 { margin: 0.3em 0; font-size: 1em; font-weight: 650; }
.chat-bubble--md a { color: inherit; text-decoration: underline; }
.chat-bubble--md code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85em; }
.chat-bubble--md :not(pre) > code {
  background: rgba(0, 0, 0, 0.22);
  padding: 0.05em 0.3em;
  border-radius: 4px;
}
.chat-bubble--md pre {
  margin: 0 0 0.5em;
  padding: 0.5em 0.6em;
  background: rgba(0, 0, 0, 0.28);
  border-radius: 8px;
  overflow-x: auto;
}
.chat-bubble--md pre code { background: none; padding: 0; }

/* "Typing" indicator: three bouncing dots in a bot bubble while awaiting a reply. */
.chat-typing { display: inline-flex; gap: 4px; align-items: center; }
.chat-typing-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.4;
  animation: chat-typing-bounce 1.2s infinite ease-in-out;
}
.chat-typing-dot:nth-child(2) { animation-delay: 0.15s; }
.chat-typing-dot:nth-child(3) { animation-delay: 0.3s; }
@keyframes chat-typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-4px); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .chat-typing-dot { animation: none; }
}

/* ===========================================================================
   Landing page (login.html for signed-out visitors)
   =========================================================================== */

body.landing {
  display: block;
  place-items: initial;
  min-height: 100vh;
  padding: 0;
}

.landing .container {
  width: 100%;
  max-width: 64rem;
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* Reusable solid CTA that works on an <a>. */
.btn-primary {
  display: inline-block;
  font-size: 0.95rem;
  font-weight: 650;
  padding: 0.7rem 1.4rem;
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: #fff;
  text-decoration: none;
  transition: background 0.15s ease;
}
.btn-primary:hover { background: var(--accent-press); }

/* Top nav */
.landing-nav {
  max-width: 64rem;
  margin: 0 auto;
  padding: 1.1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.brand img { border-radius: 6px; display: block; }

/* Hero */
.hero {
  max-width: 52rem;
  margin: 0 auto;
  padding: 4rem 1.5rem 3.5rem;
  text-align: center;
}

.eyebrow {
  margin: 0 0 1rem;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
}

.hero h1 {
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1.08;
  font-weight: 720;
  letter-spacing: -0.02em;
  margin: 0 0 1.1rem;
}

.lead {
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--muted);
  max-width: 40rem;
  margin: 0 auto;
}

.cta {
  margin-top: 2rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
}
.cta-note { margin: 0; font-size: 0.8rem; color: var(--muted); }
.cta #status { min-height: 0; }

.section-heading {
  text-align: center;
  font-size: clamp(1.4rem, 3vw, 1.9rem);
  font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 2rem;
}

/* Feature grid */
.features {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1rem;
  margin-bottom: 4rem;
}

.feature {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 1.5rem;
}

.feature-icon {
  width: 2.5rem;
  height: 2.5rem;
  display: grid;
  place-items: center;
  border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 14%, transparent);
  color: var(--accent);
  font-size: 1.2rem;
  margin-bottom: 0.9rem;
}

.feature h3 { margin: 0 0 0.4rem; font-size: 1rem; font-weight: 650; }
.feature p { margin: 0; font-size: 0.9rem; line-height: 1.55; color: var(--muted); }

/* Steps */
.steps {
  list-style: none;
  padding: 0;
  margin: 0 0 4rem;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1.5rem;
}
.steps li { text-align: center; }
.step-num {
  display: inline-grid;
  place-items: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  font-weight: 700;
  margin-bottom: 0.75rem;
}
.steps h3 { margin: 0 0 0.35rem; font-size: 1rem; font-weight: 650; }
.steps p { margin: 0; font-size: 0.9rem; line-height: 1.55; color: var(--muted); }

/* Why section */
.why {
  background: color-mix(in srgb, var(--accent) 6%, var(--bg));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 4rem 0;
}
.why-list {
  list-style: none;
  padding: 0;
  margin: 0 auto 2.5rem;
  max-width: 44rem;
  display: grid;
  gap: 1rem;
}
.why-list li {
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--muted);
  padding-left: 1.6rem;
  position: relative;
}
.why-list li::before {
  content: "✓";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}
.why-list strong { color: var(--text); font-weight: 650; }

/* Footer */
.landing-footer {
  max-width: 64rem;
  margin: 0 auto;
  padding: 2rem 1.5rem 3rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  font-size: 0.85rem;
  font-weight: 600;
}

@media (max-width: 34rem) {
  .hero { padding: 3rem 1.25rem 2.5rem; }
  .why { padding: 3rem 0; }
}
