@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);
}

/*
 * The admin: the MDX admin's design (sidebar shell, house tables, coloured action buttons, modals, light and dark) in
 * Llyner's colours (docs/brand.md: Deep Blue, the slate greys, the brand's status colours; dark derived from them).
 * Everything is scoped under `.admin` so none of it reaches the public pages, which keep their own look.
 * A colour is a token, defined in both blocks; nothing below the tokens names a colour.
 */
.admin,
.admin[data-theme='light'] {
  color-scheme: light;
  --color-bg: #f8fafc;
  --color-surface: #ffffff;
  --color-border: #e2e8f0;
  --color-border-strong: #cbd5e1;
  --color-text: #0f172a;
  --color-muted: #64748b;
  --color-primary: #1260d6;
  --color-primary-hover: #0f4fb4;
  --color-primary-soft: #e8f1fe;
  --color-danger: #b91c1c;
  --color-danger-soft: #fee2e2;
  --color-warning: #b45309;
  --color-warning-soft: #fef3c7;
  --color-info: #1260d6;
  --color-info-soft: #e8f1fe;
  --color-success: #15803d;
  --color-success-soft: #dcfce7;
  --color-accent: #6d28d9;
  --color-accent-soft: #f3eefe;
  --color-indigo: #4338ca;
  --color-indigo-soft: #eef0fd;
  --color-neutral: #475569;
  --color-neutral-soft: #f1f5f9;
  --color-surface-sunken: #f8fafc;
  /* A QR code scans only dark on light: the same in both themes. */
  --color-qr-light: #ffffff;
  --color-qr-dark: #000000;
  --color-on-primary: #ffffff;
  --color-cover-paper: #ffffff;
  --color-cover-arc: #1877f2;
  --color-cover-ink: #0f172a;
  /* Llyner's cover as the page draws it (decision 19): the same in both admin themes, it previews the page. */
  --color-cover-night: #0f172a;
  --color-cover-night-glow: rgba(24, 119, 242, 0.45);
  --color-cover-mist: #f8fafc;
  --color-cover-mist-glow: rgba(24, 119, 242, 0.2);
  --color-cover-mist-ring: rgba(24, 119, 242, 0.3);
  --color-cover-mist-eyes: #1260d6;
  --color-brand-mark: #1877f2;
  --color-danger-border: #fecaca;
  --color-tooltip: #0f172a;
  --color-on-tooltip: #ffffff;
  --color-overlay: rgba(15, 23, 42, 0.45);
  --color-edge: rgba(15, 23, 42, 0.06);
  /* The Board's status palette (prd-kanban-board §4.1): a full shade for edges and dots, a soft one for tints. */
  --color-board-gray: #64748b;
  --color-board-gray-soft: #f1f5f9;
  --color-board-red: #b91c1c;
  --color-board-red-soft: #fee2e2;
  --color-board-orange: #c2410c;
  --color-board-orange-soft: #ffedd5;
  --color-board-amber: #b45309;
  --color-board-amber-soft: #fef3c7;
  --color-board-green: #15803d;
  --color-board-green-soft: #dcfce7;
  --color-board-teal: #0f766e;
  --color-board-teal-soft: #ccfbf1;
  --color-board-blue: #1d4ed8;
  --color-board-blue-soft: #dbeafe;
  --color-board-violet: #6d28d9;
  --color-board-violet-soft: #ede9fe;

  --radius: 8px;
  --radius-sm: 6px;
  --shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 1px 3px rgba(15, 23, 42, 0.07);
  --shadow-lg: 0 12px 32px rgba(15, 23, 42, 0.16);
  /* The public page's typeface (loaded by the app's global styles), the system's while it loads (A-71). */
  --font:
    'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue',
    Arial, sans-serif;
  --gutter: 16px;
}

/*
 * Dark: the same design on a dark palette derived from the brand's (Ink deepened, Llyner Blue lightened to read on it).
 * Backgrounds step up in lightness instead of leaning on shadows; each hue is a lighter tint of its light self, so
 * "green = confirm" survives.
 */
.admin[data-theme='dark'] {
  color-scheme: dark;
  --color-cover-paper: #ffffff;
  --color-cover-arc: #1877f2;
  --color-cover-ink: #0f172a;
  /* Llyner's cover as the page draws it (decision 19): the same in both admin themes, it previews the page. */
  --color-cover-night: #0f172a;
  --color-cover-night-glow: rgba(24, 119, 242, 0.45);
  --color-cover-mist: #f8fafc;
  --color-cover-mist-glow: rgba(24, 119, 242, 0.2);
  --color-cover-mist-ring: rgba(24, 119, 242, 0.3);
  --color-cover-mist-eyes: #1260d6;
  --color-bg: #0b1120;
  --color-surface: #131c2e;
  --color-border: #273449;
  --color-border-strong: #475569;
  --color-text: #e2e8f0;
  --color-muted: #94a3b8;
  --color-primary: #6aa8ff;
  --color-primary-hover: #8dbcff;
  --color-primary-soft: #14264a;
  --color-danger: #f87171;
  --color-danger-soft: #3b1518;
  --color-warning: #fbbf24;
  --color-warning-soft: #3a2a0c;
  --color-info: #6aa8ff;
  --color-info-soft: #14264a;
  --color-success: #4ade80;
  --color-success-soft: #0f2e1c;
  --color-accent: #c4a5f5;
  --color-accent-soft: #271c45;
  --color-indigo: #a5b4fc;
  --color-indigo-soft: #1e2350;
  --color-neutral: #cbd5e1;
  --color-neutral-soft: #1c2639;
  --color-surface-sunken: #0f1729;
  /* A QR code scans only dark on light: the same in both themes. */
  --color-qr-light: #ffffff;
  --color-qr-dark: #000000;
  --color-on-primary: #0b1120;
  --color-brand-mark: #ffffff;
  --color-danger-border: #7f1d1d;
  --color-tooltip: #e2e8f0;
  --color-on-tooltip: #0b1120;
  --color-overlay: rgba(2, 6, 23, 0.65);
  --color-edge: rgba(0, 0, 0, 0.35);
  --color-board-gray: #94a3b8;
  --color-board-gray-soft: #1c2639;
  --color-board-red: #f87171;
  --color-board-red-soft: #3b1518;
  --color-board-orange: #fb923c;
  --color-board-orange-soft: #3b1d0c;
  --color-board-amber: #fbbf24;
  --color-board-amber-soft: #3a2a0c;
  --color-board-green: #4ade80;
  --color-board-green-soft: #0f2e1c;
  --color-board-teal: #5eead4;
  --color-board-teal-soft: #0d2e2b;
  --color-board-blue: #60a5fa;
  --color-board-blue-soft: #14264a;
  --color-board-violet: #c4a5f5;
  --color-board-violet-soft: #271c45;

  --shadow: 0 1px 2px rgba(0, 0, 0, 0.4), 0 1px 3px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.6);
}

.admin {
  min-height: 100vh;
  min-height: 100dvh;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

body.admin-modal-open {
  overflow: hidden;
}

.admin h1,
.admin h2,
.admin h3 {
  margin: 0;
  line-height: 1.25;
}

.admin h1 {
  font-size: 1.6rem;
}

.admin h2 {
  font-size: 1.15rem;
}

.admin a {
  color: var(--color-primary);
}

.admin p {
  margin: 0;
}

/* Utilities */
.admin .muted {
  color: var(--color-muted);
}

.admin .small {
  font-size: 0.85rem;
}

.admin .strong {
  font-weight: 600;
}

.admin .nowrap {
  white-space: nowrap;
}

.admin .break-any {
  overflow-wrap: anywhere;
}

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

/* Shell: sidebar + content; the sidebar becomes a drawer on narrow screens */
.admin .shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 248px minmax(0, 1fr);
}

.admin .sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-surface);
  border-right: 1px solid var(--color-border);
  overflow-y: auto;
}

.admin .sidebar-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  padding: 20px 16px 12px 20px;
}

.admin .brand {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* The face's arch and eyes (docs/brand.md): Llyner Blue in light, white in dark; never a business's colour. */
.admin .brand-mark {
  /* Whole pixels (the mark is 239 × 136): a fractional height would leave the rest of the sidebar on half pixels. */
  flex: none;
  width: 35px;
  height: 20px;
  color: var(--color-brand-mark);
}

.admin .brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.admin .brand-name {
  font-size: 1.05rem;
  font-weight: 600;
  line-height: 20px;
  white-space: nowrap;
}

.admin .brand-sub {
  color: var(--color-muted);
  font-size: 0.68rem;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin .sidebar-nav {
  flex: 1;
  padding: 8px 12px 16px;
}

.admin .nav-section + .nav-section {
  margin-top: 16px;
}

.admin .nav-section-title {
  display: block;
  padding: 8px 10px 6px;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-muted);
}

.admin .nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  /* A finger's 44px (Tacoma's rule): the drawer's links are tapped on phones. */
  min-height: 44px;
  margin-bottom: 0;
  padding: 9px 10px;
  border-radius: var(--radius-sm);
  color: var(--color-muted);
  text-decoration: none;
  font-weight: 500;
}

.admin .nav-link svg {
  flex-shrink: 0;
}

.admin .nav-link:hover {
  color: var(--color-text);
  background: var(--color-bg);
}

.admin .nav-link.active {
  color: var(--color-primary);
  background: var(--color-primary-soft);
}

.admin .sidebar-footer {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 18px;
  border-top: 1px solid var(--color-border);
}

.admin .sidebar-user {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.admin .sidebar-user-name {
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.admin .sidebar-user-role {
  font-size: 0.8125rem;
  color: var(--color-muted);
}

.admin .impersonation-picker {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 0 16px 8px 20px;
}

.admin .impersonation-picker .nav-section-title {
  padding: 0;
}

.admin .theme-picker {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.admin .theme-picker .nav-section-title {
  padding: 0;
}

.admin .impersonation-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 12px;
  padding: 10px 14px;
  margin-bottom: 20px;
  border: 1px solid var(--color-warning);
  border-radius: var(--radius-sm);
  background: var(--color-warning-soft);
  color: var(--color-warning);
  font-weight: 500;
}

/* .icon-btn.sidebar-close: as specific as the .icon-btn rule further down, so this one wins on wide screens. */
.admin .mobile-bar,
.admin .icon-btn.sidebar-close,
.admin .sidebar-backdrop {
  display: none;
}

.admin .content {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  padding-block: 28px 48px;
  padding-inline: max(var(--gutter), 3vw);
}

@media (max-width: 860px) {
  .admin .shell {
    display: block;
  }

  .admin .mobile-bar {
    position: sticky;
    top: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    gap: 12px;
    min-height: 56px;
    padding-inline: var(--gutter);
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
  }

  .admin .mobile-bar .brand-mark {
    width: 28px;
    height: 16px;
  }

  .admin .sidebar {
    position: fixed;
    inset: 0 auto 0 0;
    z-index: 50;
    width: min(280px, 85vw);
    transform: translateX(-100%);
    visibility: hidden;
    transition:
      transform 0.2s ease,
      visibility 0.2s;
    box-shadow: var(--shadow-lg);
  }

  .admin .sidebar-open .sidebar {
    transform: none;
    visibility: visible;
  }

  .admin .icon-btn.sidebar-close {
    display: inline-flex;
  }

  .admin .sidebar-open .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 40;
    background: var(--color-overlay);
  }

  .admin .content {
    padding-inline: var(--gutter);
    padding-top: 20px;
  }
}

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

/* Page structure */
.admin .page-header {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 20px;
}

.admin .page-header h1 {
  overflow-wrap: anywhere;
}

.admin .page-subtitle {
  margin: 4px 0 0;
  color: var(--color-muted);
}

.admin .page-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.admin .toolbar {
  display: flex;
  flex-wrap: wrap;
  /* Every control carries a label above it, so they line up on their bottom edge, and so does the action. */
  align-items: flex-end;
  gap: 12px 20px;
  margin-bottom: 16px;
}

/* A tab's primary action sits at the far end of its toolbar, as the action of the table below. */
.admin .toolbar > .btn-primary {
  margin-left: auto;
}

.admin .tab-intro {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}

.admin .tab-intro p {
  max-width: 75ch;
  color: var(--color-muted);
}

/* A line that says something needs doing (the home page no longer qualifies): amber, on its soft tint. */
.admin .tab-intro-warning {
  padding: 10px 14px;
  border-radius: var(--radius-sm);
  background: var(--color-warning-soft);
}

.admin .tab-intro-warning p {
  color: var(--color-warning);
}

/* At the intro's right: the usage chip, then the view's one primary action. */
.admin .tab-intro-end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

/* How much of a limit is used: "3 of 10" with a small bar; amber from 80 %, red at the limit. */
.admin .usage-chip {
  --usage: var(--color-primary);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 11px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  color: var(--color-muted);
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin .usage-chip-bar {
  position: relative;
  display: block;
  width: 40px;
  height: 5px;
  overflow: hidden;
  border-radius: 3px;
  background: var(--color-border);
}

.admin .usage-chip-bar > span {
  position: absolute;
  inset: 0 auto 0 0;
  border-radius: 3px;
  background: var(--usage);
}

.admin .usage-chip-near {
  --usage: var(--color-warning);
  border-color: var(--color-warning);
  color: var(--color-warning);
}

.admin .usage-chip-reached {
  --usage: var(--color-danger);
  border-color: var(--color-danger);
  color: var(--color-danger);
}

.admin .card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 20px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.admin .card + .card {
  margin-top: 16px;
}

.admin .card-title {
  font-size: 1rem;
}

.admin .card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

/* A card's title and what it holds, with its own actions (outlined, in their colour) at the right. */
.admin .card-heading {
  display: grid;
  gap: 2px;
  min-width: 0;
}

.admin .card-description {
  margin: 0;
  font-size: 0.85rem;
  color: var(--color-muted);
}

.admin .card-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

/* Buttons */
.admin .btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 38px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
  transition:
    background-color 0.15s,
    border-color 0.15s;
}

.admin .btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.admin .btn:focus-visible,
.admin .nav-link:focus-visible,
.admin .tab:focus-visible,
.admin .icon-btn:focus-visible,
.admin input:focus-visible,
.admin select:focus-visible,
.admin textarea:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  box-shadow: none;
}

