@import url(https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;0,9..40,800;1,9..40,400&family=DM+Mono:wght@400;500&display=swap);
/* The consent notice (shared/ui/ConsentNotice): a card fixed to the top of the page, under the modals. The chat's text
   box is at the bottom of the screen, so the notice never covers it, with or without the phone's keyboard. */
.consent-notice {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + var(--sp-2));
  left: 50%;
  transform: translateX(-50%);
  z-index: 90;
  box-sizing: border-box;
  width: min(560px, calc(100vw - 2 * var(--sp-3)));
  /* A short phone in landscape, or one with its keyboard open: the notice scrolls instead of reaching the text box. */
  max-height: calc(50dvh - var(--sp-2));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-card);
  color: var(--text-secondary);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-xl);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
}
.consent-notice p {
  margin: 0;
}
.consent-notice__title {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
  margin-bottom: var(--sp-1);
}
.consent-notice__actions {
  display: flex;
  gap: var(--sp-2);
}
/* Both answers are the same size and as easy to tap: 44px tall, half the notice each on a phone. */
.consent-notice__btn {
  flex: 1 1 0;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg-card);
  color: var(--text-primary);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.consent-notice__btn--accept {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}
.consent-notice__btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (min-width: 600px) {
  .consent-notice {
    flex-direction: row;
    align-items: center;
  }
  .consent-notice__text {
    flex: 1;
  }
  .consent-notice__btn {
    flex: 0 0 auto;
  }
}

/* The Reply, WhatsApp and Call buttons of the admin's Inbox rows (ReachOut.tsx): a row of small outlined buttons under
   the person's details, wrapping on a phone, each one a full touch target there. */
.admin .reach-out {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 8px;
}

.admin .reach-out .btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  text-decoration: none;
}

@media (max-width: 600px) {
  .admin .reach-out .btn {
    min-height: 44px;
  }
}

/* The added state of a product (UXM-01, docs/chat-design.md §5 "Products card"): "− n +" in a white pill with the
   --hairline-strong ring, its figure in --accent-text; tokens only, every button ≥ 44px to the touch. */
.qty-stepper {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  border-radius: 20px;
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  color: var(--accent-text);
  font-family: var(--font-sans);
}
.qty-stepper--wide {
  align-self: stretch;
  height: 44px;
  border-radius: 22px;
}
.qty-stepper-btn {
  position: relative;
  width: 40px;
  height: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--accent-text);
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.qty-stepper--wide .qty-stepper-btn {
  width: 48px;
}
/* 44px to the touch around the 40px button. */
.qty-stepper-btn::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
.qty-stepper-btn:hover:not(:disabled) {
  background: var(--accent-light);
}
.qty-stepper-btn:disabled {
  color: var(--text-faint);
  cursor: default;
}
.qty-stepper-btn:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}
.qty-stepper-n {
  min-width: 22px;
  text-align: center;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
}
/* Said, not shown: the figure between the buttons is what the eye reads. */
.qty-stepper-live {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
/* "2 in your order" between − and + (the products' card A, docs/pdr/prd-llyner-profile-and-products.md CS-09). */
.qty-stepper-n--label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-base);
}

/* ════════════════════════════════════════
  CHAT SHEET (docs/chat-design.md §15): every new thing a visitor opens over the chat.
════════════════════════════════════════ */
.chat-sheet-layer {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  /* The page's header stays visible over a full sheet. */
  --chat-sheet-top: 72px;
}
.chat-sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.42);
  animation: fadeIn var(--trans-fast);
}
.chat-sheet-layer--computer .chat-sheet-backdrop {
  background: linear-gradient(
    rgba(248, 250, 252, 0.4),
    rgba(248, 250, 252, 0.92) 18%
  );
}

.chat-sheet {
  position: absolute;
  bottom: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border-radius: var(--r-2xl) var(--r-2xl) 0 0;
  box-shadow:
    0 -8px 24px rgba(15, 23, 42, 0.16),
    0 0 0 1px var(--hairline);
  max-height: calc(100dvh - var(--chat-sheet-top));
  overflow: hidden;
  outline: none;
  animation: slideUp var(--trans-base);
}
/* The sheet takes the focus when it opens (so Tab starts inside it); that focus is not drawn. */
.chat-sheet:focus,
.chat-sheet:focus-visible {
  outline: none;
  box-shadow:
    0 -8px 24px rgba(15, 23, 42, 0.16),
    0 0 0 1px var(--hairline);
}

/* Phone: full width; the height is the sheet's (fit, 2/3, full). */
.chat-sheet--phone {
  left: 0;
  right: 0;
}
.chat-sheet--phone.chat-sheet--twoThirds {
  height: min(66dvh, calc(100dvh - var(--chat-sheet-top)));
}
.chat-sheet--phone.chat-sheet--full {
  height: calc(100dvh - var(--chat-sheet-top));
}

/* Computer: the chat's 760px column; a form fits its fields, an item or a list takes the whole column. Centred by its
   margins, not a transform: the opening animation (slideUp) owns `transform`, and would push it off-centre until done. */
.chat-sheet--computer {
  left: 0;
  right: 0;
  margin-inline: auto;
  width: min(760px, calc(100% - var(--sp-8)));
}
.chat-sheet--computer.chat-sheet--item,
.chat-sheet--computer.chat-sheet--list {
  height: calc(100dvh - var(--chat-sheet-top));
}

.chat-sheet-handle {
  flex: 0 0 auto;
  height: 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  touch-action: none;
}
.chat-sheet-handle i {
  display: block;
  width: 40px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}

.chat-sheet-head {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  padding: 2px var(--sp-3) var(--sp-3) 18px;
}
.chat-sheet--computer .chat-sheet-head {
  padding-left: 28px;
  padding-right: var(--sp-4);
}
.chat-sheet-titles {
  flex: 1;
  min-width: 0;
  align-self: center;
}
.chat-sheet-title {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  color: var(--text-primary);
}
.chat-sheet--computer .chat-sheet-title {
  font-size: var(--fs-xl);
}
.chat-sheet-subtitle {
  margin: 2px 0 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: var(--lh-snug);
}
.chat-sheet-counter {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--text-secondary);
}
.chat-sheet-counter span {
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}

/* Every round button of a sheet's header: 44px, quiet. */
.chat-sheet-icon-btn {
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  border-radius: var(--r-full);
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.chat-sheet-icon-btn:hover {
  background: var(--bg-muted);
}
.chat-sheet-icon-btn:disabled {
  color: var(--text-faint);
  cursor: default;
  background: var(--bg-card);
}
.chat-sheet-icon-btn:focus-visible {
  box-shadow: var(--focus-ring);
  outline: none;
}

.chat-sheet-progress {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 18px var(--sp-3);
}
.chat-sheet--computer .chat-sheet-progress {
  padding: 0 28px var(--sp-3);
}
.chat-sheet-progress-track {
  display: flex;
  gap: 4px;
}
.chat-sheet-progress-track i {
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: var(--bg-muted);
}
.chat-sheet-progress-track i.is-done {
  background: var(--accent-fill);
}
.chat-sheet-progress-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--text-muted);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

/* The body scrolls on its own; 20px between its last element and the bar. */
.chat-sheet-body {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 18px 20px;
}
.chat-sheet--computer .chat-sheet-body {
  padding: 0 28px 20px;
}
.chat-sheet--twoThirds .chat-sheet-body,
.chat-sheet--full .chat-sheet-body,
.chat-sheet--computer.chat-sheet--item .chat-sheet-body,
.chat-sheet--computer.chat-sheet--list .chat-sheet-body {
  flex: 1 1 auto;
}

.chat-sheet-bar {
  flex: 0 0 auto;
  border-top: 1px solid var(--hairline-strong);
  padding: var(--sp-3) 18px 18px;
  background: var(--bg-card);
}
.chat-sheet--computer .chat-sheet-bar {
  padding: var(--sp-3) 28px 18px;
}
.chat-sheet--computer:has(.chat-sheet-dock) .chat-sheet-bar {
  padding-bottom: var(--sp-3);
}

/* A computer's message box, inside the sheet's foot (an item, a list). */
.chat-sheet-dock {
  flex: 0 0 auto;
  padding: 0 20px 18px;
  background: var(--bg-card);
}
.chat-sheet-dock:first-of-type {
  border-top: 1px solid var(--hairline-strong);
  padding-top: var(--sp-3);
}

@media (prefers-reduced-motion: reduce) {
  .chat-sheet,
  .chat-sheet-backdrop {
    animation: none;
  }
}

/* ════════════════════════════════════════
  CHAT SHEET · FORMS (docs/chat-design.md §15 "Forms", prd-llyner-profile-and-products.md CS-03): the one form layout
  of support, Create your page and the diagnostics. Small uppercase section labels, 15px bold labels, 48px fields, a
  hint or an error under its field, two-choice answers as two equal 48px buttons. On a computer short fields go two to
  a row and a yes/no question is one row with its buttons at the right. The bar: one note, Back, the main action
  (phone: the note above a full-width button; computer: the note left, the buttons right). Chat tokens only.
════════════════════════════════════════ */
.chat-form {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.chat-form-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.chat-form-section + .chat-form-section {
  margin-top: var(--sp-2);
}
.chat-form-section-title {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wider);
  text-transform: uppercase;
  color: var(--text-muted);
}
.chat-form-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-3);
}
.chat-sheet--computer .chat-form-row {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.chat-form-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.chat-form-label {
  margin: 0;
  font-size: var(--fs-chat);
  font-weight: var(--fw-bold);
  line-height: var(--lh-snug);
  color: var(--text-primary);
}
.chat-form-input {
  width: 100%;
  min-height: 48px;
  padding: 0 var(--sp-3);
  border-radius: 12px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-input);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--fs-md);
}
textarea.chat-form-input {
  min-height: 110px;
  padding: var(--sp-3);
  line-height: var(--lh-base);
  resize: vertical;
}
.chat-form-input:focus,
.chat-form-input:focus-within {
  outline: 0;
  border-color: var(--accent-text);
  box-shadow: 0 0 0 3px var(--accent-light);
}
.chat-form-input[aria-invalid='true'],
.chat-form-input:has([aria-invalid='true']) {
  border-color: var(--danger);
}
.chat-form-input:disabled {
  opacity: 0.6;
}
/* A field with something before its text (a calling code): the box holds both. */
.chat-form-input--split {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.chat-form-input--split input {
  flex: 1;
  min-width: 0;
  min-height: 46px;
  border: 0;
  outline: 0;
  background: transparent;
  color: inherit;
  font: inherit;
}
.chat-form-prefix {
  flex: none;
  padding-right: var(--sp-2);
  border-right: 1px solid var(--hairline-strong);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.chat-form-hint,
.chat-form-error {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}
.chat-form-hint {
  color: var(--text-muted);
}
.chat-form-error {
  color: var(--danger);
}
/* A link under a field (the error's "Send me a sign-in link"): a 44px target. */
.chat-form-link {
  align-self: flex-start;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.chat-form-link:disabled {
  cursor: default;
  opacity: 0.6;
}
.chat-form-sent {
  margin: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
}

/* Two choices: two equal 48px buttons. */
.chat-form-choices {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}
.chat-form-choice {
  min-width: 0;
  min-height: 48px;
  padding: var(--sp-2) var(--sp-4);
  border-radius: 12px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.chat-form-choice-text {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  overflow-wrap: anywhere;
}
.chat-form-choice:hover {
  border-color: var(--accent);
}
.chat-form-choice:active {
  transform: scale(0.98);
}
.chat-form-choice[aria-pressed='true'] {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}

/* The whole form's failure, in red above the bar. */
.chat-form-failure {
  margin: 0;
  padding: var(--sp-3);
  border-radius: 12px;
  background: var(--danger-light);
  color: var(--danger);
  font-size: var(--fs-base);
  line-height: var(--lh-snug);
}

/* The bar. */
.chat-form-bar {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.chat-form-note {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--text-muted);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.chat-form-note a {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.chat-form-actions {
  display: flex;
  gap: var(--sp-2);
}
.chat-form-main,
.chat-form-back,
.chat-form-secondary {
  min-height: 48px;
  padding: 0 var(--sp-5);
  border-radius: 12px;
  font: inherit;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.chat-form-main {
  flex: 1;
  border: 0;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.chat-form-main:disabled {
  opacity: 0.5;
  cursor: default;
}
.chat-form-back,
.chat-form-secondary {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
}
.chat-form-main:focus-visible,
.chat-form-back:focus-visible,
.chat-form-secondary:focus-visible,
.chat-form-choice:focus-visible,
.chat-form-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.chat-sheet--computer .chat-form-bar {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-4);
}
.chat-sheet--computer .chat-form-note {
  flex: 1;
  min-width: 0;
  text-align: left;
}
.chat-sheet--computer .chat-form-actions {
  flex: none;
  margin-left: auto;
}
.chat-sheet--computer .chat-form-main {
  flex: none;
}

/* A finished form: the check, what happened, the next steps. */
.chat-form-done {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-4) 0 0;
  text-align: center;
}
.chat-form-done-icon {
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: var(--r-full);
  background: var(--accent-light);
  color: var(--accent-text);
}
.chat-form-done-title {
  margin: 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  color: var(--text-primary);
}
.chat-form-done-address {
  margin: 0;
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  overflow-wrap: anywhere;
}
.chat-form-done-text {
  margin: 0;
  max-width: 340px;
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--text-secondary);
}

/* "Your answers are saved": over the chat's buttons for 3 seconds after a form is left with something in it. */
.chat-form-saved {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  animation: fadeIn var(--trans-fast);
}
@media (prefers-reduced-motion: reduce) {
  .chat-form-saved {
    animation: none;
  }
}

/* A visitor's phone with its calling code (docs/pdr/prd-llyner-catalog.md LCA-11): the code's select and the number
   in one box. The box's border and size are the form's own (its class); these only lay out what is inside. */
.phone-field {
  display: flex;
  align-items: center;
  gap: 8px;
}
.phone-field > input {
  flex: 1;
  min-width: 0;
}
/* The select's face "+57 ▾" with the real select laid over it, transparent: the face stays short, the options name
   the country, the keyboard and screen readers get a plain select. 44px each way. */
.phone-field-code {
  position: relative;
  display: inline-flex;
  flex: none;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  padding-right: 8px;
  border-right: 1px solid var(--hairline-strong, rgba(15, 23, 42, 0.14));
  color: inherit;
  font-variant-numeric: tabular-nums;
}
.phone-field-code-face {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  white-space: nowrap;
}
.phone-field-code-face svg {
  opacity: 0.6;
}
.phone-field-code select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 44px;
  margin: 0;
  border: 0;
  opacity: 0;
  font: inherit;
  /* Above the face: the tap opens the select. */
  cursor: pointer;
}
.phone-field-code:focus-within {
  outline: 2px solid var(--accent-text, currentColor);
  outline-offset: 2px;
  border-radius: 6px;
}

/* A product's picture or initial, in the order tray, the catalogue sheet and the search results. */
.product-thumb {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--accent-light);
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
}
.product-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.product-thumb--fill {
  width: 100%;
  aspect-ratio: 4 / 3;
  font-size: var(--fs-2xl);
}

/* A product without a photo (docs/pdr/prd-llyner-profile-and-products.md CS-09): its first letter on the page colour,
   its category under it; it fills the photo's place (the card, the sheet, the list's grid). */
.product-tile {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-1);
  background: var(--accent-fill);
  color: var(--on-accent);
  text-align: center;
  padding: var(--sp-3);
}
.product-tile-letter {
  font-size: 56px;
  font-weight: var(--fw-extrabold);
  line-height: 1;
}
.product-tile-category {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  opacity: 0.85;
}

/* A Llyner package product's plan header (docs/pdr/prd-llyner-package-products.md PKP-05): the package's name on the
   accent gradient, in the place of the photo. */
.product-tile--plan {
  background: linear-gradient(
    145deg,
    var(--accent-fill),
    color-mix(in srgb, var(--accent-fill) 70%, #000)
  );
}
.product-tile-plan {
  max-width: 100%;
  font-size: 32px;
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  overflow-wrap: anywhere;
}

/* ════════════════════════════════════════
  PRODUCT SHEET (docs/chat-design.md §15 "One item", docs/pdr/prd-llyner-profile-and-products.md CS-10–CS-13)
  One product in the chat sheet: its photos, name, price, availability, then the whole description, what's included
  and the questions. Phone: 2/3, then full; computer: one 320px photo with its slider at the left, the details at the
  right. The chat's tokens only.
════════════════════════════════════════ */
.product-sheet-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Photos: a phone's swiping row with "1 / 3". */
.product-photos {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--bg-muted);
}
.product-photos--strip,
.product-photos--none {
  aspect-ratio: 4 / 3;
}
.product-photos-strip {
  display: flex;
  height: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.product-photos-strip::-webkit-scrollbar {
  display: none;
}
.product-photos-strip img {
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  object-fit: cover;
  scroll-snap-align: start;
}
.product-photos-n {
  position: absolute;
  right: 10px;
  bottom: 10px;
  padding: 2px 10px;
  border-radius: var(--r-full);
  background: rgba(15, 23, 42, 0.62);
  color: #ffffff;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

/* A computer's slider: one square 320px photo, ‹ › on it, the dots under its middle. */
.product-photos--slider {
  width: 320px;
  height: 320px;
  touch-action: pan-y;
}
.product-photos--slider:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
}
.product-photos--slider img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
}
.product-photos--none {
  width: 100%;
}
.product-sheet-wide .product-photos--none {
  width: 320px;
  height: 320px;
  aspect-ratio: auto;
}
.product-photos-nav {
  position: absolute;
  top: 50%;
  width: 44px;
  height: 44px;
  margin-top: -22px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-full);
  background: var(--bg-card);
  box-shadow: var(--shadow-md);
  color: var(--text-primary);
  cursor: pointer;
}
.product-photos-nav:hover {
  background: var(--bg-muted);
}
.product-photos-nav--prev {
  left: 10px;
}
.product-photos-nav--next {
  right: 10px;
}
.product-photos-dots {
  position: absolute;
  left: 50%;
  bottom: 12px;
  display: flex;
  gap: 5px;
  transform: translateX(-50%);
}
.product-photos-dot {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.6);
  box-shadow: 0 0 0 1px rgba(15, 23, 42, 0.12);
  transition: width var(--trans-base);
}
.product-photos-dot.is-on {
  width: 18px;
  background: #ffffff;
}

/* Name, price, availability. */
.product-sheet-head {
  padding-top: var(--sp-4);
}
.product-sheet-name {
  margin: 0;
  font-size: var(--fs-xl);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  color: var(--text-primary);
}
.product-sheet-price {
  margin: 6px 0 0;
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}
.product-sheet-availability {
  margin: 4px 0 0;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--success);
}
.product-sheet-availability--out {
  color: var(--text-muted);
}
.product-sheet-booking {
  margin: 6px 0 0;
  font-size: var(--fs-base);
  color: var(--text-secondary);
}

