/* ============================================================================
   livechat.css — the visitor-facing chat widget on the signup funnel.

   Two constraints drove every number here, both learned the hard way on this page
   earlier the same day:

   1. IT MUST NOT COVER THE THING THE PAGE IS FOR. Humphrey's nudge on /pricing is
      position:fixed at z-index 2147483000 and covers 64.6% of the viewport width at
      390px, sitting on top of the plan card's name and price. A chat launcher doing
      that over the Stripe Payment Element would be worse than having no chat: the
      visitor is one tap from paying and the widget is in the way. So the launcher is
      a single 56px circle, the panel only covers anything once the visitor has opened
      it, and the funnel gets scroll padding so its own CTA can always clear the
      launcher.
   2. TOUCH TARGETS ARE 44px MINIMUM. Every control here is >= 44px, matching the pass
      just made over signup2's stepper, plan CTA, Back button and billing toggle.

   Palette is signup2's own (checkout.css custom properties) with hard fallbacks, so a
   change to the funnel's theme carries here and a missing variable still renders.
   ========================================================================== */

/* Width of the docked drawer. One number, used by the panel AND by the rule that
   squeezes the funnel, so the two can never disagree. */
:root { --lc-dock: 400px; }

/* ── Theme ───────────────────────────────────────────────────────────────
   LIGHT BY DEFAULT, following Humphrey: a dark header over a white message area.
   That combination is not decoration — the funnel behind this drawer is very dark,
   so a dark header anchors the panel to the page while the white body keeps the
   conversation itself legible, which is the part people actually read.

   Every colour below is a token defined here and overridden once for dark, rather
   than a value inlined at its point of use. That is what makes the toggle a single
   attribute flip instead of a second copy of the stylesheet — and it is why these
   deliberately do NOT read from checkout.css's variables: those describe the funnel,
   which is dark in both of this widget's themes.

   Light values are Humphrey's, so the two panels look like one product:
   #fff message area, #f1f3f9 bubbles on #0f172a text, rgba(15,23,42,.08) rules. */
.lc-root {
    --lcc-panel-bg:    #ffffff;
    --lcc-border:      rgba(15, 23, 42, .10);
    --lcc-head-bg:     #0f172a;
    --lcc-head-fg:     #ffffff;
    --lcc-head-sub:    #94a3b8;
    --lcc-head-btn:    #94a3b8;
    --lcc-head-hover:  rgba(255, 255, 255, .10);
    --lcc-log-bg:      #ffffff;
    --lcc-fg:          #0f172a;
    --lcc-muted:       #5C626E;
    --lcc-them-bg:     #f1f3f9;
    --lcc-them-fg:     #0f172a;
    --lcc-them-border: rgba(15, 23, 42, .06);
    --lcc-you-bg:      #38bdf8;
    --lcc-you-fg:      #04121f;
    --lcc-form-bg:     #ffffff;
    --lcc-input-bg:    #f1f3f9;
    --lcc-warn:        #b4690e;
    --lcc-input-fg:    #0f172a;
    --lcc-placeholder: #94a3b8;
    --lcc-accent:      #0ea5e9;
    --lcc-accent-rgb:  14, 165, 233;
    --lcc-btn-bg:      #38bdf8;
    --lcc-btn-fg:      #04121f;
    --lcc-chip-bg:     #f8fafc;
    --lcc-chip-fg:     #334155;
    --lcc-hover:       rgba(15, 23, 42, .04);
    --lcc-shadow:      -18px 0 48px rgba(15, 23, 42, .18);
}

