/* ── home.css ────────────────────────────────────────────────────────────
   Layout. Class names mirror the reference Tagline source verbatim:
   .top, .middle, .lower, .stripe, .stripe-input, .bottom, .lockup, .meta,
   .headline, .mark-large. References only semantic vars (--ground, --fore,
   --fore-2, --rule) so the page renders identically under every theme.
   ─────────────────────────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--ground);
  color: var(--fore);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow: hidden;
}

main {
  width: 100vw;
  height: 100dvh;
  /* No top padding — the chat-area extends to viewport top so content can
     scroll under the absolutely-positioned, liquid-glass masthead. */
  padding: 0 var(--pad-x) var(--pad-y);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 4vmin;
  position: relative;
}

/* the bottom group (stripe + footer) sticks together so the layout
   still resolves to top / headline / bottom-block under space-between */
.lower {
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.8vmin, 24px);
}

/* ─── top row ─ glass masthead ───────────────────────────
   Lifted out of main's flex flow and floated at viewport top so the chat
   surface below can scroll under it. Background is fully transparent —
   the backdrop-filter blurs whatever sits behind without applying a color
   tint, so the apparent ground color is unchanged when nothing is passing
   under the bar (and turns into a clean blur smear when chat content is). */
.top {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  padding: clamp(10px, 1.6vmin, 18px) var(--pad-x);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1em;
  background: transparent;
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
}

.lockup {
  display: inline-flex;
  align-items: center;
  gap: 0.42em;
  font-size: clamp(14px, 2.3vmin, 36px);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--fore);
  text-decoration: none;
  white-space: nowrap;
}

.lockup svg {
  width: 1.22em;
  height: 1.22em;
  display: block;
}

.meta {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.35vmin, 22px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fore-2);
  white-space: nowrap;
}

/* ─── primary nav (header) ───────────────────────────── */
.primary-nav {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2.4vmin, 36px);
}
.primary-nav a,
.signin {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.4vmin, 17px);
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--fore);
  text-decoration: none;
  white-space: nowrap;
  opacity: 0.82;
  transition: opacity 0.18s ease;
}
.primary-nav a:hover,
.signin:hover { opacity: 1; }

/* Current page: full opacity + underline. */
.primary-nav a[aria-current="page"] {
  opacity: 1;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-underline-offset: 6px;
}

.primary-cta {
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.8vmin, 28px);
}

.cta {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.4vmin, 17px);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--cta-fore);
  background: var(--cta-bg);
  padding: clamp(8px, 1.05vmin, 14px) clamp(14px, 1.7vmin, 22px);
  border-radius: 6px;
  text-decoration: none;
  white-space: nowrap;
  line-height: 1;
  transition: opacity 0.18s ease;
}
.cta:hover { opacity: 0.9; }

/* ─── headline ───────────────────────────────────────── */
.headline {
  font-family: var(--font-sans);
  /* Source artboard: fontSize 86 at 520×620 → 16.5% of width. 16vmin keeps that ratio fluid. */
  font-size: clamp(40px, 16vmin, 280px);
  font-weight: 700;
  letter-spacing: -0.04em;
  line-height: 0.93;
  color: var(--fore);
  margin: 0;
  /* Clear the absolute masthead (which is out of flex flow). */
  margin-top: clamp(48px, 9vmin, 88px);
  text-wrap: balance;
}

/* ─── input stripe ───────────────────────────────────── */
/* Full-bleed band between the headline and the footer.
   Bleeds past main's horizontal padding via negative margins;
   the input text inside re-applies the same padding so the
   placeholder lines up with the lockup above. */
.stripe {
  margin-left: calc(-1 * var(--pad-x));
  margin-right: calc(-1 * var(--pad-x));
  padding: clamp(20px, 3.6vmin, 64px) var(--pad-x);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}

.stripe-input {
  position: relative;          /* anchor ::before so the caret isn't shoved past it */
  font-family: var(--font-condensed);
  font-weight: 500;
  font-size: clamp(22px, 4vmin, 72px);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fore);
  line-height: 1.18;
  caret-color: var(--fore);
  outline: none;
  border: none;
  background: transparent;
  min-height: 1.18em;          /* one line of space when empty */
  word-break: break-word;
  overflow-wrap: anywhere;
  white-space: pre-wrap;       /* preserve user line breaks */
}

/* Absolute-positioned so the placeholder doesn't occupy inline content
   space — keeps the caret at column 0 even after the user types and deletes. */
.stripe-input.is-empty::before {
  content: attr(data-placeholder);
  position: absolute;
  inset: 0;
  color: var(--fore-2);
  pointer-events: none;
}

.stripe-input:focus {
  outline: none;
}