/* The description: two lines at 2/3, all of it at full height. */
.product-sheet-desc {
  margin: var(--sp-3) 0 0;
  font-size: var(--fs-chat);
  line-height: var(--lh-base);
  color: var(--text-secondary);
}
.product-sheet-desc--short {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.product-sheet-more {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 44px;
  margin-top: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  cursor: pointer;
}

/* What's included, the questions, the details. */
.product-sheet-section {
  margin-top: var(--sp-5);
}
.product-sheet-section h3 {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
.product-sheet-included {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.product-sheet-included li {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-2);
  font-size: var(--fs-base);
  color: var(--text-secondary);
}
.product-sheet-included svg {
  flex: none;
  margin-top: 3px;
  color: var(--accent-text);
}
.product-sheet-faq {
  border-top: 1px solid var(--hairline-strong);
}
.product-sheet-faq:last-child {
  border-bottom: 1px solid var(--hairline-strong);
}
.product-sheet-faq summary {
  display: flex;
  align-items: center;
  min-height: 48px;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  cursor: pointer;
}
.product-sheet-faq p {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--text-secondary);
}
.product-sheet-details {
  display: grid;
  gap: var(--sp-2);
  margin: var(--sp-5) 0 0;
}
.product-sheet-details div {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  font-size: var(--fs-base);
}
.product-sheet-details dt {
  color: var(--text-muted);
}
.product-sheet-details dd {
  margin: 0;
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
  text-align: right;
}
.product-sheet-note {
  margin: 0 0 var(--sp-3);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-md);
  background: var(--success-light);
  color: var(--success);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
}

/* A computer: the photo and its facts at the left, the rest at the right (it scrolls with the body). */
.product-sheet-wide {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: var(--sp-7);
  align-items: start;
}
.product-sheet-left {
  position: sticky;
  top: 0;
}
.product-sheet-right > :first-child {
  margin-top: 0;
}

/* The bar: the quantity and the one main action. */
.product-sheet-buy {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.product-sheet-buy .qty-stepper {
  height: 48px;
  border-radius: 24px;
}
.product-sheet-main {
  flex: 1;
  width: 100%;
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 var(--sp-5);
  border: 0;
  border-radius: 24px;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}
.product-sheet-main:focus-visible {
  box-shadow: var(--focus-ring);
}
.product-sheet-main--out,
.product-sheet-main--added {
  background: var(--bg-muted);
  color: var(--text-muted);
  cursor: default;
}
.product-sheet-main--added {
  background: var(--bg-card);
  color: var(--accent-text);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
}
.product-sheet .chat-sheet-bar .qty-stepper--wide {
  width: 100%;
  height: 48px;
  border-radius: 24px;
}

/* A Llyner package product (docs/pdr/prd-llyner-package-products.md PKP-05): the caps in words beside each module, the
   bar's note over its one button. */
.product-sheet-cap {
  color: var(--text-muted);
}
.product-sheet-package-bar {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  width: 100%;
}
.product-sheet-package-note {
  margin: 0;
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
  text-align: center;
}

/* The diagnostics' list card (docs/chat-design.md §12, "The diagnostics card"): the posts card's look, one row per
   published diagnostic. */
.diagnostic-list-card {
  background: var(--bg-card);
}
.diagnostic-list-card-title {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.diagnostic-list-card-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.diagnostic-list-card-items li + li {
  border-top: 1px solid var(--hairline);
}
/* A whole row is the target: well over 44px tall on a 390px phone. */
.diagnostic-list-card-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 56px;
  padding: var(--sp-2) 14px;
  background: none;
  border: none;
  text-align: left;
  font: inherit;
  color: var(--text-muted);
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.diagnostic-list-card-item:hover:not(:disabled) {
  background: var(--accent-light);
}
/* While the assistant types the rows keep their look (chat-design.md §1.4): no fade on every reply. */
.diagnostic-list-card-item:disabled {
  cursor: progress;
}
.diagnostic-list-card-icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-md);
  background: var(--accent-light);
  color: var(--accent-text);
}
.diagnostic-list-card-text {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.diagnostic-list-card-name {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.diagnostic-list-card-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* post-card (blog item 4): the chat's post card and the Posts section's list card. */

.post-card {
  background: var(--bg-card);
}
.post-card-cover {
  display: block;
  width: 100%;
  max-height: 240px;
  object-fit: cover;
}
.post-card-body {
  padding: var(--sp-3) 14px var(--sp-3);
}
.post-card-title {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: var(--lh-tight);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.post-card-date {
  display: block;
  margin-top: 4px;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.post-card-text {
  margin-top: var(--sp-2);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}
.post-card-text p,
.post-card-text ul,
.post-card-text ol {
  margin: 0 0 var(--sp-2);
}
.post-card-text ul,
.post-card-text ol {
  padding-left: 1.25em;
}
.post-card-text h3,
.post-card-text h4 {
  margin: var(--sp-3) 0 var(--sp-1);
  line-height: var(--lh-snug);
  color: var(--text-primary);
}
.post-card-text h3 {
  font-size: var(--fs-md);
}
.post-card-text h4 {
  font-size: var(--fs-base);
}
.post-card-text a {
  color: var(--accent-text);
}
.post-card-text > :last-child {
  margin-bottom: 0;
}

.post-list-card {
  background: var(--bg-card);
}
.post-list-card-title {
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.post-list-card-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.post-list-card-items li + li {
  border-top: 1px solid var(--hairline);
}
/* A whole row is the target: well over 44px tall on a 390px phone. */
.post-list-card-item {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  width: 100%;
  min-height: 56px;
  padding: var(--sp-2) 14px;
  background: none;
  border: none;
  text-align: left;
  font: inherit;
  color: inherit;
  cursor: pointer;
}
.post-list-card-item {
  transition: background-color var(--trans-fast);
}
.post-list-card-item:hover:not(:disabled) {
  background: var(--accent-light);
}
/* While the assistant types the rows keep their look (chat-design.md §1.4): no fade on every reply. */
.post-list-card-item:disabled {
  cursor: progress;
}
.post-list-card-cover {
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: var(--r-md);
  object-fit: cover;
}
.post-list-card-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.post-list-card-name {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.post-list-card-excerpt {
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.post-list-card-date {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* A sold post's teaser (docs/pdr/prd-linked-products.md LP-12): the product that sells the rest, its button tonal. */
.post-card-sold {
  margin-top: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--hairline);
}
.post-card-sold-line {
  margin: 0 0 var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.post-card-buy {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  min-height: 44px;
  padding: 0 16px;
  border-radius: 22px;
  background: var(--accent-light);
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  transition: background-color var(--trans-fast);
}
.post-card-buy:hover {
  background: color-mix(in srgb, var(--accent-light) 70%, var(--accent) 12%);
}
.post-list-card-lock {
  display: inline-flex;
  margin-right: 4px;
  vertical-align: -1px;
  color: var(--text-muted);
}

/* "Our customers" on Llyner's own pages (docs/pdr/prd-customers-showcase.md; docs/chat-design.md, "Customers card").
   The card is framed once by its row (`msg-card-wrap--framed`): a header strip like the summaries', rows ≥ 60px with
   hairline dividers, and "See all N" as a tonal link. The sheet reuses the rows. */
.showcase-card {
  background: var(--bg-card);
}
.showcase-card-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.showcase-card-title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.showcase-card-count {
  flex: none;
  padding: 2px var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  background: var(--bg-card);
  border-radius: var(--r-full);
  box-shadow: 0 0 0 1px var(--hairline);
}
.showcase-card-items,
.showcase-sheet-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.showcase-card-items li + li,
.showcase-sheet-items li + li {
  border-top: 1px solid var(--hairline);
}
.showcase-card-note {
  margin: 0;
  padding: var(--sp-4);
  font-size: var(--fs-base);
  color: var(--text-secondary);
}

/* A whole row is the target: 60px tall at least, on a 390px phone too. */
.showcase-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 60px;
  padding: var(--sp-2) 14px;
  color: inherit;
  text-decoration: none;
  transition: background-color var(--trans-fast);
}
.showcase-row:hover {
  background: var(--accent-light);
}
.showcase-row:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}
.showcase-avatar {
  flex: none;
  border-radius: 12px;
  object-fit: cover;
  background: var(--bg-muted);
}
.showcase-avatar--initial {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: var(--fw-bold);
  color: var(--accent-text);
  background: var(--accent-light);
}
.showcase-row-text {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.showcase-row-name {
  overflow: hidden;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.showcase-row-meta {
  overflow: hidden;
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.showcase-row-go {
  flex: none;
  display: inline-flex;
  color: var(--accent-text);
}
.showcase-row-visit {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  height: 36px;
  padding: 0 var(--sp-3);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  background: var(--accent-light);
  border-radius: 22px;
}
.showcase-row--loading {
  pointer-events: none;
}
.showcase-skeleton-line {
  width: 60%;
  height: 12px;
  border-radius: var(--r-sm);
}

/* "See all N": tonal, 44px, like the cards' own actions (chat-design.md §5, "Card actions"). */
.showcase-card-all {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 44px;
  font: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  background: none;
  border: none;
  border-top: 1px solid var(--hairline);
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.showcase-card-all:hover {
  background: var(--accent-light);
}
.showcase-card-all:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}

/* The order bar and the order tray (docs/chat-design.md, "Cover"). Tokens only; every tappable is ≥ 44px. */
.order-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-bottom: var(--sp-2);
  padding: var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-4);
  border-radius: var(--r-full);
  background: var(--accent-light);
  border: 1px solid var(--accent-border);
  color: var(--text-primary);
  font-size: var(--fs-base);
  font-family: var(--font-sans);
}
.order-bar-text {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}
.order-bar-view,
.order-bar-go {
  flex: none;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.order-bar-view {
  border: 0;
  background: transparent;
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.order-bar-go {
  border: 0;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.order-bar-view:focus-visible,
.order-bar-go:focus-visible,
.order-tray-qty button:focus-visible,
.order-tray-keep:focus-visible,
.order-tray-go:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.modal-sheet.order-tray {
  width: min(480px, 100%);
}
.order-tray-body {
  padding: var(--sp-5) var(--sp-4)
    calc(var(--sp-4) + env(safe-area-inset-bottom));
}
.order-tray-title {
  margin: 0 var(--sp-10) var(--sp-3) 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.order-tray-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.order-tray-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    'pic info qty'
    'pic info sum';
  align-items: center;
  column-gap: var(--sp-3);
  row-gap: var(--sp-1);
  padding: var(--sp-3) 0;
  border-bottom: 1px solid var(--hairline);
}
.order-tray-row .product-thumb {
  grid-area: pic;
}
.order-tray-info {
  grid-area: info;
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.order-tray-name {
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.order-tray-unit {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.order-tray-qty {
  grid-area: qty;
  display: inline-flex;
  align-items: center;
}
.order-tray-qty button {
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--accent-text);
  cursor: pointer;
}
.order-tray-qty button:hover:not(:disabled) {
  background: var(--accent-light);
}
.order-tray-qty button:disabled {
  color: var(--text-faint);
  cursor: default;
}
.order-tray-qty output {
  min-width: 24px;
  text-align: center;
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}
.order-tray-line-total {
  grid-area: sum;
  justify-self: end;
  padding-right: var(--sp-3);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
}
.order-tray-total {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  padding: var(--sp-4) 0;
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}
.order-tray-actions {
  display: flex;
  gap: var(--sp-2);
}
.order-tray-keep,
.order-tray-go {
  flex: 1;
  min-height: 48px;
  border-radius: var(--r-full);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.order-tray-keep {
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  color: var(--text-secondary);
}
.order-tray-go {
  border: 0;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.order-tray-go:disabled {
  opacity: 0.5;
  cursor: default;
}
/* The last − empties the tray: says so, and offers the catalogue again (UXM-10). */
.order-tray-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-6) 0 var(--sp-4);
  text-align: center;
  color: var(--text-secondary);
}
.order-tray-empty p {
  margin: 0;
}
.order-tray-browse {
  min-height: 44px;
  padding: 0 var(--sp-5);
  border: 0;
  border-radius: var(--r-full);
  background: var(--accent-light);
  color: var(--accent-text);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.order-tray-browse:hover {
  background: var(--accent-mid);
}
.order-tray-browse:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

/* The list sheet's tray (docs/pdr/prd-llyner-profile-and-products.md CS-14): dark, the products' faces, "n items ·
   total" (it opens the tray's own sheet) and "Continue →". */
.order-tray-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 6px 6px 6px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--text-primary);
  color: var(--bg-card);
  font-family: var(--font-sans);
}
.order-tray-bar-view {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-1);
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.order-tray-bar-faces {
  display: flex;
  flex: none;
}
.order-tray-bar-face {
  display: inline-flex;
  border-radius: var(--r-full);
  box-shadow: 0 0 0 2px var(--text-primary);
  overflow: hidden;
}
.order-tray-bar-face + .order-tray-bar-face {
  margin-left: -10px;
}
.order-tray-bar-face .product-thumb {
  border-radius: var(--r-full);
  font-size: var(--fs-sm);
}
.order-tray-bar-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-chat);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
}
.order-tray-bar-go {
  flex: none;
  min-height: 44px;
  padding: 0 var(--sp-5);
  border: 0;
  border-radius: var(--r-full);
  background: var(--accent-fill);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-size: var(--fs-chat);
  font-weight: var(--fw-bold);
  cursor: pointer;
}
.order-tray-bar-view:focus-visible,
.order-tray-bar-go:focus-visible {
  outline: 2px solid var(--bg-card);
  outline-offset: 2px;
}

/* The owner's featured item in the cover's chat card (docs/pdr/prd-open-on-arrival.md OA-12 – OA-16,
   docs/chat-design.md §11 "Open on arrival"): one compact card in the row's frame (msg-card-wrap--framed), ✕ at its
   top right. Phone first; a computer (≥ 640px) takes the bigger picture and the lists' three cards side by side. */

.featured {
  position: relative;
  display: grid;
  gap: var(--sp-3);
  padding: var(--sp-3);
  color: var(--text-primary);
}
/* A sold item's teaser is the chat's own card: edge to edge, under the ✕'s strip. */
.featured--teaser {
  padding: 40px 0 0;
  gap: 0;
}
.featured--teaser .pdf-wrap,
.featured--teaser .post-card {
  border: 0;
  border-radius: 0;
}
.featured--teaser .lk-wrap {
  max-width: none;
  padding: 0 var(--sp-2) var(--sp-2);
}

/* ✕: 32px, a 44px hit area (the hit-area rule's ::before), never over the item's words (their right padding). */
.featured-hide {
  position: absolute;
  top: 6px;
  right: 6px;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
}
.featured-hide::before {
  content: '';
  position: absolute;
  inset: -6px;
}
.featured-hide:hover {
  background: var(--bg-muted);
  color: var(--text-primary);
}

.featured-top {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding-right: 28px;
}
.featured-pic {
  position: relative;
  flex: none;
  width: 96px;
  height: 96px;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg-muted);
}
.featured-pic--open {
  cursor: pointer;
}
.featured-pic img,
.featured-pic .product-tile {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.featured-tile {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  background: var(--accent-light);
  color: var(--accent-text);
  font-size: 32px;
  font-weight: var(--fw-bold);
}
.featured-lock {
  position: absolute;
  top: 6px;
  left: 6px;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--bg-card);
  color: var(--text-secondary);
  box-shadow: var(--shadow-sm);
}
.featured-text {
  display: grid;
  align-content: start;
  gap: 2px;
  min-width: 0;
}
.featured-title {
  margin: 0;
  font-size: var(--fs-md);
  line-height: var(--lh-snug);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.featured-sub {
  margin: 0;
  font-size: 13px;
  color: var(--text-muted);
}
.featured-sub--accent {
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  color: var(--accent-text);
}
.featured-desc {
  display: -webkit-box;
  margin: 2px 0 0;
  overflow: hidden;
  font-size: 13.5px;
  line-height: 1.4;
  color: var(--text-muted);
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* The item's buttons: its main action (filled; tonal for a document and a sold item's Buy), then the outlined ones. */
.featured-actions {
  display: flex;
  gap: var(--sp-2);
}
.featured-actions > .qty-stepper,
.featured-actions > .featured-bar {
  flex: 1;
  min-width: 0;
}
.featured-main,
.featured-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.featured-main {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  border: 0;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.featured-main:hover {
  background: var(--accent-dark);
}
.featured-main--tonal {
  background: var(--accent-light);
  color: var(--accent-text);
}
.featured-main--tonal:hover {
  background: var(--accent-mid);
}
.featured-btn {
  flex: none;
  min-width: 64px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-secondary);
  font-weight: var(--fw-semibold);
}
.featured-btn:hover {
  border-color: var(--accent-border);
  color: var(--accent-text);
}
.featured-btn--icon {
  width: 44px;
  min-width: 44px;
  padding: 0;
}
.featured-main:active,
.featured-btn:active {
  transform: scale(0.97);
}
/* The product sheet's bar, in the card: its one button as wide as the card's. */
.featured-bar .product-sheet-main,
.featured-bar .product-sheet-buy {
  width: 100%;
  min-height: 44px;
}
.featured-bar .product-sheet-package-note {
  display: none;
}

/* A video link: its picture with ▶ (nothing of its site loads before the tap), its player once tapped. */
.featured-video {
  display: grid;
  gap: var(--sp-2);
  padding-right: 0;
}
.featured-video .featured-title {
  padding-right: 0;
}
.featured-facade {
  position: relative;
  display: block;
  width: calc(100% - 36px);
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  overflow: hidden;
  background: #0f172a;
  cursor: pointer;
}
.featured-facade img,
.featured-facade-blank {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.featured-play {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  place-items: center;
  width: 64px;
  height: 44px;
  border-radius: 12px;
  background: rgba(15, 23, 42, 0.72);
  color: #fff;
  transform: translate(-50%, -50%);
}
.featured-video .lk-embed {
  margin-right: 36px;
}
.featured-site-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  justify-self: start;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  text-decoration: none;
}

/* The lists (OA-13): the title, three 64px rows (52px picture, the 44px + or ↗), "See all N →" at the foot. */
.featured-list-title {
  margin: 0;
  padding-right: 32px;
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
}
.featured-list {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}
.featured-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-width: 0;
}
.featured-list--rows .featured-item {
  min-height: 64px;
  padding: 6px 0;
  border-top: 1px solid var(--hairline);
}
.featured-list--rows .featured-item:first-child {
  border-top: 0;
}
.featured-item-open {
  display: flex;
  flex: 1;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
  min-height: 52px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.featured-item-pic {
  position: relative;
  display: grid;
  place-items: center;
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--bg-muted);
}
.featured-item-pic img,
.featured-item-pic .product-tile {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.featured-item-initial {
  font-size: 20px;
  font-weight: var(--fw-bold);
  color: var(--accent-text);
}
.featured-item-play {
  position: absolute;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.72);
  color: #fff;
}
.featured-item-text {
  display: grid;
  flex: 1;
  min-width: 0;
}
.featured-item-name {
  overflow: hidden;
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.featured-item-price {
  font-size: 13px;
  font-weight: var(--fw-bold);
  color: var(--accent-text);
}
.featured-item-site {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--text-muted);
}
.featured-item-go {
  display: grid;
  place-items: center;
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  color: var(--text-secondary);
}

/* A product of the list (docs/pdr/prd-cover-card.md CC-05 – CC-09): its picture, its name and price, then "Add to
   order" (40px, outlined in the accent, a 44px hit area) or "✓ Added" in its place. */
.featured-item--product {
  position: relative;
  flex-direction: column;
  align-items: stretch;
  gap: var(--sp-2);
}
.featured-item--product .featured-item-open {
  flex: none;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
}
.featured-item--product .featured-item-pic {
  width: 100%;
  height: auto;
  border-radius: 16px;
}
.featured-add,
.featured-added {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 40px;
  margin-top: auto;
  border-radius: var(--r-full);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
}
.featured-add {
  position: relative;
  padding: 0 var(--sp-3);
  border: 1.5px solid var(--accent-border);
  background: var(--bg-card);
  color: var(--accent-text);
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.featured-add::before {
  content: '';
  position: absolute;
  inset: -3px 0;
}
.featured-add:hover {
  background: var(--accent-light);
}
.featured-add:active {
  transform: scale(0.98);
}
.featured-added {
  background: var(--success-light);
  color: var(--success);
}

/* A phone: one product at a time, the next one peeking (CC-05); the last card is "See all". */
.featured-list-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding-right: 32px;
}
.featured-list-head .featured-list-title {
  flex: 1;
  min-width: 0;
  padding-right: 0;
}
.featured-head-more {
  position: relative;
  flex: none;
  min-height: 32px;
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  white-space: nowrap;
  cursor: pointer;
}
.featured-head-more::before {
  content: '';
  position: absolute;
  inset: -6px 0;
}
.featured-list--carousel {
  display: flex;
  gap: var(--sp-3);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.featured-list--carousel::-webkit-scrollbar {
  display: none;
}
.featured-list--carousel .featured-item {
  flex: 0 0 82%;
  scroll-snap-align: start;
}
.featured-list--carousel .featured-item-pic {
  aspect-ratio: 16 / 9;
}
.featured-list--carousel .featured-item-text {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-2);
}
.featured-list--carousel .featured-item-name {
  font-size: var(--fs-md);
}
.featured-list--carousel .featured-item-price {
  flex: none;
  max-width: 55%;
  overflow: hidden;
  font-size: var(--fs-base);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.featured-list--carousel .featured-item--more {
  flex: 0 0 38%;
}
.featured-more-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  height: 100%;
  min-height: 120px;
  padding: var(--sp-2);
  border: 1.5px dashed var(--accent-border);
  border-radius: 16px;
  background: var(--accent-light);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  text-align: center;
  cursor: pointer;
}
.featured-more-count {
  font-size: 24px;
}
.featured-item--playing {
  display: block;
  padding: var(--sp-2) 0;
}
.featured-more {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  margin: 0 calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3));
  padding: 0 var(--sp-3);
  border: 0;
  border-top: 1px solid var(--hairline);
  background: none;
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  cursor: pointer;
}

/* A computer: the bigger picture, the buttons at the right; the lists' three cards side by side. */
@media (min-width: 640px) {
  .featured-pic {
    width: 132px;
    height: 132px;
  }
  .featured-title {
    font-size: 18px;
  }
  .featured-actions {
    justify-content: flex-end;
  }
  .featured-main {
    flex: 0 1 auto;
    padding: 0 22px;
  }
  .featured-actions > .qty-stepper,
  .featured-actions > .featured-bar {
    flex: 0 1 280px;
  }
  .featured-list--cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sp-3);
  }
  .featured-list--cards .featured-item {
    position: relative;
    align-items: stretch;
  }
  .featured-list--cards .featured-item-open {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }
  .featured-list--cards .featured-item-pic {
    width: 100%;
    height: auto;
    aspect-ratio: 4 / 3;
    border-radius: 12px;
  }
  .featured-list--cards .featured-item-pic--link {
    aspect-ratio: 1.91 / 1;
  }
  .featured-list--cards .featured-item--product .featured-item-pic {
    aspect-ratio: 16 / 10;
  }
  .featured-list--cards .featured-item--playing {
    grid-column: 1 / -1;
  }
}

/* The cover's card grows by the item (OA-10). Chat mode keeps its own height. */
.cover:not(.cover--chat) .cover-card--featured .messages-area {
  max-height: min(70vh, 600px);
}

/* While the item shows on the cover (docs/pdr/prd-cover-card.md CC-03 – CC-05): a smaller heading, so the card with
   its item fits the screen; on a phone the item edge to edge in the card, in chat mode too (no avatar, no second frame,
   no gap under it),
   the stage at the bottom on Llyner's cover too, and no tagline while the products' carousel shows. */
.cover:not(.cover--chat):has(.cover-card--featured) .cover-heading {
  font-size: 44px;
}
@media (max-width: 639px) {
  .cover:not(.cover--chat):has(.cover-card--featured) .cover-heading {
    font-size: 26px;
  }
  .cover--llyner:not(.cover--chat):has(.cover-card--featured) .cover-stage {
    justify-content: flex-end;
    padding-top: 16px;
  }
  .cover:not(.cover--chat):has(.featured-list--carousel) .cover-tagline {
    display: none;
  }
  .cover .msg-row--card:has(.featured) {
    margin-bottom: 0;
  }
  .cover .msg-row--card:has(.featured) > .bot-avatar {
    display: none;
  }
  .cover .msg-row--card:has(.featured) > .msg-card-wrap--framed {
    width: 100%;
    max-width: none;
    margin: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }
  .cover .msg-row--card .featured {
    padding: 2px 4px 4px;
  }
  .cover .msg-row--card .featured-hide {
    top: -4px;
    right: -4px;
  }
  .cover:not(.cover--chat) .cover-card--featured .messages-area {
    padding-bottom: 2px;
  }
}

/* The list sheet (docs/chat-design.md §15 "A list", docs/pdr/prd-llyner-profile-and-products.md CS-14): search,
   category chips, sections, a grid of square cards. Tokens only; tappables ≥ 44px. */
.catalog-sheet-search {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 48px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  border: 1px solid var(--hairline-strong);
  background: var(--bg-input);
  color: var(--text-muted);
}
.catalog-sheet-search:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-light);
}
.catalog-sheet-search input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--text-primary);
  font: inherit;
  font-size: var(--fs-md);
}
.catalog-sheet-cats {
  display: flex;
  gap: var(--sp-2);
  margin: var(--sp-3) -18px 0;
  padding: 0 18px 2px;
  overflow-x: auto;
  scrollbar-width: none;
}
.chat-sheet--computer .catalog-sheet-cats {
  margin: var(--sp-3) -28px 0;
  padding: 0 28px 2px;
}
.catalog-sheet-cats::-webkit-scrollbar {
  display: none;
}
.catalog-sheet-cat {
  flex: none;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.catalog-sheet-cat-n {
  color: var(--text-muted);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}
.catalog-sheet-cat--on {
  border-color: var(--text-primary);
  background: var(--text-primary);
  color: var(--bg-card);
}
.catalog-sheet-cat--on .catalog-sheet-cat-n {
  color: inherit;
  opacity: 0.7;
}
.catalog-sheet-cat:focus-visible,
.catalog-card-open:focus-visible,
.catalog-card-add:focus-visible,
.catalog-sheet-ask:focus-visible,
.catalog-sheet-clear:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.catalog-sheet-section {
  margin-top: var(--sp-5);
}
.catalog-sheet-section-title {
  margin: 0 0 var(--sp-3);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-muted);
}
/* Two cards a row on a phone, three on a computer. */
.catalog-sheet-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-4) var(--sp-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
.catalog-sheet-grid--wide {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.catalog-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.catalog-card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  margin-bottom: 6px;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-muted);
  box-shadow: 0 0 0 1px var(--hairline);
}
.catalog-card-open {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.catalog-card-open img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.catalog-card-open .product-tile-letter {
  font-size: 44px;
}
/* + or "− n +" on the photo's bottom right. */
.catalog-card-add,
.catalog-card-added {
  position: absolute;
  right: 8px;
  bottom: 8px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-full);
  box-shadow: var(--shadow-md);
}
.catalog-card-add {
  background: var(--accent-fill);
  color: var(--on-accent);
  cursor: pointer;
}
.catalog-card-added {
  background: var(--bg-card);
  color: var(--accent-text);
}
.catalog-card-stepper {
  position: absolute;
  right: 8px;
  bottom: 8px;
  left: 8px;
  display: flex;
  justify-content: flex-end;
}
.catalog-card-stepper .qty-stepper {
  box-shadow:
    inset 0 0 0 1px var(--hairline-strong),
    var(--shadow-md);
}
.catalog-card-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.catalog-card-name {
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  font-size: var(--fs-base);
  font-weight: var(--fw-bold);
  line-height: 1.3;
  color: var(--text-primary);
}
.catalog-card-price {
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
}
.catalog-card-price--muted {
  color: var(--text-muted);
  font-weight: var(--fw-medium);
}

