/* =========================================================================
   Second Spring — warm, calm, premium. Deliberately not clinical-white and
   not wellness-pink: sand, pine, and clay.
   ========================================================================= */

:root {
  --sand-0: #fdfaf5;
  --sand-1: #f7f1e7;
  --sand-2: #efe6d8;
  --line: #e2d6c4;

  --pine: #24483c;
  --pine-deep: #1a352c;
  --pine-soft: #3d6355;

  /* --clay-bright keeps the original hue for large display use; --clay is
     darkened so the small uppercase kickers clear AA with room to spare. The
     original #c2673f measured 3.80:1 — fine for headlines, not for 12px text.
     #a85835 then measured 4.55:1 on --sand-1, which passes but sits close
     enough to the 4.5:1 line that a rounding difference between audit tools
     could read it either way. #964c2c is 5.55:1 on --sand-1, 5.99:1 on
     --sand-0 and 6.24:1 on white. */
  --clay: #964c2c;
  --clay-bright: #c2673f;
  --clay-soft: #d98a63;
  --gold: #b8912f;

  --ink: #2c2723;
  --ink-soft: #5f574e;
  --ink-faint: #756c64;   /* was #8b8177 (3.66:1) — now 4.94:1 */

  --radius: 14px;
  --radius-lg: 22px;
  --shadow-sm: 0 2px 8px rgba(44, 39, 35, 0.05);
  --shadow: 0 10px 30px -12px rgba(44, 39, 35, 0.18);
  --shadow-lg: 0 30px 60px -25px rgba(44, 39, 35, 0.3);

  --font-display: "Fraunces", ui-serif, Georgia, "Times New Roman", serif;
  --font-body: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;

  --wrap: 1120px;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--sand-0);
  color: var(--ink-soft);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  margin: 0 0 0.6rem;
  /* Fraunces carries an optical-size axis — larger settings tighten the
     letterforms, which is what makes display type feel drawn rather than
     merely scaled up. */
  font-variation-settings: "opsz" 96, "SOFT" 20;
  text-wrap: balance;
}
h1 {
  font-size: clamp(2.7rem, 6.4vw, 4.6rem);
  font-variation-settings: "opsz" 144, "SOFT" 30;
  letter-spacing: -0.032em;
}
h2 { font-size: clamp(1.95rem, 4vw, 2.85rem); }
h3 { font-size: 1.18rem; }
p { margin: 0 0 1rem; }
a { color: var(--pine); }

.wrap { width: min(var(--wrap), calc(100% - 2.5rem)); margin: 0 auto; }
.wrap-narrow { width: min(720px, calc(100% - 2.5rem)); margin: 0 auto; }

.kicker {
  font-size: 0.79rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--clay);
  margin: 0 0 0.9rem;
}
.lead { font-size: 1.13rem; color: var(--ink-soft); max-width: 62ch; text-wrap: pretty; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.97rem;
  font-weight: 600;
  padding: 0.85rem 1.7rem;
  border-radius: 999px;
  border: 1px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: transform 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn-primary { background: var(--pine); color: #fff; box-shadow: var(--shadow); }
.btn-primary:hover { background: var(--pine-deep); }
.btn-ghost { background: transparent; color: var(--pine); border-color: var(--line); }
.btn-ghost:hover { border-color: var(--pine); background: rgba(36, 72, 60, 0.04); }
.btn-block { width: 100%; }
.btn:disabled { opacity: 0.55; cursor: default; transform: none; }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(253, 250, 245, 0.88);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 1rem 0;
}
.brand {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: -0.02em;
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
}
.brand-mark {
  width: 26px; height: 26px;
  flex-shrink: 0;
}
.site-nav { display: flex; align-items: center; gap: 1.6rem; }
.site-nav a {
  font-size: 0.93rem;
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 500;
}
.site-nav a:hover { color: var(--pine); }

/* The section links used to be display:none under 780px, which deleted them
   for phone users outright. They now move into the disclosure panel below. */
.nav-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.nav-panel {
  border-top: 1px solid var(--line);
  background: var(--sand-0);
}
.nav-panel[hidden] { display: none; }
.nav-panel .wrap { display: flex; flex-direction: column; padding: 0.4rem 0 0.8rem; }
.nav-panel a {
  display: flex;
  align-items: center;
  min-height: 48px;
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid rgba(226, 214, 196, 0.5);
}
.nav-panel a:last-child { border-bottom: none; }
.nav-panel-btn {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0;
  border: none;
  border-top: 1px solid rgba(226, 214, 196, 0.5);
  background: none;
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 600;
  color: var(--pine);
  cursor: pointer;
  text-align: left;
}

@media (max-width: 780px) {
  .site-nav .nav-link { display: none; }
  .nav-toggle { display: inline-flex; }
}
/* Brand + Sign in + Start free + menu is one control too many at 375px —
   the two pills wrapped onto separate lines. Sign in moves into the menu. */
@media (max-width: 600px) {
  .site-nav #signInBtn { display: none; }
}
@media (min-width: 601px) {
  .nav-panel-btn { display: none; }
}
@media (min-width: 781px) {
  .nav-panel { display: none; }
}

/* ---------- Hero ---------- */
.hero {
  position: relative;
  padding: clamp(4rem, 10vw, 7.5rem) 0 clamp(3.5rem, 8vw, 6rem);
  overflow: hidden;
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 60% at 78% 15%, rgba(194, 103, 63, 0.13), transparent 62%),
    radial-gradient(ellipse 60% 55% at 12% 75%, rgba(36, 72, 60, 0.11), transparent 65%);
  pointer-events: none;
}
.hero-inner { position: relative; max-width: 760px; }
.hero h1 { margin-bottom: 1.2rem; }
.hero .lead { font-size: clamp(1.1rem, 2.2vw, 1.28rem); max-width: 620px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 2rem; }
.hero-note { margin-top: 1.1rem; font-size: 0.88rem; color: var(--ink-faint); }

/* ---------- Sections ---------- */
.section { padding: clamp(3.5rem, 8vw, 6rem) 0; }
.section-sand { background: var(--sand-1); }
.section-head { max-width: 680px; margin-bottom: 3rem; }

/* ---------- Cards ---------- */
.card-grid {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 720px) { .card-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1000px) { .card-grid.cols-3 { grid-template-columns: repeat(3, 1fr); } }

.card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.9rem;
  box-shadow: var(--shadow-sm);
}
.card h3 { margin-bottom: 0.5rem; }
.card p { margin: 0; font-size: 0.96rem; }
.card-icon {
  width: 42px; height: 42px;
  border-radius: 12px;
  background: var(--sand-2);
  display: flex; align-items: center; justify-content: center;
  margin-bottom: 1.1rem;
  color: var(--pine);
}