/* Dark. The header keeps its colour — it is already dark — so only the body flips. */
.lc-root[data-theme="dark"] {
    --lcc-panel-bg:    #0f172a;
    --lcc-border:      rgba(255, 255, 255, .12);
    --lcc-head-bg:     rgba(255, 255, 255, .03);
    --lcc-head-fg:     #ffffff;
    --lcc-head-sub:    #94a3b8;
    --lcc-head-btn:    #94a3b8;
    --lcc-head-hover:  rgba(255, 255, 255, .06);
    --lcc-log-bg:      #0f172a;
    --lcc-fg:          #e2e8f0;
    --lcc-muted:       #94a3b8;
    --lcc-them-bg:     rgba(255, 255, 255, .08);
    --lcc-them-fg:     #e2e8f0;
    --lcc-them-border: transparent;
    --lcc-you-bg:      #38bdf8;
    --lcc-you-fg:      #04121f;
    --lcc-form-bg:     rgba(255, 255, 255, .02);
    --lcc-input-bg:    rgba(0, 0, 0, .28);
    --lcc-warn:        #e0a828;
    --lcc-input-fg:    #ffffff;
    --lcc-placeholder: #94a3b8;
    --lcc-accent:      #38bdf8;
    --lcc-accent-rgb:  56, 189, 248;
    --lcc-btn-bg:      #38bdf8;
    --lcc-btn-fg:      #04121f;
    --lcc-chip-bg:     rgba(255, 255, 255, .04);
    --lcc-chip-fg:     #e2e8f0;
    --lcc-hover:       rgba(255, 255, 255, .06);
    --lcc-shadow:      -18px 0 48px rgba(0, 0, 0, .45);
}

.lc-root {
    /* Holds the launcher only — the panel is its own fixed drawer, so it is not
       trapped inside a 56px corner box.
       z-index is below anything modal the funnel itself opens. Deliberately NOT the
       2147483000 Humphrey uses: a support widget outranking a payment dialog is the
       bug this whole file has been avoiding. */
    position: fixed;
    right: 16px;
    bottom: 16px;
    z-index: 9000;
    font-family: inherit;
}

/* ── Docking ─────────────────────────────────────────────────────────────
   The drawer takes space rather than covering the page — the funnel is squeezed
   into what is left, the way Humphrey's dock behaves.

   Humphrey does this with margin-right on <body>. That does NOT work here: this
   shell sets body to width:100vw;height:100vh;overflow:hidden, so a margin would
   push the body out of its own fixed viewport and get clipped rather than
   reflowing anything. .app-layout is width:100% of that body, so shrinking IT
   squeezes the three columns properly — and because it is a percentage, it stays
   correct under the body{zoom} tier at >=1101px, where a hardcoded vw maths would
   not. */
body.lc-docked .app-layout {
    width: calc(100% - var(--lc-dock));
    transition: width .22s cubic-bezier(.4, 0, .2, 1);
}
.app-layout { transition: width .22s cubic-bezier(.4, 0, .2, 1); }

/* ── Launcher ───────────────────────────────────────────────────────────── */
.lc-launcher {
    width: 56px;
    height: 56px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, .14);
    background: var(--accent-primary, #38bdf8);
    color: #04121f;
    font-size: 1.25rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
    transition: transform .16s ease, box-shadow .16s ease;
}
.lc-launcher:hover { transform: translateY(-2px); }
.lc-launcher:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

/* Unread count. Sits on the launcher so a reply is visible with the panel closed. */
.lc-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 22px;
    height: 22px;
    padding: 0 6px;
    border-radius: 999px;
    background: #ef4444;
    color: var(--lcc-input-fg);
    font-size: .72rem;
    font-weight: 700;
    display: none;
    align-items: center;
    justify-content: center;
}
.lc-badge.show { display: flex; }