/* Nothing found: say so, and offer to ask the business. */
.catalog-sheet-empty {
  margin-top: var(--sp-8);
  text-align: center;
}
.catalog-sheet-empty-title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}
.catalog-sheet-empty-text {
  margin: 6px auto 0;
  max-width: 320px;
  font-size: var(--fs-base);
  color: var(--text-muted);
}
.catalog-sheet-empty-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.catalog-sheet-ask {
  min-height: 48px;
  padding: 0 var(--sp-6);
  border: 0;
  border-radius: 24px;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-size: var(--fs-chat);
  font-weight: var(--fw-bold);
  cursor: pointer;
}
.catalog-sheet-clear {
  min-height: 44px;
  padding: 0 var(--sp-4);
  border: 0;
  background: none;
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
/* A card's product opened in the list, and the list again after it: the same sheet, no new slide-up. */
.chat-sheet.catalog-sheet--product,
.chat-sheet.catalog-sheet--again,
.chat-sheet-layer:has(.catalog-sheet--product, .catalog-sheet--again)
  .chat-sheet-backdrop {
  animation: none;
}

/* Support on Llyner's own pages (docs/chat-design.md §13, §15): the sheet's form is the chat sheet's form layout
   (shared/ui/chat-sheet/chat-form.css); here only the line under its title, the screenshots' thumbnails and the
   honeypot. Chat tokens only. The guest's private page (pages/support-guest) shares the thumbnail classes. */
.support-account {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.support-account a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
}

/* Screenshots */
.support-pictures {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
.support-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.support-thumb {
  position: relative;
  width: 72px;
  height: 72px;
  border-radius: 10px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-muted);
  overflow: visible;
}
.support-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 9px;
  display: block;
}
.support-thumb--busy img {
  opacity: 0.45;
}
.support-thumb-name {
  display: block;
  padding: var(--sp-1);
  font-size: var(--fs-sm);
  overflow-wrap: anywhere;
}
/* A 44px target around a 22px dot, at the thumbnail's corner. */
.support-thumb-remove {
  position: absolute;
  top: -15px;
  right: -15px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--on-accent);
  cursor: pointer;
}
.support-thumb-remove::before {
  content: '';
  position: absolute;
  width: 22px;
  height: 22px;
  border-radius: var(--r-full);
  background: var(--text-primary);
  z-index: 0;
}
.support-thumb-remove > * {
  position: relative;
  z-index: 1;
}
.support-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 46px;
  border-radius: 12px;
  border: 1px dashed var(--accent-text);
  background: transparent;
  color: var(--accent-text);
  font: inherit;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.support-icon-btn {
  flex: none;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 0;
  background: none;
  color: var(--accent-text);
  cursor: pointer;
}
.support-icon-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

/* The honeypot: off screen, not display:none (a script that fills every field still sees it). */
.support-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* "See all" of "Our customers" (docs/chat-design.md, "Showcase sheet"): the catalogue sheet's search and chips, the
   card's rows with a tonal "Visit", and the page's one filled button at the foot. */
.modal-sheet.showcase-sheet {
  width: min(560px, 100%);
}
.showcase-sheet-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-5) var(--sp-4)
    calc(var(--sp-4) + env(safe-area-inset-bottom));
}
.showcase-sheet-title {
  margin: 0 var(--sp-10) 0 0;
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.showcase-sheet-count {
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
}
.showcase-sheet-search {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 46px;
  padding: 0 var(--sp-4);
  color: var(--text-faint);
  background: var(--bg-input);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--r-full);
}
.showcase-sheet-search:focus-within {
  border-color: var(--accent-text);
}
.showcase-sheet-search input {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: var(--fs-md);
  color: var(--text-primary);
  background: transparent;
  border: 0;
  outline: 0;
}
.showcase-sheet-chips {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-width: none;
}
.showcase-sheet-chips::-webkit-scrollbar {
  display: none;
}
.showcase-sheet-chip {
  flex: none;
  min-height: 44px;
  padding: 0 var(--sp-4);
  font: inherit;
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--text-secondary);
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  border-radius: 12px;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    color var(--trans-fast);
}
.showcase-sheet-chip--on {
  color: var(--on-accent);
  background: var(--accent-fill);
  border-color: var(--accent-fill);
}
.showcase-sheet-items {
  margin: 0 calc(-1 * var(--sp-2));
}
.showcase-sheet-note {
  margin: 0;
  padding: var(--sp-4) 0;
  font-size: var(--fs-base);
  color: var(--text-secondary);
}
.showcase-sheet-more {
  min-height: 44px;
  font: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  background: var(--accent-light);
  border: none;
  border-radius: 22px;
  cursor: pointer;
}
.showcase-sheet-more:disabled {
  cursor: progress;
}
.showcase-sheet-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  text-decoration: none;
  margin-top: var(--sp-1);
  font: inherit;
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--on-accent);
  background: var(--accent-fill);
  border: none;
  border-radius: 22px;
  cursor: pointer;
}

/* The search results above the text box (docs/chat-design.md, "Cover"): tokens only; each option ≥ 48px. */
.search-suggest {
  position: absolute;
  left: 0;
  right: 0;
  bottom: calc(100% + var(--sp-2));
  z-index: var(--z-above);
  display: flex;
  flex-direction: column;
  padding: 6px;
  border-radius: var(--r-bubble);
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-xl);
  max-height: min(60vh, 360px);
  overflow-y: auto;
}
.search-suggest-label {
  padding: 6px 10px 2px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.search-suggest-option {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: 48px;
  padding: 4px 10px;
  border-radius: var(--r-lg);
  color: var(--text-primary);
  cursor: pointer;
}
.search-suggest-option:hover,
.search-suggest-option--active,
.search-suggest-option:focus-visible {
  background: var(--bg-muted);
}
.search-suggest-option:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.search-suggest-icon {
  flex: none;
  width: 40px;
  height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-md);
  background: var(--bg-muted);
  color: var(--accent-text);
}
.search-suggest-name {
  flex: 1;
  min-width: 0;
  font-weight: var(--fw-medium);
  overflow-wrap: anywhere;
}
.search-suggest-name mark {
  background: none;
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
}
.search-suggest-price {
  flex: none;
  font-size: var(--fs-base);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* A product found by its description: the words that matched, under its name (UXM-17). */
.search-suggest-why {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}
/* Nothing found: one quiet row, not an empty panel (UXM-17). */
.search-suggest--empty {
  gap: 2px;
  padding: var(--sp-3) var(--sp-4);
}
.search-suggest-none {
  color: var(--text-primary);
  font-weight: var(--fw-medium);
  overflow-wrap: anywhere;
}
.search-suggest-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

/* ── Reset & base ── */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}
html,
body {
  height: 100%;
  overscroll-behavior: none;
}
body {
  font-family: 'DM Sans', sans-serif;
  background: #f0f4f8;
  -webkit-tap-highlight-color: transparent;
  scrollbar-width: thin;
  scrollbar-color: #cbd5e1 transparent;
}
::-webkit-scrollbar {
  display: none;
}

/* Accessibility */
:focus {
  outline: none;
}
:focus-visible {
  box-shadow: var(--focus-ring);
  border-radius: inherit;
}