/* ─── bottom row ─────────────────────────────────────── */
.bottom {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 1em;
}

.mark-large {
  width: clamp(28px, 4.5vmin, 88px);
  height: auto;
  display: block;
  flex-shrink: 0;
  color: var(--fore);
}

/* ─── legal nav (footer) ────────────────────────────────
   Sits beside the mark on the trailing edge of the bottom row. Uses the
   mono kicker treatment so it reads as operational metadata, not body. */
.bottom-right {
  display: flex;
  align-items: flex-end;
  gap: clamp(24px, 3.2vmin, 56px);
}

.legal-nav {
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 1.8vmin, 28px);
  padding-bottom: 0.2em;       /* visually align baseline with mark optical center */
}
.legal-nav a {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.2vmin, 14px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fore-2);
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.18s ease;
}
.legal-nav a:hover { color: var(--fore); }

/* ─── slogan rotation ──────────────────────────────────
   One statement-poster line per load. All variants ship in the markup;
   only the slot matching :root[data-slogan] is rendered. Removed from
   flex layout (display:none) rather than visually hidden so spacing
   resolves identically to a single-element page. */
[data-slot] { display: none; }
:root[data-slogan="0"] [data-slot="0"],
:root[data-slogan="1"] [data-slot="1"],
:root[data-slogan="2"] [data-slot="2"],
:root[data-slogan="3"] [data-slot="3"] { display: revert; }

/* ─── chat area ─────────────────────────────────────────
   Sits in the same vertical slot the headline occupies; hidden until the
   user sends the first message. At wide breakpoints it becomes a row with
   the chat on the leading edge and a live status panel on the trailing edge. */
.chat-area {
  display: none;
  flex: 1 1 auto;
  min-height: 0;
  flex-direction: column;
  gap: clamp(16px, 2vmin, 32px);
}
body.chat-active .chat-area { display: flex; }
body.chat-active .headline { display: none !important; }

.chat {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.4vmin, 18px);
  overflow-y: auto;
  overflow-x: hidden;          /* let entrance animations slide in from off-canvas-left without horizontal scroll */
  padding-right: clamp(40px, 18vw, 320px);  /* keep bubbles in the leading 70-80% at narrow widths */
  scrollbar-width: none;
}
.chat::-webkit-scrollbar { display: none; }
/* First child gets auto top-margin so short conversations still sit at the
   bottom of the surface (closest to the input stripe). When content grows
   beyond the chat's height the auto margin collapses and the surface scrolls. */
.chat > *:first-child { margin-top: auto; }
/* Once chat is going, the placeholder shouldn't keep nagging. */
body.chat-active .stripe-input.is-empty::before { content: none; }

.chat-message {
  align-self: flex-start;
  flex-shrink: 0;                                /* never compressed by flex layout */
  max-width: 100%;
  padding: clamp(12px, 1.6vmin, 22px) clamp(16px, 2.1vmin, 28px);
  border-radius: 8px;                            /* geometric, brand-aligned */
  font-family: var(--font-sans);
  /* Heading scale from Brand_Guide TypeSpecimen: 24 / 1.15 / -2.0% / 600.
     Tracked down + tight line-height because at 2.7vmin the text reads
     as a display element, not body copy. */
  font-size: clamp(18px, 2.7vmin, 36px);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-wrap: anywhere;
}

/* User bubble: filled bone surface, ink text — the brand's "card" surface
   pattern (mirrors offer cards in price-cards.jsx). Subtle 1px elevation
   shadow matches the offer cards' `box-shadow: 0 1px 0 rgba(0,0,0,0.05)`. */
.chat-message[data-author="user"] {
  background: var(--surface);
  color: var(--ink);
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.05);
}

/* LLM bubble: no border, no fill — reads as ambient brand voice over the
   ground. The operator-green dot prefix is the only signal element. */
.chat-message[data-author="llm"] {
  background: transparent;
  color: var(--fore);
}

/* ─── status feed ──────────────────────────────────────
   Trailing-edge live feed of provider-call updates as the AI fans out.
   Bare-text operator console — no card chrome — so it reads as a live
   transmission log rather than a stack of UI tiles. Theme-aware via
   --fore / --fore-2. Spacing comes from per-entry margin-bottom (not flex
   gap) so the exit animation can collapse the trailing space along with
   the entry itself, avoiding a snap when neighbors close in. */
.status {
  display: none;
  flex-direction: column;
  justify-content: flex-end;
  overflow: hidden;
}

@media (min-width: 1100px) {
  .chat-area { flex-direction: row; align-items: stretch; gap: clamp(24px, 3vmin, 56px); }
  .chat { padding-right: 0; }
  body.chat-active .status { display: flex; flex: 0 0 clamp(280px, 26vw, 380px); }
}

