/* ============================================================
   CHAT WIDGET (shared, 2026-09-28)
   The "Let's talk" assistant, moved out of index.html so /work can carry the
   same widget: the article Joe acted on put its agent on the highest-intent
   page first ("start with the one page where a fast answer is worth the most
   money"), and /work is ours. ONE copy of the CSS, markup and JS, loaded by
   every page that mounts the chat, so the two can never drift.
   The rules below are the homepage's, moved verbatim and in the same order
   (base, 960, 640, reduced motion, the desktop 1100 block, the phone 1099
   block), so the homepage renders exactly as before. The host page supplies
   the tokens (--red, --ink, --cream, --black, --red-ink, --red-lite, --on-red,
   --border, --font-*); index.html and work.html both define them.
   ============================================================ */
/* Launcher is a LABELLED pill on desktop (2026-08-01). It used to be a bare
   speech-bubble circle, which reads as a generic support widget -- nothing told
   a visitor it was Joe's intake assistant. It collapses back to a circle when
   the panel is open, because then it is purely a close (X) control. */
.chat-launcher {
  position: fixed;
  bottom: 32px; right: 32px;
  z-index: 600;
  min-width: 56px; height: 56px;
  padding: 0 22px 0 18px;
  background: var(--red);
  border: none;
  border-radius: 28px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  box-shadow: 0 4px 28px rgba(224,43,11,0.45);
  transition: background 0.25s, box-shadow 0.25s, transform 0.25s;
}
.chat-launcher-label {
  font-family: var(--font-mono); font-size: 11.5px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--on-red); font-weight: 500;
  white-space: nowrap;
}
.chat-launcher:hover { transform: scale(1.06); box-shadow: 0 6px 36px rgba(224,43,11,0.6); }
.chat-launcher.open {
  background: #2A2A2A; box-shadow: none;
  width: 56px; min-width: 56px; padding: 0; border-radius: 50%;
}
.chat-launcher.open .chat-launcher-label { display: none; }
.chat-launcher svg { width: 22px; height: 22px; fill: white; transition: all 0.2s; }
.chat-pulse {
  position: absolute;
  inset: -4px;
  border-radius: 50%;
  border: 2px solid rgba(224,43,11,0.4);
  animation: pulse-ring 2.5s ease infinite;
}
.chat-launcher.open .chat-pulse { display: none; }
@keyframes pulse-ring {
  0%   { transform: scale(1); opacity: 0.8; }
  60%  { transform: scale(1.38); opacity: 0; }
  100% { transform: scale(1.38); opacity: 0; }
}

.chat-panel {
  position: fixed;
  bottom: 104px; right: 32px;
  z-index: 599;
  width: 384px;
  /* Taller than the old fixed 548px so the notes and the conversation both
     get room, but it can never outgrow the viewport it floats in (104px
     bottom offset + 36px of breathing room above). */
  height: min(660px, calc(100vh - 140px));
  background: #FDFCF8;
  border: 1px solid rgba(0,0,0,0.12);
  border-radius: 8px;
  overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: 0 28px 80px rgba(0,0,0,0.22), 0 0 0 1px rgba(0,0,0,0.03);
  transform: translateY(18px) scale(0.96);
  opacity: 0;
  pointer-events: none;
  transition: all 0.35s cubic-bezier(0.34, 1.2, 0.64, 1);
  transform-origin: bottom right;
}
.chat-panel.open { transform: translateY(0) scale(1); opacity: 1; pointer-events: all; }

/* Deliberately ONE line. The header used to stack a name over a subline
   ("Ask me anything. No wrong answers"), which cost ~37px of a 548px panel
   to repeat what the greeting bubble already says in its first sentence.
   The panel is a workspace: the header identifies it and closes it, and
   every pixel it gives back goes to the notes and the conversation. */
/* Black cap (2026-08-29): the one dark element of the light panel, same idiom
   as the footer tray (black surface + red hairline). */