/* ── CSS Variables ── */
:root {
  /* Colors */
  --accent: rgb(33, 150, 243);
  --accent-dark: rgb(21, 101, 192);
  --accent-light: rgba(33, 150, 243, 0.1);
  --accent-mid: rgba(33, 150, 243, 0.18);
  --accent-border: rgba(33, 150, 243, 0.28);
  --accent-glow: rgba(33, 150, 243, 0.25);
  /* Derived from the brand color so text stays readable (accentPalette() recomputes them per business):
     --accent-text is the accent for text on white (≥ 4.5:1), --accent-fill fills a button that carries text, and
     --on-accent is that text's color (white, or ink on a light brand). */
  --accent-text: rgb(23, 105, 170);
  --accent-fill: rgb(26, 120, 194);
  --on-accent: #ffffff;
  --bg-page: #f8fafc;
  --bg-card: #ffffff;
  --bg-muted: #f1f5f9;
  --bg-input: #ffffff;
  --border: #cbd5e1;
  --text-primary: #020617;
  --text-secondary: #1e293b;
  --text-muted: #64748b;
  --text-faint: #94a3b8;
  --bot-bubble: #ffffff;
  --bot-bubble-border: #cbd5e1;
  --danger: #ef4444;
  --danger-light: #fee2e2;
  /* The page menu's outcome boxes ("Check your email", a warning): text ≥ 4.5:1 on its light shade. */
  --success: #15803d;
  --success-light: #dcfce7;
  --warning: #b45309;
  --warning-light: #fef3c7;
  /* Hairlines: slate at low alpha, so they sit on white and on the brand wash alike. */
  --hairline: rgba(15, 23, 42, 0.07);
  --hairline-strong: rgba(15, 23, 42, 0.14);

  /* Fonts */
  --font-sans: 'DM Sans', sans-serif;
  --font-mono: 'DM Mono', monospace;

  /* Type Scale (minor-third 1.25×, base 14px) */
  --fs-xs: 10px;
  --fs-sm: 12px;
  --fs-base: 14px;
  --fs-md: 16px;
  --fs-lg: 20px;
  --fs-xl: 22px;
  --fs-2xl: 26px;
  /* The conversation's bubbles, on every screen. */
  --fs-chat: 15px;

  /* Line Heights */
  --lh-tight: 1.2;
  --lh-snug: 1.35;
  --lh-base: 1.55;
  --lh-loose: 1.72;

  /* Font Weights */
  --fw-regular: 400;
  --fw-medium: 500;
  --fw-semibold: 600;
  --fw-bold: 700;
  --fw-extrabold: 800;

  /* Letter Spacing */
  --ls-tight: -0.01em;
  --ls-normal: 0em;
  --ls-wide: 0.04em;
  --ls-wider: 0.08em;

  /* Spacing Scale (base-4) */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 20px;
  --sp-6: 24px;
  --sp-7: 28px;
  --sp-8: 32px;
  --sp-10: 40px;
  --sp-12: 48px;

  /* Border Radius */
  --r-sm: 6px;
  --r-md: 10px;
  --r-lg: 14px;
  --r-xl: 20px;
  --r-2xl: 24px;
  --r-full: 9999px;
  /* Chat bubbles and cards; the tail is the corner that points at the sender. */
  --r-bubble: 18px;
  --r-tail: 6px;

  /* Shadows (Depth) */
  /* Tinted slate, not black: they read as the page's own shade. */
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md:
    0 2px 4px rgba(15, 23, 42, 0.08), 0 1px 2px rgba(15, 23, 42, 0.05);
  --shadow-lg:
    0 4px 8px rgba(15, 23, 42, 0.1), 0 2px 4px rgba(15, 23, 42, 0.06);
  --shadow-xl:
    0 12px 24px rgba(15, 23, 42, 0.14), 0 4px 8px rgba(15, 23, 42, 0.08);
  --shadow-glow: 0 2px 8px var(--accent-glow);

  /* Z-Index Scale */
  --z-base: 1;
  --z-above: 10;
  --z-overlay: 100;
  --z-modal: 200;
  --z-max: 300;

  /* Transitions */
  --trans-fast: 0.15s ease;
  --trans-base: 0.25s ease;
  --trans-slow: 0.38s ease;

  /* Focus States */
  --focus-ring: 0 0 0 2px var(--bg-page), 0 0 0 4px var(--accent);

  /* Font Rendering */
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ── Animations ── */
@keyframes bounce {
  0%,
  80%,
  100% {
    transform: scale(0.6);
    opacity: 0.4;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}
@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(8px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes slideUp {
  from {
    opacity: 0;
    transform: translateY(22px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes slideUpModal {
  from {
    opacity: 0;
    transform: translateY(100%);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
@keyframes pinPulse {
  0% {
    transform: translate(-50%, -50%) scale(0.5);
    opacity: 0.8;
  }
  100% {
    transform: translate(-50%, -50%) scale(2.2);
    opacity: 0;
  }
}
@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* ════════════════════════════════════════
  APP SHELL
════════════════════════════════════════ */
.app-shell {
  display: flex;
  flex-direction: column;
  height: 100dvh;
  /* A faint wash of the business's colour behind the conversation. */
  background:
    radial-gradient(
      1200px 500px at 50% -10%,
      var(--accent-light),
      transparent 70%
    ),
    var(--bg-page);
  overflow: hidden;
}

/* ════════════════════════════════════════
  HEADER
════════════════════════════════════════ */
.header {
  padding: 13px var(--sp-6);
  border-bottom: 1px solid var(--border);
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  background: var(--bg-card);
  flex-shrink: 0;
  z-index: var(--z-above);
  box-shadow: var(--shadow-sm);
}
.header-brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.header-logo {
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  background: var(--accent);
  color: #ffffff;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
  flex-shrink: 0;
}
.header-name {
  color: var(--text-primary);
  font-weight: var(--fw-extrabold);
  font-size: var(--fs-base);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
}
.header-biz {
  color: var(--text-muted);
  font-size: var(--fs-xs);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 200px;
}
.header-spacer {
  flex: 1;
}
.header-socials {
  display: flex;
  gap: var(--sp-2);
  align-items: center;
}
.social-li {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-li:hover {
  opacity: 1;
  color: #0a66c2;
}
.social-fb {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-fb:hover {
  opacity: 1;
  color: #1877f2;
}
.social-ig {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-ig:hover {
  opacity: 1;
  color: #e1306c;
}
.social-tt {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-tt:hover {
  opacity: 1;
  color: #ff0050;
}
.social-yt {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-yt:hover {
  opacity: 1;
  color: #ff0000;
}
.social-wa {
  color: var(--text-secondary);
  opacity: 0.85;
  transition:
    opacity var(--trans-fast),
    color var(--trans-fast);
}
.social-wa:hover {
  opacity: 1;
  color: #25d366;
}
.header-phone {
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-sm);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-wide);
  text-decoration: none;
  transition: color var(--trans-fast);
}
.header-phone:hover {
  color: var(--accent);
}

/* The business page's header: its content lines up with the conversation's column. */
.chat-header {
  padding: 12px var(--sp-6);
  background: rgba(255, 255, 255, 0.82);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--hairline);
  box-shadow: none;
}
.header-inner {
  max-width: 760px;
  margin: 0 auto;
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--sp-3);
}
.chat-header .header-brand {
  flex: 1;
  min-width: 0;
}
.chat-header .header-logo {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  box-shadow: none;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-size: 14px;
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--ls-tight);
}
.header-titles {
  min-width: 0;
}
.chat-header .header-name {
  font-size: 17px;
  font-weight: var(--fw-bold);
  letter-spacing: -0.02em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* A phone with the bag: no context line, the name on two lines (UX-17). */
/* Two lines that break between words ("Panadería / Doña Rosa", UXM-06), never inside one; a hyphen only where the
   page's language allows it, and a word longer than the line still breaks rather than overflow. */
.chat-header .header-titles--name-only .header-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  white-space: normal;
  overflow-wrap: break-word;
  word-break: normal;
  hyphens: auto;
  line-height: 1.15;
}
.header-context {
  margin: 1px 0 0;
  color: var(--text-muted);
  font-size: 13px;
  line-height: var(--lh-snug);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-shrink: 0;
}
.header-contact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  min-width: 36px;
  justify-content: center;
  padding: 0 var(--sp-3);
  border-radius: var(--r-full);
  border: 1px solid var(--accent-border);
  background: var(--bg-card);
  color: var(--accent-text);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  text-decoration: none;
  white-space: nowrap;
  transition:
    background var(--trans-fast),
    border-color var(--trans-fast);
}
.header-contact:hover {
  background: var(--accent-light);
  border-color: var(--accent);
}
.header-contact--primary {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}
.header-contact--primary:hover {
  background: var(--accent-dark);
  border-color: transparent;
}
/* A single item in the header on a phone (docs/pdr/prd-page-groups.md): a 36px round button (44px hit area, the rule
   at the end), named by its full label; a product shows its picture, or its initial, in place of the icon. */
.header-contact--round {
  width: 36px;
  height: 36px;
  padding: 0;
}
.header-contact-picture {
  width: 34px;
  height: 34px;
  object-fit: cover;
  border-radius: var(--r-full);
}
.header-contact-initial {
  font-size: var(--fs-base);
  line-height: 1;
}

/* The page's ☰ menu (docs/chat-design.md, "Page menu", Q): a 36px round button, the last thing at the header's right
   edge (44px hit area), pressed while its menu is open. The menu is a 320px dropdown under it, aligned to its right
   edge, on a computer; on a phone a bottom sheet over the dimmed page, the two portalled to the body. */
.chat-header {
  position: relative;
}
.page-menu-wrap {
  position: relative;
  flex-shrink: 0;
}
.header-menu-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--r-full);
  background: var(--bg-card);
  color: var(--text-secondary);
  cursor: pointer;
  transition:
    background var(--trans-fast),
    color var(--trans-fast);
}
.header-menu-btn:hover {
  background: var(--bg-muted);
}
.header-menu-btn[aria-expanded='true'] {
  border-color: var(--accent-border);
  background: var(--accent-light);
  color: var(--accent-text);
}
.page-menu-popover {
  position: absolute;
  top: calc(100% + 10px);
  right: -4px;
  z-index: var(--z-modal);
  width: 320px;
  max-height: calc(100dvh - 96px);
  overflow-y: auto;
  padding: 6px;
  border-radius: 16px;
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-xl);
  animation: fadeIn var(--trans-fast);
}
.page-menu-name {
  margin: 0;
  padding: 8px 12px 6px;
  overflow: hidden;
  color: var(--text-muted);
  font-size: 12px;
  font-weight: var(--fw-semibold);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.page-menu,
.page-menu-group {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.page-menu-divider {
  height: 1px;
  margin: 4px 12px;
  background: var(--hairline);
}
.page-menu-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 56px;
  padding: 8px 12px;
  border: none;
  border-radius: 12px;
  background: none;
  color: var(--text-primary);
  font-family: var(--font-sans);
  text-align: left;
  cursor: pointer;
  transition: background var(--trans-fast);
}
.page-menu-item:hover,
.page-menu-item:focus-visible {
  background: var(--bg-muted);
}
.page-menu-item > svg:last-child {
  flex-shrink: 0;
  color: var(--text-faint);
}
.page-menu-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: var(--bg-muted);
  color: var(--text-secondary);
}
.page-menu-icon--accent {
  background: var(--accent-light);
  color: var(--accent-text);
}
.page-menu-words {
  display: flex;
  min-width: 0;
  flex: 1;
  flex-direction: column;
  gap: 2px;
}
.page-menu-title {
  font-size: 15px;
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
}
/* Share and I own this business: the title on one line over its hint, both ellipsed in the 320px popover. */
.page-menu-words .page-menu-title {
  overflow: hidden;
  font-size: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.page-menu-hint {
  overflow: hidden;
  color: var(--text-muted);
  font-size: 13px;
  line-height: var(--lh-snug);
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* A section: its icon and its word, one line. */
.page-menu-item--section {
  min-height: 48px;
  padding-block: 6px;
}
.page-menu-item--section .page-menu-title {
  flex: 1;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* "Follow us": the label over the networks' round icons. */
.page-menu-follow {
  gap: 8px;
  padding: 6px 12px 10px;
}
.page-menu-follow-label {
  color: var(--text-muted);
  font-size: 12px;
  font-weight: var(--fw-semibold);
}
/* Privacy · Terms · Foto: Autor / Unsplash: the page's small print, last in the menu (decision 18). */
.page-menu-legal {
  padding: 4px 12px 8px;
  color: var(--text-muted);
  font-size: 12px;
}
/* Each item brings its "·" (15px) before it and the line starts 15px to the left, its first 15px clipped away: the
   first item of a line, Privacy's or a credit wrapped under Privacy · Terms, shows no dot. (An overflow clip would
   not do: the dots are inside the line's own box.) Only the left edge clips, so the links' 44px hit areas still
   reach above and below. */
.page-menu-legal-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin-left: -15px;
  clip-path: inset(-44px -44px -44px 15px);
}
.page-menu-legal-item {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}
.page-menu-legal-item::before {
  content: '·';
  content: '·' / '';
  display: inline-block;
  width: 15px;
  text-align: center;
}
/* The credit's words flow as text, so a long author's name wraps inside them; its dot hangs in a 15px indent and a
   wrapped line of it starts at the line's visible edge. */
.page-menu-credit {
  display: block;
  min-width: 0;
  padding-left: 15px;
  white-space: normal;
}
.page-menu-credit::before {
  margin-left: -15px;
}
.page-menu-legal-link {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.page-menu-legal-link:hover,
.page-menu-legal-link:focus-visible {
  color: var(--text-secondary);
}
.page-menu-socials {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.page-menu-social {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--r-full);
  background: var(--bg-muted);
  color: var(--text-secondary);
  transition:
    background var(--trans-fast),
    color var(--trans-fast);
}
.page-menu-social:hover,
.page-menu-social:focus-visible {
  background: var(--accent-light);
  color: var(--accent-text);
}
/* On a phone the menu rises from the bottom, across the width, over the page dimmed at slate 45%. */
.page-menu-scrim {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  background: rgba(15, 23, 42, 0.45);
  animation: fadeIn var(--trans-fast);
}
.page-menu-popover--sheet {
  position: fixed;
  top: auto;
  right: 0;
  bottom: 0;
  left: 0;
  width: auto;
  max-height: calc(100dvh - 80px);
  padding: 8px 12px calc(16px + env(safe-area-inset-bottom, 0px));
  border: 0;
  border-radius: 22px 22px 0 0;
  animation: slideUpModal 0.3s ease;
}
.page-menu-grab {
  width: 36px;
  height: 4px;
  margin: 2px auto 6px;
  border-radius: 2px;
  background: var(--border);
}
.page-menu-popover--sheet .page-menu-item--section {
  min-height: 52px;
}
.page-sheet {
  padding: var(--sp-5) var(--sp-5) var(--sp-5);
  font-family: var(--font-sans);
}
.page-sheet-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: 44px;
  margin: -6px var(--sp-10) var(--sp-3) -10px;
}
.page-sheet-back {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: none;
  border-radius: var(--r-full);
  background: none;
  color: var(--text-secondary);
  cursor: pointer;
}
.page-sheet-back:hover {
  background: var(--bg-muted);
}
.page-sheet-title {
  margin: 0;
  color: var(--text-primary);
  font-size: 17px;
  font-weight: var(--fw-bold);
  letter-spacing: -0.01em;
}
.page-sheet-loading {
  height: 320px;
}
.page-sheet-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  min-height: 44px;
  padding: 0 var(--sp-3);
  border: 1px solid var(--hairline-strong);
  border-radius: 22px;
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: var(--fw-semibold);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background var(--trans-fast),
    transform var(--trans-fast);
}
.page-sheet-btn:hover {
  background: var(--bg-muted);
}
.page-sheet-btn:active {
  transform: scale(0.98);
}
.page-sheet-btn--primary {
  border-color: transparent;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.page-sheet-btn--primary:hover {
  background: var(--accent-dark);
}
.page-sheet-btn:disabled {
  cursor: default;
  opacity: 0.6;
  transform: none;
}
.chat-share {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
}
/* Narrower than the card's 320px plus the sheet's padding: the card shrinks with the screen. */
.chat-share .share-card {
  --share-u: min(1px, calc((100vw - 40px) / 320));
}
.chat-share-caption {
  margin: 0 0 var(--sp-1);
  color: var(--text-muted);
  font-size: 13px;
  text-align: center;
}
.chat-share-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-2);
  width: 100%;
}
.chat-share-row .page-sheet-btn {
  padding: 0 6px;
  font-size: 13px;
}
.chat-share-status {
  min-height: 0;
  margin: 0;
  color: var(--danger);
  font-size: 13px;
}
.chat-share-status:empty {
  display: none;
}
.owner-link {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.owner-link p {
  margin: 0;
}
.owner-link-text {
  color: var(--text-secondary);
  font-size: var(--fs-chat);
  line-height: var(--lh-base);
}
.owner-link-box {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  border-radius: 14px;
  background: var(--bg-muted);
  color: var(--text-secondary);
  font-size: 14px;
  line-height: var(--lh-snug);
}
.owner-link-box > svg {
  flex-shrink: 0;
  margin-top: 1px;
}
.owner-link-box--success {
  background: var(--success-light);
  color: var(--success);
}
.owner-link-box--warning {
  background: var(--warning-light);
  color: var(--warning);
}
.owner-link-box-title {
  font-weight: var(--fw-bold);
}
.owner-link-note {
  color: var(--text-muted);
  font-size: 13px;
}
.owner-link-note a {
  color: var(--accent-text);
  font-weight: var(--fw-medium);
}

/* ════════════════════════════════════════
  MESSAGES AREA
════════════════════════════════════════ */
/* Holds the scrolling conversation and the "New message" chip over it. */
.messages-frame {
  flex: 1;
  min-height: 0;
  position: relative;
  display: flex;
  flex-direction: column;
}
.new-message-chip {
  position: absolute;
  bottom: var(--sp-3);
  left: 50%;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 var(--sp-4);
  border-radius: var(--r-full);
  border: 1px solid var(--accent-border);
  background: var(--bg-card);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  animation: fadeUp 0.2s ease backwards;
}
.messages-area {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--sp-6) var(--sp-4) var(--sp-3);
  -webkit-overflow-scrolling: touch;
}
.messages-inner {
  max-width: 760px;
  margin: 0 auto;
}

.msg-row {
  display: flex;
  margin-bottom: var(--sp-4);
  animation: fadeUp 0.3s ease backwards;
}
.msg-row--bot {
  justify-content: flex-start;
}
/* A run of one sender's messages (MessageList's runPositions): close together, one avatar, on the last. */
.msg-row--first,
.msg-row--middle {
  margin-bottom: 3px;
}
.msg-row--card.msg-row--first,
.msg-row--card.msg-row--middle {
  margin-bottom: var(--sp-2);
}
.msg-row--first .bot-avatar,
.msg-row--middle .bot-avatar {
  visibility: hidden;
}
.msg-row--user {
  justify-content: flex-end;
}
.msg-row--card {
  display: flex;
  align-items: flex-end;
  animation: fadeUp 0.4s ease backwards;
}
.msg-row--bot {
  align-items: flex-end;
}
/* Stagger entry for initial load */
.messages-inner > *:nth-child(1) {
  animation-delay: 0ms;
}
.messages-inner > *:nth-child(2) {
  animation-delay: 80ms;
}
.messages-inner > *:nth-child(3) {
  animation-delay: 160ms;
}
.messages-inner > *:nth-child(4) {
  animation-delay: 240ms;
}
.messages-inner > *:nth-child(n + 5) {
  animation-delay: 300ms;
}

.msg-bubble {
  padding: 10px 14px;
  font-size: var(--fs-chat);
  line-height: 1.5;
  text-wrap: pretty;
  font-family: var(--font-sans);
  word-break: break-word;
  overflow-wrap: break-word;
}
.msg-bubble--bot {
  border-radius: var(--r-bubble) var(--r-bubble) var(--r-bubble) var(--r-tail);
  max-width: 78%;
  background: var(--bot-bubble);
  color: var(--text-primary);
  box-shadow: var(--shadow-sm);
}
.msg-bubble--user {
  border-radius: var(--r-bubble) var(--r-bubble) var(--r-tail) var(--r-bubble);
  max-width: 78%;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-weight: var(--fw-medium);
}

/* Inside a run, the corner toward the message above is the tail's too. */
.msg-row--middle .msg-bubble--bot,
.msg-row--last .msg-bubble--bot {
  border-top-left-radius: var(--r-tail);
}
.msg-row--middle .msg-bubble--user,
.msg-row--last .msg-bubble--user {
  border-top-right-radius: var(--r-tail);
}

.msg-card-wrap {
  flex: 1;
  min-width: 0;
  border-radius: var(--r-bubble);
  overflow: hidden;
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-sm);
}
.msg-card-wrap--products {
  background: var(--bg-card);
  padding: var(--sp-2) var(--sp-2) var(--sp-2);
  box-shadow: var(--shadow-sm);
}
/* A row of product cards: each card has its own frame, so the row has none (one frame, not two). */
.msg-card-wrap--products:has(.peek) {
  background: transparent;
  border: none;
  box-shadow: none;
  padding: 2px 2px 6px;
}
.msg-card-wrap > .loc-card,
.msg-card-wrap > .pdf-wrap {
  border-radius: 0;
  border: none;
}
/* A card with its own header (summaries, an order's status, the booking cards): the row's frame is its only one,
   and the header strip runs edge to edge. */
.msg-card-wrap--framed {
  background: var(--bg-card);
  padding: 0;
}
.msg-card-wrap--framed > .osm,
.msg-card-wrap--framed > .osc {
  border: none;
  border-radius: 0;
  box-shadow: none;
  max-width: none;
}
/* An order's status reads best narrow; without :has() it simply spans the column. */
.msg-card-wrap--framed:has(> .osc) {
  flex: 0 1 420px;
}

.typing-row {
  display: flex;
  align-items: flex-end;
  margin-bottom: var(--sp-2);
  animation: fadeUp 0.3s ease;
}
.typing-bubble {
  padding: 10px 14px;
  border-radius: var(--r-bubble) var(--r-bubble) var(--r-bubble) var(--r-tail);
  background: var(--bot-bubble);
  box-shadow: var(--shadow-sm);
}
.typing-dots {
  display: flex;
  gap: var(--sp-1);
  align-items: center;
  padding: var(--sp-1) 0;
}
.typing-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-muted);
  animation: bounce 1.2s infinite;
}

.bot-avatar {
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background: var(--accent-fill);
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--on-accent);
  font-size: 11px;
  font-weight: var(--fw-extrabold);
  letter-spacing: var(--ls-tight);
  flex-shrink: 0;
  margin-right: var(--sp-2);
}
.bot-avatar--sm {
  width: 26px;
  height: 26px;
  margin-right: 7px;
  border-width: 0;
  font-size: 10px;
}

/* "The assistant can't answer": what to do instead, as buttons. */
/* A flow's correction ("Please enter a valid email."): tinted, with an alert icon, so it reads as "fix this". */
.msg-bubble--validation {
  display: flex;
  gap: var(--sp-2);
  align-items: flex-start;
  background: var(--danger-light);
  background: color-mix(in srgb, var(--danger) 7%, var(--bg-card));
  border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
  box-shadow: none;
  color: var(--text-primary);
}
.msg-bubble--validation svg {
  flex-shrink: 0;
  margin-top: 3px;
  color: var(--danger);
}
/* A flow's data-policy line (before it asks for personal data): quiet small text beside the avatar's column, not a
   bubble, so it reads as a condition of the next question rather than a message to answer. */
.msg-policy {
  max-width: min(520px, 100%);
  margin: 0;
  padding: 2px var(--sp-1);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
}
.msg-policy a {
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.msg-bubble--notice p {
  margin: 0;
}
.msg-notice-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: 10px;
}
.msg-notice-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 var(--sp-3);
  border-radius: var(--r-full);
  border: 1px solid var(--accent-border);
  background: var(--bg-card);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  text-decoration: none;
  cursor: pointer;
}
.msg-notice-btn:hover {
  background: var(--accent-light);
}
/* The website button's frame could not open Stripe's tab (docs/pdr/prd-embed-widget.md EMB-15): the words, then
   "Open the payment" as a notice button that opens it in a new tab. */
.chat-pay-blocked p {
  margin: 0 0 10px;
}

/* ════════════════════════════════════════
  INPUT AREA
════════════════════════════════════════ */
/* "Chat by Llyner" under the box of the website button's chat on the free plan (docs/pdr/prd-embed-widget.md EMB-14,
   docs/chat-design.md §18): one centred 12px muted line, "Llyner" a link to Llyner in a new tab. Never outside the frame. */