.status-card {
  font-family: var(--font-sans);
  color: var(--fore);
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: clamp(18px, 2vmin, 28px);
  overflow: hidden;             /* clips contents as the exit animation collapses height */
  animation: status-card-in 0.42s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.status-card:last-child {
  margin-bottom: 0;             /* no trailing space on the most recent entry */
}

@keyframes status-card-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Exit: fade and collapse the entry's height + bottom margin so neighbors
   reflow smoothly into the freed space. Offers hand off to the main chat;
   non-offers (voicemail / no openings / over budget) simply leave. */
.status-card--exiting {
  animation: status-card-exit 0.5s cubic-bezier(0.4, 0, 0.6, 1) forwards;
  pointer-events: none;
}
@keyframes status-card-exit {
  from { opacity: 1; max-height: 220px; margin-bottom: clamp(18px, 2vmin, 28px); }
  to   { opacity: 0; max-height: 0;     margin-bottom: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .status-card { animation: none; }
  .status-card--exiting { animation: none; opacity: 0; }
}

/* ─── chat-offer card ────────────────────────────────────
   Brand-canon offer card modeled on the PricingReceipt component in the
   .reference/ brand canvas: --surface ground, QUOTE · LIVE kicker on the
   left, honored signal on the right, mono ledger of included items, rule
   separators, big "You pay today" total, ink-fill Book CTA.

   Entrance is choreographed in two phases so the chat appears to scroll
   up to make room before the card itself slides in from the leading edge. */
/* Horizontal rail of offer cards — sits in the .lower block above the
   input stripe and bleeds past main's horizontal padding so cards can
   scroll off the trailing edge of the viewport. Grows its height once on
   first appearance so the chat above shifts up smoothly. */
.chat-offers-row {
  flex-shrink: 0;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  gap: clamp(12px, 1.8vmin, 24px);

  /* Full-bleed past main's padding — first card aligns with the page
     padding-left, last card trails off the trailing viewport edge. */
  margin-left: calc(-1 * var(--pad-x));
  margin-right: calc(-1 * var(--pad-x));
  padding-left: var(--pad-x);
  padding-right: var(--pad-x);

  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;          /* the scroll affordance is the visible trailing card */

  animation: chat-offers-row-grow 0.85s cubic-bezier(0.32, 0.72, 0, 1) both;
}
.chat-offers-row::-webkit-scrollbar { display: none; }

@keyframes chat-offers-row-grow {
  from { max-height: 0;    opacity: 0; }
  to   { max-height: 720px; opacity: 1; }
}

.chat-offer {
  /* Fixed width, no shrink — cards hold their natural size so the row
     overflows horizontally and scrolls instead of compressing to fit. */
  flex: 0 0 clamp(280px, 26vw, 360px);
  background: var(--surface);
  color: var(--ink);
  border-radius: 12px;
  border: 1px solid rgb(var(--ink-rgb) / 0.12);
  box-shadow: 0 10px 26px -10px rgba(0, 0, 0, 0.22);
  overflow: hidden;
  animation: chat-offer-arrive 1.05s cubic-bezier(0.32, 0.72, 0, 1) both;
}

/* ─── offers sort controls ──────────────────────────────
   Pill toggles that sit just above the offers row. Clicking a control
   re-sorts the row via a FLIP animation in JS. */
.chat-offers-block {
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 1.2vmin, 14px);
}

/* Header for the offers block — identifies which search produced this
   set of cards. Echoes the user's query so multiple searches in one
   chat thread stay distinguishable. Mono caps for the framing label;
   the query stays in sans + original casing so the user recognizes
   what they typed. */
.chat-offers-header {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.05vmin, 12px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fore-2);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  margin-bottom: clamp(2px, 0.4vmin, 6px);
}

.chat-offers-header-query {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.45vmin, 16px);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-transform: none;          /* preserve the user's original casing */
  color: var(--fore);
  margin: 0 0.35em;
}

.chat-offers-count {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--fore);
  font-variant-numeric: tabular-nums;
}

.chat-offers-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(6px, 0.9vmin, 12px);
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.05vmin, 12px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fore-2);
}

.controls-label {
  margin-right: clamp(2px, 0.4vmin, 6px);
}

.control {
  background: transparent;
  border: 1px solid var(--rule);
  color: var(--fore-2);
  padding: clamp(5px, 0.7vmin, 8px) clamp(10px, 1.3vmin, 14px);
  border-radius: 999px;
  cursor: pointer;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  transition: color 0.18s ease, border-color 0.18s ease, background 0.18s ease;
}
.control:hover { color: var(--fore); border-color: var(--fore); }
.control--active {
  color: var(--fore);
  border-color: var(--fore);
}