.chat-header {
  padding: 13px 18px 13px 20px;
  border-bottom: 1px solid var(--red);
  display: flex; align-items: center; justify-content: space-between;
  background: var(--black);
  flex-shrink: 0;
}
.chat-header-left { display: flex; align-items: center; gap: 10px; }
.chat-status-dot {
  width: 7px; height: 7px; background: #4CAF50;
  border-radius: 50%;
  animation: status-pulse 2.5s ease infinite;
}
@keyframes status-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}
.chat-header-name {
  font-family: var(--font-mono);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(244,240,230,0.95);
}
.chat-close {
  background: none; border: none; cursor: pointer;
  color: var(--red-lite); font-size: 18px; line-height: 1;
  transition: color 0.2s; padding: 2px;
}
.chat-close:hover { color: var(--red); }

.chat-messages {
  flex: 1; overflow-y: auto;
  padding: 20px;
  display: flex; flex-direction: column; gap: 16px;
}
.chat-messages::-webkit-scrollbar { width: 2px; }
.chat-messages::-webkit-scrollbar-track { background: transparent; }
.chat-messages::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.14); }

.msg { display: flex; flex-direction: column; gap: 4px; animation: msg-in 0.45s cubic-bezier(0.16, 1, 0.3, 1) both; }
@keyframes msg-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.msg.user { align-items: flex-end; }
.msg.agent { align-items: flex-start; animation-delay: 0.06s; }
.msg-bubble {
  max-width: 88%;
  padding: 12px 16px;
  line-height: 1.55;
  border-radius: 16px;
}
/* Agent question is the hero: editorial serif, larger, set like an interview
   prompt rather than a chat bubble. */
.msg.agent .msg-bubble {
  font-family: var(--font-display);
  font-size: 17px;
  font-weight: 400;
  line-height: 1.5;
  background: #FFFFFF;
  color: var(--ink);
  border: 1px solid rgba(0,0,0,0.08);
  border-bottom-left-radius: 5px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.10);
}
/* User answer is the response in the transcript: mono, recessed, so the eye
   lands on the question -- the deliberate hierarchy. */
.msg.user .msg-bubble {
  font-family: var(--font-mono);
  font-size: 14.5px;
  font-weight: 400;
  letter-spacing: 0.01em;
  line-height: 1.6;
  background: rgba(0,0,0,0.045);
  color: rgba(0,0,0,0.66);
  border: 1px solid rgba(0,0,0,0.05);
  border-bottom-right-radius: 5px;
}
.msg-link { color: var(--red-ink); text-decoration: underline; text-underline-offset: 2px; font-weight: 400; }
.msg-link:hover { opacity: 0.8; }

/* Opener quick-reply chips: a low-friction first tap after the greeting. Real
   <button>s (text via textContent), optional -- free typing still works. */
.chat-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chat-chip {
  font-family: var(--font-mono); font-size: 12px; letter-spacing: 0.06em;
  text-transform: uppercase; color: rgba(0,0,0,0.72);
  background: transparent; border: 1px solid var(--border);
  border-radius: 2px; padding: 7px 11px; cursor: pointer;
  transition: border-color 0.2s, color 0.2s, background 0.2s;
}
.chat-chip:hover, .chat-chip:focus-visible { border-color: var(--red); color: var(--ink); background: rgba(224,43,11,0.06); }

/* ── The Notebook ─────────────────────────────────────────────────────────
   A live intake note that fills in as the assistant hears the five signals.
   Sits under the header; hidden until the first note lands, then slides in.
   Click the head to collapse and reclaim space. */