/* ── Panel: a full-height drawer, not a popup ───────────────────────────── */
.lc-panel {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--lc-dock);
    max-width: 100vw;
    z-index: 9001;             /* over the squeezed funnel, under a payment dialog */
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border-radius: 0;          /* it is an edge of the page now, not a floating card */
    border: 0;
    border-left: 1px solid var(--lcc-border);
    background: var(--lcc-panel-bg);
    box-shadow: var(--lcc-shadow);

    /* Parked off-canvas and slid in, rather than display:none. A transform animates on
       the compositor and, unlike toggling display, lets the panel animate OUT as well —
       which is what stops it reading as a popup appearing and vanishing. */
    transform: translateX(100%);
    transition: transform .22s cubic-bezier(.4, 0, .2, 1);
    visibility: hidden;
}
.lc-root.is-open .lc-panel { transform: translateX(0); visibility: visible; }

/* The launcher would sit on top of its own drawer. It has a × of its own in there. */
.lc-root.is-open .lc-launcher { opacity: 0; pointer-events: none; }
.lc-launcher { transition: transform .16s ease, box-shadow .16s ease, opacity .16s ease; }

@media (prefers-reduced-motion: reduce) {
    .lc-panel, .app-layout, body.lc-docked .app-layout { transition: none; }
}

.lc-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--lcc-border);
    background: var(--lcc-head-bg);
}
.lc-title { font-size: .95rem; font-weight: 700; color: var(--lcc-head-fg); margin: 0; }
.lc-sub   { font-size: .74rem; color: var(--lcc-head-sub); margin: 2px 0 0; }
.lc-close {
    width: 44px; height: 44px;
    flex: 0 0 44px;
    border: 0; background: transparent;
    color: var(--lcc-head-btn);
    font-size: 1.1rem; cursor: pointer; border-radius: 8px;
}
.lc-close:hover { color: var(--lcc-head-fg); background: var(--lcc-head-hover); }

.lc-log {
    flex: 1 1 auto;
    min-height: 140px;
    overflow-y: auto;
    padding: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    scrollbar-width: thin;
}

.lc-msg {
    max-width: 84%;
    padding: 9px 12px;
    border-radius: 12px;
    font-size: .88rem;
    line-height: 1.45;
    /* Chat is arbitrary text people paste into. Wrapping is not cosmetic here: an
       unbroken 400-character URL would otherwise widen the panel past the viewport. */
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}
.lc-msg.visitor {
    align-self: flex-end;
    background: var(--lcc-you-bg);
    color: var(--lcc-you-fg);
    border-bottom-right-radius: 4px;
}
.lc-msg.admin {
    align-self: flex-start;
    background: var(--lcc-them-bg);
    color: var(--lcc-chip-fg);
    border-bottom-left-radius: 4px;
}
.lc-msg.system {
    align-self: center;
    background: transparent;
    color: var(--lcc-head-btn);
    font-size: .78rem;
    font-style: italic;
    padding: 2px 0;
}
.lc-who {
    display: block;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    opacity: .7;
    margin-bottom: 3px;
}

/* The three states every async surface owes the reader: waiting, empty, broken. */
.lc-state {
    margin: auto;
    text-align: center;
    color: var(--lcc-head-btn);
    font-size: .82rem;
    line-height: 1.5;
    padding: 12px;
}
.lc-state b { display: block; color: var(--lcc-fg); font-size: .9rem; margin-bottom: 4px; }

.lc-form {
    display: flex;
    gap: 8px;
    padding: 10px;
    border-top: 1px solid var(--lcc-border);
    background: var(--lcc-form-bg);
}
.lc-input {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 44px;
    max-height: 120px;
    resize: none;
    padding: 11px 12px;
    border-radius: 10px;
    border: 1px solid var(--lcc-border);
    background: var(--lcc-input-bg);
    color: var(--lcc-input-fg);
    font: inherit;
    font-size: .88rem;
    line-height: 1.4;
}
.lc-input::placeholder { color: var(--lcc-placeholder); }
.lc-input:focus { outline: none; border-color: var(--lcc-accent); }
.lc-send {
    flex: 0 0 auto;
    min-width: 44px;
    min-height: 44px;
    border: 0;
    border-radius: 10px;
    background: var(--lcc-btn-bg);
    color: var(--lcc-btn-fg);
    font-size: 1rem;
    cursor: pointer;
}
.lc-send:disabled { opacity: .45; cursor: default; }