/* Fixed natural width — matches the card's flex-basis so the inner content
   lays out the same as the card's final rendered size. While the outer
   card animates its max-width from 0, the inner overflows to the right
   and is clipped, so the card appears to slide in without the content
   reflowing or the height shifting. */
.chat-offer-inner {
  width: clamp(280px, 26vw, 360px);
  padding: clamp(20px, 2.2vmin, 26px) clamp(22px, 2.3vmin, 28px);
  font-family: var(--font-sans);
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vmin, 16px);
}

/* New cards grow from zero width on the leading edge, pushing the existing
   cards rightward as the flex row reflows. Inner padding stays put — the
   content is simply clipped by the card's overflow:hidden until the card
   is wide enough to reveal it. Eases on an Apple-style smooth-out curve. */
@keyframes chat-offer-arrive {
  from { opacity: 0; max-width: 0;     }
  to   { opacity: 1; max-width: 480px; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-offer, .chat-offers-row { animation: none; }
}

.chat-offer-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  /* Single line — no wrap — so the kicker row is the same height on every
     card and the rest of the content stack stays aligned. */
}

.chat-offer-kicker,
.chat-offer-honored {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1.05vmin, 12px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-offer-honored {
  color: var(--operator-2);
}

/* Heading block: clinic name on top, address (street + city) under it.
   Reserves space for 2 lines of name + 2 lines of address so every card
   has identical heading height — cards in the row line up section-by-
   section, which is the whole point of the horizontal layout. */
.chat-offer-heading {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.chat-offer-name {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: clamp(17px, 1.95vmin, 21px);
  letter-spacing: -0.02em;
  line-height: 1.18;
  color: var(--ink);
  /* Clamp to 2 lines AND reserve a 2-line slot so 1-line names don't
     compress the slot relative to their neighbors. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: calc(2em * 1.18);
}

.chat-offer-address {
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  font-size: clamp(12px, 1.25vmin, 13px);
  line-height: 1.35;
  letter-spacing: -0.005em;
  color: var(--ink-2);
}
.chat-offer-address > span {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.chat-offer-when {
  font-family: var(--font-sans);
  font-weight: 500;
  font-size: clamp(14px, 1.55vmin, 17px);
  letter-spacing: -0.01em;
  line-height: 1.2;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.chat-offer-rule {
  border-top: 1px solid rgb(var(--ink-rgb) / 0.10);
}

.chat-offer-ledger {
  display: flex;
  flex-direction: column;
  gap: clamp(7px, 0.85vmin, 10px);
  font-family: var(--font-mono);
  font-size: clamp(11px, 1.2vmin, 13px);
  line-height: 1.4;
}

.chat-offer-ledger-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  color: var(--ink-2);
  min-width: 0;
}
.chat-offer-ledger-row > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.chat-offer-ledger-row b {
  font-weight: 500;
  color: var(--ink);
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.chat-offer-pay-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
}

.chat-offer-pay-label {
  font-family: var(--font-sans);
  font-size: clamp(12px, 1.3vmin, 14px);
  letter-spacing: -0.005em;
  color: var(--ink-2);
}

.chat-offer-price {
  font-family: var(--font-sans);
  font-size: clamp(24px, 2.8vmin, 32px);
  font-weight: 600;
  letter-spacing: -0.025em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

/* Full-width CTA — every card's button row is the same height and the
   buttons line up perfectly when comparing cards side-by-side. */
.chat-offer-book {
  align-self: stretch;
  margin-top: clamp(2px, 0.4vmin, 6px);
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.35vmin, 15px);
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--bone);
  background: var(--ink);
  border: none;
  padding: clamp(11px, 1.3vmin, 14px) clamp(16px, 2vmin, 22px);
  border-radius: 8px;
  cursor: pointer;
  text-align: center;
  transition: opacity 0.18s ease;
}
.chat-offer-book:hover { opacity: 0.9; }

.status-card-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 2px;
}

.status-card-kicker {
  font-family: var(--font-mono);
  font-size: clamp(9px, 1vmin, 11px);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--fore-2);
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.status-card-time {
  font-family: var(--font-mono);
  font-size: clamp(9px, 1vmin, 11px);
  letter-spacing: 0.08em;
  color: var(--fore-2);
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}

.status-card-body {
  font-family: var(--font-sans);
  font-size: clamp(13px, 1.4vmin, 16px);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--fore);
}

.status-card-meta {
  font-family: var(--font-mono);
  font-size: clamp(10px, 1vmin, 11px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fore-2);
  margin-top: 2px;
}