/* ---------- Quote / dismissal strip ---------- */
.quote-strip {
  background: var(--pine);
  color: #e8e2d6;
  padding: clamp(3rem, 7vw, 5rem) 0;
}
.quote-strip h2 { color: #fff; }
.quote-strip p { color: rgba(232, 226, 214, 0.85); }
.quote-list { display: grid; gap: 1rem; margin-top: 2rem; }
@media (min-width: 760px) { .quote-list { grid-template-columns: 1fr 1fr; } }
.quote-item {
  border-left: 2px solid var(--clay-soft);
  padding-left: 1.1rem;
  font-size: 0.98rem;
  color: rgba(232, 226, 214, 0.9);
}

/* ---------- Pricing ---------- */
.price-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2.4rem;
  max-width: 460px;
  margin: 0 auto;
  box-shadow: var(--shadow);
  text-align: center;
}
.price-amount {
  font-family: var(--font-display);
  font-size: 3.4rem;
  color: var(--ink);
  line-height: 1;
  margin: 0.6rem 0 0.2rem;
}
.price-amount span { font-size: 1rem; color: var(--ink-faint); font-family: var(--font-body); }
.price-features {
  list-style: none;
  padding: 0;
  margin: 1.8rem 0;
  text-align: left;
  display: grid;
  gap: 0.7rem;
}
.price-features li {
  display: flex;
  gap: 0.65rem;
  align-items: flex-start;
  font-size: 0.96rem;
}
.price-features li::before {
  content: "✓";
  color: var(--clay);
  font-weight: 700;
  flex-shrink: 0;
}

/* ---------- FAQ ---------- */
.faq-item {
  border-bottom: 1px solid var(--line);
  padding: 1.35rem 0;
}
.faq-item summary {
  cursor: pointer;
  font-family: var(--font-display);
  font-size: 1.08rem;
  color: var(--ink);
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; color: var(--clay); font-size: 1.3rem; line-height: 1; }
.faq-item[open] summary::after { content: "–"; }
.faq-item p { margin: 0.9rem 0 0; font-size: 0.97rem; }

/* ---------- Disclaimer ---------- */
.disclaimer {
  background: var(--sand-2);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.2rem 1.4rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
}
.disclaimer strong { color: var(--ink); }

/* ---------- Footer ---------- */
.site-footer {
  background: var(--pine-deep);
  color: rgba(232, 226, 214, 0.75);
  padding: 3rem 0 2.2rem;
  font-size: 0.9rem;
}
.site-footer a { color: rgba(232, 226, 214, 0.9); }
.footer-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.5rem;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 2rem;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 1.3rem; }
.footer-legal {
  border-top: 1px solid rgba(232, 226, 214, 0.16);
  padding-top: 1.5rem;
  font-size: 0.82rem;
  line-height: 1.6;
  color: rgba(232, 226, 214, 0.6);
}

/* =========================================================================
   Auth modal
   ========================================================================= */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.25rem;
  background: rgba(28, 24, 20, 0.55);
  opacity: 0;
  transition: opacity 0.22s ease;
}
.modal-overlay[hidden] { display: none; }
.modal-overlay.is-open { opacity: 1; }
.modal {
  background: var(--sand-0);
  border-radius: var(--radius-lg);
  padding: 2.2rem;
  width: min(430px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
  transform: translateY(14px);
  transition: transform 0.24s cubic-bezier(0.2, 0.9, 0.3, 1.1);
}
.modal-overlay.is-open .modal { transform: none; }
.modal h2 { font-size: 1.6rem; margin-bottom: 0.4rem; }
.modal-sub { font-size: 0.94rem; margin-bottom: 1.5rem; }
.field { display: grid; gap: 0.35rem; margin-bottom: 0.9rem; }
.field label { font-size: 0.86rem; font-weight: 600; color: var(--ink); }
.field input {
  font-family: var(--font-body);
  font-size: 0.97rem;
  padding: 0.75rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #fff;
  color: var(--ink);
}
.field input:focus { outline: 2px solid var(--pine-soft); outline-offset: 1px; }
.form-error {
  background: #fbeae5;
  border: 1px solid #e8c4b6;
  color: #9c4221;
  border-radius: 10px;
  padding: 0.65rem 0.85rem;
  font-size: 0.88rem;
  margin-bottom: 0.9rem;
}
.modal-switch { margin: 1.1rem 0 0; font-size: 0.9rem; text-align: center; }
.modal-switch button {
  background: none; border: none; padding: 0;
  color: var(--pine); font-weight: 600; cursor: pointer;
  font-family: var(--font-body); font-size: 0.9rem;
  text-decoration: underline;
}
.modal-close {
  position: absolute; top: 1rem; right: 1.2rem;
  background: none; border: none; font-size: 1.6rem; line-height: 1;
  color: var(--ink-faint); cursor: pointer;
}

/* =========================================================================
   Chat app
   ========================================================================= */
.app-body { background: var(--sand-1); height: 100vh; overflow: hidden; }
.app-shell { display: flex; flex-direction: column; height: 100vh; }

.app-header {
  background: var(--sand-0);
  border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.app-header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0.85rem 0;
}
.app-header-actions { display: flex; align-items: center; gap: 0.9rem; }
.app-header-actions button {
  background: none; border: none; cursor: pointer;
  font-family: var(--font-body); font-size: 0.88rem; font-weight: 500;
  color: var(--ink-soft);
}
.app-header-actions button:hover { color: var(--pine); }

.chat-scroll { flex: 1; overflow-y: auto; padding: 2rem 0 1rem; }
.chat-inner { width: min(760px, calc(100% - 2.5rem)); margin: 0 auto; }

.msg { display: flex; gap: 0.9rem; margin-bottom: 1.6rem; }
.msg-avatar {
  width: 32px; height: 32px; flex-shrink: 0;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 0.78rem; font-weight: 700;
  font-family: var(--font-display);
}
.msg-ai .msg-avatar { background: var(--pine); color: #fff; }
.msg-user .msg-avatar { background: var(--sand-2); color: var(--ink-soft); }
.msg-body { flex: 1; min-width: 0; padding-top: 0.15rem; }
.msg-body p { margin: 0 0 0.85rem; }
.msg-body p:last-child { margin-bottom: 0; }
.msg-body strong { color: var(--ink); }
.msg-body ul { margin: 0 0 0.85rem; padding-left: 1.15rem; }
.msg-body li { margin-bottom: 0.35rem; }
.msg-user .msg-body { color: var(--ink); }

.typing { display: flex; gap: 5px; padding: 0.4rem 0; }
.typing span {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--pine-soft);
  animation: typingBounce 1.2s ease-in-out infinite;
}
.typing span:nth-child(2) { animation-delay: 0.15s; }
.typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.45; }
  30% { transform: translateY(-4px); opacity: 1; }
}