/* ── Phones ─────────────────────────────────────────────────────────────
   At 375px a 360px panel plus its 16px offsets would be wider than the screen, so
   the panel is pinned to both edges instead of given a fixed width. It is allowed
   to cover the funnel only because the visitor opened it — the LAUNCHER never does.
   Same 640px breakpoint the rest of signup2's phone rules use. */
@media (max-width: 640px) {
    .lc-root { right: 12px; bottom: 12px; left: 12px; }
    .lc-launcher { margin-left: auto; }   /* stays a circle on the right */

    /* No squeezing on a phone: 375px minus a 400px drawer leaves nothing to squeeze
       into. The drawer takes the whole screen instead, which is the same thing every
       mobile chat does and is fine BECAUSE the visitor opened it — the launcher never
       covers anything on its own. */
    .lc-panel { left: 0; right: 0; width: auto; max-width: none; border-left: 0; }
    body.lc-docked .app-layout { width: 100%; }
}

/* The funnel's own last control must be able to clear the LAUNCHER (the drawer itself
   no longer overlaps anything — it takes its own space). .step-inner already carries
   4rem of bottom padding; the launcher is 56px plus 16px of offset, so this tops it up
   rather than replacing it. Scoped to the class the widget adds to <body>, so a page
   without the widget is untouched — and dropped again while docked, since the launcher
   is hidden then and the extra gap would just be dead space. */
body.lc-present .step-inner { padding-bottom: 7rem; }
body.lc-present.lc-docked .step-inner { padding-bottom: 4rem; }

@media (prefers-reduced-motion: reduce) {
    .lc-launcher { transition: none; }
}

/* ── Identity step ───────────────────────────────────────────────────────
   Shown only when the server does not already know who is asking. Someone past
   the account step is signed in and never sees this; a question asked from the
   plan step arrives with no name, and "Anonymous visitor" in the transcript is a
   conversation nobody can follow up or tell apart from the next one.

   Same 44px control heights as the rest of the funnel. */
.lc-idform { display: block; padding: 14px; }
.lc-idlead {
    margin: 0 0 10px;
    font-size: .88rem;
    font-weight: 700;
    color: var(--lcc-input-fg);
}
.lc-idinput {
    display: block;
    width: 100%;
    box-sizing: border-box;
    min-height: 44px;
    margin-bottom: 8px;
    padding: 11px 12px;
    border-radius: 10px;
    border: 1px solid var(--lcc-border);
    background: var(--lcc-input-bg);
    color: var(--lcc-input-fg);
    font: inherit;
    font-size: .88rem;
}
.lc-idinput::placeholder { color: var(--lcc-placeholder); }
.lc-idinput:focus { outline: none; border-color: var(--lcc-accent); }
.lc-idgo {
    width: 100%;
    min-height: 44px;
    margin-top: 2px;
    border: 0;
    border-radius: 10px;
    background: var(--lcc-btn-bg);
    color: var(--lcc-btn-fg);
    font: inherit;
    font-size: .88rem;
    font-weight: 700;
    cursor: pointer;
}
.lc-idgo:disabled { opacity: .55; cursor: default; }
.lc-idnote {
    margin: 9px 0 0;
    font-size: .72rem;
    line-height: 1.45;
    color: var(--lcc-head-btn);
}

/* Sound toggle in the panel header. A chime the visitor cannot switch off is worse
   than no chime — this can fire while they are on a call, and a signup page is not
   the place to make somebody hunt through settings for it. 44px like every other
   control here. */
.lc-mute {
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
    border: 0;
    background: transparent;
    color: var(--lcc-head-btn);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    border-radius: 8px;
}
.lc-mute:hover { color: var(--lcc-head-fg); background: var(--lcc-head-hover); }
.lc-mute:focus-visible { outline: 2px solid var(--lcc-accent); outline-offset: 2px; }