.admin .btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.admin .btn-primary:hover:not(:disabled) {
  background: var(--color-primary-hover);
}

.admin .btn-secondary {
  background: var(--color-primary-soft);
  border-color: color-mix(in srgb, var(--color-primary) 45%, transparent);
  color: var(--color-primary);
  box-shadow: 0 1px 0 var(--color-edge);
}

.admin .btn-secondary:hover:not(:disabled) {
  border-color: var(--color-primary);
}

.admin .btn-ghost {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-text);
}

.admin .btn-ghost:hover:not(:disabled) {
  border-color: var(--color-border-strong);
  background: var(--color-bg);
}

.admin .btn-link {
  background: none;
  color: var(--color-primary);
  padding-inline: 4px;
  min-height: auto;
  font-weight: 500;
}

.admin .btn-link:hover:not(:disabled) {
  text-decoration: underline;
}

/* Action buttons: outlined in the colour of what they do, on a plain face so they stand out on tinted rows too. */
.admin .btn-action {
  --action: var(--color-primary);
  --action-soft: var(--color-primary-soft);
  background: var(--color-surface);
  border-color: color-mix(in srgb, var(--action) 50%, transparent);
  color: var(--action);
  box-shadow: 0 1px 0 var(--color-edge);
}

.admin .btn-action:hover:not(:disabled) {
  background: var(--action-soft);
  border-color: var(--action);
}

.admin .btn-action-confirm {
  --action: var(--color-success);
  --action-soft: var(--color-success-soft);
}

.admin .btn-action-danger {
  --action: var(--color-danger);
  --action-soft: var(--color-danger-soft);
}

/* One accent (A-70): green does the main thing, red removes; every other action is a neutral outline, and its words
   say what it does. Violet and indigo stay for the row tints a legend explains. */
.admin .btn-action-edit,
.admin .btn-action-open,
.admin .btn-action-setup {
  --action: var(--color-text);
  --action-soft: var(--color-neutral-soft);
  border-color: var(--color-border-strong);
}

.admin .btn-sm {
  min-height: 32px;
  padding: 4px 10px;
  font-size: 0.87rem;
}

.admin .btn-block {
  width: 100%;
}

.admin .icon-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  line-height: 1;
  padding: 6px;
  cursor: pointer;
  color: var(--color-muted);
  border-radius: var(--radius-sm);
}

.admin .icon-btn:hover {
  background: var(--color-bg);
}

/* Icon-only buttons with a tooltip that says what they do (data-tooltip, also the aria-label). */
.admin .btn.btn-icon {
  width: 32px;
  height: 32px;
  min-width: 32px;
  min-height: 32px;
  padding: 0;
  border-radius: 8px;
}

.admin .btn-icon.is-busy {
  opacity: 0.6;
  cursor: progress;
}

.admin .btn-icon[data-tooltip]::after {
  content: attr(data-tooltip);
  display: none;
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  z-index: 20;
  transform: translate(-50%, 2px);
  padding: 4px 8px;
  border-radius: 6px;
  background: var(--color-tooltip);
  color: var(--color-on-tooltip);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
}

.admin .btn-icon[data-tooltip]:hover::after,
.admin .btn-icon[data-tooltip]:focus-visible::after {
  display: block;
  transform: translate(-50%, 0);
}

.admin .row-actions > .btn-icon[data-tooltip]:last-child::after {
  left: auto;
  right: 0;
  transform: none;
}

@media (hover: none) {
  .admin .btn-icon[data-tooltip]:hover::after {
    display: none;
  }
}

/* Every control is at least 44px to a finger (Tacoma's rule), whatever it looks like. */
.admin .btn::before,
.admin .icon-btn::before,
.admin .tab::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

/* Forms */
.admin .form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 14px 16px;
}

.admin .span-2 {
  grid-column: 1 / -1;
}

@media (max-width: 600px) {
  .admin .form-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* A value to copy (CopyField): a long link clips in its field, never widens a modal. */
.admin .copy-field-row {
  display: flex;
  gap: 8px;
}

.admin .copy-field-row input {
  flex: 1;
  min-width: 0;
  text-overflow: ellipsis;
}

.admin .form-actions {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 20px;
}

.admin .field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.admin .admin-field-label {
  font-weight: 600;
  font-size: 0.9rem;
}

.admin .admin-field-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 8px;
}

.admin .admin-field-optional {
  font-size: 0.8rem;
  font-style: italic;
  color: var(--color-muted);
}

.admin .admin-field-help {
  position: relative;
  align-self: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-muted);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}

/* The touch area is 44px, the circle 22px. */
.admin .admin-field-help::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

.admin .admin-field-help[aria-expanded='true'] {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.admin .admin-field-help-text {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--color-text);
}

.admin .admin-field-hint {
  font-size: 0.85rem;
  color: var(--color-muted);
}

.admin .field-error {
  font-size: 0.85rem;
  color: var(--color-danger);
}

.admin input,
.admin select,
.admin textarea {
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  font: inherit;
  color: inherit;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
}

.admin input[type='checkbox'] {
  width: 20px;
  min-height: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--color-primary);
}

.admin input[type='color'] {
  width: 64px;
  padding: 4px;
  cursor: pointer;
}

.admin input[readonly] {
  background: var(--color-bg);
  color: var(--color-muted);
}

.admin textarea {
  resize: vertical;
}

.admin .field-invalid input,
.admin .field-invalid select,
.admin .field-invalid textarea {
  border-color: var(--color-danger);
}

.admin .checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  cursor: pointer;
}

.admin .search {
  max-width: 320px;
}

/* PickList: one choice among a list that may be long, radio rows of 44px at least under an optional search box. */
.admin .pick-list {
  margin: 0;
  padding: 0;
  border: 0;
  gap: 8px;
}

.admin .pick-list .search {
  max-width: none;
}

.admin .pick-list-options {
  display: flex;
  flex-direction: column;
  max-height: 280px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.admin .pick-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  cursor: pointer;
}

.admin .pick-option.is-disabled {
  color: var(--color-muted);
  cursor: not-allowed;
}

.admin .pick-option + .pick-option {
  border-top: 1px solid var(--color-border);
}

.admin .pick-option:has(input:checked) {
  background: var(--color-primary-soft);
}

.admin .pick-option input[type='radio'] {
  flex: none;
  width: 20px;
  min-height: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--color-primary);
}

.admin .pick-option-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.admin .pick-option-label {
  font-weight: 600;
}

.admin .pick-list-empty {
  margin: 0;
  padding: 12px 0;
}

.admin .filter-select {
  display: inline-grid;
  gap: 2px;
  width: auto;
  min-width: 200px;
  max-width: 100%;
}

.admin .filter-select-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--color-muted);
}

.admin .filter-search {
  width: 320px;
}

.admin .filter-search .search {
  max-width: none;
}

@media (max-width: 600px) {
  .admin .filter-select,
  .admin .filter-search {
    width: 100%;
  }
}

/* Alerts & badges */
.admin .alert {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  margin-bottom: 16px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
}

.admin .alert .icon-btn {
  padding: 0 4px;
  color: inherit;
}

/* A notice, not a state: the sunken surface with a mark of the accent, so colour stays for states (A-66). */
.admin .alert-info {
  background: var(--color-surface-sunken);
  border-color: var(--color-border);
  border-left: 3px solid var(--color-primary);
  color: var(--color-text);
}

.admin .alert-success {
  background: var(--color-success-soft);
  color: var(--color-success);
}

.admin .alert-warning {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.admin .alert-error {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.admin .card .alert,
.admin .auth-card .alert {
  margin-bottom: 0;
}

.admin .badge {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
  white-space: nowrap;
}

.admin .badge-neutral {
  background: var(--color-neutral-soft);
  color: var(--color-neutral);
}

.admin .badge-success {
  background: var(--color-success-soft);
  color: var(--color-success);
}

.admin .badge-warning {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.admin .badge-info {
  background: var(--color-info-soft);
  color: var(--color-info);
}

.admin .badge-accent {
  background: var(--color-accent-soft);
  color: var(--color-accent);
}

.admin .badge-danger {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

.admin .badge-indigo {
  background: var(--color-indigo-soft);
  color: var(--color-indigo);
}

/* A product's type (docs/pdr/prd-product-types.md PT-03): a service teal, an Access violet. */
.admin .badge-teal {
  background: var(--color-board-teal-soft);
  color: var(--color-board-teal);
}

.admin .badge-violet {
  background: var(--color-board-violet-soft);
  color: var(--color-board-violet);
}

/* Something switched off (a product off sale, PT-04): a dashed outline, no fill. */
.admin .badge-off {
  background: transparent;
  border: 1px dashed var(--color-border-strong);
  color: var(--color-muted);
}

/* Tables */
.admin .table-wrap {
  overflow-x: auto;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: opacity 0.15s;
}

.admin .table-wrap.is-reloading {
  opacity: 0.6;
}

.admin .table {
  width: 100%;
  border-collapse: collapse;
}

.admin .table th,
.admin .table td {
  padding: 12px 14px;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border);
}

.admin .table th {
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--color-muted);
  background: var(--color-surface-sunken);
  white-space: nowrap;
}

.admin .table tbody tr:last-child td {
  border-bottom: none;
}

.admin .table th.col-actions,
.admin .table td.actions {
  width: 1%;
  white-space: nowrap;
}

.admin .row-actions {
  display: inline-flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: 6px;
}

/* A product's picture in its row. */
.admin .thumb {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-sm);
  object-fit: cover;
  background: var(--color-neutral-soft);
}

.admin .row-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin: 0 0 10px;
  font-size: 0.87rem;
}

.admin .row-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.admin .row-legend-item::before {
  content: '';
  width: 22px;
  height: 10px;
  border-radius: 2px;
}

.admin .row-legend-title {
  font-weight: 600;
}

/* Rows are tinted by the item's status, with a bar down the first cell for anyone who cannot rely on the tint. */
.admin .table tr.row-tone-success {
  --row-accent: var(--color-success);
  --row-tint: var(--color-success-soft);
}

.admin .table tr.row-tone-warning {
  --row-accent: var(--color-warning);
  --row-tint: var(--color-warning-soft);
}

.admin .table tr.row-tone-info {
  --row-accent: var(--color-info);
  --row-tint: var(--color-info-soft);
}

.admin .table tr.row-tone-accent {
  --row-accent: var(--color-accent);
  --row-tint: var(--color-accent-soft);
}

.admin .table tr.row-tone-danger {
  --row-accent: var(--color-danger);
  --row-tint: var(--color-danger-soft);
}

.admin .table tr.row-tone-indigo {
  --row-accent: var(--color-indigo);
  --row-tint: var(--color-indigo-soft);
}

.admin .table tr.row-tone-neutral {
  --row-accent: var(--color-border-strong);
  --row-tint: var(--color-bg);
}

.admin .table tr.row-tone td {
  /* A light tint, so a list of new things is not a wall of colour; the edge carries the status (A-41). */
  background: color-mix(in srgb, var(--row-tint) 45%, var(--color-surface));
}

.admin .table tr.row-tone td:first-child {
  box-shadow: inset 4px 0 0 var(--row-accent);
}

.admin .row-legend-success::before {
  background: var(--color-success-soft);
  box-shadow: inset 4px 0 0 var(--color-success);
}

.admin .row-legend-warning::before {
  background: var(--color-warning-soft);
  box-shadow: inset 4px 0 0 var(--color-warning);
}

.admin .row-legend-info::before {
  background: var(--color-info-soft);
  box-shadow: inset 4px 0 0 var(--color-info);
}

.admin .row-legend-accent::before {
  background: var(--color-accent-soft);
  box-shadow: inset 4px 0 0 var(--color-accent);
}