/* Crisis card — must be impossible to miss. */
.crisis-card {
  background: #fff5f2;
  border: 1.5px solid var(--clay);
  border-radius: var(--radius);
  padding: 1.3rem 1.5rem;
  margin: 0 0 1.6rem;
}
.crisis-card h4 {
  font-family: var(--font-display);
  font-size: 1.05rem;
  color: #8f3a15;
  margin: 0 0 0.8rem;
}
.crisis-card ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 0.6rem; }
.crisis-card li { font-size: 0.93rem; color: var(--ink); }
.crisis-card li strong { display: block; color: #8f3a15; }

.chat-disclosure {
  background: var(--sand-2);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  font-size: 0.86rem;
  color: var(--ink-soft);
  margin-bottom: 1.8rem;
}

.composer-wrap {
  flex-shrink: 0;
  background: var(--sand-0);
  border-top: 1px solid var(--line);
  padding: 1rem 0 1.3rem;
}
.composer-inner { width: min(760px, calc(100% - 2.5rem)); margin: 0 auto; }
.composer {
  display: flex;
  gap: 0.7rem;
  align-items: flex-end;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 0.6rem 0.6rem 0.6rem 1.1rem;
  box-shadow: var(--shadow-sm);
}
.composer textarea {
  flex: 1;
  border: none;
  resize: none;
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: transparent;
  padding: 0.5rem 0;
  max-height: 160px;
}
.composer textarea:focus { outline: none; }
.composer-send {
  width: 40px; height: 40px; flex-shrink: 0;
  border-radius: 50%; border: none;
  background: var(--pine); color: #fff;
  cursor: pointer; font-size: 1rem;
  display: flex; align-items: center; justify-content: center;
}
.composer-send:hover { background: var(--pine-deep); }
.composer-send:disabled { opacity: 0.4; cursor: default; }
.composer-note {
  margin: 0.7rem 0 0;
  font-size: 0.78rem;
  color: var(--ink-faint);
  text-align: center;
}

.free-banner {
  background: var(--sand-2);
  border-radius: 999px;
  padding: 0.4rem 1rem;
  font-size: 0.82rem;
  color: var(--ink-soft);
  text-align: center;
  margin: 0 auto 0.9rem;
  width: fit-content;
}

/* Paywall */
.paywall {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2rem;
  text-align: center;
  box-shadow: var(--shadow);
  margin-bottom: 1.6rem;
}
.paywall h3 { font-size: 1.35rem; margin-bottom: 0.5rem; }
.paywall p { font-size: 0.96rem; }
.paywall .btn { margin-top: 0.6rem; }

/* Welcome bloom — the 3D piece on the app's first screen. Sized in vh so it
   never squeezes the copy or the composer off a short laptop screen. */
.bloom-stage {
  width: 100%;
  height: clamp(190px, 32vh, 320px);
  margin: 0 auto 0.4rem;
  position: relative;
  /* Warm halo so the bloom reads as lit rather than pasted on. */
  background:
    radial-gradient(ellipse 55% 60% at 50% 58%, rgba(217, 164, 65, 0.16), transparent 70%);
}
.bloom-stage canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}
@media (max-height: 700px) {
  .bloom-stage { height: 170px; }
}

/* Onboarding suggestion chips */
.starters { display: flex; flex-wrap: wrap; gap: 0.55rem; margin-top: 1.4rem; }
.starter-chip {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--ink-soft);
  cursor: pointer;
  text-align: left;
}
.starter-chip:hover { border-color: var(--pine-soft); color: var(--pine); }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* =========================================================================
   Plans & tiers — pricing cards, sidebar, premium panels.
   Cards not a wide table: per the UX rules, comparison tables overflow on
   mobile, so each plan is a self-contained card that stacks.
   ========================================================================= */

.plan-grid {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 900px) { .plan-grid { grid-template-columns: repeat(3, 1fr); } }

.plan {
  position: relative;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 2rem 1.7rem;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  height: 100%;
}
.plan-featured {
  border-color: var(--pine);
  box-shadow: var(--shadow);
}
@media (min-width: 900px) {
  .plan-featured { transform: translateY(-10px); }
}
.plan-badge {
  position: absolute;
  top: -0.7rem; left: 1.7rem;
  background: var(--pine);
  color: #fff;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.3rem 0.75rem;
  border-radius: 999px;
}
.plan-name {
  font-family: var(--font-display);
  font-size: 1.35rem;
  color: var(--ink);
  margin: 0 0 0.2rem;
}
.plan-blurb { font-size: 0.9rem; color: var(--ink-faint); margin: 0 0 1.1rem; min-height: 2.5em; }
.plan-price {
  font-family: var(--font-display);
  font-size: 2.7rem;
  color: var(--ink);
  line-height: 1;
  margin: 0 0 1.4rem;
}
.plan-price span { font-family: var(--font-body); font-size: 0.95rem; color: var(--ink-faint); }

.plan-features { list-style: none; padding: 0; margin: 0 0 1.6rem; display: grid; gap: 0.6rem; flex: 1; }
/* Absolutely-positioned marker rather than flex: a flex row would treat inner
   <b> tags as separate children and break the sentence into columns. */
.plan-features li {
  display: block;   /* explicit: flex here would split inner <b> into a column */
  position: relative;
  padding-left: 1.45rem;
  font-size: 0.92rem;
  line-height: 1.45;
}
.plan-features li::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--clay);
  font-weight: 700;
}
/* Absent features read as genuinely absent, not merely unstyled. */
.plan-features li.is-absent { color: var(--ink-faint); }
.plan-features li.is-absent::before { content: "—"; color: var(--ink-faint); font-weight: 500; }

.plan .btn { width: 100%; }
.plan-current {
  text-align: center;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--pine);
  padding: 0.85rem;
  border: 1px dashed var(--line);
  border-radius: 999px;
}

/* ---------- App shell with sidebar ---------- */
.app-main { display: flex; flex: 1; min-height: 0; }

.sidebar {
  width: 264px;
  flex-shrink: 0;
  background: var(--sand-0);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  min-height: 0;
}
.sidebar-head { padding: 1rem 1rem 0.7rem; }
.btn-newchat {
  width: 100%;
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  background: var(--pine); color: #fff;
  border: none; border-radius: 10px;
  padding: 0.7rem 1rem;
  font-family: var(--font-body); font-size: 0.9rem; font-weight: 600;
  cursor: pointer;
}
.btn-newchat:hover { background: var(--pine-deep); }
.btn-newchat[data-locked="true"] { background: var(--sand-2); color: var(--ink-faint); }