/* ── Suggested questions ─────────────────────────────────────────────────
   One tap instead of composing a sentence. Somebody hesitating at the card step
   will not open a chat and type a paragraph — they close the tab. Full-width
   chips so a thumb cannot miss, and >=44px like every other control here. */
.lc-sugg { margin-top: auto; padding-top: 6px; }
.lc-sugg-lead {
    margin: 0 0 8px;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--lcc-head-btn);
}
.lc-chip {
    display: block;
    width: 100%;
    min-height: 44px;
    margin-bottom: 7px;
    padding: 10px 12px;
    text-align: left;
    border-radius: 10px;
    border: 1px solid var(--lcc-border);
    background: var(--lcc-chip-bg);
    color: var(--lcc-chip-fg);
    font: inherit;
    font-size: .82rem;
    line-height: 1.35;
    cursor: pointer;
    transition: border-color .14s ease, background .14s ease;
}
.lc-chip:hover {
    background: var(--lcc-them-bg);
    border-color: var(--lcc-accent);
    color: var(--lcc-input-fg);
}
.lc-chip:focus-visible { outline: 2px solid var(--lcc-accent); outline-offset: 2px; }
.lc-chip:last-child { margin-bottom: 0; }

@media (prefers-reduced-motion: reduce) { .lc-att-chip { transition: none; } }

/* Theme toggle, beside the sound button. Same 44px target as everything else here. */
.lc-theme {
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
    border: 0;
    background: transparent;
    color: var(--lcc-head-btn);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    border-radius: 8px;
}
.lc-theme:hover { color: var(--lcc-head-fg); background: var(--lcc-head-hover); }
.lc-theme:focus-visible { outline: 2px solid var(--lcc-accent); outline-offset: 2px; }

/* The log's own surface, so a light panel is white behind the bubbles rather than
   inheriting the panel colour by accident. */
.lc-log { background: var(--lcc-log-bg); }
.lc-msg.system { color: var(--lcc-muted); }
.lc-idlead { color: var(--lcc-fg); }
.lc-idnote, .lc-sugg-lead { color: var(--lcc-muted); }
.lc-idinput { background: var(--lcc-input-bg); border-color: var(--lcc-border); color: var(--lcc-input-fg); }
.lc-idinput::placeholder { color: var(--lcc-placeholder); }
.lc-idinput:focus { border-color: var(--lcc-accent); }
.lc-idgo { background: var(--lcc-btn-bg); color: var(--lcc-btn-fg); }
.lc-idform { background: var(--lcc-form-bg); }

/* ── Attachments ─────────────────────────────────────────────────────────────
   Uses the same --lcc-* tokens as the rest of the widget, so the light/dark
   toggle covers these without a second set of rules. */

/* Off-screen rather than display:none — the paperclip is the visible control, but
   the input stays reachable by keyboard and screen reader. */