.admin .row-legend-danger::before {
  background: var(--color-danger-soft);
  box-shadow: inset 4px 0 0 var(--color-danger);
}

.admin .row-legend-indigo::before {
  background: var(--color-indigo-soft);
  box-shadow: inset 4px 0 0 var(--color-indigo);
}

.admin .row-legend-neutral::before {
  background: var(--color-bg);
  box-shadow: inset 4px 0 0 var(--color-border-strong);
}

/* The Board's status colours (the kit's `board-{name}` tones, toneFor's board_* keys): each one names its two shades
   once; rows, legends, filter dots and the kanban's columns draw from them. */
.admin .tone-board-gray,
.admin .row-tone-board-gray,
.admin .row-legend-board-gray {
  --board-tone: var(--color-board-gray);
  --board-tone-soft: var(--color-board-gray-soft);
}

.admin .tone-board-red,
.admin .row-tone-board-red,
.admin .row-legend-board-red {
  --board-tone: var(--color-board-red);
  --board-tone-soft: var(--color-board-red-soft);
}

.admin .tone-board-orange,
.admin .row-tone-board-orange,
.admin .row-legend-board-orange {
  --board-tone: var(--color-board-orange);
  --board-tone-soft: var(--color-board-orange-soft);
}

.admin .tone-board-amber,
.admin .row-tone-board-amber,
.admin .row-legend-board-amber {
  --board-tone: var(--color-board-amber);
  --board-tone-soft: var(--color-board-amber-soft);
}

.admin .tone-board-green,
.admin .row-tone-board-green,
.admin .row-legend-board-green {
  --board-tone: var(--color-board-green);
  --board-tone-soft: var(--color-board-green-soft);
}

.admin .tone-board-teal,
.admin .row-tone-board-teal,
.admin .row-legend-board-teal {
  --board-tone: var(--color-board-teal);
  --board-tone-soft: var(--color-board-teal-soft);
}

.admin .tone-board-blue,
.admin .row-tone-board-blue,
.admin .row-legend-board-blue {
  --board-tone: var(--color-board-blue);
  --board-tone-soft: var(--color-board-blue-soft);
}

.admin .tone-board-violet,
.admin .row-tone-board-violet,
.admin .row-legend-board-violet {
  --board-tone: var(--color-board-violet);
  --board-tone-soft: var(--color-board-violet-soft);
}

.admin .table tr[class*='row-tone-board-'] {
  --row-accent: var(--board-tone);
  --row-tint: var(--board-tone-soft);
}

.admin [class*='row-legend-board-']::before {
  background: var(--board-tone-soft);
  box-shadow: inset 4px 0 0 var(--board-tone);
}

.admin .status-dot[class*='tone-board-'] {
  background: var(--board-tone);
}

/* Tabs: a page's own views, as a bar across the page under its header. */
.admin .tabs-page {
  display: flex;
  flex-wrap: nowrap;
  gap: 4px;
  margin: -4px 0 20px;
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}

/* A tab's own views, inside its panel: a quieter row of pills under the page's tabs. */
.admin .tabs-sub {
  display: flex;
  flex-wrap: nowrap;
  gap: 6px;
  margin: 0 0 16px;
  overflow-x: auto;
  scrollbar-width: none;
}

.admin .tabs-sub .tab {
  padding: 8px 14px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-size: 14px;
}

/* The page's tabs underline the active one; a pill is its own mark. */
.admin .tabs-sub .tab::after {
  display: none;
}

.admin .tabs-sub .tab-active {
  border-color: var(--color-primary);
  background: var(--color-primary-soft, var(--color-surface));
  color: var(--color-primary);
}

.admin .tab {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: none;
  background: none;
  padding: 10px 16px 12px;
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  font: inherit;
  font-weight: 600;
  white-space: nowrap;
  color: var(--color-muted);
  cursor: pointer;
  transition:
    color 0.15s,
    background-color 0.15s;
}

.admin .tab svg {
  opacity: 0.8;
}

/* A tab's counts stand apart from its name ("Contact ②", not "Contact②"). */
.admin .tab .count-badge {
  margin-inline-start: 6px;
}

.admin .tab:hover:not(.tab-active) {
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-border) 45%, transparent);
}

.admin .tab::after {
  content: '';
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: -1px;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: transparent;
}

.admin .tab-active {
  color: var(--color-primary);
}

.admin .tab-active svg {
  opacity: 1;
}

.admin .tab-active::after {
  background: var(--color-primary);
}

.admin .tab:focus-visible {
  outline-offset: -2px;
}

.admin .pager {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  color: var(--color-muted);
}

/* States */
.admin .loading {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 20px 0;
  color: var(--color-muted);
}

.admin .spinner {
  width: 18px;
  height: 18px;
  border: 2px solid var(--color-border-strong);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: admin-spin 0.8s linear infinite;
}

@keyframes admin-spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .admin .spinner {
    animation-duration: 2s;
  }
}

.admin .full-page-center {
  min-height: 100vh;
  display: grid;
  place-items: center;
}

.admin .state {
  padding: 36px 20px;
  text-align: center;
  color: var(--color-muted);
  background: var(--color-surface);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius);
}

.admin .state p {
  margin: 0 0 12px;
}

/* The view's icon in a soft circle above an empty state's sentence. */
.admin .state-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-bottom: 12px;
  border-radius: 50%;
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.admin .state p:last-child {
  margin-bottom: 0;
}

.admin .state-error {
  color: var(--color-danger);
  border-color: var(--color-danger-border);
}

/* Modal */
.admin .admin-modal-backdrop {
  /* A modal opened from a table row is drawn inside the row's actions cell, which does not wrap: start afresh. */
  white-space: normal;
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 5vh var(--gutter);
  background: var(--color-overlay);
  overflow-y: auto;
}

/* Centred in the window; a modal taller than the window starts at its top and scrolls (auto margins never clip). */
.admin .modal {
  margin: auto 0;
  width: 100%;
  max-width: 640px;
  background: var(--color-surface);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

/* A whole record to read and edit (a Board card, BD-28); the whole window on a phone. */
.admin .modal.is-wide {
  max-width: 820px;
}

@media (max-width: 599px) {
  .admin .admin-modal-backdrop:has(> .modal.is-wide) {
    padding: 0;
  }

  .admin .modal.is-wide {
    margin: 0;
    min-height: 100dvh;
    border-radius: 0;
  }
}

.admin .modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--color-border);
}

.admin .admin-modal-body {
  padding: 20px;
}

/* Previous / next (a list's items one by one) beside the close button. */
.admin .admin-modal-nav {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

/* A modal with a footer: the footer stays at its foot and the body scrolls inside it, never taller than the window. */
.admin .modal:has(> .admin-modal-footer) {
  display: flex;
  flex-direction: column;
  max-height: 90dvh;
}

.admin .modal:has(> .admin-modal-footer) > .admin-modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.admin .admin-modal-footer {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 20px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--color-border);
}

.admin .modal form > .alert {
  margin-bottom: 16px;
}

/* A dialog that takes the whole screen on a phone (Modal fullOnPhone): a preview, a picture picker. */
@media (max-width: 599px) {
  .admin .admin-modal-backdrop:has(> .modal-full-phone) {
    padding: 0;
  }

  .admin .modal.modal-full-phone {
    margin: 0;
    max-width: none;
    min-height: 100%;
    border-radius: 0;
    box-shadow: none;
  }
}

/* Sign-in pages */
.admin .auth-page {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 24px var(--gutter);
}

.admin .auth-card {
  width: 100%;
  max-width: 400px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 32px 28px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.admin .auth-card form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Business details: a list of pictures or videos, each a small card with its own fields. */
.admin .media-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr));
  gap: 12px;
}

.admin .media-item {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
}

.admin .media-item-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-weight: 600;
}

.admin .video-thumb {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius-sm);
  object-fit: cover;
}

/* A week of hours as groups of days (HoursGroups, docs/pdr/prd-hours-groups.md): each group folds to one line, one
   open at a time; closed days are a dashed row of "+ Sat" buttons; the Undo line last. A group's colour is one of
   the board's (set in both themes), so a day held by another group shows that group's dot. */
.admin {
  --color-hours-1: var(--color-board-blue);
  --color-hours-2: var(--color-board-teal);
  --color-hours-3: var(--color-board-violet);
  --color-hours-4: var(--color-board-amber);
  --color-hours-5: var(--color-board-green);
  --color-hours-6: var(--color-board-orange);
  --color-hours-7: var(--color-board-red);
}

.admin .hours-groups {
  display: grid;
  gap: 8px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: none;
}

.admin .hours-group {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  overflow: hidden;
}

.admin .hours-group-open {
  border-color: var(--hours-color);
  box-shadow: inset 0 0 0 1px var(--hours-color);
}

.admin .hours-group-invalid {
  border-color: var(--color-danger);
}

.admin .hours-group-head {
  display: grid;
  grid-template-columns: 12px auto minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 56px;
  padding: 8px 14px;
  border: none;
  background: transparent;
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.admin .hours-group-head:hover:not(:disabled) {
  background: var(--color-surface-sunken);
}

.admin .hours-group-head:disabled {
  cursor: default;
}

.admin .hours-group-head:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: -2px;
}

.admin .hours-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--hours-color);
}

.admin .hours-dot-closed {
  background: transparent;
  border: 2px solid var(--color-border-strong);
}

.admin .hours-group-days {
  font-weight: 700;
  white-space: nowrap;
}

.admin .hours-group-hours {
  min-width: 0;
  color: var(--color-muted);
  font-size: 0.9rem;
  font-variant-numeric: tabular-nums;
}

.admin .hours-group-warn {
  display: inline-flex;
  color: var(--color-danger);
}

.admin .hours-chevron {
  display: inline-flex;
  color: var(--color-muted);
  transition: transform 0.15s;
}

.admin .hours-group-open .hours-chevron {
  transform: rotate(180deg);
}

.admin .hours-group-body {
  display: grid;
  gap: 14px;
  padding: 4px 14px 14px;
}

.admin .hours-group-body .segmented {
  justify-self: start;
}

.admin .hours-field {
  display: grid;
  gap: 6px;
}

.admin .hours-label {
  color: var(--color-muted);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.admin .hours-days {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.admin .hours-day {
  position: relative;
  width: 44px;
  height: 44px;
  border: 1px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
  color: var(--color-muted);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
}

.admin .hours-day[aria-pressed='true'] {
  border-color: var(--hours-color);
  background: var(--hours-color);
  color: var(--color-surface);
}

.admin .hours-day:focus-visible,
.admin .hours-add-day:focus-visible,
.admin .hours-presets-grid button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.admin .hours-day-owner {
  position: absolute;
  bottom: 5px;
  left: 50%;
  width: 6px;
  height: 6px;
  margin-left: -3px;
  border-radius: 50%;
  background: var(--hours-owner);
}

.admin .hours-range {
  display: grid;
  grid-template-columns: minmax(0, 160px) auto minmax(0, 160px);
  justify-content: start;
  align-items: center;
  gap: 8px;
}

.admin .hours-range-break {
  grid-template-columns: minmax(0, 160px) auto minmax(0, 160px) auto;
}

.admin .hours-range select {
  min-width: 0;
}

.admin .hours-add-break {
  justify-self: start;
}

.admin .hours-next-day {
  color: var(--color-indigo);
  font-weight: 600;
}

.admin .hours-next-day-tag {
  justify-self: start;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--color-indigo-soft);
  color: var(--color-indigo);
  font-size: 0.8rem;
  font-weight: 700;
}

.admin .hours-group-body .action-group {
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
}

.admin .hours-closed {
  display: grid;
  grid-template-columns: 12px auto minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  min-height: 56px;
  padding: 8px 14px;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius);
}

.admin .hours-closed-days {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.admin .hours-add-day {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--color-border-strong);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-action-create);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}

.admin .hours-add-day:hover {
  border-color: var(--color-action-create);
}

.admin .hours-presets {
  display: grid;
  gap: 8px;
}

.admin .hours-presets-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
}

.admin .hours-presets-grid button {
  display: grid;
  gap: 2px;
  min-height: 56px;
  padding: 8px 12px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.admin .hours-presets-grid button:hover {
  border-color: var(--color-primary);
}

.admin .hours-presets-grid button span {
  color: var(--color-muted);
  font-size: 0.8rem;
}

.admin .hours-presets-grid .hours-preset-own {
  border-style: dashed;
  color: var(--color-action-create);
}

.admin .hours-presets-grid .hours-preset-own strong {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.admin .hours-undo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  padding: 6px 6px 6px 14px;
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  font-size: 0.88rem;
}

/* The hours the page will say (opening hours): the card's first line, tinted. */
.admin .hours-result {
  display: flex;
  gap: 10px;
  align-items: baseline;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--color-primary-soft);
  font-size: 0.9rem;
}

.admin .hours-result strong {
  color: var(--color-primary);
  white-space: nowrap;
}

.admin .hours-groups:disabled {
  opacity: 0.7;
}

