/* LovelyHair — "Lovely Support" chat (snippets/lh-chat.liquid, assets/lh-chat.js).
   Mobile first: a bottom sheet on phones, a 24rem card above the launcher from 640px.
   Tokens only. Fields, buttons and the close control are the design system's own
   (input.css, button.css, icon-button.css); this file is layout, the bubbles and the popup
   that holds the two steps. */

.lh-chat {
  --lh-chat-edge: var(--space-5);
  --lh-chat-ease: var(--ease-emphasis);
  /* Forced by Shopify Inbox, not chosen: its host is a full-viewport layer at
     z-index 2147483000 whose launcher wrapper keeps `pointer-events: auto` even
     while the launcher itself is hidden, and that wrapper has no ::part to style.
     Anything of ours in that corner has to sit above it or it cannot be clicked.
     Both yield to drawers and modals through body.lh-no-scroll instead. */
  --lh-chat-z: 2147483001;
}

/* One launcher, not two: if Shopify Inbox is enabled, ours stands where its button
   stood. The class is set by lh-chat.js, so if the script never boots, Inbox is
   untouched. `visibility`, not `display`: the host's own :host display wins
   (docs/claude/gotchas.md, Chat-launcher gotcha). */
html.lh-chat-on shopify-chat::part(activator) { visibility: hidden; }

/* ---- launcher ---- */
.lh-chat__launcher {
  position: fixed;
  right: var(--lh-chat-edge);
  bottom: 5rem;
  /* Lifted clear of a bottom sticky bar (PDP add to cart, Book Now), as Inbox's was. */
  translate: 0 calc(-1 * var(--lh-fab-safe-bottom));
  z-index: var(--lh-chat-z);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: 0 var(--space-5) 0 var(--space-4);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--surface-inverse);
  color: var(--text-on-dark);
  font-family: var(--font-body);
  font-size: var(--font-body-md);
  font-weight: var(--weight-semibold);
  box-shadow: var(--shadow-lg);
  cursor: pointer;
  transition:
    translate var(--duration-base) var(--ease-standard),
    opacity var(--duration-fast) var(--ease-out),
    scale var(--duration-fast) var(--ease-out),
    visibility 0s;
}
.lh-chat__launcher:active { scale: var(--scale-press); }
.lh-chat__launcher:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .lh-chat__launcher:hover { box-shadow: var(--shadow-xl); }
}
/* Any drawer or modal owns the screen; the launcher would sit on its CTA. Read from each one's own open
   state as well as the shared scroll lock: one popup's late close can take body.lh-no-scroll from under
   the next (Quick View closes 600ms after an add to cart that has already opened the cart drawer, and
   the launcher came back on top of the drawer: owner, 2026-10-31). */
body.lh-no-scroll .lh-chat__launcher,
body:has(dialog[open], .is-open:is([data-cart-drawer], [data-quick-view-root], [data-mobile-nav], [data-search-modal],
  [data-account-modal-root], [data-welcome-banner-root], [data-review-modal], [data-pdp-lightbox], [data-size-guide],
  [data-collection-facets])) .lh-chat__launcher { visibility: hidden; }
/* On phones the open sheet covers the launcher's corner. */
.lh-chat.is-open .lh-chat__launcher {
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--duration-fast) var(--ease-out), visibility 0s linear var(--duration-fast);
}