.chat-list { flex: 1; overflow-y: auto; padding: 0.4rem 0.6rem 1rem; }
.chat-item {
  display: flex; align-items: center; gap: 0.4rem;
  width: 100%;
  border: none; background: transparent;
  border-radius: 8px;
  padding: 0.6rem 0.7rem;
  font-family: var(--font-body); font-size: 0.88rem;
  color: var(--ink-soft);
  cursor: pointer;
  text-align: left;
}
.chat-item:hover { background: var(--sand-2); }
.chat-item.is-active { background: var(--sand-2); color: var(--ink); font-weight: 600; }
.chat-item-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-item-del {
  border: none; background: transparent; cursor: pointer;
  color: var(--ink-faint); font-size: 1rem; line-height: 1;
  padding: 0.15rem 0.25rem; border-radius: 4px;
  opacity: 0; flex-shrink: 0;
}
.chat-item:hover .chat-item-del { opacity: 1; }
.chat-item-del:hover { color: #9c4221; background: #fbeae5; }

.sidebar-foot { border-top: 1px solid var(--line); padding: 0.9rem 1rem; }
.tier-chip {
  display: inline-flex; align-items: center; gap: 0.4rem;
  font-size: 0.76rem; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--pine); background: var(--sand-2);
  padding: 0.3rem 0.7rem; border-radius: 999px;
}
.tier-chip[data-tier="premium"] { background: var(--pine); color: #fff; }
.tier-chip[data-tier="free"] { background: var(--sand-2); color: var(--ink-faint); }
.sidebar-foot .link-btn {
  display: block; margin-top: 0.6rem;
  background: none; border: none; padding: 0;
  font-family: var(--font-body); font-size: 0.83rem;
  color: var(--ink-soft); cursor: pointer; text-decoration: underline;
}
.sidebar-foot .link-btn:hover { color: var(--pine); }

/* Sidebar becomes an off-canvas drawer on small screens. */
.sidebar-toggle { display: none; background: none; border: none; cursor: pointer; padding: 0.3rem; }
.sidebar-scrim { display: none; }
@media (max-width: 820px) {
  .sidebar-toggle { display: block; }
  .sidebar {
    position: fixed; top: 0; bottom: 0; left: 0; z-index: 120;
    transform: translateX(-100%);
    /* Off-canvas but still in the tab order meant Tab walked into an
       invisible drawer. `visibility` takes its contents out of the tab
       order too, and delaying it keeps the slide-out animation intact. */
    visibility: hidden;
    transition: transform 0.24s ease, visibility 0s linear 0.24s;
    box-shadow: var(--shadow-lg);
  }
  .sidebar.is-open {
    transform: none;
    visibility: visible;
    transition: transform 0.24s ease, visibility 0s;
  }
  .sidebar-scrim.is-open {
    display: block; position: fixed; inset: 0; z-index: 110;
    background: rgba(28, 24, 20, 0.45);
  }
}
@media (prefers-reduced-motion: reduce) { .sidebar { transition: none; } }

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

/* ---------- Premium panels ---------- */
.premium-panel {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 1.6rem;
  margin-bottom: 1.6rem;
}
.premium-panel h3 { display: flex; align-items: center; gap: 0.6rem; margin-bottom: 0.3rem; }
.premium-tag {
  font-size: 0.62rem; font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase;
  background: var(--pine); color: #fff; padding: 0.2rem 0.5rem; border-radius: 4px;
}
.plan-day { display: flex; gap: 0.9rem; padding: 0.55rem 0; border-bottom: 1px solid var(--sand-2); font-size: 0.92rem; }
.plan-day:last-child { border-bottom: none; }
.plan-day b { min-width: 5.5rem; color: var(--ink); font-weight: 600; }
.plan-section { margin-top: 1.1rem; }
.plan-section h4 {
  font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--clay); margin: 0 0 0.5rem;
}
.plan-section ul { margin: 0; padding-left: 1.1rem; font-size: 0.92rem; }
.plan-section li { margin-bottom: 0.3rem; }

.log-row { display: flex; gap: 0.5rem; flex-wrap: wrap; align-items: flex-end; }
.log-row select, .log-row input {
  font-family: var(--font-body); font-size: 0.9rem;
  padding: 0.55rem 0.7rem; border: 1px solid var(--line);
  border-radius: 9px; background: #fff; color: var(--ink);
}
.log-row input { flex: 1; min-width: 8rem; }
.log-field { display: grid; gap: 0.25rem; }
.log-field label { font-size: 0.75rem; font-weight: 600; color: var(--ink-soft); }

/* Simple, dependency-free trend bars. Severity is shown as height AND a
   number — never colour alone, per the charts rule. */
.trend { display: flex; align-items: flex-end; gap: 3px; height: 64px; margin-top: 0.9rem; }
.trend-bar { flex: 1; background: var(--clay-soft); border-radius: 3px 3px 0 0; min-height: 4px; position: relative; }
.trend-bar[data-sev="4"], .trend-bar[data-sev="5"] { background: var(--clay); }
.trend-legend { display: flex; justify-content: space-between; font-size: 0.72rem; color: var(--ink-faint); margin-top: 0.35rem; }

.locked-note {
  background: var(--sand-2);
  border-radius: var(--radius);
  padding: 1.1rem 1.3rem;
  font-size: 0.9rem;
  color: var(--ink-soft);
  margin-bottom: 1.6rem;
}
.locked-note strong { color: var(--ink); }

/* =========================================================================
   Landing polish.
   Motion per the design rules: 150–300ms for interaction feedback, 400–600ms
   for entrances, and everything silenced under prefers-reduced-motion.
   ========================================================================= */

/* ---------- Hero: two columns, bloom alongside the promise ---------- */
.hero-grid {
  position: relative;
  display: grid;
  gap: 2rem;
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 940px) {
  .hero-grid { grid-template-columns: 1.05fr 0.95fr; gap: 3rem; }
  .hero { padding-top: clamp(3rem, 6vw, 5rem); }
}
.hero-inner { max-width: 620px; }
.hero-visual { position: relative; }
.bloom-hero {
  height: clamp(240px, 42vh, 420px);
  /* Capped and centred: in a full-width grid column the flower rendered at
     its own size in the middle of a lot of empty sand, which read as a small
     picture floating in a large box rather than as the hero image. */
  width: min(100%, 440px);
  margin-inline: auto;
  background:
    radial-gradient(ellipse 60% 62% at 50% 55%, rgba(217, 164, 65, 0.20), transparent 70%);
}
/* The stem runs off the bottom of the canvas by design, but a hard edge in
   the middle of open sand looks like a clipping bug rather than a crop. */