@media (max-width: 600px) {
  .admin .hours-group-head {
    grid-template-columns: 12px minmax(0, 1fr) auto auto;
    row-gap: 0;
  }

  .admin .hours-group-head .hours-group-hours {
    grid-row: 2;
    grid-column: 2;
  }

  /* Seven days share the row: each as wide as it can be, 44px tall, rounded instead of round. */
  .admin .hours-days {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 4px;
  }

  .admin .hours-day {
    width: auto;
    border-radius: 12px;
  }

  .admin .hours-range {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    justify-content: stretch;
  }

  .admin .hours-range-break {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto;
  }

  .admin .hours-closed {
    grid-template-columns: 12px minmax(0, 1fr);
  }

  .admin .hours-closed-days {
    grid-column: 1 / -1;
    justify-content: flex-start;
  }

  .admin .hours-presets-grid {
    grid-template-columns: 1fr 1fr;
  }

  .admin .hours-result {
    flex-direction: column;
    gap: 2px;
  }
}

.admin .color-field {
  display: flex;
  align-items: center;
  gap: 12px;
}

.admin .definitions {
  margin: 0;
  display: grid;
  gap: 8px;
}

.admin .definitions > div {
  display: grid;
  grid-template-columns: minmax(90px, 35%) 1fr;
  gap: 12px;
}

.admin .definitions dt {
  color: var(--color-muted);
}

.admin .definitions dd {
  margin: 0;
  font-weight: 500;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* documents: the Documents tab (business-features item 2) */
.admin .document-name {
  overflow-wrap: anywhere;
}

.admin .document-file-input {
  min-height: 44px;
  padding: 8px 0;
}

.admin .document-upload-status:empty {
  display: none;
}

.admin .document-upload-done {
  color: var(--color-success);
  font-weight: 500;
  overflow-wrap: anywhere;
}

/* admin-knowledge: Documents › Assistant knowledge, the files only the assistant reads (assistant-knowledge item 2) */
.admin .admin-knowledge .card {
  margin-bottom: 16px;
}

.admin .admin-knowledge-switch {
  align-items: flex-start;
}

/* The label wraps on a phone: the switch stays its size, on the first line. */
.admin .admin-knowledge-switch input {
  flex: none;
}

.admin .admin-knowledge-hint {
  margin: 4px 0 0;
  font-size: 0.85rem;
  color: var(--color-muted);
}

.admin .admin-knowledge-warning {
  margin: 12px 0 0;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
  font-size: 0.9rem;
}

.admin .admin-knowledge-name {
  overflow-wrap: anywhere;
}

/* A file's status in words under its name: the row's tint is never the only signal. */
.admin .admin-knowledge-status {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 8px;
  margin-top: 2px;
  font-size: 0.85rem;
  color: var(--color-muted);
  min-width: 12rem;
}

.admin .admin-knowledge-status-word {
  font-weight: 600;
  color: var(--color-text);
}

.admin .admin-knowledge-file-input {
  min-height: 44px;
  padding: 8px 0;
  max-width: 100%;
}

.admin .admin-knowledge-upload-status:empty {
  display: none;
}

/* appointments: the Appointments tab (business-features item 5) */

.admin .appointments-tab {
  display: grid;
  gap: 16px;
}

/* messages: the Contact tab's inbox (what visitors wrote, and the owner's follow-up) */

.admin .messages-tab {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.admin .message-cell {
  min-width: 200px;
}

.admin .message-excerpt {
  display: -webkit-box;
  overflow: hidden;
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
}

.admin .message-facts {
  display: grid;
  grid-template-columns: minmax(80px, max-content) 1fr;
  gap: 4px 14px;
  margin: 0;
}

.admin .message-facts dt {
  color: var(--color-text-muted);
}

.admin .message-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.admin .message-whole {
  white-space: pre-line;
}

/* orders: the Orders tab (the inbox, the order's modal, the settings card) */

/* One column that may shrink below its table's width: the table scrolls inside its wrap, not the page. */
.admin .orders-tab {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 16px;
}

.admin .orders-tab .card {
  margin: 0;
}

.admin .order-code {
  letter-spacing: 0.04em;
}

.admin .order-details {
  display: grid;
  gap: 18px;
}

.admin .order-details-title {
  margin: 0 0 6px;
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.admin .order-details p {
  margin: 0 0 8px;
}

.admin .order-facts {
  display: grid;
  grid-template-columns: minmax(90px, max-content) 1fr;
  gap: 4px 14px;
  margin: 0;
}

.admin .order-facts dt {
  color: var(--color-text-muted);
}

.admin .order-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.admin .order-pre {
  white-space: pre-line;
}

.admin .order-lines,
.admin .order-history {
  display: grid;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin .order-lines li,
.admin .order-history li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  overflow-wrap: anywhere;
}

.admin .order-quote {
  display: block;
  margin-top: 4px;
  font-style: italic;
  overflow-wrap: anywhere;
}

.admin .order-details-actions {
  flex-wrap: wrap;
}

.admin .order-settings {
  display: grid;
  gap: 16px;
}

.admin .order-settings-group {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  border: 0;
}

.admin .order-methods {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 8px;
}

/* A business's AI key: removing it is asked inside the card, before anything is removed. */
.admin .ai-key-remove {
  display: grid;
  gap: 8px;
  margin-bottom: 12px;
  padding: 12px;
  border: 1px solid var(--color-action-danger);
  border-radius: var(--radius-sm);
  background: var(--color-action-danger-soft);
}

.admin .ai-key-remove p {
  margin: 0;
}

/* Options › AI keys: one card per use, each in its own form. */
.admin .ai-keys {
  display: grid;
  gap: 16px;
}

/* Options › Maintenance: Update the app, then the DynamoDB import. */
.admin .maintenance-tools {
  display: grid;
  gap: 16px;
}

.admin .appointment-settings {
  display: grid;
  gap: 16px;
}

.admin .appointment-settings .card {
  margin: 0;
}

.admin .blocked-dates {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}

.admin .blocked-dates li {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding-left: 12px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
}

.admin .block-date {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}

.admin .block-date .field {
  flex: 1 1 180px;
  max-width: 240px;
}

.admin .appointment-note {
  min-width: 160px;
  white-space: pre-line;
  overflow-wrap: anywhere;
}

@media (max-width: 480px) {
  .admin .block-date .field {
    max-width: none;
  }

  .admin .block-date .btn {
    width: 100%;
  }
}

/* Every tab's views row: the views at the left (when it has some) and "On my page" at the right, so the control never
   moves between tabs; under the views below 600px. A tab with neither (AI key, Plan) has no row. */

.admin .views-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px 16px;
  margin: -12px 0 18px;
}

.admin .views-row .segmented {
  margin: 0;
}

.admin .views-slot {
  /* As wide as its link: an empty slot takes no room, and it wraps under the views only when it does not fit (below
     600px always, next rule). */
  flex: 1 1 auto;
  display: flex;
  justify-content: flex-end;
  min-width: 0;
}

@media (max-width: 599px) {
  .admin .views-slot {
    flex-basis: 100%;
    justify-content: flex-start;
  }
}

.admin .switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-weight: 600;
  cursor: pointer;
}

/* The checkbox drawn as a sliding switch; it stays a real checkbox (role="switch") for keyboards and readers. */
.admin .switch input {
  appearance: none;
  position: relative;
  width: 44px;
  min-height: 24px;
  height: 24px;
  padding: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: 999px;
  background: var(--color-neutral-soft);
  cursor: pointer;
  transition: background-color 0.15s;
}

.admin .switch input::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: var(--shadow);
  transition: transform 0.15s;
}

.admin .switch input:checked {
  background: var(--color-primary);
  border-color: var(--color-primary);
}

.admin .switch input:checked::after {
  transform: translateX(20px);
}

@media (prefers-reduced-motion: reduce) {
  .admin .switch input,
  .admin .switch input::after {
    transition: none;
  }
}

/* configure-analytics: Options › Analytics, the codes per surface (platform-controls item 1) */
.admin .configure-analytics-surfaces {
  margin: 12px 0;
  padding-left: 18px;
  display: grid;
  gap: 6px;
  font-size: 0.9rem;
}

/* One code per surface: three across on a computer, one under the other on a phone. */
.admin .configure-analytics-codes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px 16px;
}