/* ---- panel ---- */
.lh-chat__panel {
  position: fixed;
  inset: auto 0 0 0;
  z-index: calc(var(--lh-chat-z) + 1);
  display: flex;
  flex-direction: column;
  height: min(92dvh, 40rem);
  overflow: hidden;
  background: var(--surface-card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-xl);
  font-family: var(--font-body);
  color: var(--text-body);
  /* Closed: out of the tab order and the accessibility tree, no JS timer needed.
     Leaving is quicker than arriving. */
  visibility: hidden;
  opacity: 0;
  transform: translateY(1.5rem);
  transition:
    opacity var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out),
    visibility 0s linear var(--duration-fast);
}
.lh-chat.is-open .lh-chat__panel {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition:
    opacity var(--duration-base) var(--lh-chat-ease),
    transform var(--duration-base) var(--lh-chat-ease),
    visibility 0s;
}
/* Reopened by a page load mid-conversation: it was already open, so it does not perform again. */
.lh-chat.is-restored .lh-chat__panel { transition: none; }
body.lh-no-scroll .lh-chat__panel,
body:has(dialog[open], .is-open:is([data-cart-drawer], [data-quick-view-root], [data-mobile-nav], [data-search-modal],
  [data-account-modal-root], [data-welcome-banner-root], [data-review-modal], [data-pdp-lightbox], [data-size-guide],
  [data-collection-facets])) .lh-chat__panel { visibility: hidden; }
/* Focused by script on phones in place of the message box; it is a container, not a control. */
.lh-chat__panel:focus { outline: none; }

/* ---- header: who you are talking to ---- */
.lh-chat__head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-3) var(--space-3) var(--space-4);
  background: var(--surface-inverse);
  color: var(--text-on-dark);
}
/* Phones: the grabber every sheet has (sheet.css), on the header that is pulled down to minimise
   (lh-chat.js swipe). No swipe with reduced motion, so no grabber either. */
@media (max-width: 639px) and (prefers-reduced-motion: no-preference) {
  .lh-chat__head { position: relative; }
  .lh-chat__head::before {
    content: '';
    position: absolute;
    top: 6px;
    left: 50%;
    width: 40px;
    height: 4px;
    margin-left: -20px;
    border-radius: var(--radius-pill);
    background: var(--border-on-dark);
    pointer-events: none;
  }
}
.lh-chat__who { position: relative; flex: none; display: flex; }
.lh-chat-avatar { display: block; flex: none; border-radius: var(--radius-circle); }
.lh-chat__who .lh-chat-avatar { box-shadow: 0 0 0 2px var(--border-on-dark); }
/* "Here now". The ring is the header's own colour, so the dot reads as cut into the avatar. */
.lh-chat__online {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 11px;
  height: 11px;
  border-radius: var(--radius-circle);
  background: var(--lh-success);
  box-shadow: 0 0 0 2px var(--surface-inverse);
}
.lh-chat__id { flex: 1; min-width: 0; }
.lh-chat__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--font-h4);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-heading);
  letter-spacing: var(--tracking-heading);
  color: var(--text-on-dark);
}
.lh-chat__sub {
  margin: 1px 0 0;
  font-size: var(--font-caption);
  color: var(--text-on-dark-muted);
}
/* Minimize, then End chat: the one that only hides sits before the one that ends. */
.lh-chat__actions { flex: none; display: flex; gap: var(--space-2); }

/* The design system's control transitions (--transition-fast, --transition-base)
   include `visibility`. In a panel that opens by flipping visibility, a control
   carrying them is still "hidden" on its first frame, and the browser refuses the
   focus() that open() makes. Inside the panel, controls transition only what they
   actually change. */
.lh-chat__panel .lh-field__control,
.lh-chat__text {
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard);
}
.lh-chat__panel .lh-button,
.lh-chat__panel .lh-icon-button {
  transition:
    background-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard),
    opacity var(--duration-fast) var(--ease-standard),
    scale var(--duration-fast) var(--ease-out);
}
/* The field's control already draws the focus ring (focus-within); a second ring on the input inside it doubles the border. */
.lh-chat__panel .lh-field__input:focus-visible { outline: none; box-shadow: none; }

/* ---- conversation ---- */
.lh-chat__log {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-4) var(--space-3);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--surface-page);
}
.lh-chat__log:focus-visible { outline: 2px solid var(--border-focus); outline-offset: -2px; }

/* Lovely's side: her avatar, then what she says. */
.lh-chat__row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  max-width: 92%;
}
.lh-chat__msg {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-lg);
  font-size: var(--font-body-md);
  line-height: var(--leading-snug);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* The tight corner points at who is speaking. */