.bloom-hero canvas {
  -webkit-mask-image: linear-gradient(to bottom, #000 74%, transparent 98%);
  mask-image: linear-gradient(to bottom, #000 74%, transparent 98%);
}
/* On narrow screens the bloom follows the copy. It used to be `order: -1`,
   which meant a phone visitor's entire first screen was flower and the
   headline didn't appear until roughly 800px down the page. */
@media (max-width: 939px) {
  .bloom-hero { height: clamp(170px, 26vh, 240px); }
}

/* ---------- Entrance motion ---------- */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.rise {
  opacity: 0;
  animation: riseIn 620ms cubic-bezier(0.22, 0.75, 0.28, 1) forwards;
  animation-delay: var(--d, 0ms);
}

/* Scroll-revealed sections. Starts visible and is only hidden once JS
   confirms it can animate — so content is never trapped invisible. */
.js .reveal-up { opacity: 0; transform: translateY(22px); }
.reveal-up {
  transition: opacity 560ms cubic-bezier(0.22, 0.75, 0.28, 1),
              transform 560ms cubic-bezier(0.22, 0.75, 0.28, 1);
}
.reveal-up.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .rise { animation: none; opacity: 1; }
  .js .reveal-up { opacity: 1; transform: none; }
}

/* ---------- Interaction feedback ---------- */
.card {
  transition: transform 220ms cubic-bezier(0.22, 0.75, 0.28, 1),
              box-shadow 220ms ease, border-color 220ms ease;
}
.card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow);
  border-color: var(--line);
}
.card-icon { transition: background 220ms ease, color 220ms ease; }
.card:hover .card-icon { background: var(--pine); color: #fff; }

.plan { transition: transform 220ms cubic-bezier(0.22, 0.75, 0.28, 1), box-shadow 220ms ease; }
.plan:hover { box-shadow: var(--shadow); }
@media (min-width: 900px) {
  .plan:hover { transform: translateY(-4px); }
  .plan-featured:hover { transform: translateY(-14px); }
}

.faq-item summary { transition: color 180ms ease; }
.faq-item summary:hover { color: var(--clay); }
.site-nav a { transition: color 180ms ease; }

/* Every interactive element states its affordance. */
button, summary, [role="button"], .btn { cursor: pointer; }

/* Visible keyboard focus everywhere — never removed, only restyled. */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 3px solid var(--pine-soft);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ---------- Section rhythm ---------- */
.section-head h2 { margin-bottom: 0.7rem; }
.quote-strip { position: relative; overflow: hidden; }
.quote-strip::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse 55% 70% at 88% 10%, rgba(217, 138, 99, 0.16), transparent 62%);
  pointer-events: none;
}
.quote-strip .wrap { position: relative; }

/* A hairline between stacked light sections, so they read as distinct
   without needing another background colour. */
.section + .section { border-top: 1px solid rgba(226, 214, 196, 0.55); }
.section-sand + .section, .section + .section-sand { border-top: none; }

.quote-lead {
  margin: 2rem 0 0.9rem;
  font-size: 0.79rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--clay-soft);
}
.quote-list { margin-top: 0; }

/* `.site-nav a` (0,1,1) outranks `.btn-primary` (0,1,0), which silently
   repainted the header CTA's label in body-text brown on dark green — about
   1.4:1. Restore each button's own colour explicitly. */
.site-nav a.btn-primary { color: #fff; }
.site-nav a.btn-ghost { color: var(--pine); }
.site-nav a.btn-primary:hover { color: #fff; }
.site-nav a.btn-ghost:hover { color: var(--pine); }

/* Guarantee the 44×44 touch minimum regardless of padding tweaks below. */
.btn { min-height: 44px; }

/* At ~390px the brand plus two pill buttons overflowed and the nav wrapped to
   a second line, pushing the header to 110px. Tighten only the header. */
@media (max-width: 560px) {
  .site-header .btn { padding: 0.55rem 0.95rem; font-size: 0.85rem; }
  .site-nav { gap: 0.5rem; }
  .brand { font-size: 1.1rem; gap: 0.4rem; }
  .brand-mark { width: 22px; height: 22px; }
  .header-inner { padding: 0.7rem 0; }
}

/* =========================================================================
   SEE IT WORK — phone thread.
   The messages are real markup and readable without JS; the script only
   staggers their arrival.
   ========================================================================= */
.demo-wrap {
  display: grid;
  gap: 2.5rem;
  grid-template-columns: 1fr;
  align-items: center;
}
@media (min-width: 960px) {
  .demo-wrap { grid-template-columns: 1fr 0.86fr; gap: 4rem; }
}
.demo-copy .lead { margin-bottom: 1.4rem; }
.demo-points { list-style: none; padding: 0; margin: 0 0 2rem; display: grid; gap: 0.75rem; }
.demo-points li {
  position: relative;
  padding-left: 1.5rem;
  font-size: 0.95rem;
  line-height: 1.5;
}
.demo-points li::before {
  content: "";
  position: absolute;
  left: 0; top: 0.55em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--clay);
}
.demo-points b { color: var(--ink); }

.demo-thread-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
}

/* ---------- the conversation panel ----------
   Deliberately not a phone. A device mockup adds a bezel, a fake status bar
   and a hard height limit, all of which cost legibility and none of which
   say anything about the product. This is just the thread. */
.demo-thread {
  position: relative;
  width: min(430px, 100%);
  height: clamp(430px, 64vh, 620px);
  min-height: 0;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--sand-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.demo-thread-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 1.1rem;
  background: var(--sand-0);
  border-bottom: 1px solid var(--line);
}
.demo-thread-dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: #2f9e5f;
  flex-shrink: 0;
}
.demo-thread-name {
  font-family: var(--font-display);
  font-size: 0.98rem;
  font-weight: 600;
  color: var(--ink);
}

.demo-thread-body {
  flex: 1;
  min-height: 0;
  /* Scrollable: the thread is taller than the panel by design, and it
     auto-scrolls as messages land. Readers can also scroll it themselves. */
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 1rem 0.9rem 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.demo-thread-body::-webkit-scrollbar { width: 0; height: 0; }

/* ---------- bubbles ---------- */
.pm {
  max-width: 86%;
  font-size: 0.9rem;
  line-height: 1.55;
  padding: 0.6rem 0.85rem;
  border-radius: 16px;
  margin: 0;
}
.pm b { color: inherit; font-weight: 700; }

.pm-her {
  align-self: flex-end;
  background: var(--pine);
  color: #f4efe6;
  border-radius: 16px 16px 5px 16px;
}
.pm-bot {
  align-self: flex-start;
  background: #fff;
  color: var(--ink-soft);
  border: 1px solid var(--line);
  border-radius: 16px 16px 16px 5px;
}
.pm-bot b { color: var(--ink); }

.pm-plan {
  align-self: flex-start;
  max-width: 92%;
  background: linear-gradient(160deg, #fffaf0, #f6e9d2);
  border: 1px solid var(--clay-soft);
  border-radius: 16px;
  padding: 0.75rem 0.9rem;
}
.pm-plan-tag {
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--clay);
  margin: 0 0 0.4rem;
}
.pm-plan-row {
  font-size: 0.855rem;
  line-height: 1.45;
  margin: 0 0 0.18rem;
  color: var(--ink-soft);
}
.pm-plan-row b { display: inline-block; min-width: 2.1rem; color: var(--ink); }
.pm-plan-note {
  margin: 0.45rem 0 0;
  padding-top: 0.4rem;
  border-top: 1px solid rgba(217, 138, 99, 0.35);
  font-size: 0.78rem;
  color: var(--clay);
  font-weight: 600;
}

.pm-note {
  align-self: center;
  background: none;
  padding: 0.4rem 0;
  font-size: 0.74rem;
  color: var(--ink-faint);
  text-align: center;
  max-width: 100%;
}

/* ---------- arrival ----------
   A keyframe animation with no fill mode, rather than a transition out of a
   hidden class. The distinction matters: a transition parks the element at
   its start value until the frame loop advances it, and a backgrounded tab
   stops that loop — which left every bubble sitting at opacity 0 with no way
   back. Here the *resting* state is the plain, visible one, so the worst
   case is that a message appears without its entrance rather than never
   appearing at all. */
@keyframes pmIn {
  from { opacity: 0; transform: translateY(10px) scale(0.94); }
  to   { opacity: 1; transform: none; }
}
.pm-enter { animation: pmIn 300ms cubic-bezier(0.3, 1.2, 0.5, 1); }
.pm-her { transform-origin: bottom right; }
.pm-bot, .pm-plan, .pm-typing { transform-origin: bottom left; }
.pm-note { transform-origin: bottom center; }

/* ---------- typing indicator ---------- */
.pm-typing {
  align-self: flex-start;
  display: flex;
  align-items: center;
  gap: 4px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px 16px 16px 5px;
  padding: 0.65rem 0.9rem;
  width: fit-content;
}
.pm-typing span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--pine-soft);
  animation: typingBounce 1.2s ease-in-out infinite;
}
.pm-typing span:nth-child(2) { animation-delay: 0.15s; }
.pm-typing span:nth-child(3) { animation-delay: 0.3s; }