.chat-byline {
  margin: 0;
  padding: 2px 0 var(--sp-1);
  text-align: center;
  font-size: 12px;
  line-height: var(--lh-base);
  color: var(--text-muted);
}
.chat-byline a {
  color: inherit;
  font-weight: var(--fw-semibold);
  text-decoration: underline;
  text-underline-offset: 2px;
}
/* The page's one message box moves between the chat and a sheet's foot (CS-01): its holders draw no box of their own. */
.movable,
.movable-slot {
  display: contents;
}
.input-area {
  padding: var(--sp-2) var(--sp-6)
    calc(var(--sp-4) + env(safe-area-inset-bottom));
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.9);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--hairline);
  position: relative;
}
.input-inner {
  max-width: 760px;
  margin: 0 auto;
}

.pills-row {
  display: flex;
  gap: var(--sp-2);
  overflow-x: auto;
  padding-bottom: var(--sp-2);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.pills-row::-webkit-scrollbar {
  display: none;
}
/* On a device that hovers, ‹ › at the row's ends while it overflows (UXM-04): a mouse cannot swipe. */
.pills-row-wrap {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}
.pills-row-wrap .pills-row {
  flex: 1;
  min-width: 0;
}
.pills-row-arrow {
  position: relative;
  flex: none;
  width: 32px;
  height: 32px;
  margin-bottom: var(--sp-2);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  color: var(--text-primary);
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    opacity var(--trans-fast);
}
.pills-row-arrow::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}
.pills-row-arrow:hover:not(:disabled) {
  background: var(--accent-light);
  color: var(--accent-text);
}
.pills-row-arrow:disabled {
  opacity: 0.4;
  cursor: default;
}
.pills-row-arrow:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (hover: none) {
  .pills-row-arrow {
    display: none;
  }
}
/* More pills to the right than the row shows: their edge fades, so the row says it scrolls. */
.pills-row--more {
  mask-image: linear-gradient(to right, #000 calc(100% - 40px), transparent);
}
/* Scrolled from its start: the left edge fades too, so the first pill seen is never cut flat (UX-13). */
.pills-row--start {
  mask-image: linear-gradient(to right, transparent, #000 40px);
}
.pills-row--start.pills-row--more {
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 40px,
    #000 calc(100% - 40px),
    transparent
  );
}
.pill {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 6px 14px;
  border-radius: var(--r-full);
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: var(--fw-medium);
  font-family: var(--font-sans);
  letter-spacing: var(--ls-normal);
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color var(--trans-fast),
    border-color var(--trans-fast),
    color var(--trans-fast),
    transform var(--trans-fast);
}
.pill:active:not(:disabled) {
  transform: scale(0.97);
}
.pill:hover:not(:disabled) {
  background: var(--accent-light);
  border-color: var(--accent-border);
  color: var(--accent-text);
}
/* While the assistant answers: the pills stay as they are (no flicker on every reply), they just wait. */
.pill:disabled {
  cursor: progress;
}
.pill--used {
  background: var(--accent-light);
  border-color: var(--accent-border);
  color: var(--accent-text);
}
.pill-icon {
  color: var(--text-muted);
  display: flex;
}
.pill--used .pill-icon {
  color: var(--accent-text);
}
/* The business's main action (the first pill): filled. */
.pill--primary {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
  font-weight: var(--fw-semibold);
}
.pill--primary .pill-icon {
  color: var(--on-accent);
}
.pill--primary:hover:not(:disabled) {
  background: var(--accent-dark);
  border-color: transparent;
  color: var(--on-accent);
}

.input-box {
  background: var(--bg-input);
  border: 1px solid var(--hairline-strong);
  border-radius: 22px;
  padding: 5px 5px 5px var(--sp-4);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  transition:
    border-color var(--trans-fast),
    box-shadow var(--trans-fast);
}
/* The readable shade, not --accent: a light brand (yellow) would leave the focus border invisible on white. */
.input-box:focus-within {
  border-color: var(--accent-text);
}
/* A flow's phone step (docs/pdr/prd-llyner-catalog.md LCA-12): the calling code's select at the left of the text,
   "+57 ▾", 44px, a hairline after it (shared/ui/phone-field.css); it leaves with the step. */
.input-phone-code {
  color: var(--text-secondary);
  font-size: var(--fs-base);
}
.input-textarea {
  flex: 1;
  background: none;
  border: none;
  color: var(--text-primary);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  resize: none;
  font-family: var(--font-sans);
  max-height: 140px;
  overflow-y: auto;
  display: block;
  padding: 0;
  margin: 0;
  outline: none;
}
.input-textarea:focus-visible {
  box-shadow: none;
  outline: none;
}
/* Characters typed out of the 2,000 a message may hold, shown from 1,800 on (QA-0015). */
.input-count {
  align-self: flex-end;
  padding-bottom: var(--sp-2);
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Over the limit (UXM-02): red, with how much is over; the text stays and Send waits. */
.input-count--over {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--danger);
}
.send-btn {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    color var(--trans-fast),
    transform var(--trans-fast);
}
.send-btn--active {
  background: var(--accent-fill);
  color: var(--on-accent);
}
.send-btn--active:active {
  transform: scale(0.88);
  box-shadow: none;
  filter: brightness(1.12);
}
.send-btn--inactive {
  background: transparent;
  color: var(--text-faint);
  cursor: not-allowed;
}
.input-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px var(--sp-3);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  margin-top: 10px;
  font-family: var(--font-sans);
}
.input-footer a {
  color: var(--accent-text);
  font-weight: var(--fw-medium);
}
.input-footer-brand {
  color: var(--text-secondary);
  font-weight: var(--fw-semibold);
}

/* ════════════════════════════════════════
  COVER (docs/chat-design.md, "Cover")
  Every business page opens on its cover: the business's picture (a photo, with a slate veil) or Llyner's own cover
  (decision 19: Ink night and a blue glow, no face since CC-01; dark by default, light as the owner's choice), the
  facts, the heading and the tagline over the 760px chat card. A dark cover (`.cover--dark`: a photo, or Llyner's
  dark one) carries light text and glass controls; Llyner's light one (`.cover--light`) dark text and white controls.
  Chat mode (`.cover--chat`, docs/pdr/prd-cover-card.md CC-10) keeps every backdrop (a photo darker and blurred) and the
  header's look; the light card grows to just under the header and to the bottom, its top edge rising (CC-11). Only Llyner's cover uses Llyner's brand values (docs/brand.md §2); everything else is the chat's tokens.
════════════════════════════════════════ */
.cover {
  --llyner-blue: #1877f2;
  --llyner-blue-deep: #1260d6;
  --llyner-sky: #e8f1fe;
  --llyner-ink: #0f172a;
  --llyner-slate: #475569;
  --llyner-muted: #64748b;
  --llyner-line: #e2e8f0;
  --llyner-mist: #f8fafc;
  /* Llyner's dark cover: its secondary text and its credit over Ink. */
  --llyner-night-soft: #cbd5e1;
  --llyner-night-faint: #94a3b8;
  /* Light text and controls over a veiled photo. */
  --cover-ink: #ffffff;
  --cover-ink-soft: rgba(255, 255, 255, 0.85);
  --cover-glass: rgba(255, 255, 255, 0.14);
  --cover-glass-strong: rgba(255, 255, 255, 0.24);
  --cover-chip: rgba(15, 23, 42, 0.5);
  --cover-chip-strong: rgba(15, 23, 42, 0.65);
  --cover-open: color-mix(in srgb, var(--success) 55%, #ffffff);
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
  color: var(--cover-ink);
  font-family: var(--font-sans);
  background: var(--text-primary);
}
/* Llyner's dark cover: the photo's light-on-dark look, its chips and glass white over Ink instead of slate. */
.cover--llyner.cover--dark {
  --cover-ink-soft: var(--llyner-night-soft);
  --cover-glass: rgba(255, 255, 255, 0.12);
  --cover-glass-strong: rgba(255, 255, 255, 0.2);
  --cover-chip: rgba(255, 255, 255, 0.1);
  --cover-chip-strong: rgba(255, 255, 255, 0.16);
  --cover-open: #86efac;
  background: var(--llyner-ink);
}
.cover--light {
  --cover-ink: var(--llyner-ink);
  --cover-ink-soft: var(--llyner-slate);
  background: var(--llyner-mist);
}
/* The picture, its veil and the chat mode's dim stay put while the cover scrolls on a short phone. */
.cover-bg,
.cover-veil,
.cover-dim {
  position: fixed;
  inset: 0;
  pointer-events: none;
}
.cover-bg {
  overflow: hidden;
  transition:
    filter var(--trans-slow),
    transform var(--trans-slow);
}
.cover-bg-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.cover-veil {
  background: linear-gradient(
    180deg,
    rgba(15, 23, 42, 0.7) 0%,
    rgba(15, 23, 42, 0.4) 40%,
    rgba(15, 23, 42, 0.82) 100%
  );
}
.cover--llyner .cover-veil {
  display: none;
}
.cover-dim {
  background: rgba(15, 23, 42, 0.5);
  opacity: 0;
  transition: opacity var(--trans-slow);
}
.cover--chat .cover-dim {
  opacity: 1;
}
/* Llyner's own ground needs no dimming behind the grown card (CC-10): only a photo is darkened. */
.cover--llyner .cover-dim {
  display: none;
}
.cover--photo.cover--chat .cover-bg {
  filter: blur(16px) saturate(0.9);
  transform: scale(1.08);
}

/* Llyner's cover (decision 19): a soft blue glow over Ink (Mist in the light theme); no face (CC-01). */
.cover-llyner {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: var(--llyner-ink);
}
.cover-llyner-glow {
  position: absolute;
  top: 60px;
  left: 50%;
  width: 630px;
  height: 520px;
  transform: translateX(-50%);
  background: radial-gradient(
    closest-side,
    rgba(24, 119, 242, 0.45),
    rgba(24, 119, 242, 0)
  );
}
.cover-llyner--light {
  background: var(--llyner-mist);
}
.cover-llyner--light .cover-llyner-glow {
  background: radial-gradient(
    closest-side,
    rgba(24, 119, 242, 0.2),
    rgba(24, 119, 242, 0)
  );
}
@media (min-width: 640px) {
  .cover-llyner-glow {
    top: -60px;
    width: 700px;
    height: 560px;
  }
}

/* The header on the cover: transparent, over the backdrop; light on a dark cover, dark on Llyner's light one. */
.chat-header--cover {
  position: relative;
  z-index: 2;
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-bottom-color: transparent;
}
.chat-header--cover .header-inner {
  max-width: 1200px;
}
.chat-header--cover .header-name {
  color: var(--cover-ink);
  font-size: 19px;
}
.chat-header--cover .header-context {
  color: var(--cover-ink-soft);
}
.chat-header--on-dark .header-contact,
.chat-header--on-dark .header-menu-btn,
.chat-header--on-dark .header-bag {
  border: 0;
  background: var(--cover-glass);
  color: #ffffff;
}
.chat-header--on-dark .header-contact:hover,
.chat-header--on-dark .header-menu-btn:hover,
.chat-header--on-dark .header-bag:hover {
  background: var(--cover-glass-strong);
}
/* Call: the one filled contact, white on a dark cover. */
.chat-header--on-dark .header-contact--primary,
.chat-header--on-dark .header-contact--primary:hover {
  background: #ffffff;
  color: var(--text-primary);
}
.chat-header--on-light .header-contact:not(.header-contact--primary),
.chat-header--on-light .header-menu-btn {
  border: 0;
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--llyner-line);
  color: var(--llyner-ink);
}
.chat-header--on-light .header-contact:not(.header-contact--primary):hover,
.chat-header--on-light .header-menu-btn:hover {
  background: var(--accent-light);
}
/* The ☰ while its menu is open: white on a dark cover, the accent's tint on Llyner's light one. */
.chat-header--on-dark .header-menu-btn[aria-expanded='true'] {
  background: #ffffff;
  color: var(--text-primary);
}
.chat-header--on-light .header-menu-btn[aria-expanded='true'] {
  background: var(--accent-light);
  box-shadow: inset 0 0 0 1px var(--accent);
  color: var(--accent-text);
}
.header-status-dot {
  color: var(--text-faint);
}
.header-status-dot--open {
  color: var(--success);
}
.chat-header--on-dark .header-status-dot--open {
  color: var(--cover-open);
}
/* "Mi pedido · 2": the tray, while it holds something. */
.header-bag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-full);
  background: var(--accent-light);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
/* The owner's logo in the tile: whole, on white, with the tile's corners. */
.header-logo--image,
.chat-header .header-logo--image {
  background: var(--bg-card);
}
.header-logo-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
}

.cover-stage {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-2) var(--sp-4) var(--sp-6);
  min-height: 0;
}
.cover-facts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
  margin: 0;
  padding: 0;
  list-style: none;
  max-width: 100%;
}
.cover-facts li {
  min-width: 0;
  max-width: 100%;
}
.cover-fact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  min-height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--r-full);
  background: var(--cover-chip);
  color: #ffffff;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.cover-fact:hover {
  background: var(--cover-chip-strong);
}
.cover-fact-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cover-fact svg {
  flex-shrink: 0;
}
.cover-fact-dot {
  color: var(--text-faint);
}
.cover-fact-dot--open {
  color: var(--cover-open);
}
.cover--light .cover-fact {
  background: var(--bg-card);
  color: var(--llyner-ink);
  box-shadow: inset 0 0 0 1px var(--llyner-line);
}
.cover--light .cover-fact:hover {
  background: var(--accent-light);
}
.cover--light .cover-fact svg {
  color: var(--accent-text);
}
.cover--light .cover-fact-dot--open {
  color: var(--success);
}
.cover-heading {
  margin: 0;
  max-width: 22ch;
  color: var(--cover-ink);
  font-size: clamp(30px, 5vw, 52px);
  font-weight: var(--fw-bold);
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-align: center;
  text-wrap: balance;
}
.cover-tagline {
  margin: -6px 0 0;
  max-width: 56ch;
  color: var(--cover-ink-soft);
  font-size: 17px;
  line-height: 1.45;
  text-align: center;
  text-wrap: balance;
}
.cover--photo .cover-tagline {
  color: rgba(255, 255, 255, 0.92);
}

/* The chat card: the conversation and the composer, 760px, on the cover. */
.cover-card {
  display: flex;
  flex-direction: column;
  width: min(760px, 100%);
  padding: var(--sp-4);
  border-radius: 28px;
  background: var(--bg-page);
  color: var(--text-primary);
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.35);
  transition:
    background-color var(--trans-slow),
    box-shadow var(--trans-slow);
}
/* Chat mode's card has no shadow (`.cover--chat .cover-card`): these are the cover's. */
.cover--llyner.cover--dark:not(.cover--chat) .cover-card {
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.4);
}
.cover--light .cover-card {
  box-shadow:
    0 0 0 1px rgba(15, 23, 42, 0.06),
    0 18px 40px rgba(15, 23, 42, 0.12);
}
.cover-card .messages-frame {
  flex: none;
}
.cover-card .messages-area {
  max-height: min(46vh, 440px);
  padding: 2px 2px var(--sp-2);
  overscroll-behavior: contain;
}
.cover-card .input-area {
  padding: var(--sp-1) 0 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  border-top: 0;
}
.cover-card .input-inner {
  max-width: none;
}
/* The search's results sit over the text box. */
.input-search {
  position: relative;
}

/* Chat mode (docs/pdr/prd-cover-card.md CC-10 – CC-12): the page is one screen; the backdrop and the header stay, and
   the cover's light card grows from where it was to just under the header and down to the bottom, its top edge rising
   (a clip from the bottom, 280ms). Its top is the handle back to the cover. No footer: the card reaches the bottom. */
.cover--chat {
  height: 100dvh;
  overflow: hidden;
}
.cover--chat .cover-stage {
  justify-content: flex-start;
  gap: 0;
  padding-top: var(--sp-2);
  padding-bottom: 0;
}
.cover--chat .cover-card {
  flex: 1;
  min-height: 0;
  padding: 0 var(--sp-5) calc(14px + env(safe-area-inset-bottom));
  border-radius: 28px 28px 0 0;
  box-shadow: 0 -12px 40px rgba(15, 23, 42, 0.3);
  animation: cover-card-grow 280ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.cover--light.cover--chat .cover-card {
  box-shadow:
    0 0 0 1px rgba(15, 23, 42, 0.06),
    0 -12px 40px rgba(15, 23, 42, 0.1);
}
@keyframes cover-card-grow {
  from {
    clip-path: inset(38% 0 0 0 round 28px 28px 0 0);
  }
  to {
    clip-path: inset(0 0 0 0 round 28px 28px 0 0);
  }
}
@keyframes cover-card-fade {
  from {
    opacity: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .cover--chat .cover-card {
    animation: cover-card-fade 150ms ease-out;
  }
}
.cover--chat .cover-footer {
  display: none;
}
.cover--chat .cover-card .messages-frame {
  flex: 1;
}
/* The conversation fades out under the card's top instead of being cut straight across (UX-12): a 24px strip in the
   card's own colour over its top edge. Never a mask on the conversation itself: Chrome then never loads its lazy
   pictures. */
.cover--chat .cover-card .messages-frame::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 1;
  height: 24px;
  pointer-events: none;
  background: linear-gradient(to bottom, var(--bg-page), transparent);
}
.cover--chat .cover-card .messages-area {
  max-height: none;
  /* Room on top keeps the first message clear of the fade at the start. */
  padding-top: var(--sp-4);
}
/* The grown card's top (CC-12): "Back to the start". A phone's sheet handle (tap, or drag it down); on a computer a
   small "⌄ Back to the start" in the same place. */
.cover-card-handle {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  min-height: 44px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-full);
  background: none;
  color: var(--text-secondary);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  touch-action: none;
}
.cover-card-grip {
  display: none;
}
.cover-card-home {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 0 12px;
  border-radius: var(--r-full);
  transition: background-color var(--trans-fast);
}
.cover-card-handle:hover .cover-card-home {
  background: var(--bg-muted);
  color: var(--text-primary);
}
.cover-card-handle:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: -2px;
}