.lh-chat__msg--bot {
  min-width: 0;
  background: var(--surface-card);
  border: 1px solid var(--border-subtle);
  border-bottom-left-radius: var(--radius-xs);
}
.lh-chat__msg--user {
  align-self: flex-end;
  max-width: 86%;
  background: var(--color-primary-tint);
  color: var(--text-heading);
  border-bottom-right-radius: var(--radius-xs);
}
.lh-chat__msg a {
  color: var(--text-link);
  font-weight: var(--weight-medium);
  text-underline-offset: 2px;
}
/* ---- product cards: what Lovely recommends, shown rather than linked ----
   The card itself is rendered by sections/chat-product.liquid (Price and Badge are the
   design system's own); this is where it sits and how it is laid out. */
.lh-chat__cards {
  display: grid;
  gap: var(--space-2);
  /* The avatar's width and the row's gap: the cards start where her bubble starts,
     and end where a bubble would. */
  margin-left: calc(28px + var(--space-2));
  width: calc(92% - 28px - var(--space-2));
}
/* As tall as the card it is waiting for, so nothing below it moves when the card lands.
   Until then (and if the card cannot be fetched) it holds the plain link. */
.lh-chat__card-slot {
  display: flex;
  align-items: center;
  min-height: 6rem;
  font-size: var(--font-body-sm);
}
.lh-chat__card-slot > a:not(.lh-chat-card) {
  color: var(--text-link);
  font-weight: var(--weight-medium);
  text-underline-offset: 2px;
}
.lh-chat-card {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--surface-card);
  box-shadow: var(--shadow-sm);
  color: var(--text-body);
  text-decoration: none;
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    box-shadow var(--duration-fast) var(--ease-standard),
    scale var(--duration-fast) var(--ease-out);
}
.lh-chat-card:active { scale: var(--scale-press); }
.lh-chat-card:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .lh-chat-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-md); }
}
.lh-chat-card__img {
  flex: none;
  width: 4.5rem;
  height: 4.5rem;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--surface-image);
}
.lh-chat-card__img--empty {
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: var(--font-h4);
  color: var(--text-subtle);
}
.lh-chat-card__body { flex: 1; min-width: 0; display: grid; gap: var(--space-2); }
/* Wig names are long: two lines, then cut. The product page has the rest. */
.lh-chat-card__title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  overflow: hidden;
  font-size: var(--font-body-sm);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  color: var(--text-heading);
}
.lh-chat-card__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1) var(--space-2);
  font-size: var(--font-body-sm);
  color: var(--text-muted);
}
.lh-chat-card__from strong { color: var(--text-heading); font-weight: var(--weight-semibold); }
.lh-chat-card__duration { display: inline-flex; align-items: center; gap: var(--space-1); }

/* Only a message that has just arrived moves; a restored transcript sits still. */
.lh-chat__row.is-new,
.lh-chat__msg--user.is-new,
.lh-chat__cards.is-new {
  transition: opacity var(--duration-base) var(--ease-out), transform var(--duration-base) var(--ease-out);
}
@starting-style {
  .lh-chat__row.is-new,
  .lh-chat__msg--user.is-new,
  .lh-chat__cards.is-new { opacity: 0; transform: translateY(6px); }
}

.lh-chat__typing { display: inline-flex; gap: 5px; padding: var(--space-4); }
.lh-chat__typing i {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-circle);
  background: var(--text-subtle);
  animation: lh-chat-dot 1.1s var(--ease-standard) infinite;
}
.lh-chat__typing i:nth-child(2) { animation-delay: 0.15s; }
.lh-chat__typing i:nth-child(3) { animation-delay: 0.3s; }
@keyframes lh-chat-dot {
  0%, 60%, 100% { opacity: 0.35; transform: none; }
  30% { opacity: 1; transform: translateY(-3px); }
}