@media (max-width: 760px) {
  .admin .configure-analytics-codes {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* configure-limits: Options › Limits, the default caps (platform-controls item 2) */
.admin .configure-limits .form-grid {
  margin: 16px 0;
}

/* set-business-limits: All businesses › Limits, a business's caps with its usage (platform-controls item 2) */
/* "Copy the defaults" with its note beside it, under it on a phone. */
.admin .set-business-limits-copy {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

/* disable-business: All businesses › Disable / Enable (platform-controls item 4); delete-business: › Delete (item 6) */
.admin .disable-business-question,
.admin .delete-business-question {
  margin: 0;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* business-usage: the owner's caps and usage on the Plan tab (platform-controls item 3, admin-redesign item 7) */
.admin .business-usage {
  margin-top: 16px;
}

.admin .business-usage__rest {
  margin: 12px 0 0;
  color: var(--color-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.admin .business-usage__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 12px;
}

@media (min-width: 720px) {
  .admin .business-usage__list {
    grid-template-columns: 1fr 1fr;
    column-gap: 24px;
  }
}

.admin .business-usage__row {
  display: grid;
  gap: 6px;
  padding: 10px 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
}

.admin .business-usage__row--near {
  border-color: var(--color-warning);
  background: var(--color-warning-soft);
}

.admin .business-usage__row--reached {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}

.admin .business-usage__head,
.admin .business-usage__foot {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 12px;
  flex-wrap: wrap;
}

.admin .business-usage__foot:empty {
  display: none;
}

.admin .business-usage__label {
  font-size: 0.9rem;
}

.admin .business-usage__value {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.admin .business-usage__bar {
  height: 6px;
  border-radius: 3px;
  background: var(--color-edge);
  overflow: hidden;
}

.admin .business-usage__fill {
  display: block;
  height: 100%;
  border-radius: 3px;
  background: var(--color-primary);
}

.admin .business-usage__row--near .business-usage__fill {
  background: var(--color-warning);
}

.admin .business-usage__row--reached .business-usage__fill {
  background: var(--color-danger);
}

.admin .business-usage__note {
  color: var(--color-muted);
  font-size: 0.85rem;
}

.admin .business-usage__state {
  font-size: 0.85rem;
  font-weight: 600;
}

.admin .business-usage__row--near .business-usage__state {
  color: var(--color-warning);
}

.admin .business-usage__row--reached .business-usage__state {
  color: var(--color-danger);
}

/* configure-billing: Options › Billing, Stripe's keys and the price table (billing item 3) */
.admin .configure-billing__mode {
  border: 0;
  margin: 0 0 var(--space-4, 16px);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
  align-items: center;
}

.admin .configure-billing__mode legend {
  width: 100%;
  padding: 0;
}

.admin .configure-billing__choice {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 14px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  cursor: pointer;
}

.admin .configure-billing__choice:has(input:checked) {
  border-color: var(--color-primary, currentColor);
  font-weight: 600;
}

.admin .configure-billing__mode > p {
  width: 100%;
  margin: 0;
}

.admin .configure-billing__test {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin-top: 12px;
}

.admin .configure-billing__price {
  margin-top: 16px;
}

.admin .configure-billing__line {
  margin: 0 0 4px;
  font-size: 1rem;
}

.admin .configure-billing__price .admin-field-hint {
  overflow-wrap: anywhere;
}

/* extend-trial: All businesses › Extend trial (billing item 3) */
.admin .extend-trial__status {
  margin: 0;
}

/* choose-modules: the owner's Plan tab, modules, prices, Pay and the portal (billing item 4) */

.admin .choose-modules__list {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each module is a card: the whole box is the checkbox's label, so a finger can tap anywhere on it. */
.admin .choose-modules__module {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  padding: 12px 14px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.admin .choose-modules__module.is-chosen {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.admin .choose-modules__module:has(input:disabled) {
  cursor: default;
}

.admin .choose-modules__text {
  display: grid;
  gap: 2px;
}

.admin .choose-modules__price {
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.admin .choose-modules__addons {
  margin: 16px 0 0;
  font-size: 1rem;
}

.admin .choose-modules__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--color-border);
  font-size: 1.05rem;
}

.admin .choose-modules__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

@media (max-width: 600px) {
  /* The price goes under the words on a phone, beside nothing. */
  .admin .choose-modules__module {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .admin .choose-modules__price {
    grid-column: 2;
  }

  .admin .choose-modules__actions .btn {
    width: 100%;
    min-height: 44px;
  }
}

/* package-plan: the Plan tab of a business on a package: the package card and "Add to your plan" */

.admin .package-plan__name {
  margin: 8px 0 0;
  font-size: 1.15rem;
}

.admin .package-plan__subtitle {
  margin: 16px 0 8px;
  font-size: 1rem;
}

.admin .package-plan__ticks {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin .package-plan__ticks li {
  position: relative;
  min-height: 24px;
  padding-left: 28px;
}

.admin .package-plan__ticks li::before {
  content: '';
  position: absolute;
  left: 6px;
  top: 4px;
  width: 6px;
  height: 11px;
  border: solid var(--color-action-confirm, var(--color-primary));
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* An included module is a row with no switch: the price column says so. */
.admin .package-plan .choose-modules__module:not(:has(input)) {
  grid-template-columns: minmax(0, 1fr) auto;
  cursor: default;
}

.admin .package-plan .choose-modules__list {
  margin: 12px 0;
}

@media (max-width: 600px) {
  .admin .package-plan .choose-modules__module:not(:has(input)) {
    grid-template-columns: minmax(0, 1fr);
  }

  .admin
    .package-plan
    .choose-modules__module:not(:has(input))
    .choose-modules__price {
    grid-column: 1;
  }
}

/* plan-choices: Change plan's "Plans" card (docs/pdr/prd-llyner-catalog.md LCA-05): one block per plan, its switch last */

.admin .plan-choices__list {
  display: grid;
  gap: 16px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin .plan-choices__plan {
  display: grid;
  gap: 8px;
  justify-items: start;
}

.admin .plan-choices__plan + .plan-choices__plan {
  padding-top: 16px;
  border-top: 1px solid var(--color-border);
}

.admin .plan-choices__plan p {
  margin: 0;
}

.admin .plan-choices__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 12px;
  width: 100%;
}

.admin .plan-choices__head .package-plan__name {
  margin: 0;
}

@media (max-width: 600px) {
  .admin .plan-choices__plan > .action-btn,
  .admin .plan-choices__plan > button {
    width: 100%;
  }
}

/* billing-banner: the trial's days left, or that it ended or a payment failed, above a business's tabs (billing item 4) */

.admin .billing-banner .alert > span {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.admin .billing-banner__label {
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.78rem;
}

.admin .billing-banner__text {
  flex: 1 1 16rem;
  color: var(--color-text);
}

.admin .billing-banner__action {
  min-height: 44px;
}

.admin .billing-banner__note {
  flex-basis: 100%;
  font-weight: 600;
}

@media (max-width: 600px) {
  .admin .billing-banner__action {
    width: 100%;
  }
}

/* missing-details-banner: what the details save would refuse, by tab, above a business's tabs (completeness item 2) */

.admin .missing-details-banner .alert > span {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 12px;
}

.admin .missing-details-banner__text {
  flex: 1 1 16rem;
  color: var(--color-text);
}

.admin .missing-details-banner__tabs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* "Profile (3) · Contact (3)": the dot between, each link 44px to a finger. */
.admin .missing-details-banner__tabs li + li::before {
  content: '·';
  margin: 0 4px;
  color: var(--color-muted);
}

.admin .missing-details-banner__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 4px;
  font-weight: 600;
  color: var(--color-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* admin-campaigns: Platform › Campaigns, the list with its leads and wizards (campaigns item 1) */
.admin .admin-campaigns {
  display: block;
}

.admin .admin-campaigns .table td:first-child {
  min-width: 160px;
}

/* The home page's line (docs/pdr/prd-home-page.md HP-01): "llyner.com/ opens …" and Change; below 600px the button
   goes under the words. */
.admin .home-page-line a {
  font-weight: 600;
  overflow-wrap: anywhere;
}

@media (max-width: 600px) {
  .admin .home-page-line .tab-intro-end {
    width: 100%;
    margin-left: 0;
  }
}

/* One column at every width: the choice, its list, the note. */
.admin .home-page-dialog {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 14px;
}

.admin .home-page-dialog > .segmented {
  align-self: flex-start;
}

.admin .home-page-dialog__note {
  margin: 0;
  color: var(--color-muted);
}

/* edit-campaign: the create / edit modal of a campaign (campaigns item 1) */
.admin .edit-campaign__slug .admin-field-hint {
  font-family: ui-monospace, monospace;
  overflow-wrap: anywhere;
}

/* admin-posts: the owner's Posts tab, its table, editor and caps (blog item 3) */
.admin .admin-posts-title {
  overflow-wrap: anywhere;
}

.admin .admin-posts-excerpt {
  max-width: 48ch;
  overflow-wrap: anywhere;
}

/* On a phone the row's four actions would squeeze the Post column to a word's width and break "autumn" into
   "autu mn": the column keeps room for words, and the table scrolls inside its frame like the admin's other tables. */
.admin .admin-posts-title,
.admin .admin-posts-excerpt {
  min-width: 10rem;
}

/* ── Admin redesign (docs/pdr/prd-admin-redesign.md), item 0: the kit's new pieces ─────────────────────────────── */

/* A form at reading width; tables keep the shell's full width (A-25). */
.admin .narrow {
  max-width: 760px;
}

/* A tab bar (and a ChoiceRow) that overflows fades on the side that hides tabs (A-01; useScrollEdges). */
/* A tab scrolled into view stops clear of the fades. */
.admin .tabs-page {
  scroll-padding-inline: 48px;
}

.admin .tabs-page.tabs-more-end,
.admin .choice-row.choice-row-more-end {
  mask-image: linear-gradient(to right, #000 calc(100% - 48px), transparent);
}

.admin .tabs-page.tabs-more-start,
.admin .choice-row.choice-row-more-start {
  mask-image: linear-gradient(to left, #000 calc(100% - 48px), transparent);
}

.admin .tabs-page.tabs-more-start.tabs-more-end,
.admin .choice-row.choice-row-more-start.choice-row-more-end {
  mask-image: linear-gradient(
    to right,
    transparent,
    #000 48px,
    #000 calc(100% - 48px),
    transparent
  );
}

/* A tab's views: a segmented control attached under the tab bar (A-26). */
.admin .segmented {
  display: inline-flex;
  flex-wrap: nowrap;
  max-width: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  gap: 2px;
  margin: -12px 0 18px;
  padding: 3px;
  background: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.admin .segment {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 6px 12px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-muted);
  font: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background 0.15s,
    color 0.15s;
}

.admin .segment::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

.admin .segment:hover {
  color: var(--color-text);
}

.admin .segment-active {
  background: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow);
}

/* A few short views on a phone: the control as wide as the row, each view an equal share (Your brand). */
@media (max-width: 599px) {
  .admin .views-row .segmented-fill {
    display: flex;
    width: 100%;
  }

  .admin .segmented-fill .segment {
    flex: 1 1 0;
    justify-content: center;
  }
}

/* A switch inside a view (List / Week): smaller, not attached to the tab bar. Its targets stay 44px (::before). */
.admin .segmented-sm {
  margin: 0;
}

.admin .segmented-sm .segment {
  min-height: 30px;
  padding: 4px 10px;
  font-size: 0.85rem;
}

.admin .segment:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* How many things wait somewhere. */
.admin .count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.admin .count-badge-warning {
  background: var(--color-warning-soft);
  color: var(--color-warning);
}

.admin .count-badge-neutral {
  background: var(--color-neutral-soft);
  color: var(--color-neutral);
}

/* What happened since the owner last opened the tab (docs/pdr/prd-notifications.md): filled, the one blue circle. */
.admin .count-badge-new {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

/* A row new since the tab was last opened: the blue of the sidebar's circle, beside the row's first line. */
.admin .new-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-inline-start: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.5;
  text-transform: uppercase;
  vertical-align: middle;
}

.admin .new-chip::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}

/* What blocks the owner: details the save refuses (docs/pdr/prd-completeness.md). */
.admin .count-badge-danger {
  background: var(--color-danger-soft);
  color: var(--color-danger);
}

/* The row legend as the status filter: chips with the colour and the count (A-73). */
.admin .row-legend-chips {
  gap: 6px;
}

.admin .status-chip {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 32px;
  padding: 4px 12px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 0.85rem;
  cursor: pointer;
}

.admin .status-chip::after {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

.admin .status-chip[aria-pressed='true'] {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.admin .status-chip-count {
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* Below 600px a table's rows are cards: each cell on its own line, its column's name before it (A-80). */
@media (max-width: 600px) {
  .admin .table-cards thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .admin .table-cards,
  .admin .table-cards tbody,
  .admin .table-cards tr,
  .admin .table-cards td {
    display: block;
    width: 100%;
  }

  .admin .table-cards tr {
    padding: 10px 14px;
    border-bottom: 1px solid var(--color-border);
  }

  /* A card's status: the whole card tinted, its bar down the card's edge, clear of the text the padding moves in. */
  .admin .table-cards tr.row-tone {
    background: color-mix(in srgb, var(--row-tint) 45%, var(--color-surface));
    box-shadow: inset 4px 0 0 var(--row-accent);
  }

  .admin .table-cards tr.row-tone td {
    background: transparent;
  }

  .admin .table-cards tr.row-tone td:first-child {
    box-shadow: none;
  }

  .admin .table-cards tbody tr:last-child {
    border-bottom: none;
  }

  .admin .table-cards td {
    padding: 4px 0;
    border-bottom: none;
  }

  .admin .table-cards td[data-label]::before {
    content: attr(data-label);
    display: block;
    color: var(--color-muted);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
  }

  /* The first cell is the row's title; the actions sit at the bottom, full width. */
  .admin .table-cards td:first-child::before,
  .admin .table-cards td.actions::before {
    display: none;
  }

  .admin .table-cards td.actions {
    width: 100%;
    padding-top: 10px;
  }

  /* The actions wrap onto lines of their own: each button is a finger's 44px itself (Tacoma's rule), as the hit
     areas of small buttons on lines close together would overlap. */
  .admin .table-cards .row-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
  }

  .admin .table-cards .row-actions .btn {
    min-height: 44px;
  }

  .admin .table-wrap:has(.table-cards) {
    overflow-x: visible;
  }
}

/* A list loading in its own shape. */
.admin .skeleton-rows {
  display: grid;
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
}

.admin .skeleton-row {
  display: grid;
  gap: 8px;
  padding: 14px;
  background: var(--color-surface);
}

.admin .skeleton-bar {
  display: block;
  width: 40%;
  height: 10px;
  border-radius: 4px;
  background: var(--color-neutral-soft);
  animation: admin-skeleton 1.2s ease-in-out infinite alternate;
}

.admin .skeleton-bar-wide {
  width: 70%;
}

@keyframes admin-skeleton {
  to {
    opacity: 0.45;
  }
}

/* Unsaved changes: a bar at the bottom of the form, sticky so Save is always in reach (A-33, A-82). */
.admin .save-bar {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-top: 20px;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
}

.admin .save-bar-text {
  margin: 0;
  font-weight: 600;
}

.admin .save-bar-message {
  min-width: 0;
}

/* What blocks the save on another tab: a line, then a link to each tab, wrapping on a phone (SAV-06). */
.admin .save-bar-problems {
  margin-top: 6px;
}

.admin .save-bar-problems-text {
  margin: 0;
}

.admin .save-bar-links {
  display: flex;
  flex-wrap: wrap;
  /* Apart enough that two links' 44px hit areas never overlap. */
  gap: 8px;
  margin: 8px 0 0;
  padding: 0;
  list-style: none;
}

.admin .save-bar-link {
  min-height: 44px;
  white-space: normal;
}

.admin .save-bar-actions {
  display: flex;
  gap: 8px;
}

/* The header's Save (SaveControl): the status, Discard and Save come in before everything else in the header's actions,
   so "View page" and the buttons after it never move when the form has something to save (they are right-aligned).
   Where it does not fit, the status goes first, then the whole group gives way to the bar. Quiet (and out of reach)
   while the bar at the bottom has the buttons. Never pinned. */
.admin .save-slot {
  display: contents;
}

.admin .header-save {
  display: contents;
}

.admin .header-save-status {
  order: -3;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--color-warning);
}

.admin .header-save-status::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
}

.admin .header-save-refused {
  color: var(--color-danger);
}

.admin .header-save-status-hidden {
  display: none;
}

.admin .header-save > .btn-ghost {
  order: -2;
}

.admin .header-save-button {
  order: -1;
}

.admin .header-save-quiet > .btn {
  visibility: hidden;
}

.admin .save-pulse {
  animation: save-pulse 1.1s ease-out 1;
}

@keyframes save-pulse {
  0% {
    box-shadow: 0 0 0 0
      color-mix(in srgb, var(--color-primary) 70%, transparent);
  }
  70% {
    box-shadow: 0 0 0 12px
      color-mix(in srgb, var(--color-primary) 0%, transparent);
  }
  100% {
    box-shadow: 0 0 0 0 transparent;
  }
}

.admin .page-actions {
  align-items: center;
}

@media (max-width: 599px) {
  .admin .header-save {
    display: none;
  }
}

/* The page's buttons (View page, Share · QR, Sign-in link): side by side on a computer and a tablet; on a phone one
   "Page ▾" menu (a bottom sheet) at the right of the business's name, on its line, so the row never wraps. */
.admin .header-page-buttons {
  display: contents;
}

.admin .menu-button.header-page-menu {
  display: none;
}

@media (max-width: 599px) {
  .admin .header-page-buttons {
    display: none;
  }

  .admin .menu-button.header-page-menu {
    display: inline-flex;
    border-color: var(--color-action-open);
    color: var(--color-action-open);
    font-weight: 600;
  }

  .admin .menu-button.header-page-menu:hover,
  .admin .menu-button.header-page-menu[aria-expanded='true'] {
    border-color: var(--color-action-open);
    background: var(--color-action-open-soft);
  }

  /* The name takes the line's room and gives way to a wrap only when an open item's actions are there too. */
  .admin .page-header:has(.header-page-menu) {
    align-items: flex-start;
  }

  .admin .page-header:has(.header-page-menu) > div:first-child {
    flex: 1 1 12rem;
    min-width: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .admin .skeleton-bar {
    animation: none;
  }

  .admin .save-pulse {
    animation: none;
  }
}

/* ── Admin redesign, item 9 (look and feel) ──────────────────────────────────────────────────────────────────────── */

/* Numbers line up in tables, counts and money (A-71). */
.admin .table td,
.admin .count-badge,
.admin .status-chip-count,
.admin .pager {
  font-variant-numeric: tabular-nums;
}

/* Table meta (the second line of a cell) readable at arm's length (A-72). */
.admin .table td .small,
.admin .table td .muted {
  font-size: 0.85rem;
}

/* A canvas's zoom control (ZoomControl: the Lead flows board, the Board's kanban): −, the percent, +, Fit, joined in
   one raised bar of 44px targets; the canvas places it. */
.admin .zoom-control {
  display: flex;
  align-items: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.admin .zoom-control-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 6px;
  color: var(--color-text);
  font: inherit;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  background: transparent;
  border: 0;
  cursor: pointer;
}

.admin .zoom-control-btn + .zoom-control-btn {
  border-left: 1px solid var(--color-border);
}

.admin .zoom-control-btn:hover:not(:disabled) {
  background: var(--color-primary-soft);
}

.admin .zoom-control-btn:disabled {
  color: var(--color-muted);
  cursor: default;
}

.admin .zoom-control-level {
  min-width: 60px;
}

/* studio: the Studio tab (docs/pdr/prd-studio.md) */
.admin .studio-choice {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.admin .studio-view {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.admin .studio-video {
  width: 100%;
  max-height: 60vh;
  border-radius: var(--radius);
  background: var(--color-surface-sunken);
}

.admin .studio-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 0;
}

.admin .studio-facts dt {
  color: var(--color-muted);
}

.admin .studio-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.admin .studio-file {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  min-height: 44px;
}

/* The documents attached to a Studio topic: one row each, its name and its Remove (44px tall: a finger's room). */
.admin .studio-files {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin .studio-files .studio-file {
  flex-wrap: nowrap;
  gap: 8px 12px;
  padding: 0 4px 0 12px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.admin .studio-file-name {
  flex: 1;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* A Studio file field: drop a file on it, or choose one. */
.admin .studio-drop {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 8px 12px;
  min-height: 88px;
  padding: 16px;
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface-sunken);
  color: var(--color-muted);
  text-align: center;
}

.admin .studio-drop.is-dropping {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.admin .studio-drop.is-off {
  opacity: 0.6;
}

/*
 * Studio's voice recorder (docs/pdr/prd-studio.md): one box under the voice choice. Its buttons are 44px tall and
 * full width on a phone, so the thumb finds Record and Stop; the player takes the box's width.
 */
.admin .studio-recorder-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  min-height: 72px;
  padding: 12px 16px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface-sunken);
}

.admin .studio-recorder-box .btn {
  min-height: 44px;
}

.admin .studio-recorder-box .btn svg {
  flex-shrink: 0;
}

.admin .studio-recorder-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}

.admin .studio-recorder-live {
  display: inline-flex;
  flex: 1;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-variant-numeric: tabular-nums;
}

.admin .studio-recorder-dot {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--color-danger);
  animation: studio-recorder-pulse 1.2s ease-in-out infinite;
}

@keyframes studio-recorder-pulse {
  50% {
    opacity: 0.3;
  }
}

@media (prefers-reduced-motion: reduce) {
  .admin .studio-recorder-dot {
    animation: none;
  }
}

.admin .studio-recorder-audio {
  width: 100%;
  min-height: 44px;
}

.admin .studio-recorder-take {
  flex-basis: 100%;
  overflow-wrap: anywhere;
}

@media (max-width: 599px) {
  .admin .studio-recorder-actions,
  .admin .studio-recorder-actions .btn,
  .admin .studio-recorder-box > .btn {
    width: 100%;
  }

  .admin .studio-recorder-actions .btn,
  .admin .studio-recorder-box > .btn {
    justify-content: center;
  }
}

/* A view whose label is long has a short one for phones (SegmentOption.shortLabel). */
.admin .segment-label-short {
  display: none;
}
@media (max-width: 599px) {
  .admin .segment-label-long {
    display: none;
  }
  .admin .segment-label-short {
    display: inline;
  }
}

/*
 * The admin's actions (docs/pdr/prd-admin-polish.md, C.1 – C.4): the action colours, buttons outside tables, a row's
 * SplitButton and its menu. Loaded after admin.css (index.ts), scoped under `.admin`, light and dark.
 */
.admin,
.admin[data-theme='light'] {
  /* The action colours (C.1): what a button does, the same hue everywhere. A full shade for fills and text, a soft
     shade for tints; the full shade on its soft one, on the surface, and --color-on-action on the full one are all
     at least 4.5:1 (kit.actions.test.tsx checks it). */
  --color-action-confirm: #15803d;
  --color-action-confirm-soft: #dcfce7;
  --color-action-danger: #b91c1c;
  --color-action-danger-soft: #fee2e2;
  --color-action-edit: #1260d6;
  --color-action-edit-soft: #e8f1fe;
  --color-action-open: #6d28d9;
  --color-action-open-soft: #f3eefe;
  --color-action-file: #0f766e;
  --color-action-file-soft: #e0f5f2;
  --color-action-create: #4338ca;
  --color-action-create-soft: #eef0fd;
  --color-action-revert: #b45309;
  --color-action-revert-soft: #fef3c7;
  --color-action-contact: #be185d;
  --color-action-contact-soft: #fce7f3;
  --color-on-action: #ffffff;
}

.admin[data-theme='dark'] {
  --color-action-confirm: #4ade80;
  --color-action-confirm-soft: #0f2e1c;
  --color-action-danger: #f87171;
  --color-action-danger-soft: #3b1518;
  --color-action-edit: #6aa8ff;
  --color-action-edit-soft: #14264a;
  --color-action-open: #c4a5f5;
  --color-action-open-soft: #271c45;
  --color-action-file: #5eead4;
  --color-action-file-soft: #0d2e2b;
  --color-action-create: #a5b4fc;
  --color-action-create-soft: #1e2350;
  --color-action-revert: #fbbf24;
  --color-action-revert-soft: #3a2a0c;
  --color-action-contact: #f9a8d4;
  --color-action-contact-soft: #3a1729;
  --color-on-action: #0b1120;
}

/* Action buttons (C.4): outlined in the colour of what they do, on a plain face so they stand out on tinted rows too;
   the group's one main action is filled in its colour (`main`). Cancel / Clear selection stay a plain ghost button. */
.admin .btn-action {
  --action: var(--color-action-confirm);
  --action-soft: var(--color-action-confirm-soft);
  background: var(--color-surface);
  border-color: color-mix(in srgb, var(--action) 55%, transparent);
  color: var(--action);
  box-shadow: 0 1px 0 var(--color-edge);
}

.admin .btn-action[class*='action-'] {
  border-color: color-mix(in srgb, var(--action) 55%, transparent);
}

.admin .btn-action:hover:not(:disabled) {
  background: var(--action-soft);
  border-color: var(--action);
}

.admin .btn-action.btn-main {
  background: var(--action);
  border-color: var(--action);
  color: var(--color-on-action);
}

.admin .btn-action.btn-main:hover:not(:disabled) {
  background: color-mix(in srgb, var(--action) 85%, var(--color-text));
  border-color: color-mix(in srgb, var(--action) 85%, var(--color-text));
}

/* One pair of tokens per kind; every kind-coloured control (button, split button, menu item) sets these two. The
   `.btn-action.action-*` selectors outrank admin.css's older neutral outline of edit, open and setup. */
.admin .action-confirm,
.admin .btn-action.action-confirm {
  --action: var(--color-action-confirm);
  --action-soft: var(--color-action-confirm-soft);
}

.admin .action-danger,
.admin .btn-action.action-danger {
  --action: var(--color-action-danger);
  --action-soft: var(--color-action-danger-soft);
}

.admin .action-edit,
.admin .btn-action.action-edit {
  --action: var(--color-action-edit);
  --action-soft: var(--color-action-edit-soft);
}

.admin .action-open,
.admin .btn-action.action-open {
  --action: var(--color-action-open);
  --action-soft: var(--color-action-open-soft);
}

.admin .action-file,
.admin .btn-action.action-file {
  --action: var(--color-action-file);
  --action-soft: var(--color-action-file-soft);
}

.admin .action-create,
.admin .action-setup,
.admin .btn-action.action-create,
.admin .btn-action.action-setup {
  --action: var(--color-action-create);
  --action-soft: var(--color-action-create-soft);
}

.admin .action-revert,
.admin .btn-action.action-revert {
  --action: var(--color-action-revert);
  --action-soft: var(--color-action-revert-soft);
}

.admin .action-contact,
.admin .btn-action.action-contact {
  --action: var(--color-action-contact);
  --action-soft: var(--color-action-contact-soft);
}

/* A group of buttons outside a table (ActionGroup): the destructive one at the start, the rest at the end. */
/* Grows to fill a flex footer or toolbar it sits in, so its start and end are the row's edges. */
.admin .action-group {
  display: flex;
  flex: 1 1 auto;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
}

.admin .action-group-start {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-right: auto;
}

.admin .action-group-end {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-left: auto;
}

/*
 * A row's actions (SplitButton, C.2): the main action worded and joined edge to edge to a narrow chevron, one control
 * with one radius and a thin divider, filled in the main action's colour. "More ▾" alone when there is no main action.
 */
/* The default kind sits in :where() so any action-<kind> class on the control wins. */
:where(.admin .split-button) {
  --action: var(--color-action-open);
  --action-soft: var(--color-action-open-soft);
}

.admin .split-button {
  display: inline-flex;
  align-items: stretch;
  border-radius: var(--radius);
  vertical-align: middle;
}

.admin .split-button > button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 36px;
  margin: 0;
  border: 1px solid var(--action);
  font: inherit;
  font-size: 0.87rem;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.admin .split-button > .split-main,
.admin .split-button > .split-toggle {
  background: var(--action);
  color: var(--color-on-action);
}

.admin .split-button > .split-main {
  padding: 0 14px;
  border-radius: var(--radius) 0 0 var(--radius);
}

.admin .split-button.split-button-single > .split-main {
  border-radius: var(--radius);
}

.admin .split-button > .split-toggle {
  width: 34px;
  padding: 0;
  border-left-color: color-mix(
    in srgb,
    var(--color-on-action) 45%,
    var(--action)
  );
  border-radius: 0 var(--radius) var(--radius) 0;
}

.admin .split-button > .split-main:hover:not(:disabled),
.admin .split-button > .split-toggle:hover,
.admin .split-button > .split-toggle[aria-expanded='true'] {
  background: color-mix(in srgb, var(--action) 85%, var(--color-text));
}

.admin .split-button > .split-more {
  padding: 0 10px 0 14px;
  border-color: var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
}

.admin .split-button > .split-more:hover,
.admin .split-button > .split-more[aria-expanded='true'] {
  background: var(--color-bg);
}

/* `moreIcon`: the icon alone, a round button (a picture's ⋯ on its tile). */
.admin .split-button > .split-more.split-icon {
  width: 32px;
  min-width: 32px;
  height: 32px;
  padding: 0;
  border-radius: 50%;
}

.admin .split-button > button:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.admin .split-button > button:focus-visible {
  z-index: 1;
  outline: 2px solid var(--color-text);
  outline-offset: 2px;
}

/* 44px to a finger, whatever the button looks like. */
.admin .split-button > button::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: max(100%, 44px);
  height: max(100%, 44px);
  transform: translate(-50%, -50%);
}

/* A layer on <body> (menus, sheets): carries the theme's tokens, takes no room and paints nothing itself. */
.admin.admin-layer {
  min-height: 0;
  background: none;
}

/* The menu (C.3): groups under a small uppercase heading, the destructive group last after a divider; each item on its
   action's soft tint, icon and label in the full hue, deeper on hover and focus. */
.admin .action-menu {
  position: fixed;
  z-index: 1000;
  width: 300px;
  max-width: calc(100vw - 16px);
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  box-sizing: border-box;
  padding: 4px 6px 8px;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: 10px;
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.4;
}

.admin .action-menu-heading {
  margin: 10px 10px 2px;
  color: var(--color-muted);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.admin .action-menu-divider {
  margin: 8px 4px 4px;
  border: 0;
  border-top: 1px solid var(--color-border);
}

.admin .action-menu-item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  margin-top: 4px;
  padding: 8px 10px;
  border: 0;
  border-radius: var(--radius);
  background: var(--action-soft);
  color: var(--action);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.admin .action-menu-item:hover,
.admin .action-menu-item:focus-visible,
.admin .action-menu-item[aria-expanded='true'] {
  background: color-mix(in srgb, var(--action) 16%, var(--action-soft));
}

.admin .action-menu-item:focus-visible {
  outline: 2px solid var(--action);
  outline-offset: 1px;
}

.admin .action-menu-item[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
}

.admin .action-menu-icon {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  background: var(--action);
  color: var(--color-on-action);
}

.admin .action-menu-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.admin .action-menu-label {
  font-size: 14px;
  font-weight: 700;
}

.admin .action-menu-description {
  color: var(--color-neutral);
  font-size: 12px;
}

/* An option of a choice (MenuButton): neutral, its icon on a grey tile; the current one on the primary's soft tint,
   its icon filled, a tick at the right. */
.admin .action-menu-item.action-menu-choice {
  align-items: center;
  background: transparent;
  color: var(--color-text);
}

.admin .action-menu-choice .action-menu-icon {
  background: var(--color-neutral-soft);
  color: var(--color-muted);
}

.admin .action-menu-item.action-menu-choice:hover,
.admin .action-menu-item.action-menu-choice:focus-visible {
  background: var(--color-surface-sunken);
}

.admin .action-menu-item.action-menu-choice:focus-visible {
  outline-color: var(--color-primary);
}

.admin .action-menu-item.action-menu-choice[aria-checked='true'] {
  background: var(--color-primary-soft);
}

.admin .action-menu-choice[aria-checked='true'] .action-menu-icon {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.admin .action-menu-choice .action-menu-text {
  flex: 1;
}

.admin .action-menu-check {
  display: flex;
  flex: none;
  color: var(--color-primary);
}

.admin .action-menu-choice .action-menu-description {
  color: var(--color-muted);
}

/* MenuButton: an outlined button with the current choice's icon, its words and a chevron. */
.admin .menu-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  max-width: 100%;
  min-height: 44px;
  padding: 6px 12px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 14px;
  text-align: left;
  cursor: pointer;
}

.admin .menu-button:hover,
.admin .menu-button[aria-expanded='true'] {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.admin .menu-button:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.admin .menu-button:disabled {
  opacity: 0.55;
  cursor: default;
}

.admin .menu-button-icon {
  display: flex;
  flex: none;
  color: var(--color-primary);
}

.admin .menu-button-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A risky action's confirmation is a dialog (Modal): its question and optional reason. */
.admin .action-confirm-question {
  margin: 0 0 12px;
}

.admin .action-confirm-reason {
  display: flex;
  flex-direction: column;
  gap: 4px;
  color: var(--color-muted);
  font-size: 13px;
}

.admin .action-confirm-reason textarea {
  box-sizing: border-box;
  width: 100%;
  min-height: 44px;
  padding: 6px 8px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-size: 14px;
  resize: vertical;
}

/* On a phone (≤ 640px): a bottom sheet over a scrim, the row's name as its title, 48px full-width items. */
.admin .action-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: var(--color-overlay);
}

.admin .action-sheet {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1001;
  max-height: 85vh;
  max-height: 85dvh;
  overflow-y: auto;
  box-sizing: border-box;
  padding: 8px 16px calc(20px + env(safe-area-inset-bottom));
  border-radius: 16px 16px 0 0;
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
  font-family: var(--font);
}

.admin .action-sheet-handle {
  width: 40px;
  height: 4px;
  margin: 0 auto 10px;
  border-radius: 2px;
  background: var(--color-border-strong);
}

.admin .action-sheet-title {
  font-size: 16px;
}

.admin .action-menu.action-menu-sheet {
  position: static;
  width: auto;
  max-width: none;
  max-height: none;
  padding: 0;
  border: 0;
  box-shadow: none;
}

.admin .action-menu-sheet .action-menu-heading {
  margin: 12px 0 0;
}

.admin .action-menu-sheet .action-menu-item {
  align-items: center;
  gap: 12px;
  min-height: 48px;
  margin-top: 6px;
  padding: 8px 12px;
  border-radius: 10px;
}

.admin .action-menu-sheet .action-menu-icon {
  width: 26px;
  height: 26px;
}

@media (max-width: 640px) {
  .admin .split-button {
    display: flex;
    width: 100%;
  }

  .admin .split-button > button {
    min-height: 44px;
  }

  .admin .split-button > .split-main,
  .admin .split-button > .split-more {
    flex: 1;
  }

  .admin .split-button > .split-toggle {
    width: 48px;
  }
}

/* A button opening a panel of its own content (`Popover`): the panel is a raised box under it, a bottom sheet on a
   phone. Unavailable, it stays focusable and dimmed, its tooltip saying why. */
.admin .popover-button {
  gap: 4px;
}

.admin .popover-button[aria-expanded='true'] {
  background: var(--action-soft);
  border-color: var(--action);
}

.admin .popover-button[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
}

.admin .popover-button[aria-disabled='true']:hover {
  background: var(--color-surface);
  border-color: color-mix(in srgb, var(--action) 55%, transparent);
}

.admin .popover {
  position: fixed;
  z-index: 1000;
  width: 360px;
  max-width: calc(100vw - 16px);
  max-height: calc(100vh - 16px);
  overflow-y: auto;
  box-sizing: border-box;
  padding: 14px;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: 10px;
  box-shadow: var(--shadow-lg);
  color: var(--color-text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.4;
}

.admin .popover.popover-sheet {
  position: static;
  width: auto;
  max-width: none;
  max-height: none;
  padding: 8px 0 0;
  border: 0;
  box-shadow: none;
}

/* The open item's actions in the page header (`HeaderActions`): before "View page" and the header's "Unsaved
   changes" and Discard (orders -2, -1); Save stays at the far right. */
.admin .header-actions-slot,
.admin .header-actions {
  display: contents;
}

.admin .header-actions > * {
  order: -3;
}

/* Without a page header to host them, they are a row of their own. */
.admin .header-actions.header-actions-inline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}

/* A dialog of two columns (`Modal wide`). */
.admin .modal.modal-wide {
  max-width: 880px;
}

@media (max-width: 599px) {
  .admin .page-actions .header-actions > .btn {
    min-height: 44px;
  }
}

/*
 * The filters above a table (TableFilters, C.5): one row of labelled controls lined up on their bottom edge, "Clear
 * filters", the table's own action at the end; under it the active filters as chips and "x of y <things>".
 */
.admin .table-filters {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 16px;
}

.admin .table-filters-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 12px;
}

.admin .table-filters-action {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.admin .filter-field {
  display: inline-grid;
  gap: 2px;
  min-width: 180px;
  max-width: 100%;
}

.admin .filter-field.filter-search {
  width: 280px;
}

.admin .filter-field .search {
  max-width: none;
}

.admin .filter-popover-host {
  position: relative;
}

.admin .filter-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  padding: 8px 10px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.admin .filter-trigger[aria-expanded='true'],
.admin .filter-trigger:hover {
  border-color: var(--color-muted);
}

.admin .filter-trigger:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.admin .filter-trigger > svg {
  flex: none;
  color: var(--color-muted);
}

.admin .filter-popover {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 50;
  box-sizing: border-box;
  padding: 6px;
  border: 1px solid var(--color-border-strong);
  border-radius: 10px;
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
}

.admin .filter-options {
  width: 240px;
}

.admin .filter-option {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.admin .filter-option:hover {
  background: var(--color-bg);
}

.admin .status-dot {
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-border-strong);
}

.admin .status-dot.tone-success {
  background: var(--color-success);
}

.admin .status-dot.tone-warning {
  background: var(--color-warning);
}

.admin .status-dot.tone-info {
  background: var(--color-info);
}

.admin .status-dot.tone-accent {
  background: var(--color-accent);
}

.admin .status-dot.tone-danger {
  background: var(--color-danger);
}

.admin .status-dot.tone-indigo {
  background: var(--color-indigo);
}

/* The range calendar: presets, the month with ‹ ›, a Monday-first grid; the picked days filled, the days between tinted. */
.admin .filter-calendar {
  width: 300px;
  padding: 12px;
}

.admin .filter-presets {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 10px;
}

.admin .calendar-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.admin .calendar-month {
  font-size: 14px;
  font-weight: 700;
  text-transform: capitalize;
}

.admin .calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
}

.admin .calendar-weekday {
  margin-bottom: 4px;
  color: var(--color-muted);
  font-size: 11px;
  font-weight: 700;
  text-align: center;
}

.admin .calendar-day {
  position: relative;
  min-height: 36px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  font: inherit;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
}

.admin .calendar-day:hover {
  background: var(--color-bg);
}

.admin .calendar-day.is-today {
  box-shadow: inset 0 0 0 1px var(--color-border-strong);
}

.admin .calendar-day.is-inside {
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.admin .calendar-day.is-edge {
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: 700;
}

.admin .calendar-day:focus-visible {
  z-index: 1;
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

.admin .calendar-hint {
  margin-top: 8px;
  color: var(--color-muted);
  font-size: 12px;
}

.admin .filter-range {
  display: flex;
  align-items: center;
  gap: 6px;
}

.admin .filter-range input {
  flex: 1;
  width: 90px;
  min-width: 0;
}

.admin .table-filters-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
}

.admin .filter-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.admin .filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 2px 2px 10px;
  border-radius: 999px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-size: 12px;
  font-weight: 600;
}

.admin .filter-chip button {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.admin .filter-chip button:hover {
  background: color-mix(in srgb, var(--color-primary) 15%, transparent);
}

.admin .filter-chip button::before {
  content: '';
  position: absolute;
  inset: 50% auto auto 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

.admin .filter-count {
  margin-left: auto;
  color: var(--color-muted);
  font-size: 13px;
}

/* On a phone the filters are a bottom sheet: the controls stacked full width, their popovers in the flow. */
.admin .filter-sheet-fields {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin: 12px 0 16px;
}

.admin .filter-sheet .filter-field,
.admin .filter-sheet .filter-field.filter-search {
  width: 100%;
  min-width: 0;
}

.admin .filter-sheet .filter-popover {
  position: static;
  width: auto;
  margin-top: 4px;
  box-shadow: none;
}

.admin .filter-sheet-footer {
  display: flex;
  gap: 8px;
}

.admin .filter-sheet-footer .btn {
  flex: 1;
  min-height: 44px;
}

@media (max-width: 600px) {
  .admin .table-filters-open {
    min-height: 44px;
  }
}

/* SortableList: rows dragged into order within and across the lists of one group (README, "Lists in order"). */
.admin .sortable-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-height: 52px;
  border-radius: var(--radius-sm);
}

.admin .sortable-list.is-over {
  outline: 2px dashed var(--color-border-strong);
  outline-offset: 2px;
}

.admin .sortable-empty {
  display: flex;
  align-items: center;
  min-height: 48px;
  padding: 0 12px;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  color: var(--color-muted);
  font-size: 0.9rem;
}

.admin .sortable-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 52px;
  padding: 4px 8px 4px 4px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.admin .sortable-row.is-dragging {
  opacity: 0.4;
}

.admin .sortable-row.is-overlay {
  box-shadow: var(--shadow-lg);
  cursor: grabbing;
}

.admin .sortable-row-body {
  flex: 1;
  min-width: 0;
}

/* The ⋮⋮ handle: a 44px button; a finger presses it a moment to drag, so the page still scrolls under a swipe. */
.admin .sortable-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-muted);
  cursor: grab;
  touch-action: manipulation;
  -webkit-touch-callout: none;
  user-select: none;
}

.admin .sortable-handle:hover {
  background: var(--color-neutral-soft);
  color: var(--color-text);
}

.admin .sortable-handle:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 1px;
}

/* A table's selection and its bulk bar (Selection.tsx; docs/pdr/prd-product-types.md PT-05). */
.admin .table th.select-col,
.admin .table td.select-cell {
  width: 44px;
  padding-right: 0;
}

/* The checkbox is 20px; its label is the 44px a finger needs. */
.admin .select-box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: -12px -12px -12px -12px;
  cursor: pointer;
}

.admin .table tr:has(> td.select-cell input:checked) td {
  background: var(--color-primary-soft);
}

.admin .bulk-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  margin-bottom: 12px;
  padding: 8px 12px;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
}

.admin .bulk-bar-count {
  font-weight: 600;
}

.admin .bulk-bar .action-group {
  margin-left: auto;
}

@media (max-width: 600px) {
  /* Below 600px the bar sticks to the bottom of the window while rows are selected. */
  .admin .bulk-bar {
    position: sticky;
    bottom: 0;
    z-index: 5;
    margin: 0 -16px;
    border-radius: 0;
    border-width: 1px 0 0;
    box-shadow: 0 -4px 12px var(--color-overlay);
  }

  .admin .bulk-bar .btn {
    min-height: 44px;
  }

  /* A card's checkbox sits at its top right; the next cell is the card's title. */
  .admin .table-cards tr:has(> td.select-cell) {
    position: relative;
    padding-right: 56px;
  }

  .admin .table-cards td.select-cell {
    position: absolute;
    top: 4px;
    right: 6px;
    width: auto;
    padding: 0;
  }

  .admin .table-cards td.select-cell::before,
  .admin .table-cards td.select-cell + td::before {
    display: none;
  }
}

/* Combobox: a text box filtering a list that opens under it, in the page's flow (a dialog never clips it). Under
   .admin, every class prefixed combobox-; the kit's tokens only; each entry a 44px target. */

.admin .combobox {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.admin .combobox-box {
  position: relative;
}

.admin .combobox-box input {
  padding-right: 36px;
}

.admin .combobox-chevron {
  position: absolute;
  top: 50%;
  right: 10px;
  display: flex;
  color: var(--color-muted);
  transform: translateY(-50%);
  pointer-events: none;
}

.admin .combobox-list {
  max-height: 264px;
  margin: 0;
  padding: 4px;
  overflow-y: auto;
  list-style: none;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
}

.admin .combobox-option,
.admin .combobox-empty {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  overflow-wrap: anywhere;
}

.admin .combobox-option {
  cursor: pointer;
}

.admin .combobox-option > span {
  flex: 1;
  min-width: 0;
}

.admin .combobox-option[aria-selected='true'] {
  font-weight: 600;
  color: var(--color-primary);
}

.admin .combobox-option:hover,
.admin .combobox-option.is-active {
  background: var(--color-primary-soft);
}

.admin .combobox-empty {
  color: var(--color-muted);
}

/* "New table…": an action, not a value; set apart from the values above it. */
.admin .combobox-action {
  border-top: 1px solid var(--color-border);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  color: var(--color-action-create);
  font-weight: 600;
}

/* RadioCards: a few large choices side by side (stacked on a phone). Under .admin, classes prefixed radio-card; kit tokens only. */

.admin .radio-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.admin .radio-card {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  min-height: 44px;
  padding: 12px 14px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.admin .radio-card:hover:not(:disabled) {
  background: var(--color-primary-soft);
}

.admin .radio-card[aria-checked='true'] {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
  box-shadow: 0 0 0 1px var(--color-primary);
}

.admin .radio-card:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.admin .radio-card:disabled {
  color: var(--color-muted);
  cursor: not-allowed;
  opacity: 0.75;
}

.admin .radio-card-dot {
  flex: none;
  box-sizing: border-box;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  border: 2px solid var(--color-border-strong);
  border-radius: 50%;
  background: var(--color-surface);
}

.admin .radio-card[aria-checked='true'] .radio-card-dot {
  border-color: var(--color-primary);
  background: radial-gradient(
    circle,
    var(--color-primary) 0 4px,
    var(--color-surface) 5px
  );
}

.admin .radio-card-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.admin .radio-card-label {
  font-weight: 600;
}

.admin .radio-card-hint {
  color: var(--color-muted);
  font-size: 0.875rem;
}

/* ChoiceRow: a row of a few choices in one line, scrolling sideways when narrow. Under .admin, classes prefixed
   choice-row; kit tokens only. */

.admin .choice-row {
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: thin;
  /* Room for the focus ring inside the scrolling box. */
  padding: 3px;
  margin: -3px;
}

.admin .choice-row-tab {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 14px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.admin .choice-row-tab:hover {
  background: var(--color-primary-soft);
}

.admin .choice-row-tab[aria-selected='true'] {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
  box-shadow: 0 0 0 1px var(--color-primary);
}

.admin .choice-row-tab:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.admin .choice-row-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 28px;
  height: 28px;
  padding: 0 4px;
  border-radius: var(--radius-sm);
  background: var(--color-neutral-soft);
  color: var(--color-muted);
  font-size: 0.75rem;
  font-weight: 700;
  margin-left: -6px;
}

.admin .choice-row-tab[aria-selected='true'] .choice-row-mark {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

/* 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%);
}
/* Its product switched off (PT-12): the teaser stays, nothing to buy. */
.post-card-buy--off,
.post-card-buy--off:hover {
  background: var(--bg-muted);
  color: var(--text-muted);
}
.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-remove: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-remove {
  grid-area: qty;
  min-width: 44px;
  min-height: 44px;
  padding: 0 var(--sp-3);
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  color: var(--accent-text);
  font-family: var(--font-sans);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.order-tray-remove:hover {
  background: var(--accent-light);
}
.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;
}

/* The report dialog (docs/pdr/prd-newsletter.md NL-23): label beside value, the provider's payload in a scrolling
   block. Tokens only, under .admin. */
.admin .nl-report-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 6px 16px;
  margin: 0 0 16px;
}

.admin .nl-report-facts > div {
  display: contents;
}

.admin .nl-report-facts dt {
  font-weight: 600;
  color: var(--color-muted);
}

.admin .nl-report-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.admin .nl-report-raw-title {
  margin: 0 0 8px;
  font-size: 0.95rem;
}

.admin .nl-report-raw {
  max-height: 360px;
  margin: 0;
  padding: 12px;
  overflow: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface-sunken);
  color: var(--color-text);
  font-size: 0.8rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Phones: label over value. */
@media (max-width: 600px) {
  .admin .nl-report-facts {
    grid-template-columns: 1fr;
    gap: 2px;
  }

  .admin .nl-report-facts dd {
    margin-bottom: 8px;
  }
}

/* "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. */

/* content card: InlineContentCard (.content-card*) and its sheet (.content-sheet*), docs/pdr/prd-content-and-assistants.md
   CT-14, docs/chat-design.md "Content card". Framed once by its row (msg-card-wrap--framed), on the chat's tokens: a
   header strip like the summaries', kind chips, rows ≥ 60px with hairline dividers, "Ver todo (N)" as a tonal link.
   Phones first: every target is 44px or more. */
.content-card {
  width: 100%;
  max-width: 480px;
  background: var(--bg-card);
}
/* The row's frame is the card's: 480px at most too, as an order's status (it spanned the column on a computer, the
   card's strip and rows stopping short of its right edge). */
.msg-card-wrap--framed:has(> .content-card) {
  flex: 0 1 480px;
}
.content-card-strip {
  padding: var(--sp-3) var(--sp-4);
  background: var(--bg-muted);
  border-bottom: 1px solid var(--hairline);
}
.content-card-title {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  color: var(--text-secondary);
}
.content-card-chips {
  display: flex;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  overflow-x: auto;
  scrollbar-width: none;
}
.content-card-chips::-webkit-scrollbar {
  display: none;
}
.content-card-chip {
  flex: none;
  min-height: 44px;
  padding: 0 var(--sp-4);
  font: inherit;
  font-size: var(--fs-base);
  color: var(--text-secondary);
  background: var(--bg-card);
  border: none;
  border-radius: var(--r-full);
  box-shadow: 0 0 0 1px var(--hairline-strong);
  cursor: pointer;
}
.content-card-chip:hover {
  background: var(--accent-light);
}
.content-card-chip:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.content-card-chip--on {
  color: var(--accent-text);
  background: var(--accent-light);
  box-shadow: 0 0 0 1px var(--accent);
  font-weight: var(--fw-semibold);
}
.content-card-items {
  list-style: none;
  margin: 0;
  padding: 0;
}
.content-card-items li + li {
  border-top: 1px solid var(--hairline);
}
.content-card-items--bare {
  background: var(--bg-card);
  border-radius: var(--r-lg);
  box-shadow: 0 0 0 1px var(--hairline);
  overflow: hidden;
}
/* A whole row is the target: a link (<a>), a button, or a playing video. */
.content-card-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  width: 100%;
  min-height: 60px;
  padding: var(--sp-2) 14px;
  font: inherit;
  text-align: left;
  color: inherit;
  text-decoration: none;
  background: transparent;
  border: none;
  cursor: pointer;
  transition: background-color var(--trans-fast);
}
.content-card-row:hover {
  background: var(--accent-light);
}
.content-card-row:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}
.content-card-row--playing {
  display: block;
  cursor: default;
}
.content-card-row--playing:hover {
  background: transparent;
}
.content-card-thumb {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  overflow: hidden;
  color: var(--accent-text);
  background: var(--accent-light);
  border-radius: var(--r-md);
}
.content-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.content-card-play {
  position: absolute;
  right: 3px;
  bottom: 3px;
  display: inline-flex;
  padding: 3px;
  color: white;
  background: rgba(15, 23, 42, 0.62);
  border-radius: var(--r-full);
}
.content-card-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.content-card-name {
  overflow: hidden;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  line-height: 1.3;
  color: var(--text-primary);
  text-overflow: ellipsis;
  white-space: nowrap;
}
.content-card-meta {
  font-size: var(--fs-sm);
  color: var(--text-muted);
}
.content-card-row--sold .content-card-meta {
  color: var(--accent-text);
}
.content-card-go {
  flex: none;
  display: inline-flex;
  color: var(--text-muted);
}
.content-card-all {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  font: inherit;
  font-size: var(--fs-base);
  font-weight: var(--fw-semibold);
  color: var(--accent-text);
  background: transparent;
  border: none;
  border-top: 1px solid var(--hairline);
  cursor: pointer;
}
.content-card-all:hover {
  background: var(--accent-light);
}
.content-card-all:focus-visible {
  outline: none;
  box-shadow: inset var(--focus-ring);
}
/* The sheet (§15 "A list"): the chips, then on All the first published post large, then the rows. */
.content-sheet-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
  padding-bottom: var(--sp-5);
}
.content-sheet-body .content-card-chips {
  padding: 0;
}
.content-sheet-body .content-card-items {
  background: var(--bg-card);
  border-radius: var(--r-lg);
  box-shadow: 0 0 0 1px var(--hairline);
  overflow: hidden;
}
.content-sheet-lead {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  overflow: hidden;
  font: inherit;
  text-align: left;
  color: inherit;
  background: var(--bg-card);
  border: none;
  border-radius: var(--r-lg);
  box-shadow: 0 0 0 1px var(--hairline);
  cursor: pointer;
}
.content-sheet-lead:focus-visible {
  outline: none;
  box-shadow: var(--focus-ring);
}
.content-sheet-lead-cover {
  width: 100%;
  aspect-ratio: 1.91;
  object-fit: cover;
}
.content-sheet-lead-text {
  display: flex;
  flex-direction: column;
  gap: var(--sp-1);
  padding: var(--sp-3) var(--sp-4) var(--sp-4);
}
.content-sheet-lead-title {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
  line-height: 1.3;
  color: var(--text-primary);
}
.content-sheet-lead-excerpt {
  display: -webkit-box;
  overflow: hidden;
  font-size: var(--fs-base);
  color: var(--text-secondary);
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
}

/* ════════════════════════════════════════
  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);
}
/* What the server wrote about the business, under the message (UXM-21): read as a page, not centred. */
.page-load-failed-summary {
  width: 100%;
  max-width: 560px;
  margin-top: var(--sp-4);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--border);
  text-align: left;
}
.page-load-failed .page-load-failed-summary p,
.page-load-failed-summary address {
  margin: 0 0 var(--sp-3);
  font-style: normal;
}
.page-load-failed-summary h2 {
  margin: var(--sp-4) 0 var(--sp-2);
  color: var(--text-primary);
  font-size: var(--fs-md);
}
.page-load-failed-summary a {
  color: inherit;
}
.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 Subscribe sheet (docs/pdr/prd-newsletter.md NL-01, docs/chat-design.md §15): the consent box as the
   diagnostics' (unticked, a 44px row, its Privacy policy link), the honeypot out of sight and out of reach, and the
   done state's "send it again", a text button with a 44px hit area. Chat tokens only: light and dark alike. */
.newsletter-sheet-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;
}
.newsletter-sheet-consent input {
  flex: none;
  width: 20px;
  height: 20px;
  margin: 0;
  accent-color: var(--accent-fill);
}
.newsletter-sheet-consent a {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.newsletter-sheet-trap {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.newsletter-sheet-again-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.newsletter-sheet-again-link:disabled {
  color: var(--text-muted);
  cursor: default;
}
.newsletter-sheet-again-sent {
  color: var(--accent-text);
}

/* 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);
}
/* Sold by a product switched off (docs/pdr/prd-product-types.md PT-12): still locked, nothing to buy; muted and inert. */
.pdf-buy-btn--off,
.pdf-buy-btn--off:hover {
  background: var(--bg-muted);
  color: var(--text-muted);
  cursor: default;
}
.lk-card--off .lk-meta,
.content-card-row--off .content-card-meta {
  color: var(--text-muted);
}
.lk-card--off,
.content-card-row--off {
  cursor: default;
}
/* 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;
}