.lc-file {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.lc-clip {
    flex: 0 0 auto;
    min-width: 44px; min-height: 44px;   /* the same 44px touch target as Send */
    border: 1px solid var(--lcc-border);
    border-radius: 10px;
    background: var(--lcc-input-bg);
    color: var(--lcc-text);
    font-size: 1rem;
    cursor: pointer;
    line-height: 1;
}
.lc-clip:hover  { border-color: var(--lcc-accent); }
.lc-clip:focus  { outline: 2px solid var(--lcc-accent); outline-offset: 1px; }

/* The tray of files chosen but not yet sent. */
.lc-tray {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
    padding: 8px 10px 0;
    background: var(--lcc-form-bg);
}
.lc-att-chip {
    position: relative;
    width: 46px; height: 46px;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid var(--lcc-border);
    flex: 0 0 auto;
}
.lc-att-chip img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lc-att-chip-x {
    position: absolute; top: 0; right: 0;
    width: 18px; height: 18px;
    border: 0; border-radius: 0 0 0 8px;
    background: rgba(0, 0, 0, 0.62);
    color: #fff; font-size: 0.72rem; line-height: 1;
    cursor: pointer; padding: 0;
}
.lc-att-note {
    font-size: 0.7rem;
    color: var(--lcc-warn);
    flex: 1 1 100%;
}

/* A received image inside a message bubble. Capped in height so a tall phone
   screenshot cannot push the whole conversation off screen. */
.lc-att {
    display: block;
    margin-top: 6px;
    border-radius: 8px;
    overflow: hidden;
    line-height: 0;
}
.lc-att img {
    display: block;
    max-width: 100%;
    max-height: 220px;
    object-fit: cover;
    border-radius: 8px;
}

/* Drag feedback on the whole panel — people aim at the conversation, not the
   composer, so the drop target is the big one and it has to say so. */
.lc-panel.lc-dropping { outline: 2px dashed var(--lcc-accent); outline-offset: -6px; }
.lc-panel.lc-dropping .lc-log { opacity: 0.7; }

/* ── The nudge ───────────────────────────────────────────────────────────────
   Shown only after a payment has actually failed — see nudge() for why it is
   never on a timer. It has to be noticeable enough to find at a bad moment and
   quiet enough not to feel like a pop-up ad, which is the whole tension. */

.lc-nudge {
    position: fixed;
    right: 20px;
    bottom: 88px;                    /* clears the 56px launcher + its offset */
    /* 9000: the same rank as the launcher it belongs to, and BELOW the payment
       dialog at 9001. 2147483000 was the first value here and it was wrong for the
       exact reason this file already documents — a support prompt must never cover
       the Stripe Payment Element, least of all one that appears BECAUSE a payment
       just failed. The existing z-index test caught it. */
    z-index: 9000;
    max-width: min(280px, calc(100vw - 40px));
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    border-radius: 12px;
    background: var(--lcc-panel-bg, #fff);
    color: var(--lcc-text, #26282B);
    border: 1px solid var(--lcc-border, #e6e4e0);
    box-shadow: 0 10px 30px rgba(0, 0, 0, .18);
    font-size: 0.82rem;
    line-height: 1.35;
    animation: lc-nudge-in .22s ease-out both;
}
@keyframes lc-nudge-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}
.lc-nudge-text { flex: 1 1 auto; }
.lc-nudge-go {
    flex: 0 0 auto;
    border: 0;
    border-radius: 8px;
    padding: 7px 10px;
    min-height: 32px;
    background: var(--lcc-accent, #1E8E5A);
    color: #fff;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.lc-nudge-x {
    flex: 0 0 auto;
    border: 0;
    background: none;
    color: var(--lcc-muted, #8b9098);
    font-size: 1rem;
    line-height: 1;
    padding: 2px 2px 2px 0;
    cursor: pointer;
}

/* Two slow pulses, then still. A permanently animating button is an irritant, and
   after two it has either been noticed or it has not. */
.lc-launcher--nudge {
    animation: lc-pulse 1.6s ease-out 2;
}
@keyframes lc-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(var(--lcc-accent-rgb, 30, 142, 90), .55); }
    70%  { box-shadow: 0 0 0 14px rgba(var(--lcc-accent-rgb, 30, 142, 90), 0); }
    100% { box-shadow: 0 0 0 0 rgba(var(--lcc-accent-rgb, 30, 142, 90), 0); }
}

/* Motion is decoration here — the bubble carries the whole message on its own. */
@media (prefers-reduced-motion: reduce) {
    .lc-nudge { animation: none; }
    .lc-launcher--nudge { animation: none; }
}

@media (max-width: 640px) {
    /* On a phone the bubble is the width of the screen, so the launcher sits under
       it rather than beside it. */
    .lc-nudge { right: 12px; left: 12px; max-width: none; bottom: 82px; }
}