/* ---- starter questions ---- */
.lh-chat__chips {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0 var(--space-4) var(--space-3);
  background: var(--surface-page);
}
.lh-chat__chips[hidden] { display: none; }
.lh-chat__chip {
  min-height: 36px;
  padding: 0 var(--space-3);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-pill);
  background: var(--surface-card);
  color: var(--text-body);
  font: inherit;
  font-size: var(--font-body-sm);
  text-align: left;
  cursor: pointer;
  transition:
    border-color var(--duration-fast) var(--ease-standard),
    background-color var(--duration-fast) var(--ease-standard),
    scale var(--duration-fast) var(--ease-out);
}
.lh-chat__chip:active { scale: var(--scale-press); }
.lh-chat__chip:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .lh-chat__chip:hover { border-color: var(--color-primary); background: var(--color-primary-tint); }
}

/* ---- a question left waiting: the popup was closed before it was answered ---- */
.lh-chat__resume {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-2);
  margin: 0;
  padding: var(--space-1) var(--space-4);
  background: var(--color-primary-tint);
  font-size: var(--font-body-sm);
  color: var(--text-heading);
}
.lh-chat__resume[hidden] { display: none; }

/* The message box keeps its own bottom padding: the field's focus ring needs the room,
   and the WhatsApp line under it is a separate strip, not part of the composer. */
.lh-chat__composer {
  flex: none;
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-card);
}
.lh-chat__text {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  max-height: 7.5rem;
  padding: 10px 14px;
  border: 1.5px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  font-family: var(--font-body);
  font-size: var(--font-input); /* 16px: below that iOS zooms the page on focus */
  line-height: var(--leading-snug);
  color: var(--text-body);
  resize: none;
}
.lh-chat__text::placeholder { color: var(--text-subtle); }
.lh-chat__text:focus { outline: none; border-color: var(--color-primary); box-shadow: var(--ring-focus); }
.lh-chat__send { flex: none; }
.lh-chat__send:disabled { opacity: 0.45; cursor: not-allowed; }

/* ---- the two steps between a first message and its answer: a popup over the chat ----
   The modal is its own scrim. It sits near the top on phones, where the keyboard takes
   the lower half of the sheet, and in the middle of the card from 640px.
   `visibility: inherit`, never `visible`: a visible child shows through a hidden parent,
   and the panel hides itself by visibility when the chat is closed. */
.lh-chat__modal {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 4.5rem var(--space-3) var(--space-3);
  background: var(--scrim-dark);
  visibility: hidden;
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-out), visibility 0s linear var(--duration-fast);
}
.lh-chat__dialog {
  position: relative;
  width: 100%;
  max-height: 100%;
  /* Top padding = the close button's inset, so the title row and the button share a line. */
  padding: var(--space-2) var(--space-4) var(--space-4);
  overflow-y: auto;
  overscroll-behavior: contain;
  border-radius: var(--radius-lg);
  background: var(--surface-card);
  box-shadow: var(--shadow-xl);
  transform: scale(0.96);
  transition: transform var(--duration-fast) var(--ease-out);
}
.lh-chat.is-open .lh-chat__panel:not([data-view="chat"]) .lh-chat__modal {
  visibility: inherit;
  opacity: 1;
  transition: opacity var(--duration-base) var(--lh-chat-ease), visibility 0s;
}
.lh-chat.is-open .lh-chat__panel:not([data-view="chat"]) .lh-chat__dialog {
  transform: none;
  transition: transform var(--duration-base) var(--lh-chat-ease);
}
.lh-chat.is-restored .lh-chat__modal,
.lh-chat.is-restored .lh-chat__dialog { transition: none; }
.lh-chat__dialog-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
}

.lh-chat__step {
  display: none;
  flex-direction: column;
  gap: var(--space-3);
}
.lh-chat__panel[data-view="identify"] .lh-chat__step--identify,
.lh-chat__panel[data-view="verify"] .lh-chat__step--verify,
.lh-chat__panel[data-view="end"] .lh-chat__step--end { display: flex; }
.lh-chat__lead {
  /* As tall as the close button beside it and clear of it, so the title is centred on the
     button and nothing below the title can run under it. */
  display: flex;
  align-items: center;
  min-height: 44px;
  margin: 0;
  padding-right: 44px;
  font-size: var(--font-body-lg);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  color: var(--text-heading);
  text-wrap: balance;
}
.lh-chat__note {
  margin: calc(-1 * var(--space-2)) 0 0;
  font-size: var(--font-body-sm);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}
