/* Chat app, chat panel, message rows, artifact cards, lead-capture form. */
/* ---- chat panel: NOT a card -------------------------------------------------
   The chat area sits directly on the app shell's grey (--bg, #F2F2F2). It used to
   be a white card mirroring the sidebar's, so the layout read as two floating cards
   side by side; now only the sidebar is a card and the conversation is on the
   background itself.

   `background: transparent` rather than restating the grey: the shell (.app) already
   paints --bg, and inheriting it means the two can never drift apart if the shell's
   background changes. No border-radius and no box-shadow, both only existed to
   describe a card edge that no longer exists.

   overflow:hidden stays. It is not about the corners: .messages is a scroll
   container inside a fixed-height flex column, and without the clip a stray pixel of
   its content can escape the column's box. Nothing here depended on .chat being
   white -- bot bubbles are already `background: transparent` (see .row.bot .bubble
   below) and artifact cards are their own --panel white, which now reads as
   surface-1-on-surface-0 instead of white-on-white.
   ------------------------------------------------------------------------- */
.chat { flex: 1; min-width: 0; display: flex; flex-direction: column; background: transparent; overflow: hidden; }
header { padding: 12px 18px; display: flex; align-items: center; gap: 10px; min-height: 56px; }
.icon-btn { border: none; background: transparent; color: var(--muted); cursor: pointer; padding: 7px; border-radius: var(--r); display: grid; place-items: center; text-decoration: none; transition: background 0.14s, color 0.14s; }
.icon-btn[hidden] { display: none; }
/* No hover FILL: the disc behind these buttons is gone. The icon itself changing colour
   is the whole hover signal now -- these are bare glyphs (close, download, copy,
   regenerate, sidebar toggle), and a grey circle around a glyph reads as chrome the rest
   of the app does not have. */
.icon-btn:hover { background: transparent; color: var(--text); }
.icon-btn svg { width: 20px; height: 20px; }
.sidebar-toptools .icon-btn svg, .sb-tools .icon-btn svg { width: 18px; height: 18px; }
.sidebar-toptools .icon-btn.active, .sb-tools .icon-btn.active { background: var(--hover-2); color: var(--text); }
#toggleSidebar { display: none; }
body.sidebar-collapsed #toggleSidebar { display: grid; }
.spacer { flex: 1; }
/* The close (✕) button carries a visible "Go back" label, so it lays out as an
   icon+text row rather than the icon-only grid the base .icon-btn uses. The explicit
   [hidden] rule is re-stated because the id selector above would otherwise out-specify
   .icon-btn[hidden] and show the button while it's still meant to be hidden. */
#closeChatBtn { display: inline-flex; align-items: center; gap: 6px; width: auto; padding: 7px 12px; }
#closeChatBtn[hidden] { display: none; }
.close-label { font-size: 13px; font-weight: 500; white-space: nowrap; }

/* Reading column. */
/* min-width:0 + overflow-x:hidden here matter specifically for streaming: a
   flex column's children default to sizing at their MAX CONTENT width unless
   told otherwise, so a long unbroken token mid-stream (before markdown/code
   fences fully close and get their own internal scroll) could force this
   whole column wider, which is exactly the "breaks wide while generating,
   fine once settled" bug. Locking the container's own width here means
   nothing inside can ever push it, regardless of what's mid-render. */
.messages { flex: 1; min-width: 0; overflow-y: auto; overflow-x: hidden;
  padding: 30px max(var(--reading-pad), calc((100% - var(--reading-max)) / 2)) 10px; display: flex; flex-direction: column; scroll-behavior: smooth; }