.chat-notepad {
  flex-shrink: 0;
  background: #E7E3DB;
  border-bottom: 1px solid rgba(0,0,0,0.08);
  padding: 10px 20px 12px;
  display: none;
}
.chat-notepad.show { display: block; animation: notepad-in 0.5s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes notepad-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.notepad-head { display: flex; align-items: center; justify-content: space-between; cursor: pointer; user-select: none; }
.notepad-title { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(0,0,0,0.66); }
.notepad-right { display: flex; align-items: center; gap: 8px; }
.notepad-count { font-family: var(--font-mono); font-size: 11px; color: rgba(0,0,0,0.6); }
.notepad-caret { color: rgba(0,0,0,0.62); font-size: 11px; transition: transform 0.2s; }
.chat-notepad.collapsed .notepad-caret { transform: rotate(-90deg); }
.notepad-progress { display: flex; gap: 3px; margin-top: 8px; }
.notepad-progress span { flex: 1; height: 2px; background: rgba(0,0,0,0.12); border-radius: 1px; transition: background 0.5s ease; }
.notepad-progress span.on { background: var(--red); }
.notepad-lines {
  margin-top: 10px; display: flex; flex-direction: column; gap: 6px;
  /* Capped on purpose. At five signals the uncapped panel took 36% of the chat
     on a 390px phone and 42% on a 360px one, squeezing the conversation into
     309px. Nothing is hidden, it just scrolls, and the closing card still shows
     the complete set at the end. Raised from 88px once the one-line header gave
     37px back, so four of the five lines are visible without scrolling. The vh
     term keeps it honest on a SHORT panel (a 568px phone, a 700px laptop),
     where a flat 108px would still crowd the conversation. */
  max-height: min(108px, 14vh); overflow-y: auto; overscroll-behavior: contain;
  scrollbar-width: thin; scrollbar-color: rgba(0,0,0,0.22) transparent;
}
/* Only masked WHEN it actually scrolls, so a short list keeps crisp edges. A
   half-clipped row with no fade reads as a rendering bug rather than as more
   content below. */
.notepad-lines.scrolls {
  /* Top only. The list always scrolls to the newest note, so nothing is ever
     hidden below, and fading the bottom would dim the line that just landed. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
  mask-image: linear-gradient(to bottom, transparent 0, #000 14px);
}
.notepad-lines::-webkit-scrollbar { width: 3px; }
.notepad-lines::-webkit-scrollbar-thumb { background: rgba(0,0,0,0.22); border-radius: 3px; }
.chat-notepad.collapsed .notepad-lines { display: none; }
/* ============================================================
   THE QUIET ASK (2026-08-01)
   The contact ask used to live ONLY in the bot's sentences, which meant it
   either nagged (it asked five times in four turns on the first live test) or
   vanished entirely. Splitting it into two channels fixes that: the bot asks
   conversationally at most twice, and this carries a permanent, pressure-free
   version. It sits under the live notes on purpose -- by the time it appears
   the visitor can SEE what they would be getting, so the ask is "want these
   notes" rather than "give me your email".
   Deliberately quiet: muted text, outline button, no animation, never expands
   on its own. Do not make this red or auto-open; it would cut against the free
   band's promise that nothing here needs booking or follows up unless asked.
   ============================================================ */
.notepad-ask { display: none; margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(0,0,0,0.08); }
.chat-notepad.ask-on .notepad-ask { display: block; }
.chat-notepad.collapsed .notepad-ask { display: none; }
.notepad-ask-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.notepad-ask-line { font-size: 13.5px; line-height: 1.5; color: rgba(0,0,0,0.7); font-weight: 300; }
.notepad-ask-btn {
  flex-shrink: 0; background: none; cursor: pointer;
  border: 1px solid rgba(10,10,10,0.3); color: rgba(0,0,0,0.72);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; padding: 9px 14px;
  transition: border-color 0.25s, color 0.25s;
}
.notepad-ask-btn:hover { border-color: var(--red); color: var(--ink); }
.notepad-form { display: none; margin-top: 10px; gap: 6px; }
.notepad-ask.open .notepad-form { display: flex; }
.notepad-ask.open .notepad-ask-row { display: none; }
.notepad-form input {
  flex: 1 1 0; min-width: 0; background: #FFFFFF;
  border: 1px solid rgba(0,0,0,0.14); color: var(--ink);
  font-family: var(--font-body); font-size: 16px; padding: 10px 12px;
}
.notepad-form input::placeholder { color: rgba(0,0,0,0.4); }
.notepad-form input:focus { outline: none; border-color: var(--red); }
.notepad-form input.err { border-color: var(--red); }
.notepad-form button {
  flex-shrink: 0; background: var(--red); color: var(--on-red); border: none; cursor: pointer;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; padding: 10px 14px;
}
@media (max-width: 420px) { .notepad-form { flex-wrap: wrap; } .notepad-form input { flex: 1 1 100%; } }
/* Delivery status under the notes. Same quiet register as the ask: muted line,
   outline retry button, no colour fill, no animation. Red lettering only on
   failure, and only the --red-ink token (it sits on the light Notebook strip). */
.notepad-delivery { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(0,0,0,0.08); }
.notepad-delivery[hidden], .chat-notepad.collapsed .notepad-delivery { display: none; }
.notepad-delivery-line { font-size: 13.5px; line-height: 1.5; color: rgba(0,0,0,0.7); font-weight: 300; }
.notepad-delivery.err .notepad-delivery-line { color: var(--red-ink); font-weight: 400; }
.notepad-form button:disabled, .notepad-ask-btn:disabled { opacity: 0.6; cursor: default; }

.notepad-line { display: flex; gap: 10px; font-size: 14.5px; line-height: 1.45; animation: note-line-in 0.5s cubic-bezier(0.16,1,0.3,1) both; }
@keyframes note-line-in { from { opacity: 0; transform: translateX(-5px); } to { opacity: 1; transform: none; } }
.notepad-k { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--red-ink); flex-shrink: 0; width: 74px; padding-top: 2px; }
.notepad-v { font-family: var(--font-body); color: rgba(0,0,0,0.8); font-weight: 300; }

/* Closing "here's what I heard" card, rendered in the message flow at the close. */
.note-card { align-self: stretch; background: #FFFFFF; border: 1px solid rgba(0,0,0,0.10); border-left: 2px solid var(--red); border-radius: 10px; padding: 16px 18px; box-shadow: 0 6px 20px rgba(0,0,0,0.08); }
.note-card-title { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(0,0,0,0.55); margin-bottom: 13px; }
.note-card .notepad-lines { gap: 10px; margin-top: 0; }
.note-card .notepad-line { font-size: 15px; }
.note-card-foot { margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(0,0,0,0.08); }
.note-card-foot p { font-family: var(--font-mono); font-size: 12.5px; line-height: 1.6; letter-spacing: 0.02em; color: rgba(0,0,0,0.7); margin: 0 0 12px; }
.note-card-book {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase;
  color: #fff; background: var(--red); padding: 11px 17px; border-radius: 2px;
  text-decoration: none; transition: background 0.2s, transform 0.2s;
}
.note-card-book:hover { background: #C02409; transform: translateX(2px); }

.typing-indicator { display: none; align-items: flex-start; padding: 0; }
.typing-indicator.visible { display: flex; }
.typing-dots {
  background: #FFFFFF;
  border: 1px solid rgba(0,0,0,0.08);
  border-radius: 16px;
  border-bottom-left-radius: 5px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.10);
  padding: 13px 16px;
  display: flex; gap: 4px; align-items: center;
}
.typing-dots span {
  width: 5px; height: 5px;
  background: rgba(0,0,0,0.35);
  border-radius: 50%;
  animation: dot-bounce 1.2s ease infinite;
}
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
.typing-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes dot-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.3; }
  30% { transform: translateY(-5px); opacity: 1; }
}