/* The footer's links, under the card. */
.cover-footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  color: var(--cover-ink-soft);
  font-size: var(--fs-sm);
  text-align: center;
}
.cover--photo .cover-footer {
  color: rgba(255, 255, 255, 0.78);
}
.cover--llyner.cover--dark .cover-footer {
  color: var(--llyner-night-faint);
}
.cover--light .cover-footer {
  color: var(--llyner-muted);
}
.cover-footer-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 2px var(--sp-2);
}
.cover-footer-link {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.cover-made {
  margin: 0;
}
.cover-made strong {
  color: var(--cover-ink);
  font-weight: var(--fw-semibold);
}
.cover-made a {
  color: inherit;
  font-weight: var(--fw-medium);
}

/* ════════════════════════════════════════
  HERO CAROUSEL
════════════════════════════════════════ */

/* A 24px hit area: the dots sit too close together for 44px. */

/* ════════════════════════════════════════
  PRODUCTS CARD (N2b peek cards, 2026-10-10; docs/chat-design.md "Products card")
  A row of fixed-width cards that scrolls sideways so the next one peeks in: 220px on a computer (three whole cards
  in the 760px column and the start of the fourth), 250px on a phone (one and the next peeking). Under it "Ver los N
  productos →" and ‹ › (computer) or the position's dots (phone). White cards on any cover; the controls under the row
  turn white on the photo's chat mode.
════════════════════════════════════════ */
.peek {
  width: 100%;
  min-width: 0;
}
.peek-scroll {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  scroll-padding-inline: 2px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  /* Room for the cards' shadow, which the row would otherwise clip. */
  padding: 2px 2px 10px;
  border-radius: var(--r-lg);
}
.peek-scroll::-webkit-scrollbar {
  display: none;
}
.peek-scroll:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
}
.peek-list {
  display: flex;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
}
.peek-card {
  flex: none;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  scroll-snap-align: start;
  border-radius: 18px;
  background: var(--bg-card);
  color: var(--text-primary);
  box-shadow:
    0 0 0 1px var(--hairline),
    var(--shadow-lg);
  animation: fadeUp 0.4s ease backwards;
}
/* Card A (docs/pdr/prd-llyner-profile-and-products.md CS-09): a square photo, cover-fit. */
.peek-card-media {
  position: relative;
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--bg-muted);
  cursor: pointer;
}
.peek-card-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* "1 of 10": the card's place in the row, on the photo. */
.peek-card-count {
  position: absolute;
  top: 10px;
  left: 10px;
  padding: 2px 10px;
  border-radius: var(--r-full);
  background: rgba(15, 23, 42, 0.62);
  color: #ffffff;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 20px;
  font-variant-numeric: tabular-nums;
}
/* ⤢ "See <name>": the product at full height. */
.peek-card-expand {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-full);
  background: var(--bg-card);
  box-shadow: var(--shadow-md);
  color: var(--text-primary);
  cursor: pointer;
}
.peek-card-expand:hover {
  background: var(--bg-muted);
}
.peek-card-expand:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 2px;
}
/* The price as a white tag at the photo's bottom left: the figure 20px bold, its note beside it. */
.peek-card-price {
  position: absolute;
  left: 10px;
  bottom: 10px;
  max-width: calc(100% - 20px);
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 6px 12px;
  border-radius: 12px;
  background: var(--bg-card);
  box-shadow: var(--shadow-md);
  color: var(--text-primary);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.peek-card-figure,
.peek-card-note {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.peek-card-figure {
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
}
.peek-card-note {
  flex: none;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.peek-card-tags {
  position: absolute;
  right: 10px;
  bottom: 10px;
  display: flex;
  gap: 6px;
}
.peek-card-service {
  padding: 3px 10px;
  border-radius: var(--r-full);
  background: var(--bg-card);
  box-shadow: var(--shadow-sm);
  color: var(--accent-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
}
.peek-card-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
  padding: 12px 14px 14px;
}
.peek-card-name {
  margin: 0;
  min-width: 0;
  font-size: 17px;
  font-weight: var(--fw-bold);
  line-height: 1.3;
}
.peek-card-name-btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.peek-card-name-btn:hover {
  color: var(--accent-text);
}
.peek-card-name-btn:focus-visible {
  outline: 2px solid var(--accent-text);
  outline-offset: 1px;
  border-radius: 4px;
}
.peek-card-name-text {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* Two lines of description; none: the line is left out (the row's cards stretch to one height, the foot at the bottom). */
.peek-card-line {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
  color: var(--text-muted);
  font-size: var(--fs-base);
  line-height: 1.4;
}
.peek-card-foot {
  display: flex;
  align-items: center;
  margin-top: auto;
  padding-top: var(--sp-2);
}
.peek-card-foot > * {
  flex: 1;
}
/* The products card's Add is filled in the business colour: the one exception to the tonal card actions. 48px. */
.peek-card-add {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 48px;
  padding: 0 var(--sp-4);
  border: 0;
  border-radius: 24px;
  background: var(--accent-fill);
  color: var(--on-accent);
  font-family: var(--font-sans);
  font-size: var(--fs-chat);
  font-weight: var(--fw-bold);
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.peek-card-add:active {
  transform: scale(0.97);
}
.peek-card-add--added,
.peek-card-add--ask {
  background: var(--bg-card);
  color: var(--accent-text);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
}
.peek-card-foot .qty-stepper--wide {
  height: 48px;
  border-radius: 24px;
}
.peek-under {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  min-height: 44px;
  padding: 0 2px;
}
.peek-see-all {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 14px;
  border: 0;
  border-radius: var(--r-full);
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.peek-see-all:hover {
  background: var(--accent-light);
}
.peek-arrows,
.peek-dots {
  display: flex;
  align-items: center;
  margin-left: auto;
}
.peek-arrows {
  gap: var(--sp-2);
}
.peek-arrow {
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: var(--bg-card);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  color: var(--text-primary);
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    opacity var(--trans-fast);
}
.peek-arrow:hover:not(:disabled) {
  background: var(--accent-light);
  color: var(--accent-text);
}
.peek-arrow:disabled {
  opacity: 0.4;
  cursor: default;
}
.peek-dots {
  gap: 5px;
}
.peek-dot {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: var(--text-faint);
  transition:
    width var(--trans-base),
    background-color var(--trans-base);
}
.peek-dot--on {
  width: 18px;
  background: var(--accent-text);
}

/* ════════════════════════════════════════
  PRODUCT MODAL
════════════════════════════════════════ */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-modal);
  padding: var(--sp-5);
  animation: fadeIn var(--trans-fast);
}
.modal-sheet {
  background: var(--bg-card);
  border-radius: var(--r-2xl);
  width: min(420px, 100%);
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-xl);
  border: 1px solid var(--hairline);
  animation: slideUp var(--trans-base);
  position: relative;
  z-index: var(--z-modal);
}
.modal-drag-handle {
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  margin: var(--sp-3) auto 0;
}
.modal-close {
  position: absolute;
  top: var(--sp-4);
  right: var(--sp-3);
  z-index: var(--z-above);
  width: 36px;
  height: 36px;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid var(--hairline-strong);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-sm);
  transition:
    background-color var(--trans-fast),
    color var(--trans-fast);
}
.modal-close:hover {
  background: var(--bg-muted);
  color: var(--text-primary);
}

.modal-body {
  padding: var(--sp-6) var(--sp-7) var(--sp-7);
}
/* In the order: the stepper takes Add's place and width (UXM-11). */

/* ════════════════════════════════════════
  LOCATION CARD
════════════════════════════════════════ */
.loc-card {
  width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--border);
  box-shadow: var(--shadow-md);
}
.loc-map-wrap {
  position: relative;
  overflow: hidden;
  background: #e8f0fe;
}
.loc-map-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.loc-map-vignette {
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse at center,
    transparent 50%,
    rgba(255, 255, 255, 0.4) 100%
  );
  pointer-events: none;
}
.loc-map-fade {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 50px;
  background: linear-gradient(to top, rgba(255, 255, 255, 0.95), transparent);
  pointer-events: none;
}
.loc-pin-wrap {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
.loc-pin-pulse {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  background: var(--accent-mid);
}
.loc-pin-pulse--outer {
  width: 40px;
  height: 40px;
  transform: translate(-50%, -50%);
  animation: pinPulse 2s ease-out infinite;
}
.loc-pin-pulse--inner {
  width: 24px;
  height: 24px;
  transform: translate(-50%, -50%);
  animation: pinPulse 2s ease-out infinite 0.4s;
}
.loc-pin-dot {
  position: relative;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--accent);
  border: 2.5px solid white;
  box-shadow: var(--shadow-glow);
  z-index: var(--z-above);
}
.loc-coords {
  position: absolute;
  bottom: var(--sp-2);
  right: var(--sp-2);
  background: rgba(255, 255, 255, 0.88);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  padding: 2px 7px;
  font-size: 9px;
  color: var(--text-muted);
  font-family: var(--font-mono);
}
.loc-body {
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
}
.loc-body-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: var(--sp-2);
}
.loc-biz-name {
  color: var(--text-primary);
  font-size: var(--fs-md);
  font-weight: var(--fw-extrabold);
  margin: 0 0 2px;
  letter-spacing: var(--ls-tight);
}
.loc-landmark {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.loc-copy-btn {
  min-height: 32px;
  border-radius: var(--r-md);
  padding: 0 10px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
  transition: all var(--trans-fast);
  font-family: var(--font-sans);
}
.loc-copy-btn--default {
  background: var(--bg-muted);
  border: 1px solid var(--border);
  color: var(--text-secondary);
}
.loc-copy-btn--copied {
  background: var(--accent-light);
  border: 1px solid var(--accent-border);
  color: var(--accent-text);
}
.loc-divider {
  height: 1px;
  background: var(--border);
  margin-bottom: 6px;
}
.loc-info-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.loc-info-row {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  padding: 6px var(--sp-1);
  border-radius: var(--r-sm);
}
.loc-info-row--link {
  color: inherit;
  text-decoration: none;
  min-height: 44px;
  align-items: center;
}
.loc-info-row--link:hover {
  background: var(--bg-muted);
}
.loc-info-row--link .loc-info-primary {
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
}
.loc-info-icon {
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--accent-text);
}
.loc-info-primary {
  color: var(--text-primary);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
}
.loc-info-secondary {
  color: var(--text-secondary);
  font-size: var(--fs-sm);
}
.loc-directions {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  margin-top: var(--sp-3);
  min-height: 44px;
  padding: var(--sp-2) 0;
  border-radius: 22px;
  background: var(--accent-light);
  color: var(--accent-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  transition: background-color var(--trans-fast);
}
.loc-directions:hover {
  background: var(--accent-mid);
}

/* ════════════════════════════════════════
  PROFILE PANEL
════════════════════════════════════════ */
.profile-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.35);
  backdrop-filter: blur(6px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: var(--z-overlay);
  animation: fadeIn var(--trans-fast);
}
.profile-sheet {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  width: min(520px, 95vw);
  max-height: 85vh;
  overflow-y: auto;
  padding: var(--sp-8);
  animation: slideUp var(--trans-base);
  box-shadow: var(--shadow-xl);
  position: relative;
  z-index: var(--z-overlay);
}
.profile-drag-handle {
  width: 36px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  margin: 0 auto var(--sp-4);
}
.profile-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 22px;
}
.profile-title {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-tight);
}
.profile-subtitle {
  margin: 3px 0 0;
  color: var(--text-secondary);
  font-size: var(--fs-sm);
}
.profile-close-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px;
}
.profile-field {
  margin-bottom: var(--sp-4);
}
.field-label {
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  margin-bottom: 5px;
  display: block;
  font-family: var(--font-mono);
  font-weight: var(--fw-medium);
}
.field-input,
.field-textarea {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: var(--sp-2) 13px;
  color: var(--text-primary);
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
  transition: border-color var(--trans-fast);
  font-family: var(--font-sans);
}
.field-input:focus,
.field-textarea:focus {
  border-color: var(--accent);
}
.field-textarea {
  resize: vertical;
}
.profile-socials {
  border-top: 1px solid var(--border);
  padding-top: 18px;
  margin-bottom: 18px;
}
.profile-socials-title {
  font-size: var(--fs-xs);
  color: var(--text-secondary);
  text-transform: uppercase;
  letter-spacing: var(--ls-wider);
  margin-bottom: 14px;
  display: block;
  font-family: var(--font-mono);
  font-weight: var(--fw-medium);
}
.profile-social-row {
  margin-bottom: var(--sp-3);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.profile-save-btn {
  width: 100%;
  padding: 13px;
  border-radius: var(--r-lg);
  color: white;
  border: none;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  transition: all var(--trans-base);
  box-shadow: var(--shadow-md);
  font-family: var(--font-sans);
}
.profile-save-btn--default {
  background: var(--accent);
}
.profile-save-btn--saved {
  background: #10b981;
}

/* ════════════════════════════════════════
  LINKS CARD
════════════════════════════════════════ */
/* links card: InlineLinksCard (.lk-*), its player (LinkEmbed), a link's pill and the pictures' full-screen viewer
   (docs/chat-design.md). The size comes from React (.lk-wrap--one/two/grid/rows, .lk-tile--wide), never from :has().
   One frame per card: each tile carries its own, the rows' list one for all, so the row (msg-card-wrap--links) has
   none. */
.msg-card-wrap--links {
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}
.msg-card-wrap--links > .msg-bubble--lead {
  width: fit-content;
  max-width: 100%;
}
.lk-wrap {
  width: 100%;
  max-width: 420px;
}
.lk-wrap--rows {
  max-width: 480px;
}
.lk-grid,
.lk-rows {
  list-style: none;
  margin: 0;
  padding: 0;
}
.lk-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sp-2);
}
.lk-grid--one {
  grid-template-columns: minmax(0, 1fr);
}
.lk-tile {
  min-width: 0;
}
.lk-tile--wide {
  grid-column: 1 / -1;
}

/* A card: a link (<a>), a video's facade (<button>) or its player. */
.lk-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
  font: inherit;
  text-align: left;
  text-decoration: none;
  color: var(--text-primary);
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  cursor: pointer;
  transition:
    border-color var(--trans-fast),
    transform var(--trans-fast);
}
.lk-wrap--one .lk-card {
  border-radius: var(--r-bubble);
}
a.lk-card:hover,
.lk-card--facade:hover {
  border-color: var(--accent-border);
}
a.lk-card:active,
.lk-card--facade:active {
  transform: scale(0.98);
}
.lk-card--playing {
  cursor: auto;
}

/* The picture: ours, cropped; the site's icon as a tile, never stretched; or the site's initial. */
.lk-media {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
  background: var(--bg-muted);
}
.lk-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.lk-media--icon img {
  width: 48px;
  height: 48px;
  object-fit: contain;
}
.lk-media--initial {
  background: var(--accent-light);
  color: var(--accent-text);
}
/* A known site without a picture: its icon on the muted tint (UXM-19), as the ☰ menu draws the networks. */
.lk-media--site {
  background: var(--bg-muted);
  color: var(--text-secondary);
}
.lk-site {
  display: inline-flex;
  line-height: 0;
}
.lk-thumb .lk-site svg {
  width: 22px;
  height: 22px;
}
.lk-initial {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-bold);
  line-height: 1;
}
.lk-picture {
  width: 100%;
  aspect-ratio: 1;
}
.lk-tile--wide .lk-picture {
  aspect-ratio: 1.91;
}
/* A short, a TikTok or a reel alone: 9:16, at most 320px tall, centred on the muted band. */
.lk-tile--vertical .lk-picture {
  aspect-ratio: auto;
  height: 320px;
}
.lk-tile--vertical .lk-picture img {
  width: auto;
  aspect-ratio: 9 / 16;
}
.lk-tile--vertical .lk-media--icon img {
  width: 48px;
  height: 48px;
}
/* A tile without a picture: a band with the site's initial, not a square of empty colour. Only where no tile beside it
   has a picture (a tile across its row, or a card with none: .lk-wrap--no-pictures, set in React), so a row of tiles
   keeps one height. */
.lk-wrap--one .lk-picture.lk-media--initial,
.lk-tile--wide .lk-picture.lk-media--initial,
.lk-tile--vertical .lk-picture.lk-media--initial,
.lk-wrap--one .lk-picture.lk-media--site,
.lk-tile--wide .lk-picture.lk-media--site,
.lk-tile--vertical .lk-picture.lk-media--site {
  aspect-ratio: auto;
  height: 88px;
}
/* No tile of the card has a picture: a shorter band, so the card is its words, not empty colour (UXM-19). */
.lk-wrap--no-pictures .lk-picture.lk-media--initial,
.lk-wrap--no-pictures .lk-picture.lk-media--site {
  aspect-ratio: auto;
  height: 56px;
}
.lk-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--r-md);
}
.lk-thumb.lk-media--icon img {
  width: 32px;
  height: 32px;
}
.lk-thumb .lk-initial {
  font-size: var(--fs-lg);
}

/* The facade's play button, and the badge of a video that opens on its site. */
.lk-play,
.lk-badge {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(15, 23, 42, 0.62);
  color: white;
}
.lk-play {
  inset: 0;
  margin: auto;
  width: 44px;
  height: 44px;
}
.lk-wrap--one .lk-play {
  width: 56px;
  height: 56px;
}
.lk-thumb .lk-play {
  width: 32px;
  height: 32px;
}
.lk-badge {
  left: var(--sp-2);
  bottom: var(--sp-2);
  width: 24px;
  height: 24px;
}
.lk-thumb .lk-badge {
  left: 4px;
  bottom: 4px;
  width: 20px;
  height: 20px;
}

.lk-body {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding: var(--sp-2) 10px 10px;
}
.lk-wrap--one .lk-body {
  padding: 10px 14px 12px;
}
.lk-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  overflow-wrap: anywhere;
}
.lk-wrap--one .lk-title {
  font-size: var(--fs-chat);
}
.lk-meta {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.lk-meta svg {
  flex-shrink: 0;
}
.lk-meta-text {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Five links and more: rows, one frame for all, hairline dividers. */
.lk-rows {
  background: var(--bg-card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-bubble);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.lk-row + .lk-row {
  border-top: 1px solid var(--hairline);
}
.lk-row .lk-card {
  border: none;
  border-radius: 0;
  box-shadow: none;
}
.lk-row-main {
  flex-direction: row;
  align-items: center;
  gap: var(--sp-3);
  min-height: 72px;
  padding: var(--sp-2) var(--sp-3);
}
.lk-row-main:active {
  transform: none;
}
.lk-row-main .lk-body {
  flex: 1;
  padding: 0;
}
.lk-row-main:hover {
  background: var(--bg-muted);
}
.lk-row-go {
  display: flex;
  flex-shrink: 0;
  color: var(--text-muted);
}
.lk-row .lk-card--playing {
  padding: var(--sp-2) var(--sp-3) 0;
}
.lk-row .lk-card--playing .lk-body {
  padding: var(--sp-2) 0 0;
}

/* The player, loaded on the tap, with the link to its site always under it. */
.lk-embed {
  display: flex;
  flex-direction: column;
}
.lk-player {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--text-primary);
}
.lk-player--vertical {
  align-self: center;
  width: min(100%, 280px);
  aspect-ratio: 9 / 16;
}
.lk-row .lk-player {
  border-radius: var(--r-md);
  overflow: hidden;
}
.lk-player iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.lk-open {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  min-height: 44px;
  padding: 0 10px;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  text-decoration: none;
}
.lk-wrap--one .lk-open {
  padding: 0 14px;
}
.lk-row .lk-open {
  padding: 0;
}
.lk-open:hover {
  text-decoration: underline;
}

/* A link's pill: an <a> that looks like the other pills; it waits (aria-disabled) while the assistant types. */
a.pill {
  text-decoration: none;
}
.pill[aria-disabled='true'] {
  pointer-events: none;
  cursor: progress;
}

/* A tap on the hero's picture: it opens full screen in the products' gallery. Below the arrows and dots, which come
   after it. */

/* ════════════════════════════════════════
  PDF PREVIEW
════════════════════════════════════════ */
.pdf-wrap {
  width: 100%;
  background: var(--bg-card);
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--border);
}
.pdf-header {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) 14px var(--sp-2);
  border-bottom: 1px solid var(--border);
}
.pdf-icon-badge {
  width: 34px;
  height: 34px;
  border-radius: var(--sp-2);
  background: var(--bg-muted);
  border: 1px solid var(--border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-secondary);
  flex-shrink: 0;
}
.pdf-header-info {
  flex: 1;
  min-width: 0;
}
.pdf-filename {
  color: var(--text-primary);
  font-size: var(--fs-base);
  font-weight: var(--fw-extrabold);
  line-height: var(--lh-tight);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pdf-meta {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-family: var(--font-sans);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--ls-wide);
  margin-top: 1px;
}
.pdf-preview-area {
  position: relative;
  height: 200px;
  overflow: hidden;
  background: #f8f9fa;
  cursor: pointer;
}
.pdf-preview-area:hover .pdf-preview-overlay {
  opacity: 1;
}
.pdf-preview-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  display: block;
}
.pdf-preview-overlay {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, 0.45);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity var(--trans-fast);
}
.pdf-open-hint {
  background: white;
  border-radius: var(--r-md);
  padding: var(--sp-2) var(--sp-4);
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  box-shadow: var(--shadow-md);
}
.pdf-footer {
  padding: var(--sp-2) 14px;
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}
.pdf-open-btn {
  flex: 1;
  min-height: 44px;
  padding: 9px;
  border-radius: 22px;
  background: var(--accent-light);
  color: var(--accent-text);
  border: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: var(--font-sans);
  transition: background var(--trans-fast);
}
.pdf-open-btn:hover {
  background: var(--accent-mid);
}
/* On a computer the button is as wide as its words need, not the card's 720px. */
@media (min-width: 640px) {
  .pdf-open-btn {
    flex: 0 1 260px;
  }
}
.pdf-download-btn {
  width: 44px;
  height: 44px;
  border-radius: var(--r-full);
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  color: var(--text-secondary);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background-color var(--trans-fast),
    color var(--trans-fast);
  flex-shrink: 0;
}
.pdf-download-btn:hover {
  background: var(--accent-light);
  border-color: var(--accent-border);
  color: var(--accent-text);
}