/* ---------- replay ---------- */
.demo-replay {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  margin-top: 1rem;
  min-height: 44px;
  padding: 0.5rem 1.1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: transparent;
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-soft);
  cursor: pointer;
}
.demo-replay:hover { border-color: var(--pine); color: var(--pine); }
.demo-replay:disabled { opacity: 0.45; cursor: default; }
.demo-replay[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .pm-enter { animation: none; }
}

/* =========================================================================
   App feel, phone-sized layout, and the accessibility floor.
   ========================================================================= */

/* ---------- Skip link ----------
   First thing in the tab order on every page, visible the moment it takes
   focus. WCAG 2.4.1. */
.skip-link {
  position: absolute;
  left: 1rem;
  top: -100px;
  z-index: 500;
  background: var(--pine);
  color: #fff;
  font-weight: 600;
  font-size: 0.95rem;
  padding: 0.8rem 1.3rem;
  border-radius: 0 0 12px 12px;
  text-decoration: none;
  transition: top 160ms ease;
}
.skip-link:focus { top: 0; }
#main:focus { outline: none; }

/* ---------- Anchors clear the sticky header ----------
   Jumping to #pricing used to park the heading underneath the header, so
   the first line of every section was hidden. */
:target,
#demo, #how, #pricing, #faq, #main {
  scroll-margin-top: 5.5rem;
}

/* ---------- Native-app chrome ---------- */
html {
  /* iOS rubber-banding past the end of the document is the single clearest
     "this is a web page" tell. */
  overscroll-behavior-y: none;
}
body {
  /* Grey flash on every tap is the second. */
  -webkit-tap-highlight-color: transparent;
}
.site-header,
.nav-panel,
.site-footer {
  padding-left: env(safe-area-inset-left);
  padding-right: env(safe-area-inset-right);
}
.site-footer { padding-bottom: calc(2.2rem + env(safe-area-inset-bottom)); }

/* Buttons and cards answer a finger the way a native control does. */
.btn:active { transform: translateY(0) scale(0.975); }
.starter-chip:active,
.demo-replay:active,
.nav-toggle:active { transform: scale(0.97); }
.btn, .starter-chip, .demo-replay, .nav-toggle, .chat-item, .plan {
  -webkit-user-select: none;
  user-select: none;
}
.plan-features, .pm, .msg-body, .lead, p { -webkit-user-select: auto; user-select: auto; }

@media (prefers-reduced-motion: reduce) {
  .btn:active, .starter-chip:active, .demo-replay:active, .nav-toggle:active {
    transform: none;
  }
}

/* Installed to the home screen, the landing page's marketing chrome is
   noise — the app is what was installed. */
@media (display-mode: standalone) {
  .site-header { position: static; }
}

/* ---------- Pricing ---------- */
.plan-error {
  margin: 0.7rem 0 0;
  font-size: 0.85rem;
  color: #8f3a15;
  background: #fbeae5;
  border: 1px solid #e8c4b6;
  border-radius: 10px;
  padding: 0.55rem 0.75rem;
}
.plan-foot {
  text-align: center;
  font-size: 0.9rem;
  color: var(--ink-soft);
  margin: 2rem 0 0;
}
.plan-foot a { color: var(--pine); }

/* ---------- The demo panel on a phone ----------
   Full width, and short enough that the whole panel plus the copy above it
   is legible without the thread swallowing the screen. */
@media (max-width: 720px) {
  .demo-thread { width: 100%; height: clamp(380px, 58vh, 480px); }
}
@media (max-width: 480px) {
  .demo-thread { height: 62vh; max-height: 460px; border-radius: var(--radius); }
  .demo-thread-body { padding: 0.85rem 0.75rem 1rem; }
  .pm { max-width: 90%; font-size: 0.875rem; }
}

/* ---------- Chat app shell ----------
   100vh on iOS is the height of the viewport *without* the browser chrome,
   so the composer sat below the fold and the on-screen keyboard pushed it
   further. dvh tracks the visible viewport as the chrome and keyboard move. */
.app-body { height: 100dvh; }
.app-shell { height: 100dvh; }
@supports not (height: 100dvh) {
  .app-body, .app-shell { height: 100vh; }
}

.chat-scroll { overscroll-behavior: contain; -webkit-overflow-scrolling: touch; }
.chat-list { overscroll-behavior: contain; }

.composer-wrap {
  padding-bottom: calc(1.3rem + env(safe-area-inset-bottom));
}
.sidebar { padding-bottom: env(safe-area-inset-bottom); }

/* iOS zooms the page in whenever a focused input is under 16px. */
.composer textarea,
.field input,
.log-row select,
.log-row input { font-size: max(16px, 1rem); }

/* ---------- Touch targets ----------
   WCAG 2.5.8 asks for 24×24 as a minimum; 44×44 is the figure Apple and the
   WCAG 2.1 AAA criterion use, and this audience skews toward reading
   glasses and away from precise tapping. */
.modal-close {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 0.6rem;
  right: 0.7rem;
  border-radius: 50%;
}
.modal-close:hover { background: var(--sand-2); color: var(--ink); }
.app-header-actions button { min-height: 44px; padding: 0 0.3rem; }
.sidebar-toggle { min-width: 44px; min-height: 44px; }
.chat-item { min-height: 44px; }
.chat-item-del { min-width: 32px; min-height: 32px; }
.starter-chip { min-height: 44px; }
.modal-switch button { min-height: 44px; padding: 0 0.2rem; }
.sidebar-foot .link-btn { min-height: 44px; }
.faq-item summary { min-height: 44px; align-items: center; }
.footer-links a { display: inline-flex; align-items: center; min-height: 44px; }

/* The delete control was opacity:0 until hover, so it did not exist for
   keyboard or touch. Now it is always present on touch, and reveals on
   focus as well as hover. */
.chat-item:focus-within .chat-item-del { opacity: 1; }
@media (hover: none) {
  .chat-item-del { opacity: 1; }
}