/* ---- scrollbars: one appearance for every scroll surface in the app ----------
   Listed together on purpose. These are the app's scrollable regions (the message
   list, the conversation list, the artifact drawer, the Settings modal body and its
   Instructions textarea, the Library grid, the search results), and the point of a
   single rule is that none of them can drift to a different colour or width from
   the others.

   Colour comes from --scroll-thumb (see css/chat-base.css for the value and why):
   a light AlphaVenture neutral that reads as an affordance rather than a piece of
   chrome.

   `::-webkit-scrollbar-button` is the stepper arrow at each end. Chromium hides it
   once ::-webkit-scrollbar is styled at all, but it is set explicitly here because
   that is incidental behaviour, not a guarantee, and the arrows are exactly the
   heavy native detail this styling exists to get rid of.
   ---------------------------------------------------------------------------- */
.messages, .list, .drawer-body, #libraryBody, .settings-instructions, .search-results, textarea {
  scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent;
}
.messages::-webkit-scrollbar, .list::-webkit-scrollbar, .drawer-body::-webkit-scrollbar, #libraryBody::-webkit-scrollbar, .settings-instructions::-webkit-scrollbar, .search-results::-webkit-scrollbar, textarea::-webkit-scrollbar { width: 10px; height: 10px; }
.messages::-webkit-scrollbar-button, .list::-webkit-scrollbar-button, .drawer-body::-webkit-scrollbar-button, #libraryBody::-webkit-scrollbar-button, .settings-instructions::-webkit-scrollbar-button, .search-results::-webkit-scrollbar-button, .feed-thought-body::-webkit-scrollbar-button, textarea::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
.messages::-webkit-scrollbar-track, .list::-webkit-scrollbar-track, .drawer-body::-webkit-scrollbar-track, #libraryBody::-webkit-scrollbar-track, .settings-instructions::-webkit-scrollbar-track, .search-results::-webkit-scrollbar-track, textarea::-webkit-scrollbar-track { background: transparent; }
.messages::-webkit-scrollbar-thumb, .list::-webkit-scrollbar-thumb, .drawer-body::-webkit-scrollbar-thumb, #libraryBody::-webkit-scrollbar-thumb, .settings-instructions::-webkit-scrollbar-thumb, .search-results::-webkit-scrollbar-thumb, textarea::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: var(--r-pill); border: 2px solid transparent; background-clip: padding-box; }
/* :active is the dragged ("clicked to scroll") thumb, and takes the SAME value as
   hover -- a thumb that reverts to its resting grey the moment you grab it reads as
   unresponsive at exactly the moment the user is interacting with it. */
.messages::-webkit-scrollbar-thumb:hover, .messages::-webkit-scrollbar-thumb:active, .list::-webkit-scrollbar-thumb:hover, .list::-webkit-scrollbar-thumb:active, .drawer-body::-webkit-scrollbar-thumb:hover, .drawer-body::-webkit-scrollbar-thumb:active, #libraryBody::-webkit-scrollbar-thumb:hover, #libraryBody::-webkit-scrollbar-thumb:active, .settings-instructions::-webkit-scrollbar-thumb:hover, .settings-instructions::-webkit-scrollbar-thumb:active, .search-results::-webkit-scrollbar-thumb:hover, .search-results::-webkit-scrollbar-thumb:active, textarea::-webkit-scrollbar-thumb:hover, textarea::-webkit-scrollbar-thumb:active { background: var(--scroll-thumb-hover); background-clip: padding-box; }

/* ---- messages: assistant flat (document), user orange pill (no avatar) ---- */
.row { display: flex; gap: 12px; margin-top: 26px; align-items: flex-start; min-width: 0; animation: pop 0.3s var(--ease); }
@keyframes pop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }
.row.user { align-self: flex-end; flex-direction: row-reverse; max-width: 80%; }
/* align-items: stretch (overriding the base .row's flex-start) so the bubble
   always fills the row's full width, regardless of how much surrounding prose
   there is, without it, a reply that's ALMOST entirely a report/chart/table
   card with little text around it shrinks to the card's own width instead of
   matching every other message, since flex-start's cross-axis sizing here is
   "shrink to content" rather than "fill the row". */