/* PDF full-screen modal */
.pdf-modal-backdrop {
  position: fixed;
  inset: 0;
  /* Opaque: a full-screen viewer owns the screen (at 92% the page's header read through the bar). */
  background: rgb(15, 23, 42);
  display: flex;
  flex-direction: column;
  z-index: var(--z-max);
  animation: fadeIn var(--trans-fast);
}
.pdf-modal-bar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5);
  background: rgba(255, 255, 255, 0.06);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  flex-shrink: 0;
}
.pdf-modal-title {
  color: white;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pdf-modal-close {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: white;
  cursor: pointer;
  border-radius: var(--r-full);
  min-height: 36px;
  padding: 0 14px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-sans);
  transition: background var(--trans-fast);
  flex-shrink: 0;
}
.pdf-modal-close:hover {
  background: rgba(255, 255, 255, 0.2);
}
.pdf-modal-iframe {
  flex: 1;
  border: none;
  display: block;
}

/* ════════════════════════════════════════
  LOADER
════════════════════════════════════════ */
/* The business page while it loads (ChatSkeleton): the chat's shape, shimmering. */
@keyframes shimmer {
  from {
    background-position: 100% 0;
  }
  to {
    background-position: -100% 0;
  }
}
.skeleton-block {
  display: block;
  border-radius: var(--r-sm);
  background: linear-gradient(
    90deg,
    var(--bg-muted) 25%,
    var(--hairline) 50%,
    var(--bg-muted) 75%
  );
  background-size: 200% 100%;
  animation: shimmer 1.4s ease-in-out infinite;
}
/* A business page that could not load (QA-0017): the message and Try again, centred in the page's own frame. */
.page-load-failed {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-4);
  padding: var(--sp-6);
  text-align: center;
  color: var(--text-secondary);
}
/* Whose page it is, over the message (UXM-21). */
.page-load-failed-name {
  margin: 0;
  color: var(--text-primary);
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  letter-spacing: -0.02em;
}
.page-load-failed p {
  margin: 0;
}
.page-load-failed-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-2);
}
.chat-skeleton-header {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  max-width: 760px;
  margin: 0 auto;
  padding: 12px var(--sp-6);
}
.chat-skeleton-logo {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  flex-shrink: 0;
}
.chat-skeleton-titles {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1;
}
.chat-skeleton-line {
  height: 12px;
  width: 45%;
}
.chat-skeleton-line--short {
  width: 30%;
}
.skeleton-bubble {
  height: 64px;
  width: 78%;
  margin-left: 40px;
  border-radius: var(--r-bubble) var(--r-bubble) var(--r-bubble) var(--r-tail);
}
.skeleton-bubble--short {
  height: 44px;
  width: 55%;
}
.chat-skeleton-input {
  height: 48px;
  border-radius: 22px;
}
/* The cover's skeleton (UXM-20): the header over the cover, two fact pills, the heading's bar and the card. */
.chat-skeleton .chat-skeleton-header {
  position: relative;
  z-index: 1;
  max-width: 1200px;
}
.chat-skeleton-facts {
  display: flex;
  gap: var(--sp-2);
}
.chat-skeleton-fact {
  width: 150px;
  height: 36px;
  border-radius: var(--r-full);
}
.chat-skeleton-fact--short {
  width: 110px;
}
.chat-skeleton-heading {
  width: min(420px, 80%);
  height: 40px;
  border-radius: var(--r-md);
}
.chat-skeleton-card {
  gap: var(--sp-3);
}
.chat-skeleton-card .skeleton-bubble {
  margin-left: 0;
}
/* Over a dark cover the blocks are glass, not the light page's grey. */
.chat-skeleton.cover--dark .chat-skeleton-header .skeleton-block,
.chat-skeleton.cover--dark .chat-skeleton-facts .skeleton-block,
.chat-skeleton.cover--dark .chat-skeleton-heading {
  background: linear-gradient(
    90deg,
    var(--cover-glass) 25%,
    var(--cover-glass-strong) 50%,
    var(--cover-glass) 75%
  );
  background-size: 200% 100%;
}
@media (max-width: 639px) {
  .chat-skeleton-header {
    padding: 12px 14px;
  }
}

.loader-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
  width: 100vw;
  background: var(--bg-page);
}

.loader-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid var(--accent-light);
  border-top: 4px solid var(--accent);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

/* ════════════════════════════════════════
  ORDER FLOW
════════════════════════════════════════ */
.order-action-pills {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-3);
  flex-wrap: wrap;
}
.order-action-pill {
  flex: 1;
  min-width: 120px;
  padding: var(--sp-3) var(--sp-4);
  border-radius: var(--r-lg);
  border: 1.5px solid var(--accent-border);
  background: var(--accent-light);
  color: var(--accent-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  font-family: var(--font-sans);
  cursor: pointer;
  transition: all var(--trans-fast);
  min-height: 44px;
}
.order-action-pill:hover {
  background: var(--accent-mid);
  border-color: var(--accent);
}
.order-action-pill:active {
  transform: scale(0.97);
}

/* Order Summary Message (osm) */
.osm {
  border: 1px solid var(--bot-bubble-border);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-card);
  min-width: 240px;
}
.osm-header {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.osm-header-icon {
  color: var(--accent);
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.osm-header-title {
  flex: 1;
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  letter-spacing: var(--ls-tight);
}
.osm-header-badge {
  background: var(--accent-fill);
  color: var(--on-accent);
  font-size: var(--fs-sm);
  font-weight: var(--fw-bold);
  width: 18px;
  height: 18px;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  line-height: 1;
}
.osm-items {
  display: flex;
  flex-direction: column;
  padding: var(--sp-2) 0;
}
.osm-item {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4);
}
.osm-item + .osm-item {
  border-top: 1px solid var(--border);
}
.osm-item-img {
  width: 38px;
  height: 38px;
  object-fit: cover;
  border-radius: var(--r-sm);
  flex-shrink: 0;
  border: 1px solid var(--border);
}
.osm-item-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.osm-item-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.osm-item-unit {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.osm-price {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex-shrink: 0;
}
.osm-price-currency {
  font-size: 0.75em;
  font-weight: var(--fw-bold);
  margin-right: 1px;
  opacity: 0.6;
}
.osm-total {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-muted);
  border-top: 1px solid var(--border);
}
.osm-total-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.osm-total .osm-price {
  font-size: var(--fs-base);
  font-weight: var(--fw-extrabold);
  color: var(--accent-text);
}
.osm-hint {
  margin: 0;
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.osm-note {
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.osm-divider {
  height: 1px;
  background: var(--border);
}
.osm-contact {
  padding: var(--sp-3) var(--sp-4);
}
.osm-contact-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  margin-bottom: var(--sp-2);
}
.osm-contact-rows {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
}
.osm-contact-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-sm);
  color: var(--text-secondary);
}
.osm-contact-row svg {
  color: var(--text-muted);
  flex-shrink: 0;
}
.osm-contact-name {
  font-weight: var(--fw-semibold);
  color: var(--text-primary);
}
.osm-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border-top: 1px solid var(--border);
}
.osm-btn {
  width: 100%;
  padding: var(--sp-3);
  border: none;
  border-radius: var(--r-md);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  font-family: var(--font-sans);
  transition: all var(--trans-fast);
}
.osm-btn--confirm {
  min-height: 44px;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.osm-btn--confirm:hover {
  background: var(--accent-dark);
}
.osm-btn--cancel {
  min-height: 44px;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  padding: var(--sp-1);
}
.osm-btn--cancel:hover {
  color: var(--text-secondary);
}

/* Order status card (osc): an order as its buyer follows it */
.osc {
  border: 1px solid var(--bot-bubble-border);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--bg-card);
  min-width: 240px;
  max-width: 420px;
  font-size: var(--fs-base);
  color: var(--text-secondary);
}
.osc p {
  margin: 0;
}
.osc-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.osc-header-icon {
  display: flex;
  color: var(--accent-text);
}
.osc-header-title {
  flex: 1;
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  letter-spacing: var(--ls-wide);
  white-space: nowrap;
}
.osc-status {
  padding: 2px var(--sp-2);
  border-radius: var(--r-full);
  background: var(--accent-fill);
  color: var(--on-accent);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}