/* ---------- Contrast ----------
   rgba(...,0.6) over the deep pine footer measured about 3.4:1. */
.footer-legal { color: rgba(240, 235, 224, 0.82); }
.site-footer { color: rgba(240, 235, 224, 0.86); }
.quote-strip p { color: rgba(240, 235, 224, 0.92); }
.quote-item { color: rgba(240, 235, 224, 0.95); }
.quote-lead { color: #f0c9a8; }

/* ---------- Forced colours / high contrast ---------- */
@media (forced-colors: active) {
  .btn, .card, .plan, .demo-thread, .modal, .nav-toggle { border: 1px solid ButtonText; }
  .plan-features li::before { forced-color-adjust: none; }
}

/* Anyone who asks for less transparency gets a solid header rather than a
   blur that can smear text against whatever is scrolling underneath. */
@media (prefers-reduced-transparency: reduce) {
  .site-header { background: var(--sand-0); backdrop-filter: none; }
}

/* =========================================================================
   EDITORIAL PASS
   Two references, both chosen because they fit the brand that already
   exists rather than replacing it:

   - "Nature Distilled" (terracotta / sand / warm clay / olive, grain
     overlays, natural ease-out) — essentially a description of this
     palette, so it's used to add tactility rather than colour.
   - "Editorial Grid / Magazine" (pull quotes, section dividers, print
     hierarchy) — the quote strip was always a pull quote in disguise.

   The skill's own palette recommendation (lavender #8B5CF6 on #FAF5FF with
   Lora/Raleway) is deliberately not used: it is the generic wellness-tech
   look this brand was defined against, and #4C1D95 body text on #FAF5FF is
   a worse read for an audience largely in reading glasses.
   ========================================================================= */

/* ---------- Grain ----------
   The single biggest tactility win for an earthy palette: it stops large
   flat sand fields reading as flat digital fills and gives them the tooth
   of uncoated paper.

   Applied as an extra background layer on the sections that have a fill,
   NOT as one fixed full-viewport overlay. A fixed overlay with
   `mix-blend-mode: multiply` promotes the entire document into a single
   composited layer: every scroll repaints the whole page, and it broke
   compositing outright in testing. Per-section backgrounds cost nothing. */
:root {
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.055'/%3E%3C/svg%3E");
}

.hero::before {
  background-image:
    var(--grain),
    radial-gradient(ellipse 70% 60% at 78% 15%, rgba(194, 103, 63, 0.13), transparent 62%),
    radial-gradient(ellipse 60% 55% at 12% 75%, rgba(36, 72, 60, 0.11), transparent 65%);
  background-size: 140px 140px, auto, auto;
  opacity: 1;
}
.section-sand,
.quote-strip,
.site-footer,
.card,
.plan,
.demo-thread {
  background-image: var(--grain);
  background-size: 140px 140px;
  background-repeat: repeat;
}
/* The fills above are set with `background` shorthand elsewhere, so the
   colour has to ride along with the texture rather than under it. */
.section-sand { background-color: var(--sand-1); }
.quote-strip { background-color: var(--pine); }
.site-footer { background-color: var(--pine-deep); }
.card { background-color: #fff; }
.plan { background-color: #fff; }
.demo-thread { background-color: var(--sand-1); }
.plan-featured {
  background-image: var(--grain),
    linear-gradient(168deg, #ffffff 0%, #fffdf8 46%, #fdf6e9 100%);
  background-size: 140px 140px, auto;
}

/* Texture must never sit between someone and their body copy. */
@media (prefers-contrast: more), (forced-colors: active) {
  :root { --grain: none; }
}

/* ---------- Depth ----------
   A single blurred shadow is the flat-design tell. Real objects cast a
   tight contact shadow plus a wide ambient one; layering the two is most
   of what "Soft UI Evolution" means in practice. */
:root {
  --shadow-sm:
    0 1px 2px rgba(44, 39, 35, 0.045),
    0 2px 7px -2px rgba(44, 39, 35, 0.05);
  --shadow:
    0 1px 2px rgba(44, 39, 35, 0.05),
    0 6px 16px -6px rgba(44, 39, 35, 0.12),
    0 18px 40px -22px rgba(44, 39, 35, 0.2);
  --shadow-lg:
    0 2px 4px rgba(44, 39, 35, 0.06),
    0 12px 28px -10px rgba(44, 39, 35, 0.16),
    0 40px 70px -35px rgba(44, 39, 35, 0.3);

  /* back.out(1.4), which is what the motion preset asks for: a small
     overshoot so things settle rather than stop dead. */
  --ease-back: cubic-bezier(0.34, 1.46, 0.64, 1);
  --ease-out: cubic-bezier(0.22, 0.75, 0.28, 1);
}

/* ---------- Eyebrow rule ----------
   Print convention: a short rule sets a kicker as a department heading
   rather than just small text. */
.kicker { display: flex; align-items: center; gap: 0.7rem; }
.kicker::before {
  content: "";
  width: 1.8rem;
  height: 1px;
  background: currentColor;
  opacity: 0.55;
  flex-shrink: 0;
}
.section-head[style*="center"] .kicker { justify-content: center; }

/* ---------- Pull quote ----------
   This section was already the emotional centre of the page and was set as
   an ordinary h2. Given the treatment it earns. */
.quote-strip .section-head h2 {
  font-size: clamp(2.1rem, 4.4vw, 3.2rem);
  font-style: italic;
  font-variation-settings: "opsz" 144, "SOFT" 40;
  max-width: 18ch;
  position: relative;
}
.quote-strip .section-head h2::before {
  content: "\201C";
  position: absolute;
  left: -0.62em;
  top: -0.16em;
  font-size: 2.6em;
  line-height: 1;
  color: var(--clay-soft);
  opacity: 0.34;
  pointer-events: none;
}
@media (max-width: 780px) {
  /* No room to hang the mark in the margin on a phone. */
  .quote-strip .section-head h2::before { display: none; }
  .quote-strip .section-head h2 { max-width: none; }
}

/* ---------- Section dividers ----------
   A centred ornament instead of a full-bleed hairline: it reads as a
   deliberate break between chapters rather than a table border. */
.section + .section { border-top: none; position: relative; }
.section + .section::before {
  content: "";
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: min(420px, 60%);
  height: 1px;
  background: linear-gradient(
    to right, transparent, var(--line) 22%, var(--line) 78%, transparent);
}

/* ---------- Cards ----------
   Ring-and-fill icon wells rather than filled tiles: lighter, and the ring
   is what carries the hover rather than a colour swap. */
.card-icon {
  border-radius: 50%;
  background: transparent;
  border: 1px solid var(--line);
  box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.9);
  transition: border-color 240ms var(--ease-out),
              background 240ms var(--ease-out),
              color 240ms var(--ease-out),
              transform 320ms var(--ease-back);
}
.card:hover .card-icon {
  background: var(--pine);
  border-color: var(--pine);
  color: #fff;
  transform: rotate(-6deg) scale(1.06);
  box-shadow: inset 0 0 0 4px rgba(255, 255, 255, 0.14);
}
.card { transition: transform 260ms var(--ease-back), box-shadow 260ms var(--ease-out); }
.card:hover { transform: translateY(-4px); }

/* ---------- Pricing ----------
   The featured tier gets warmth rather than just a border, so the eye
   lands on it before it reads any of the three. */
.plan-featured { border-width: 1.5px; }
.plan-featured .plan-price { color: var(--pine); }
.plan-price { letter-spacing: -0.03em; }
.plan-price span { letter-spacing: 0; }

/* ---------- Buttons ----------
   A warm inner highlight along the top edge is what separates a filled
   rectangle from something that looks lit. */
.btn-primary {
  background: linear-gradient(180deg, #2b5648 0%, var(--pine) 55%, #1f4034 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    var(--shadow);
}
.btn-primary:hover {
  background: linear-gradient(180deg, #2f5d4e 0%, #23473b 55%, #1a3830 100%);
}
.btn { transition: transform 200ms var(--ease-back), background 200ms var(--ease-out), box-shadow 200ms var(--ease-out); }

/* ---------- Editorial links ---------- */
.faq-item p a,
.plan-foot a,
main p a:not(.btn) {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
  text-decoration-color: var(--clay-soft);
  transition: text-decoration-color 180ms var(--ease-out);
}
.faq-item p a:hover,
.plan-foot a:hover,
main p a:not(.btn):hover { text-decoration-color: var(--clay); }

/* ---------- Motion ----------
   300–450ms with a slight overshoot, per the stagger preset. The previous
   560ms ease-out felt like the page was loading rather than arriving. */
.reveal-up {
  transition: opacity 420ms var(--ease-out),
              transform 460ms var(--ease-back);
}
.js .reveal-up { transform: translateY(18px) scale(0.985); }
.reveal-up.is-in { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .card:hover, .card:hover .card-icon { transform: none; }
  .js .reveal-up { transform: none; }
}

/* ---------- Card headings ----------
   At 1.18rem with Fraunces' optical size at 96, these sat almost level with
   the body copy underneath and the card had no clear entry point. */
.card h3 {
  font-size: 1.3rem;
  font-variation-settings: "opsz" 40, "SOFT" 16;
  letter-spacing: -0.012em;
  margin-bottom: 0.65rem;
}
.card-icon { margin-bottom: 1.25rem; }

/* ---------- FAQ ----------
   Print convention again: the question is the heading, so it gets the
   display face and a rule that closes each answer rather than opening it. */
.faq-item summary { font-size: 1.14rem; font-variation-settings: "opsz" 40, "SOFT" 16; }
.faq-item[open] summary { color: var(--clay); }
.faq-item summary::after { transition: transform 220ms var(--ease-back); }
.faq-item[open] summary::after { transform: rotate(180deg); }

/* =========================================================================
   Conversation drawer, mobile.
   Three separate problems, all of which forced people onto the browser back
   button to get out of a chat:
     - the open drawer sat on top of the hamburger that opened it, so there
       was no visible control to close it;
     - the only ways out were tapping the dimmed scrim or pressing Escape,
       neither of which is discoverable on a phone;
     - the hamburger itself was a borderless three-line glyph, which does
       not read as a button.
   ========================================================================= */

/* Wide screens: the sidebar is permanent furniture, so it needs no bar. */
.sidebar-bar { display: none; }

.sidebar-toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.sidebar-toggle:hover { border-color: var(--pine); color: var(--pine); }
.sidebar-toggle:active { transform: scale(0.96); }

@media (max-width: 820px) {
  .sidebar-toggle { display: inline-flex; }

  /* A hair wider than the desktop rail, and never wider than the phone. */
  .sidebar { width: min(310px, 86vw); }

  .sidebar-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-shrink: 0;
    padding: 0.6rem 0.6rem 0.6rem 1rem;
    padding-top: calc(0.6rem + env(safe-area-inset-top));
    border-bottom: 1px solid var(--line);
  }
  .sidebar-title {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--ink);
    margin: 0;
  }
  .sidebar-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    flex-shrink: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--ink-soft);
    cursor: pointer;
  }
  .sidebar-close:hover { background: var(--sand-2); color: var(--ink); }
  .sidebar-close:active { transform: scale(0.94); }
}

/* The hidden attribute has to win over the media query above, or a
   signed-out visitor gets a hamburger opening an empty drawer. */
.sidebar-toggle[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
  .sidebar-toggle:active, .sidebar-close:active { transform: none; }
}

/* =========================================================================
   Compliance fixes from the WCAG 2.1 AA audit pass.
   ========================================================================= */

/* 2.4.7 — the skip link relies on moving into view to show focus. Give it a
   real indicator too, so it is visible under `:focus` and not only under
   `:focus-visible` (which some ATs and programmatic focus never match). */
.skip-link:focus,
.skip-link:focus-visible {
  top: 0;
  outline: 3px solid var(--clay);
  outline-offset: 2px;
}

/* 2.5.5 / 2.5.8 — header nav links were 25px tall. AA only asks for 24, but
   this audience skews toward reading glasses and imprecise tapping, so every
   target clears 44px. */
.site-nav .nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.brand { min-height: 44px; }
.site-footer .footer-links a { min-width: 44px; justify-content: center; }
/* Any header nav link, whether or not it carries .nav-link — the legal
   pages use a bare <a>Home</a>, which measured 42x25. */
.site-nav a:not(.btn):not(.brand) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
}
.modal-switch button { display: inline-flex; align-items: center; }