.chat-input-area {
  border-top: 1px solid rgba(0,0,0,0.08);
  padding: 14px 16px;
  display: flex; gap: 10px; align-items: flex-end;
  background: var(--cream);
  flex-shrink: 0;
  transition: box-shadow 0.2s;
}
/* Active input reads as "your turn" -- a 1px red top hairline (echoes the brand
   and Typeform's always-obvious input focus). */
.chat-input-area:focus-within { box-shadow: inset 0 1px 0 var(--red); }
.chat-input {
  flex: 1;
  background: transparent; border: none; outline: none;
  color: rgba(0,0,0,0.85);
  font-family: var(--font-body);
  font-size: 16px; font-weight: 300;
  resize: none; line-height: 1.5;
  max-height: 80px; min-height: 20px;
  overflow-y: auto; padding: 2px 0;
}
.chat-input::placeholder { color: rgba(0,0,0,0.45); }
.chat-input:focus-visible { outline: none; } /* the panel frames it already */
.chat-send {
  background: var(--red); border: none;
  width: 32px; height: 32px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; flex-shrink: 0;
  transition: all 0.2s; border-radius: 50%;
}
.chat-send:hover { background: #C02409; }
.chat-send svg { width: 14px; height: 14px; fill: white; }
.chat-send:disabled { background: #CFCCC4; cursor: not-allowed; }

/* The saved-conversation disclosure (2026-09-28). Every conversation is now
   kept so Joe can read back what converts and what loses people, and the
   honest place to say so is where the typing happens, not only on /privacy.
   One quiet mono line on the cream strip under the input: same register as
   the notepad labels, never red, never a banner. */
.chat-foot {
  flex-shrink: 0;
  background: var(--cream);
  padding: 0 16px 10px;
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.04em;
  line-height: 1.5; color: rgba(0,0,0,0.6);
}
.chat-foot a { color: rgba(0,0,0,0.72); text-decoration: underline; text-underline-offset: 2px; }
.chat-foot a:hover { color: var(--ink); }

/* The phone scroll lock while the full-screen panel is up. Its own class so
   a host page's own lock (the homepage mobile menu's .no-scroll) never has
   to know the chat exists. */
body.chat-no-scroll { overflow: hidden; }

@media (max-width: 960px) {
  .chat-panel { width: calc(100vw - 32px); right: 16px; bottom: 88px; height: 70vh; }
  .chat-launcher { right: 16px; bottom: 16px; }
}

@media (max-width: 640px) {
  /* Full-screen chat on phones. 100dvh (dynamic viewport) keeps the panel
     sized to the visible area when the keyboard / browser chrome appears, so
     the input never ends up behind the keyboard. 100vh is the fallback for
     browsers without dvh. The flex column (messages flex:1 overflow-y:auto +
     input flex-shrink:0) keeps the input pinned and the messages scrollable.
     JS (visualViewport) refines this for iOS, where the keyboard does not
     shrink dvh. */
  .chat-panel {
    top: 0; left: 0; right: 0; bottom: 0;
    width: 100%;
    height: 100vh;
    height: 100dvh;
    border: none;
    border-radius: 0;
  }
  /* The safe-area inset moves to whichever strip is last: the disclosure
     line now sits under the input. */
  .chat-foot {
    padding-bottom: calc(10px + env(safe-area-inset-bottom));
  }
  /* On phones the panel is full-screen and the floating launcher would sit on
     top of the send button. The panel header already has a close (X), so hide
     the launcher while open. */
  .chat-launcher.open { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .chat-pulse,
  .chat-status-dot,
  .msg,
  .chat-notepad.show,
  .notepad-line {
    animation: none !important;
  }
}

/* Desktop (the homepage's 2026-09-03 readability passes, chat rows). */
@media (min-width: 1100px) {
  .chat-launcher-label { font-size: 12.5px; }

  /* Round three: the chat. Joe: "the chatbot on desktop is tiny." The panel
     was a fixed 384px wide, one fifth of a 1920 monitor, with the visitor's
     own words at 14.5px and the chips at 12px. Wider and taller on desktop,
     and every text style inside steps up one notch. The min-height/calc terms
     still keep it inside a short laptop viewport (verified 1366x700). Phones
     are full-screen and unaffected. */
  .chat-panel { width: 480px; height: min(780px, calc(100vh - 120px)); }
  .msg.agent .msg-bubble { font-size: 18px; }
  .msg.user .msg-bubble { font-size: 16px; }
  .chat-chip { font-size: 13px; padding: 8px 13px; }
  .chat-header-name { font-size: 15px; }
  .chat-input { font-size: 17px; }
  .notepad-lines { max-height: min(140px, 16vh); }
  .notepad-line { font-size: 15.5px; }
  .notepad-title, .notepad-k { font-size: 12px; }
  .notepad-ask-line { font-size: 15px; }
  .notepad-ask-btn, .notepad-form button { font-size: 12.5px; }
  .note-card-line { font-size: 16px; }
  .note-card-k { font-size: 12px; }
  .note-card-foot { font-size: 13.5px; }
  .chat-foot { font-size: 12px; }
}

/* Phone and tablet (the homepage's mobile readability pass, chat rows). */
@media (max-width: 1099px) {
  .note-card-k { font-size: 11px; }
  .chat-launcher-label, .notepad-ask-btn, .notepad-form button { font-size: 12px; }
  .msg.user .msg-bubble { font-size: 15.5px; }
  .chat-chip { font-size: 12.5px; }
}