.lh-chat__note strong { color: var(--text-heading); font-weight: var(--weight-semibold); overflow-wrap: anywhere; }
.lh-chat__note.is-alert { color: var(--text-heading); font-weight: var(--weight-medium); }
.lh-chat__hp { position: absolute; left: -200vw; width: 1px; height: 1px; overflow: hidden; }
.lh-chat__error {
  margin: 0;
  font-size: var(--font-body-sm);
  color: var(--color-error);
}
.lh-chat__error.is-info { color: var(--color-savings); }
.lh-chat__fine {
  margin: 0;
  font-size: var(--font-caption);
  line-height: var(--leading-snug);
  color: var(--text-muted);
}
.lh-chat__fine a { color: var(--text-link); text-underline-offset: 2px; }
/* Six digits, spaced so they can be checked against the email at a glance. */
.lh-chat__code {
  font-variant-numeric: tabular-nums;
  font-weight: var(--weight-semibold);
  letter-spacing: 0.4em;
  text-align: center;
}
.lh-chat__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-1) var(--space-4);
  margin: 0;
}
.lh-chat__link {
  min-height: 32px;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--font-body-sm);
  font-weight: var(--weight-medium);
  color: var(--text-link);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.lh-chat__link:disabled { opacity: 0.5; cursor: default; }
.lh-chat__link:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: var(--radius-xs); }

/* ---- Lovely Support: a person, on WhatsApp ---- */
.lh-chat__foot {
  flex: none;
  display: flex;
  justify-content: center;
  margin: 0;
  padding: var(--space-1) var(--space-4) max(var(--space-1), env(safe-area-inset-bottom));
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-page);
}
.lh-chat__person {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  font-size: var(--font-body-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-heading);
  text-decoration: none;
}
.lh-chat__person .lh-icon { color: var(--color-savings); }
.lh-chat__person:focus-visible { outline: 2px solid var(--border-focus); outline-offset: 2px; border-radius: var(--radius-xs); }
@media (hover: hover) and (pointer: fine) {
  .lh-chat__person:hover span { text-decoration: underline; text-underline-offset: 2px; }
}

/* ---- tablet and up: a card above the launcher ---- */
@media (min-width: 640px) {
  .lh-chat { --lh-chat-edge: var(--space-8); }
  .lh-chat__panel {
    inset: auto var(--lh-chat-edge) calc(5rem + var(--lh-fab-safe-bottom)) auto;
    width: 24rem;
    height: min(38rem, 100dvh - 7.5rem);
    border-radius: var(--radius-lg);
    border: 1px solid var(--border-subtle);
    transform: translateY(0.5rem) scale(0.98);
    transform-origin: bottom right;
  }
  .lh-chat__foot { padding-bottom: var(--space-1); }
  .lh-chat__modal { align-items: center; padding: var(--space-4); }
}

@media (prefers-reduced-motion: reduce) {
  .lh-chat__panel,
  .lh-chat.is-open .lh-chat__panel,
  .lh-chat__dialog { transform: none; }
  .lh-chat__row.is-new,
  .lh-chat__msg--user.is-new,
  .lh-chat__cards.is-new { transition: opacity var(--duration-fast) linear; }
  .lh-chat__typing i { animation: none; opacity: 0.6; }
  .lh-chat__launcher { transition: opacity var(--duration-fast) linear, visibility 0s; }
  .lh-chat-card:active { scale: none; }
  @starting-style {
    .lh-chat__row.is-new,
    .lh-chat__msg--user.is-new,
    .lh-chat__cards.is-new { opacity: 0; transform: none; }
  }
}