.osc-status--cancelled,
.osc-status--completed {
  background: var(--bg-muted);
  color: var(--text-secondary);
  border: 1px solid var(--border);
}
.osc-steps {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  list-style: none;
}
.osc-step {
  display: grid;
  grid-template-columns: 12px 1fr auto;
  align-items: center;
  gap: var(--sp-2);
  color: var(--text-muted);
}
.osc-step-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--r-full);
  border: 2px solid var(--border);
  background: var(--bg-card);
}
.osc-step--done .osc-step-dot {
  border-color: var(--accent-fill);
  background: var(--accent-fill);
}
.osc-step--current .osc-step-dot {
  border-color: var(--accent-fill);
  box-shadow: 0 0 0 3px var(--accent-mid);
}
.osc-step--done,
.osc-step--current {
  color: var(--text-secondary);
}
.osc-step--current .osc-step-label {
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}
.osc-step-at {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  white-space: nowrap;
}
.osc-lines {
  display: grid;
  gap: var(--sp-2);
  margin: 0;
  padding: var(--sp-3) var(--sp-4);
  list-style: none;
  border-top: 1px solid var(--border);
}
.osc-lines li {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  overflow-wrap: anywhere;
}
.osc-amount {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.osc-total {
  padding-top: var(--sp-2);
  border-top: 1px solid var(--border);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
}
.osc-fact,
.osc-note,
.osc-block {
  padding: var(--sp-2) var(--sp-4);
}
.osc-fact {
  border-top: 1px solid var(--border);
  font-weight: var(--fw-semibold);
}
.osc-note {
  background: var(--bg-muted);
  overflow-wrap: anywhere;
}
.osc-note--warning {
  background: var(--accent-light);
  color: var(--text-primary);
}
.osc-block {
  display: grid;
  gap: 2px;
  overflow-wrap: anywhere;
}
.osc-block-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: var(--ls-wide);
}
.osc-pre {
  white-space: pre-line;
}
.osc-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent-text);
  font-weight: var(--fw-semibold);
}
.osc-actions {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border-top: 1px solid var(--border);
}
.osc-ask {
  color: var(--text-primary);
}
.osc-btn {
  width: 100%;
  min-height: 44px;
  padding: var(--sp-2) var(--sp-3);
  border-radius: 22px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  font-family: var(--font-sans);
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.osc-btn:hover:not(:disabled) {
  background: var(--bg-muted);
}
.osc-btn:active:not(:disabled) {
  transform: scale(0.98);
}
/* Cancel order: a secondary button whose words carry the risk. */
.osc-btn--danger {
  color: var(--danger);
}
.osc-btn--danger:hover:not(:disabled) {
  background: var(--danger-light);
}
.osc-btn--primary {
  border-color: transparent;
  background: var(--accent-fill);
  color: var(--on-accent);
}
.osc-btn--primary:hover:not(:disabled) {
  background: var(--accent-dark);
}
.osc-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Order flow choice buttons — replaces ChatInput when the flow offers fixed options */
.order-flow-choices {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
}
.order-flow-choice-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 44px;
  padding: var(--sp-3) var(--sp-2);
  border-radius: 22px;
  border: none;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  font-family: var(--font-sans);
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.order-flow-choice-btn:active:not(:disabled) {
  transform: scale(0.98);
}
.order-flow-choice-btn--primary {
  background: var(--accent-fill);
  color: var(--on-accent);
}
.order-flow-choice-btn--primary:hover {
  background: var(--accent-dark);
}
.order-flow-choice-btn--secondary {
  background: var(--bg-card);
  color: var(--text-primary);
  border: 1px solid var(--hairline-strong);
}
.order-flow-choice-btn--secondary:hover {
  background: var(--bg-muted);
}
/* Cancel at a summary (UXM-14): a plain ghost button, the step's verb the filled one, Change the secondary. */
.order-flow-choice-btn--ghost {
  flex: 0 1 auto;
  padding-inline: var(--sp-4);
  background: transparent;
  color: var(--text-secondary);
}
.order-flow-choice-btn--ghost:hover {
  background: var(--bg-muted);
  color: var(--text-primary);
}
/* A package order's sector (docs/pdr/prd-llyner-package-products.md PKP-06): many answers wrap, each as wide as its
   words, never under 44px; the full list scrolls inside the composer's place instead of pushing the page. */
.order-flow-choices--wrap {
  flex-wrap: wrap;
  max-height: 40vh;
  overflow-y: auto;
}
.order-flow-choices--wrap .order-flow-choice-btn {
  flex: 0 1 auto;
  padding-inline: var(--sp-4);
}

/* Mobile tweaks for new components */
@media (max-width: 639px) {
  .pdf-preview-area {
    height: 150px;
  }
}

/* ════════════════════════════════════════
  MOBILE  (max-width: 639px)
════════════════════════════════════════ */
@media (max-width: 639px) {
  .header {
    padding: 10px 14px;
    gap: var(--sp-2);
  }
  .header-logo {
    width: 30px;
    height: 30px;
    border-radius: var(--sp-2);
  }
  .chat-header {
    padding: 12px 14px;
  }
  .chat-header .header-logo {
    width: 36px;
    height: 36px;
    font-size: 13px;
  }
  .chat-header .header-name {
    font-size: var(--fs-md);
  }
  .header-context {
    font-size: var(--fs-sm);
  }
  .header-inner {
    gap: var(--sp-2);
  }
  .header-biz {
    font-size: var(--fs-xs);
    max-width: 120px;
  }
  .header-socials {
    display: flex;
    gap: var(--sp-2);
  }

  .messages-area {
    padding: var(--sp-3) 0 var(--sp-2);
  }
  .msg-row,
  .typing-row {
    padding: 0 var(--sp-3);
  }

  .input-area {
    padding: var(--sp-2) 10px calc(var(--sp-2) + env(safe-area-inset-bottom));
  }
  .pills-row {
    gap: 6px;
    padding-bottom: var(--sp-2);
  }
  .pill {
    font-size: var(--fs-sm);
    padding: 6px 12px;
  }
  .input-box {
    padding: 5px 5px 5px 13px;
  }
  .input-textarea {
    max-height: 100px;
    /* Under 16px, iOS Safari zooms the page when the box gets focus. */
    font-size: 16px;
  }
  .input-footer {
    margin-top: 6px;
  }

  /* The cover on a phone: the card at the bottom, two facts, a smaller heading; chat mode without the footer. */
  .chat-header--cover .header-name {
    font-size: var(--fs-md);
  }
  .cover-stage {
    justify-content: flex-end;
    gap: 10px;
    padding: 0 10px calc(12px + env(safe-area-inset-bottom));
  }
  /* Llyner's cover has no picture to show above the card: its stage sits in the middle of the screen instead of
     leaving a blank band under the header (UX-16). */
  .cover--llyner:not(.cover--chat) .cover-stage {
    justify-content: center;
  }
  /* Two facts on one row: the address gives way (ellipsed) to the other. */
  .cover-facts {
    flex-wrap: nowrap;
  }
  .cover-facts li {
    flex: none;
  }
  .cover-facts li.cover-fact-item--place {
    flex: 0 1 auto;
  }
  .cover-facts li:nth-child(n + 3) {
    display: none;
  }
  .cover-fact {
    font-size: 13px;
    padding: 0 12px;
  }
  .cover-tagline {
    font-size: var(--fs-chat);
  }
  .cover-card {
    padding: var(--sp-3);
    border-radius: var(--r-2xl);
  }
  .cover-card .messages-area {
    max-height: 40vh;
  }
  .cover-card .msg-row,
  .cover-card .typing-row {
    padding: 0;
  }
  /* Chat mode on a phone: the card edge to edge under the header, its top a sheet's handle (CC-12). */
  .cover--chat .cover-stage {
    padding: 6px 0 0;
  }
  .cover--chat .cover-card {
    padding: 0 12px calc(10px + env(safe-area-inset-bottom));
    border-radius: 22px 22px 0 0;
  }
  .cover-card-handle {
    position: relative;
    align-self: stretch;
    min-height: 28px;
    margin-bottom: -4px;
  }
  /* A 44px hit area over the 28px strip. */
  .cover-card-handle::before {
    content: '';
    position: absolute;
    inset: -8px 0;
  }
  .cover-card-grip {
    display: block;
    width: 40px;
    height: 5px;
    border-radius: 3px;
    background: var(--hairline-strong);
  }
  .cover-card-home {
    display: none;
  }

  .modal-backdrop {
    padding: 0;
    align-items: flex-end;
  }
  .modal-sheet {
    border-radius: min(var(--r-xl), 20px) min(var(--r-xl), 20px) 0 0;
    width: 100%;
    max-height: 92vh;
    animation: slideUpModal 0.3s ease;
  }
  /* Level with the sheet's first row (a title bar, the business, the product's picture) under the grab handle. */
  .modal-close {
    top: 34px;
  }
  .modal-body {
    padding: var(--sp-4) var(--sp-4) var(--sp-6);
  }

  .loc-body {
    padding: 12px 13px 14px;
  }
  .loc-biz-name {
    font-size: var(--fs-sm);
  }
  .loc-info-primary {
    font-size: var(--fs-sm);
  }
  .loc-info-secondary {
    font-size: var(--fs-sm);
  }
  .loc-directions {
    font-size: var(--fs-sm);
  }

  .profile-backdrop {
    align-items: flex-end;
  }
  .profile-sheet {
    border-radius: min(var(--r-xl), 20px) min(var(--r-xl), 20px) 0 0;
    width: 100%;
    max-height: 90vh;
    padding: var(--sp-5) 18px var(--sp-8);
    animation: slideUpModal 0.3s ease;
  }
  .profile-title {
    font-size: var(--fs-md);
  }
}

/* ── Added in the rebuild ── */
.msg-bubble--lead {
  margin-bottom: 8px;
}
.loc-map-wrap {
  border-radius: 12px 12px 0 0;
}
.loc-map-frame {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
.pdf-preview-area {
  display: block;
  width: 100%;
  border: 0;
  padding: 0;
  font: inherit;
  text-align: inherit;
}
.header-name {
  margin: 0;
}
.not-found {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100dvh;
  gap: 12px;
  font-family: var(--font-sans);
  color: var(--text-primary);
  background: var(--bg-page);
}
.not-found-code {
  font-size: 48px;
  font-weight: var(--fw-extrabold);
  color: var(--accent);
}
.not-found-text {
  font-size: var(--fs-md);
  color: var(--text-secondary);
}
.not-found-link {
  margin-top: 8px;
  font-size: var(--fs-base);
  color: var(--accent-text);
  text-decoration: none;
  font-weight: var(--fw-semibold);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

/* Touch targets ≥ 44px on phones (PRD §11.3) without changing how the controls look: an invisible hit area around
   the small ones. The carousel and image dots stay small on purpose — they sit too close together, and their arrows
   do the same job. */
/* :where() has no specificity, so a control the design already positions (absolute arrows) keeps its position. */
:where(
  .header-socials a,
  .header-phone,
  .header-contact,
  .header-menu-btn,
  .page-menu-social,
  .page-menu-legal-link,
  .header-bag,
  .cover-fact,
  .cover-footer-link,
  .cover-made a,
  .msg-notice-btn,
  .new-message-chip,
  .peek-see-all,
  .peek-card-add,
  .peek-card-name-btn,
  .loc-copy-btn,
  .pill,
  .input-footer a,
  .msg-policy a,
  .chat-byline a,
  .send-btn,
  .modal-close,
  .modal-gallery-nav,
  .pdf-modal-close
) {
  position: relative;
}
.header-socials a::before,
.header-phone::before,
.header-contact::before,
.header-menu-btn::before,
.page-menu-social::before,
.page-menu-legal-link::before,
.header-bag::before,
.cover-fact::before,
.cover-footer-link::before,
.cover-made a::before,
.msg-notice-btn::before,
.new-message-chip::before,
.peek-see-all::before,
.peek-card-add::before,
.peek-card-name-btn::before,
.loc-copy-btn::before,
.pill::before,
.input-footer a::before,
.msg-policy a::before,
.chat-byline a::before,
.send-btn::before,
.modal-close::before,
.pdf-modal-close::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}
/* The pills row scrolls sideways, which clips anything outside it: room above and below for the pills' hit areas. */
.pills-row {
  padding-top: 9px;
  padding-bottom: calc(var(--sp-2) + 9px);
  margin-top: -9px;
  margin-bottom: -9px;
}

.osm-contact-row--top {
  align-items: flex-start;
}
.osm-contact-message {
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* The tagline wraps instead of being cut ("Time to have your…"). */
.bf-brand .header-biz,
.reg-brand .header-biz {
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
  max-width: none;
}

/* A visitor who asked for less motion gets none that starts by itself (the hero also stops advancing, in
   InlineCarousel). */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/*
 * The business as the server writes it into #root (templates/business/page.html.twig): what crawlers without
 * JavaScript read, and what a visitor sees for the moment before React replaces it.
 */
.business-summary {
  max-width: 640px;
  margin: 0 auto;
  padding: var(--sp-6) 16px;
  color: var(--text-secondary);
  line-height: 1.6;
  overflow-wrap: anywhere;
}
.business-summary h1 {
  color: var(--text-primary);
  font-size: 24px;
  line-height: 1.25;
  margin-bottom: 8px;
}
.business-summary h2 {
  color: var(--text-primary);
  font-size: 18px;
  margin: 24px 0 8px;
}
.business-summary h3 {
  color: var(--text-primary);
  font-size: 16px;
}
.business-summary address {
  font-style: normal;
}
.business-summary ul {
  list-style: none;
  display: grid;
  gap: 12px;
}
.business-summary nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin-top: 24px;
}
.business-summary a {
  color: var(--accent-dark);
  display: inline-block;
  min-height: 44px;
  line-height: 44px;
}

/* appointment flow: the booking chips in the chat (business-features item 6) */
.apt-card {
  max-width: 100%;
}
/* The booking cards' title is a quiet label over the chips, not a strip. */
.apt-card .osm-header {
  background: transparent;
  border-bottom: none;
  padding-bottom: 0;
}
/* An answered card: kept for the record, its title and other chips faded; the chip that answered it keeps its fill,
   so what was picked stays readable. */
.apt-card--used .osm-header,
.apt-card--used .apt-chip:not(.apt-chip--chosen) {
  opacity: 0.55;
}
/* The days and times wrap in rows of chips: each one a 44px target, tapped with a thumb on a 390px phone. */
.apt-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
}
/* The days ("Thu, Oct 8") differ in width: a grid lines them up, three across on a phone. */
.apt-chips--days {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
}
.apt-chips--days .apt-chip {
  min-width: 0;
  padding: 0 var(--sp-2);
}
@media (max-width: 639px) {
  .apt-chips--days {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
/* The services (UXM-08): names, not figures, so two across on a phone and wrapping inside the tile. */
.apt-chips--services {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
}
.apt-chips--services .apt-chip {
  min-width: 0;
  padding: var(--sp-2) var(--sp-3);
  line-height: 1.3;
  text-wrap: balance;
}
@media (max-width: 639px) {
  .apt-chips--services {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
.apt-chip {
  min-height: 44px;
  min-width: 64px;
  padding: 0 14px;
  border-radius: 12px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    border-color var(--trans-fast),
    color var(--trans-fast),
    transform var(--trans-fast);
}
.apt-chip:hover:not(:disabled) {
  background: var(--accent-light);
  border-color: var(--accent);
  color: var(--accent-text);
}
.apt-chip:active:not(:disabled) {
  transform: scale(0.97);
}
.apt-chip--chosen,
.apt-chip--chosen:disabled {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}
.apt-chip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
/* "More days" / "Another day": not a time, so a text link. */
.apt-chip--more {
  background: transparent;
  border-color: transparent;
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
/* An older card's chips: the card fades as a whole (.apt-card--used), so they don't fade again. */
.apt-chip:disabled {
  cursor: default;
}
.apt-when {
  color: var(--text-primary);
}

/* A diagnostic's answers in the text box's place (docs/chat-design.md "Diagnostics"): a muted "Question 2 of 10", then
   full-width tiles in the booking chips' style (12px corners, a hairline ring, the brand fill once chosen), the hint a
   muted second line. Over half the screen the tiles scroll inside the composer, so the question above stays in sight;
   Next stays at the foot. */
.diagnostic-answers {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
}
.diagnostic-answers-step {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.diagnostic-answers-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  max-height: 50vh;
  max-height: 50dvh;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Room for the tiles' focus ring inside the scroll box. */
  padding: 4px;
  margin: -4px;
}
.diagnostic-answer {
  position: relative;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  width: 100%;
  min-height: 48px;
  padding: var(--sp-2) var(--sp-4);
  border-radius: 12px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: var(--font-sans);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    border-color var(--trans-fast),
    color var(--trans-fast),
    transform var(--trans-fast);
}
.diagnostic-answer:hover:not(:disabled) {
  background: var(--accent-light);
  border-color: var(--accent);
}
.diagnostic-answer:active:not(:disabled) {
  transform: scale(0.98);
}
.diagnostic-answer:disabled {
  cursor: default;
}
.diagnostic-answer--chosen,
.diagnostic-answer--chosen:hover:not(:disabled),
.diagnostic-answer--chosen:disabled {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}
.diagnostic-answer:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.diagnostic-answer-text {
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
  overflow-wrap: anywhere;
}
.diagnostic-answer-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.diagnostic-answer--chosen .diagnostic-answer-hint {
  color: inherit;
  opacity: 0.85;
}
/* Several answers: a box at the right that holds the check once chosen. */
.diagnostic-answer--several {
  padding-right: calc(var(--sp-4) + 30px);
}
.diagnostic-answer-check {
  position: absolute;
  top: 50%;
  right: var(--sp-4);
  width: 22px;
  height: 22px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1.5px solid var(--hairline-strong);
}
.diagnostic-answer--chosen .diagnostic-answer-check {
  border-color: currentColor;
}
.diagnostic-answers-next {
  flex: 0 0 auto;
  width: 100%;
}
.diagnostic-answers-next:disabled {
  opacity: 0.5;
  cursor: default;
}

/* A diagnostic answered all at once (docs/chat-design.md §12 and §15, prd-diagnostics-v2.md §1): a form chat sheet
   (the header, the count and the bar are the sheet's) with every question in order, hairline rules between them (no
   boxes), its answers as the booking's tiles (12px corners, a hairline ring, ≥ 48px, the brand fill once chosen);
   Yes / No and any two answers as two equal buttons, a Yes / No question one row on a computer with its tiles at the
   right (84px each). */
.diagnostic-form-questions {
  list-style: none;
  margin: 0;
  padding: 0;
}
.diagnostic-form-question {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--sp-3) var(--sp-4);
  padding: var(--sp-4) 0;
  border-top: 1px solid var(--hairline);
}
.diagnostic-form-question > .diagnostic-form-q {
  flex: 1 1 100%;
}
/* On a computer a Yes / No question is one row: its words at the left, its two tiles at the right. */
.diagnostic-form-question--yesno {
  flex-wrap: nowrap;
}
.diagnostic-form-question--yesno > .diagnostic-form-q {
  flex: 1 1 auto;
  min-width: 0;
}
/* The first question sits right under the header: no line there. */
.diagnostic-form-body > :first-child > .diagnostic-form-question:first-child {
  border-top: 0;
}
.diagnostic-form-q {
  margin: 0;
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-snug);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.diagnostic-form-n {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.diagnostic-form-several {
  display: block;
  margin-top: 2px;
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  color: var(--text-muted);
}
/* More than two answers, or several to tick: one tile under the other. Two answers are the form layout's two choices
   (shared/ui/chat-sheet/chat-form.css); Yes / No keep them narrow beside the question on a computer. */
.diagnostic-form-answers {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-2);
  width: 100%;
}
.chat-form-choices.diagnostic-form-answers--yesno {
  flex: none;
  grid-template-columns: repeat(2, 84px);
}
/* A phone: every question's words over its answers; Yes / No as two equal buttons across the width. */
.chat-sheet--phone .diagnostic-form-question--yesno {
  flex-wrap: wrap;
}
.chat-sheet--phone .diagnostic-form-question--yesno > .diagnostic-form-q {
  flex: 1 1 100%;
}
.chat-sheet--phone .chat-form-choices.diagnostic-form-answers--yesno {
  flex: 1 1 100%;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.diagnostic-form-answer {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  gap: 2px;
  min-width: 0;
  min-height: 48px;
  padding: var(--sp-2) var(--sp-4);
  border-radius: 12px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  color: var(--text-primary);
  font-family: var(--font-sans);
  text-align: left;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    border-color var(--trans-fast),
    color var(--trans-fast),
    transform var(--trans-fast);
}
.diagnostic-form-answer:hover {
  background: var(--accent-light);
  border-color: var(--accent);
}
.diagnostic-form-answer:active {
  transform: scale(0.98);
}
.diagnostic-form-answer--chosen,
.diagnostic-form-answer--chosen:hover {
  background: var(--accent-fill);
  border-color: transparent;
  color: var(--on-accent);
}
.diagnostic-form-answer:focus-visible,
.keep-btn:focus-visible,
.keep-row-input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.diagnostic-form-answer-text {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-chat);
  font-weight: var(--fw-semibold);
  overflow-wrap: anywhere;
}
.diagnostic-form-answer-hint {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
/* An answer's hint under its words, in a tile or in one of two choices. */
.chat-form-choice .diagnostic-form-answer-hint {
  display: block;
}
.chat-form-choice[aria-pressed='true'] .diagnostic-form-answer-hint,
.diagnostic-form-answer--chosen .diagnostic-form-answer-hint {
  color: inherit;
  opacity: 0.85;
}
/* Several answers: a box at the right that holds the check once chosen, as in the chat's tiles. */
.diagnostic-form-answer--several {
  padding-right: calc(var(--sp-4) + 30px);
}
.diagnostic-form-answer-check {
  position: absolute;
  top: 50%;
  right: var(--sp-4);
  width: 22px;
  height: 22px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  border: 1.5px solid var(--hairline-strong);
}
.diagnostic-form-answer--chosen .diagnostic-form-answer-check {
  border-color: currentColor;
}

/* "Tus datos" (prd-diagnostics-v2.md §4): the form layout's fields (shared/ui/chat-sheet/chat-form.css), then the
   data-policy tick with its link. */
.chat-form-section.diagnostic-details {
  padding-top: var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.diagnostic-form-body > .diagnostic-details:first-child {
  padding-top: 0;
  border-top: 0;
}
.diagnostic-details-consent {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-3);
  min-height: 44px;
  padding-top: var(--sp-1);
  font-size: var(--fs-sm);
  line-height: var(--lh-snug);
  color: var(--text-secondary);
  cursor: pointer;
}
.diagnostic-details-consent input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--accent-fill);
}
.diagnostic-details-consent a {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* The diagnosis (prd-diagnostics-v2.md §3): the summaries' card (.osm) with its header strip; the level in its tone's
   text colour and the score at its right; a meter of every level (6px bars, the visitor's strong, the others light,
   their names under them); the level's text. Tones only with the chat's success / warning / danger tokens. */
.osm.diagnosis {
  min-width: 0;
}
.diagnosis-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
}
.diagnosis-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sp-3);
}
.diagnosis-level {
  margin: 0;
  font-size: 22px;
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: var(--ls-tight);
  overflow-wrap: anywhere;
}
.diagnosis-level--good {
  color: var(--success);
}
.diagnosis-level--watch {
  color: var(--warning);
}
.diagnosis-level--alert {
  color: var(--danger);
}
.diagnosis-score {
  flex: none;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.diagnosis-meter {
  display: grid;
  gap: var(--sp-1) 4px;
}
.diagnosis-meter--1 {
  grid-template-columns: minmax(0, 1fr);
}
.diagnosis-meter--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.diagnosis-meter--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.diagnosis-meter--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}
.diagnosis-meter--5 {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}
.diagnosis-meter-bar {
  height: 6px;
  border-radius: 3px;
}
.diagnosis-meter-bar--good {
  background: var(--success-light);
}
.diagnosis-meter-bar--watch {
  background: var(--warning-light);
}
.diagnosis-meter-bar--alert {
  background: var(--danger-light);
}
.diagnosis-meter-bar--good.diagnosis-meter-bar--on {
  background: var(--success);
}
.diagnosis-meter-bar--watch.diagnosis-meter-bar--on {
  background: var(--warning);
}
.diagnosis-meter-bar--alert.diagnosis-meter-bar--on {
  background: var(--danger);
}
.diagnosis-meter-name {
  font-size: 12px;
  line-height: var(--lh-snug);
  text-align: center;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}
.diagnosis-meter-name--on {
  color: var(--text-primary);
  font-weight: var(--fw-semibold);
}
.diagnosis-text {
  margin: 0;
  font-size: var(--fs-chat);
  line-height: var(--lh-base);
  color: var(--text-primary);
  white-space: pre-line;
  overflow-wrap: anywhere;
}

/* "Guárdalo" (prd-diagnostics-v2.md §5): at the diagnosis card's foot (a hairline above), or alone under the
   business's text (--loose, no frame). Tonal buttons (the card's own actions), 22px corners, ≥ 44px; sent: white with
   the strong hairline ring and a green check. */
.keep-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
  border-top: 1px solid var(--hairline);
}
.keep-row--loose {
  flex: 1;
  min-width: 0;
  padding: 0;
  border-top: 0;
}
.keep-row-label {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--text-muted);
}
.keep-row-buttons,
.already-answered-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
}
.keep-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  max-width: 100%;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border: 0;
  border-radius: 22px;
  background: var(--accent-light);
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  overflow-wrap: anywhere;
  cursor: pointer;
  transition:
    background-color var(--trans-fast),
    transform var(--trans-fast);
}
.keep-btn:hover:not(:disabled):not(.keep-btn--sent) {
  background: var(--accent-mid);
}
.keep-btn:active:not(:disabled):not(.keep-btn--sent) {
  transform: scale(0.97);
}
.keep-btn:disabled {
  opacity: 0.6;
  cursor: default;
}
.keep-btn--sent {
  background: var(--bg-card);
  color: var(--text-secondary);
  box-shadow: inset 0 0 0 1px var(--hairline-strong);
  cursor: default;
}
.keep-btn--sent svg {
  color: var(--success);
}
.keep-row-field {
  display: flex;
  gap: var(--sp-2);
}
.keep-row-input {
  flex: 1;
  min-width: 0;
  min-height: 44px;
  padding: 0 var(--sp-4);
  border-radius: 22px;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-input);
  color: var(--text-primary);
  font: inherit;
  font-size: var(--fs-md);
}
.keep-row-input:focus {
  outline: 0;
  border-color: var(--accent-text);
  box-shadow: 0 0 0 3px var(--accent-light);
}
.keep-row-input[aria-invalid='true'] {
  border-color: var(--danger);
}
.keep-row-error {
  margin: 0;
  font-size: var(--fs-sm);
  color: var(--danger);
}

/* A repeat of a limited diagnostic (prd-diagnostics-v2.md §4, QA-0043): the business's card in the chat. */
.already-answered {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding: var(--sp-4);
}
.already-answered-title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  color: var(--text-primary);
  overflow-wrap: anywhere;
}
.already-answered-text {
  margin: 0;
  font-size: var(--fs-chat);
  line-height: var(--lh-base);
  color: var(--text-secondary);
  overflow-wrap: anywhere;
}

@media (max-width: 639px) {
  .diagnosis-level {
    font-size: 20px;
  }
  /* The buttons share the card's width, two or three to a line. */
  .keep-btn {
    flex: 1 1 auto;
    padding: 0 var(--sp-3);
  }
}

/* The page the server wrote, kept while React waits for its own (shared/ui/ServerPaint): no box of its own. */
.server-paint {
  display: contents;
}

/*
 * Pinch-zoom is allowed (QA-0008: no maximum-scale or user-scalable=no in the viewport). iOS zooms into a field whose
 * text is under 16px when it takes the focus: on iOS only (Chromium has no -webkit-touch-callout, so the visual
 * baseline is unchanged), every field's text is at least 16px, over the admin's and the chat's own sizes.
 */
@supports (-webkit-touch-callout: none) {
  input,
  select,
  textarea {
    font-size: max(16px, 1em) !important;
  }
}

/*
  Linked products (docs/pdr/prd-linked-products.md, docs/chat-design.md §14): the kind chip of a product that unlocks
  something, Out of stock, the product sheet's own page and Share, a sold document's and link's teaser, and the order
  card's access buttons. Tokens only; every control ≥ 44px tall (no entry in the hit-area list needed).
*/
.product-kind-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 8px;
  border-radius: var(--r-full);
  background: var(--accent-light);
  color: var(--accent-text);
  font-size: 12px;
  font-weight: var(--fw-semibold);
  line-height: 1.5;
  white-space: nowrap;
}
.peek-card-tags .product-kind-chip {
  background: var(--bg-card);
  box-shadow: var(--shadow-sm);
}
.peek-card-add--out {
  background: var(--bg-muted);
  color: var(--text-muted);
  box-shadow: none;
  cursor: not-allowed;
}
/* A sold document: its first page and what sells it, never the file. */
.pdf-buy-btn {
  justify-content: center;
  min-height: 44px;
  background: var(--accent-light);
  color: var(--accent-text);
  text-decoration: none;
}
.pdf-wrap--sold .pdf-icon-badge {
  color: var(--text-muted);
}
.lk-card--sold .lk-meta {
  color: var(--accent-text);
}
/* The order card's linked lines: their button under the line, or why it waits. */
.osc-line--linked {
  flex-wrap: wrap;
}
.osc-sku {
  display: block;
  font-size: 12px;
  color: var(--text-muted);
}
.osc-access {
  flex-basis: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
.osc-access-btn {
  width: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sp-4);
  text-decoration: none;
}
.osc-access-note {
  font-size: 13px;
  color: var(--text-muted);
}

/* A Llyner package order's page (docs/pdr/prd-llyner-package-products.md PKP-07): the state in a sentence, then Open
   my admin, a filled 44px link, as wide as its words. */
.osc-package {
  gap: var(--sp-1);
}
.osc-package-name {
  font-weight: var(--fw-semibold);
}
.osc-package-admin {
  width: auto;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--sp-4);
  text-decoration: none;
}