/* 1.4.12 — text spacing. Deliberately NOT changing the two fixed heights on
   this page. The criterion prohibits loss of content or functionality, and a
   fixed-height container whose overflow scrolls loses neither: `.demo-thread`
   is a scroll region by design, and `.plan-blurb`'s min-height only ever
   grows. Removing them would break the demo card's sizing for no compliance
   gain — a column flex item with an auto height sizes to its content, which
   is exactly the bug that made the card 1650px tall. */

/* ---------- /app audit fixes ---------- */

/* 1.4.3 — --ink-faint on --sand-2 measured 4.16:1. Both of these are small
   text (12px uppercase on the tier chip), so they need the darker ink. */
.btn-newchat[data-locked="true"] { color: var(--ink-soft); }
.tier-chip[data-tier="free"] { color: var(--ink-soft); }

/* 2.5.8 — the conversation title button was 23px tall inside a 44px row, so
   the row looked like the target but only half of it was. Fill the row. */
.chat-item { padding: 0; }
.chat-item-title {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 0.2rem 0 0.7rem;
}
.chat-item-del { margin-right: 0.45rem; }

/* 2.5.5 — bring the remaining app controls up to 44px. */
.btn-newchat { min-height: 44px; }
.composer-send { width: 44px; height: 44px; }
.composer textarea { min-height: 44px; padding: 0.7rem 0; }