.row.bot { align-self: stretch; max-width: 100%; flex-direction: column; align-items: stretch; gap: 6px; }
.msg-head { display: flex; align-items: center; gap: 9px; }
.msg-head span:last-child { font-size: 13px; font-weight: 500; color: var(--text); font-family: var(--font-display); }
.pfp { width: 22px; height: 22px; border-radius: var(--r-pill); flex: none; display: grid; place-items: center; font-size: 11px; font-weight: 500; color: #fff; }
.row.bot .pfp { background: linear-gradient(150deg, var(--accent), var(--accent-2)); }
.row.user .pfp { display: none; } /* modern: user messages carry no avatar */

.bubble-wrap { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.row.bot .bubble-wrap { flex: 1; }
.row.user .bubble-wrap { align-items: flex-end; }
.bubble { padding: 10px 14px; border-radius: var(--r); font-size: var(--chat-font-size); line-height: 1.62; white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere; }
/* The user's own message is an ORANGE card in var(--lp-orange) with white text. It sits
   on the shell's #F2F2F2, and the orange fill separates it without a stroke.
   Radius is a uniform 24px: it used to be `20px 20px 6px 20px`, a speech-bubble tail
   pointing at an avatar that .row.user .pfp explicitly hides. A tail with nothing to
   point at is just an inconsistent corner, and 6px is not on the 40/24/100 scale. */
.row.user .bubble { background: var(--lp-orange); color: #fff; border-radius: var(--r); padding: 11px 16px; }
.row.bot .bubble { background: #fff; color: var(--text); padding: 11px 16px; border-radius: var(--r); max-width: 100%; }
.msg-actions { display: flex; gap: 4px; margin-top: 2px; opacity: 0; transition: opacity 0.15s; }
.row.bot .msg-actions { padding-left: 0; }
.row.user .msg-actions { justify-content: flex-end; padding-right: 2px; }
.row:hover .msg-actions, .msg-actions:focus-within { opacity: 1; }
.msg-actions button { border: none; background: none; color: var(--muted); cursor: pointer; padding: 5px; border-radius: var(--r); display: inline-flex; align-items: center; justify-content: center; transition: background 0.14s, color 0.14s; }
/* No hover FILL behind the icon -- the glyph changing colour is the signal. Matches
   .icon-btn (chat-messages.css): a grey disc around a bare icon is chrome this app
   does not use anywhere else. */
.msg-actions button:hover { color: var(--text); }
.msg-actions button svg { width: 15px; height: 15px; }

/* rendered markdown (assistant) */
.row.bot .bubble p { margin: 0 0 10px; }
.row.bot .bubble > :last-child { margin-bottom: 0; }
.row.bot .bubble ul, .row.bot .bubble ol { margin: 6px 0 10px; padding-left: 22px; }
.row.bot .bubble li { margin: 3px 0; }
.row.bot .bubble li > ul, .row.bot .bubble li > ol { margin: 3px 0; }
.row.bot .bubble h1, .row.bot .bubble h2, .row.bot .bubble h3,
.row.bot .bubble h4, .row.bot .bubble h5, .row.bot .bubble h6 { margin: 16px 0 8px; line-height: 1.3; font-weight: 500; font-family: var(--font-display); letter-spacing: -0.01em; }
.row.bot .bubble h1 { font-size: 1.3em; } .row.bot .bubble h2 { font-size: 1.18em; } .row.bot .bubble h3 { font-size: 1.06em; }
.row.bot .bubble h4, .row.bot .bubble h5, .row.bot .bubble h6 { font-size: 1em; }
.row.bot .bubble strong { font-weight: 500; } .row.bot .bubble em { font-style: italic; } .row.bot .bubble del { opacity: 0.7; }
.row.bot .bubble a { color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
.row.bot .bubble code { background: rgba(133,133,133,0.18); padding: 1px 6px; border-radius: var(--r); font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.9em; }
.row.bot .bubble pre { position: relative; background: rgba(133,133,133,0.12); padding: 12px 14px; border-radius: var(--r); overflow-x: auto; max-width: 100%; margin: 10px 0; }
.row.bot .bubble pre code { background: none; padding: 0; font-size: 0.88em; }
.row.bot .bubble hr { border: none; border-top: 1px solid var(--border); margin: 14px 0; }
.row.bot .bubble blockquote { margin: 10px 0; padding: 4px 14px; border-left: 3px solid var(--accent); color: var(--muted); }
/* Markdown tables scroll sideways rather than being crushed to fit. The scroller is
   added by enhanceTables() in js/chat/message-html.js, because this needs two boxes:
   the container holds the scrollbar at the reading width, and the table inside is
   free to be as wide as its content. `overflow-x` on the table alone just shrinks it,
   which is what produced 40px columns wrapped over five lines on a phone. */
.md-table-scroll {
  max-width: 100%; overflow-x: auto; margin: 10px 0;
  scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent;
}
.md-table-scroll::-webkit-scrollbar { height: 8px; }
.md-table-scroll::-webkit-scrollbar-button { display: none; width: 0; height: 0; }
.md-table-scroll::-webkit-scrollbar-track { background: transparent; }
.md-table-scroll::-webkit-scrollbar-thumb { background: var(--scroll-thumb); border-radius: var(--r-pill); border: 2px solid transparent; background-clip: padding-box; }
/* This one had no hover/active state, so the markdown-table scrollbar was the one
   scrollbar in the app that never responded to the pointer. */
.md-table-scroll::-webkit-scrollbar-thumb:hover, .md-table-scroll::-webkit-scrollbar-thumb:active { background: var(--scroll-thumb-hover); background-clip: padding-box; }
.md-table-scroll::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover); background-clip: padding-box; }
.row.bot .bubble table {
  border-collapse: collapse; margin: 0; font-size: 0.92em;
  /* min-width is what makes the container scroll instead of the table compressing.
     max-content = the width the table wants; on a wide screen the container is
     wider still, so no scrollbar appears and nothing changes. */
  min-width: max-content;
}
/* Keep a cell on one line inside the scroller. Wrapping is what turned a data row
   into a five-line block; the reader can scroll instead. */
.row.bot .bubble th, .row.bot .bubble td { white-space: nowrap; }
/* Row rules instead of the per-cell box that went with the stroke sweep. Same
   reasoning as .artifact-table in chat-drawer.css. */
.row.bot .bubble th, .row.bot .bubble td { padding: 6px 10px; text-align: left; border-bottom: 1px solid var(--border); }
.row.bot .bubble tr:last-child td { border-bottom: none; }
.row.bot .bubble th { background: rgba(133,133,133,0.12); font-weight: 500; }
.code-copy { position: absolute; top: 7px; right: 7px; font-size: 11px; padding: 3px 8px; border-radius: var(--r); background: var(--panel); color: var(--muted); cursor: pointer; opacity: 0; transition: opacity 0.15s; }
pre:hover .code-copy { opacity: 1; }

/* artifact card, one shared structure/hover for report, chart, and table
   (no icon, no arrow-style "Open in..." subtitle; plain type label instead,
   Claude-file-card style). Full-width block so every kind matches, regardless
   of how short the surrounding message text is. */
/* WHITE (--surface-1), no stroke, no shadow, no lift. These cards sit on the chat's
   #F2F2F2 ground, so white is the level above it and the fill alone separates them --
   which is the whole point of the surface-alternation scale. They were --surface-2 grey,
   i.e. the same value as the ground behind them, so the card edge was invisible.
   NO hover change at all. It went grey on hover, which made a white card flicker to the
   colour of the ground behind it; the whole card is already a click target and the cursor
   is the affordance. */
.artifact-card { display: flex; flex-wrap: wrap; align-items: center; gap: 13px; width: 100%; box-sizing: border-box; margin: 20px 0; padding: 13px 15px; background: var(--bg); border-radius: var(--r); cursor: pointer; transition: background 0.15s; }
/* Chart caption: full-width line under the title/buttons row (flex-wraps onto its own line). */
.artifact-desc { flex: 0 0 100%; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.artifact-card:hover { background: var(--bg); }
.artifact-meta { flex: 1; min-width: 0; }
.artifact-title { font-size: 14px; font-weight: 500; letter-spacing: -0.005em; }
.artifact-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.artifact-btns { display: flex; align-items: center; gap: 6px; flex: none; }
.artifact-btns .view, .artifact-btns .dl { height: 32px; box-sizing: border-box; border-radius: var(--r); cursor: pointer; transition: background 0.15s, color 0.15s; }
.artifact-btns .view { background: var(--accent); color: #fff; font: inherit; font-size: 12px; font-weight: 500; padding: 0 14px; display: flex; align-items: center; }
/* Hover turns the View button BRAND BLACK with a white label -- not a darker orange, and
   not the grey the rest of the card avoids. --btn-solid-* is the same black/white pair the
   send button uses, so the three read as one "solid brand-black button" role rather than
   three rules that happen to share a colour. */
.artifact-btns .view:hover { background: var(--btn-solid-bg); color: var(--btn-solid-fg); }
/* Download is a secondary action, a plain icon-only square button, same height
   as View but visually quieter (no label, no color fill) rather than a second
   text pill competing with it. */
.artifact-btns .dl { background: transparent; color: var(--muted); width: 32px; display: flex; align-items: center; justify-content: center; padding: 0; }
.artifact-btns .dl svg { width: 15px; height: 15px; }
/* No hover FILL behind the icon -- the glyph changing colour is the signal. Matches
   .icon-btn (chat-messages.css): a grey disc around a bare icon is chrome this app
   does not use anywhere else. */
.artifact-btns .dl:hover { color: var(--text); }
.rich-error { color: #C05227; font-size: 12.5px; margin: 4px 0; }
/* Self-imposed limits (rate_limited/capacity/budget_exceeded), a calm neutral
   card, not the red error text, since the app isn't broken, just pacing things. */
.notice-graceful {
  display: flex; flex-direction: column; gap: 10px; align-items: flex-start;
  padding: 12px 14px; border-radius: var(--r); background: rgba(133,133,133,0.08);
  max-width: 380px; box-shadow: var(--elev-1);
}
.notice-graceful-text { font-size: 13.5px; color: var(--text); line-height: 1.5; }
/* A small lift (box-shadow) rather than a fill/border tells this button apart from
   the translucent-tinted notice it sits on, the same way artifact-card and lead-form
   get their separation from a real shadow now that one renders again. */
.notice-graceful-btn {
  background: var(--panel); color: var(--text); box-shadow: var(--elev-1);
  font: inherit; font-size: 13px; font-weight: 500; padding: 7px 15px;
  border-radius: var(--r); cursor: pointer; transition: background 0.14s, opacity 0.14s;
}
.notice-graceful-btn:hover:not(:disabled) { background: var(--hover); color: var(--text); }
.notice-graceful-btn:disabled { opacity: 0.55; cursor: default; }
/* Session-length heads-up, a calm informational card, distinct from the answer
   above it (never blended into the model's own prose as an inline aside). */
.notice-session {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  margin-top: 10px; padding: 11px 14px; border-radius: var(--r);
  background: rgba(133,133,133,0.08); max-width: 480px;
}
.notice-session-text { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.notice-session-btn {
  flex: none; background: var(--panel); color: var(--text); box-shadow: var(--elev-1);
  font: inherit; font-size: 12.5px; font-weight: 500; padding: 6px 12px;
  border-radius: var(--r); cursor: pointer; transition: background 0.14s;
}
.notice-session-btn:hover { background: var(--hover); }
/* "You stopped this response". Deliberately the quietest of the three notices: it
   is a neutral fact about what the user themselves just did, not a warning and not a
   failure, so it gets muted text and no card chrome (no border, no fill) rather than
   the boxed treatment the rate-limit and session notices use. It still has to read as
   app chrome rather than as prose, which the icon plus the muted colour handle. */
.notice-stopped {
  display: flex; align-items: center; gap: 7px;
  margin-top: 8px; font-size: 12.5px; color: var(--muted);
}
.notice-stopped svg { width: 13px; height: 13px; flex: none; }

/* lead-capture form */
/* ---- the email ask, as a WHITE CARD ------------------------------------------------
   The whole thing -- label, field, Send, hint, Skip -- lives in one white box so it reads
   as a single form to complete rather than loose controls floating in the message flow.
   It was --surface-2 (#F2F2F2), the same value as the shell behind it, so it had no edge
   of its own; white is the correct next step on the surface-alternation scale and it makes
   the sunken #E0E0E0 field below possible, which grey-on-grey could not support. */
.lead-form { margin: 10px 0 2px; padding: 14px 16px; background: var(--surface-1); border-radius: var(--r); max-width: 380px; box-shadow: var(--elev-1); }
.lead-form .lead-label { font-size: 12.5px; color: var(--muted); margin-bottom: 9px; }
/* align-items: flex-start, not the flex default `stretch`. `.lead-actions` (Send stacked
   over Skip, see below) is taller than the bare input, and `stretch` would pull the input
   down to match that height -- which grows a single-line field for no reason. flex-start
   keeps the input at its own intrinsic height while `.lead-actions` sets the row's height. */
.lead-form .lead-row { display: flex; gap: 8px; align-items: flex-start; }
/* ---- Send + Skip, ONE flex column ---------------------------------------------------
   This is what makes "Skip aligned with Send" true by construction rather than by
   coincidence. Two elements of different widths sharing a right edge (which is what a
   space-between flex row gives you) still reads as Skip hugging the corner of a much
   wider button, not sitting "under" it. A flex COLUMN with `align-items: center` instead
   centres each child within the column's own width, and that width is set by its widest
   child -- Send -- so Skip centres itself on Send's midpoint automatically, at any locale
   or font size, with no measurement or fixed width anywhere. */
.lead-form .lead-actions { display: flex; flex-direction: column; align-items: center; gap: 5px; flex: none; }
/* #E0E0E0 -- an approved AV neutral, one step darker than the shell, so the field reads as
   SUNKEN into the white card. A literal rather than var(--border) on purpose: --border is
   reserved for hairlines, and using a stroke token as a fill would make a future change to
   hairline colour silently repaint this field.
   The 8px .lead-row gap shows the white card between this field and the Send button, which
   is what keeps them apart when Send is disabled and also #E0E0E0. */
.lead-form input[type="email"] { flex: 1; min-width: 0; background: #E0E0E0; color: var(--text); border-radius: var(--r); padding: 9px 12px; font: inherit; font-size: 13.5px; outline: none; }
/* ---- kill the browser's autofill styling --------------------------------------------
   Chrome paints an autofilled field with its own blue/lilac wash and its own text colour,
   ignoring `background-color` -- so a remembered address arrived looking like a different
   control from the one beside it. The fill can only be overridden through the inset
   box-shadow trick (Chrome draws the wash as a background layer that `background` cannot
   reach), and `-webkit-text-fill-color` is what actually governs autofilled glyph colour.
   The huge transition delay is the standard hold-off that stops Chrome re-applying its
   colour a frame later. `!important` is required: the UA rule is more specific than any
   author selector. box-shadow is otherwise globally disabled, so this inset is the single
   deliberate exception -- it is a fill, not elevation. */
.lead-form input[type="email"]:-webkit-autofill,
.lead-form input[type="email"]:-webkit-autofill:hover,
.lead-form input[type="email"]:-webkit-autofill:focus,
.lead-form input[type="email"]:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 100px #E0E0E0 inset !important;
          box-shadow: 0 0 0 100px #E0E0E0 inset !important;
  -webkit-text-fill-color: var(--text) !important;
  caret-color: var(--text);
  transition: background-color 6000000s 0s, color 6000000s 0s;
}
.lead-form .lead-send { border: none; background: var(--accent); color: #fff; border-radius: var(--r); padding: 9px 17px; font: inherit; font-size: 13.5px; font-weight: 500; cursor: pointer; flex: none; transition: background 0.15s; }
.lead-form .lead-send:hover:not(:disabled) { background: var(--accent-press); }
/* ---- disabled Send: a real greyed state, not a faded orange ------------------------
   Matches the reference pattern on immigration.alphaventure.com (the "See your
   recommendation" button before the quiz is answered): a flat light-grey pill with grey
   text, reading clearly as "not yet". No arrow -- this button has never had one, and the
   reference's arrow is part of a wizard's forward motion, which does not apply to a
   two-field form.
   ENABLED stays orange (#F06731), unchanged -- the orange is the affordance and only the
   OFF state changes.
   Explicit palette colours rather than the old `opacity: 0.4`: opacity on #F06731 produced
   an unapproved washed-out orange (the brand doc treats opacity on a palette colour as a
   workaround for a missing tint), and it dimmed the label to near-illegible. #E0E0E0 on
   #858585 are both approved neutrals and both fully opaque. */
.lead-form .lead-send:disabled { background: #E0E0E0; color: #858585; cursor: default; }
/* Skip now lives in `.lead-actions` above, directly under Send -- see that rule for why.
   `.lead-foot` is left with exactly two items: the validation hint (grows to fill) and
   "Use a different email" (shown only when a remembered address is prefilled), so
   space-between still does the right thing with one fewer item than before. */
.lead-form .lead-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; min-height: 16px; }
/* .lead-foot-empty: collapse the reserved row entirely when it holds NEITHER a hint
   message nor a visible "Use a different email" button (js/chat/lead-capture.js's
   syncFoot() toggles this class on every state change that can flip either). Without it,
   the row's `margin-top: 8px` + `min-height: 16px` above stayed reserved even with
   nothing in it -- 24px of dead air below Skip in the ordinary case (a fresh ask, no
   error, no remembered address), which is most of the time this card is on screen.
   The base rule is UNCHANGED and still applies the moment either child has something to
   show, so an error message popping in still can't jump the card's height. */
.lead-form .lead-foot.lead-foot-empty { margin-top: 0; min-height: 0; }
.lead-form .lead-hint { font-size: 11.5px; color: #C05227; flex: 1; }
/* "Use a different email": shown only when a remembered address is prefilled. Styled as
   a quiet text button, the same treatment Skip keeps in `.lead-actions` -- it is an
   alternative, not the main action, which stays the Send button. */
.lead-form .lead-change { border: none; background: none; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; padding: 2px 4px; flex: none; text-decoration: underline; }
.lead-form .lead-change:hover { color: var(--text); }
.lead-form .lead-change:disabled { opacity: 0.4; cursor: default; }
.lead-form .lead-change[hidden] { display: none; }
.lead-form .lead-skip { border: none; background: none; color: var(--muted); font: inherit; font-size: 12px; cursor: pointer; padding: 2px 4px; text-decoration: underline; }
.lead-form .lead-skip:hover { color: var(--text); }
.lead-form .lead-skip:disabled { opacity: 0.4; cursor: default; }
.lead-confirm { display: flex; align-items: center; gap: 6px; margin: 6px 0 0; font-size: 13px; color: var(--muted); }
.lead-confirm .check { color: var(--accent); font-weight: 500; }

