/* Flowella 2026 shared components that page modules build on: cards, mock-screen frames, FAQ disclosure
   rows, tables, forms, the hero's wayfinding tab and section motif, and the WhatsApp Flow sheet and CRM record
   card that the product page's mocks share (DESIGN.md, Components). Tokens come from tokens.css; buttons,
   tags, stickers and links live in base.css.
   Logical properties throughout, so Arabic (dir="rtl") mirrors without overrides. */

/* Cards
   .card: white surface, Hairline border, Press shadow (.card-sheet uses the mock-screen Sheet instead).
   .card-field: a chapter field, no border. Pick the field with .card-sky, .card-mint, .card-green,
   .card-coral or .card-periwinkle, or set --field yourself. --card-r carries the radius to the link overlay. */
.card {
  --card-r: var(--r-lg);
  position: relative; min-width: 0;
  display: flex; flex-direction: column; gap: 14px;
  padding: clamp(20px, 2.4vw, 28px);
  border: 1px solid var(--line); border-radius: var(--card-r);
  background: var(--card-bg, var(--surface)); color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.card-sheet { --card-bg: var(--sheet-bg); }
.card-field { --card-bg: var(--field, var(--field-sky)); border-color: transparent; }
.card-sky { --field: var(--field-sky); }
.card-mint { --field: var(--field-mint); }
.card-green { --field: var(--field-green); }
.card-coral { --field: var(--field-coral); }
.card-periwinkle { --field: var(--field-blue); }
.card-title { font: 800 1.28rem/1.25 var(--text); letter-spacing: -0.01em; text-wrap: balance; }
.card-text { font-size: 16px; line-height: 1.5; color: var(--ink-soft); text-wrap: pretty; }
.card-cta { margin-top: auto; display: inline-flex; align-items: center; gap: 8px; font-weight: 800; font-size: 16px; }
.card-cta .i { width: 18px; height: 18px; }

/* Whole-card link: the title link's ::after covers the card, so the card is one target and its focus ring
   follows the card radius. Optional --tilt (small, -2deg to 2deg) mirrors in right-to-left pages.
   On fine pointers hover straightens the card, rises 6px and deepens to Lift; keyboard focus does the same. */
.card-link { rotate: calc(var(--tilt, 0deg) * var(--tilt-dir, 1)); }
[dir="rtl"] .card-link { --tilt-dir: -1; }
/* The Lift shadow waits on a pseudo-element and fades in, so the lift animates opacity, not box-shadow */
.card-link::before {
  content: ""; position: absolute; inset: -1px; border-radius: var(--card-r);
  box-shadow: var(--shadow-lift); opacity: 0; pointer-events: none;
  transition: opacity 280ms ease;
}
.card-link .card-title a { color: inherit; text-decoration: none; }
.card-link .card-title a::after { content: ""; position: absolute; inset: -1px; border-radius: var(--card-r); }
.card-link .card-title a:focus-visible { outline: none; }
.card-link .card-title a:focus-visible::after { outline: 3px solid var(--focus); outline-offset: 4px; }
.card-link:has(.card-title a:focus-visible)::before { opacity: 1; }
@media (hover: hover) and (pointer: fine) {
  .card-link:hover::before { opacity: 1; }
}
/* Travel only when motion is welcome; under reduced motion only the shadow fades in */
@media (prefers-reduced-motion: no-preference) {
  .card-link { transition: rotate 280ms var(--ease-out), translate 280ms var(--ease-out); }
  .card-link:has(.card-title a:focus-visible) { rotate: 0deg; translate: 0 -6px; }
}
/* A strip under the card covers the 6px it rises, so a pointer resting on the bottom edge keeps the hover
   instead of the card bouncing out from under it */
.card-link::after { content: ""; position: absolute; inset-inline: 0; top: 100%; height: 0; }
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .card-link:hover { rotate: 0deg; translate: 0 -6px; }
  .card-link:hover::after { height: 7px; }
}

/* Mock-screen frames (DESIGN.md "Mock Screens"): a Sheet frame (26px, Float), a header bar with a Hairline
   divider holding a title and the "Sample data" tag, then the body. Named .screen so it never meets a module's
   own .mock (how-it-works has one). */
.screen {
  min-width: 0;
  border-radius: 26px;
  background: var(--sheet-bg); color: var(--ink);
  box-shadow: var(--shadow);
}
/* Demo surfaces change while people read them, so Chrome must never pick one as its scroll anchor: the page would
   follow a moving bubble or a growing record. The theme's 104px scroll padding puts the risky spot just under
   the header. */
.screen, .wa-flow, .crm-rec { overflow-anchor: none; }
.screen-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
  min-height: 56px; padding: 10px 18px;
  border-bottom: 1px solid var(--line);
}
.screen-title { min-width: 0; font: 800 16px/1.25 var(--text); overflow-wrap: anywhere; }
.screen-bar small { display: block; font-size: 13px; line-height: 1.3; color: var(--ink-soft); }
.screen-bar .tag { margin-inline-start: auto; }
.screen-body { padding: 16px 18px 18px; font-size: 15px; line-height: 1.45; }
/* Avatar disc in a chat header (initials only) */
.screen-ava {
  flex: none; width: 38px; height: 38px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--btn-bg); color: var(--btn-ink);  /* Navy On Bright in dark mode, as the primary button */
  font: 800 14px/1 var(--display);
}

/* WhatsApp chat: .screen.screen-chat, with .bubble.bubble-in / .bubble.bubble-out on Chat Paper. Bubbles cut the
   corner on the speaker's side to 4px; logical corners swap sides in right-to-left pages, as WhatsApp does. */
.screen-chat .screen-body {
  display: flex; flex-direction: column; gap: 8px;
  padding-block: 18px 22px;
  background: var(--chat-bg);
  border-end-start-radius: inherit; border-end-end-radius: inherit;
}
.bubble {
  max-width: min(84%, 36ch);
  padding: 8px 12px 6px; border-radius: 16px;
  font-size: 15px; line-height: 1.4; overflow-wrap: anywhere;
  box-shadow: var(--shadow-xs);
}
.bubble-in { align-self: flex-start; background: var(--bubble-in); border-start-start-radius: 4px; }
.bubble-out { align-self: flex-end; background: var(--bubble-out); border-start-end-radius: 4px; }
.bubble time {
  display: block; margin-top: 2px; text-align: end;
  font: 500 12px/1.2 var(--mono); font-variant-numeric: tabular-nums; color: var(--ink-soft);
}
/* A Flow or template button under the message text */
.bubble-cta {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin: 8px -12px -6px; padding: 9px 12px 10px;
  border-top: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  font-weight: 700; color: var(--accent-ink);
}
.bubble-cta .i { width: 18px; height: 18px; }

/* FAQ disclosure rows: native details/summary, the mobile menu row (56px, 18px 700, Hairline dividers,
   chevron turning 180deg). Put .faq on a .card or a .card-field; on fields the dividers step up to Steel Line
   so they still read against the tint. Markup: details > summary (text, then the i-chev icon) + .faq-a. */
.faq { --faq-line: var(--line); }
.card-field .faq, .faq-field { --faq-line: var(--line-strong); }
.faq details + details { border-top: 1px solid var(--faq-line); }
.faq summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 56px; padding-block: 12px;
  padding-inline: 12px; margin-inline: -12px;  /* room for the focus ring, text stays on the content edge */
  border-radius: 12px;
  font: 700 18px/1.3 var(--text); text-wrap: pretty;
  list-style: none; cursor: pointer;
  transition: color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::marker { content: ""; }
.faq summary:focus-visible { outline-offset: 2px; }
.faq summary .i { width: 20px; height: 20px; color: var(--ink-soft); transition: rotate 200ms var(--ease-out), color 160ms ease; }
.faq details[open] > summary .i { rotate: 180deg; }
@media (hover: hover) and (pointer: fine) {
  .faq summary:hover, .faq summary:hover .i { color: var(--accent-ink); }
}
.faq-a { max-width: 62ch; padding-bottom: 20px; font-size: 17px; line-height: 1.55; color: var(--ink-soft); text-wrap: pretty; }
.faq-a > * + * { margin-top: 10px; }
.faq-a a { color: var(--accent-ink); font-weight: 700; }
/* The answer opens progressively where the browser can animate to auto height (closing a touch faster);
   elsewhere, and under reduced motion, it opens instantly */
@supports (interpolate-size: allow-keywords) and selector(::details-content) {
  @media (prefers-reduced-motion: no-preference) {
    .faq { interpolate-size: allow-keywords; }
    /* The clip holds only while the answer moves, so a focus ring in an open answer is never cut off */
    .faq details::details-content {
      block-size: 0; overflow-y: clip;
      transition: block-size 150ms var(--ease-out), content-visibility 150ms allow-discrete, overflow-y 0s allow-discrete;
    }
    .faq details[open]::details-content {
      block-size: auto; overflow-y: visible;
      transition: block-size 200ms var(--ease-out), content-visibility 200ms allow-discrete, overflow-y 0s 200ms allow-discrete;
    }
  }
}

/* Tables: .table-wrap (role="region", tabindex="0", aria-label) is the rounded card and the sideways scroll
   region; .table inside has a caption, th scope, a Mist header row and Hairline row dividers. The first
   column stays put while the rest scrolls. .is-recommended on every cell of one column highlights a plan;
   included / not included cells hold an i-check (.yes) or i-x (.no) icon plus sr-only text. */
/* position: relative keeps absolutely placed children (the sr-only text) inside the scroll box, so they
   can't widen the page on phones */
.table-wrap {
  position: relative; max-width: 100%;
  overflow-x: auto; overscroll-behavior-x: contain;
  border: 1px solid var(--line); border-radius: 24px;
  background: var(--surface); color: var(--ink);
  box-shadow: var(--shadow-sm);
  scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent;
}
.table-wrap:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
.table {
  width: 100%;
  border-collapse: separate; border-spacing: 0;
  font-size: 16px; line-height: 1.4; font-variant-numeric: tabular-nums;
}
.table caption { caption-side: top; padding: 16px 18px 14px; text-align: start; font: 800 17px/1.35 var(--text); }
.table caption .tag { margin-inline-start: 8px; vertical-align: 1px; }
.table :is(th, td) {
  min-width: 7.5rem; padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  text-align: center; vertical-align: middle;
}
.table thead th { background: var(--surface-2); font: 700 15px/1.3 var(--text); }
.table tbody th { font-weight: 700; }
.table tbody tr:last-child > * { border-bottom: 0; }
.table :is(th, td):first-child {
  position: sticky; inset-inline-start: 0; z-index: 1;
  min-width: 10rem; text-align: start;
  background: var(--surface);
  border-inline-end: 1px solid var(--line);
}
.table thead :is(th, td):first-child { background: var(--surface-2); }
.table .is-recommended { background: var(--field-sky); }
.table thead .is-recommended { background: var(--sky); color: var(--on-bright); }
/* A tag on the bright header stays paper-light in both themes, as stickers do */
.table thead .is-recommended .tag { margin: 6px auto 0; display: flex; inline-size: fit-content; background: var(--sticker-bg); color: var(--sticker-ink); }
.table :is(.yes, .no) { width: 26px; height: 26px; padding: 5px; border-radius: 50%; }
.table .yes { background: var(--green); color: var(--on-bright); }
.table .no { background: var(--surface-2); color: var(--ink-soft); }

/* Forms (native markup): .form > .field (label.field-label, optional .field-help, the control, optional
   .field-error). Inputs, selects and textareas take the look by element; wrap a select in .field-select for
   the drawn chevron. Choice rows: fieldset.field > legend.field-label + .choices > label.choice
   (input first, then its text; the 22px ring sits at the row's end, as in the mini Flow). Errors: set
   aria-invalid="true" on the control and point aria-describedby at the .field-error id. */
.form, .flw-form {
  --mask-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.6l4.4 4.4L19 7.4' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  --mask-alert: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.4v5.6'/%3E%3Ccircle cx='12' cy='16.6' r='1.3' fill='black' stroke='none'/%3E%3C/svg%3E");
}
.form { display: grid; gap: 22px; min-width: 0; max-inline-size: var(--form-max, 40rem); }  /* keeps each label near its control */
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 22px 16px; }
.form .field { display: grid; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.form .field-label { display: block; padding: 0; font: 700 13px/1.3 var(--text); color: var(--ink); }
/* A legend sits outside its fieldset's grid, so it takes the field gap as a margin */
.form legend.field-label { margin-bottom: 10px; font: 800 16px/1.3 var(--text); }  /* the question above a group, as the mini Flow */
.form .field-help { font-size: 14px; line-height: 1.45; color: var(--ink-soft); }
.form .field-error { display: flex; align-items: flex-start; gap: 6px; font: 700 13px/1.4 var(--text); color: var(--err); }
.form .field-error .i { width: 16px; height: 16px; margin-top: 1px; }
.form .choices { display: grid; gap: 8px; }

/* Text inputs, selects and textareas: 48px, 14px radius, 2px Field Line (3:1, WCAG 1.4.11), Sheet, 700 16px.
   Mock screens keep the softer Hairline: they illustrate a form rather than ask for input. */
.form :is(input:not([type="checkbox"], [type="radio"], [type="submit"], [type="button"], [type="reset"], [type="file"], [type="range"], [type="color"], [type="hidden"]), select, textarea),
.flw-form .hs-form .hs-input:not([type="checkbox"], [type="radio"], [type="file"]) {
  display: block; width: 100%; max-width: 100%; min-height: 48px; margin: 0;
  padding: 10px 14px;
  border: 2px solid var(--field-line); border-radius: 14px;
  background: var(--sheet-bg); color: var(--ink);
  font: 700 16px/1.3 var(--text);
  box-shadow: none;
  transition: border-color 160ms ease;
}
.form textarea, .flw-form .hs-form textarea.hs-input { min-height: 120px; padding-block: 12px; line-height: 1.5; resize: vertical; }
.form select, .flw-form .hs-form select.hs-input { padding-inline-end: 44px; text-overflow: ellipsis; cursor: pointer; }
.form :is(input, textarea)::placeholder, .flw-form .hs-input::placeholder { color: var(--ph); opacity: 1; }
.flw-form .hs-form select.hs-input.is-placeholder { color: var(--ph); }
/* Email addresses, phone numbers and links read left to right even on Arabic pages; they sit on the start side */
.form :is(input[type="email"], input[type="tel"], input[type="url"]),
.flw-form .hs-input:is([type="email"], [type="tel"], [type="url"]) { direction: ltr; }
[dir="rtl"] :is(.form, .flw-form) :is(input[type="email"], input[type="tel"], input[type="url"]) { text-align: right; }
.form select:has(> option[value=""]:checked) { color: var(--ph); }
.form :is(input, select, textarea):focus-visible,
.flw-form .hs-form .hs-input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .form :is(input:not([type="checkbox"], [type="radio"]), select, textarea):not(:disabled, [aria-invalid="true"]):hover,
  .flw-form .hs-form .hs-input:not([type="checkbox"], [type="radio"], :disabled, .error):hover { border-color: var(--ink-soft); }
}
.form :is(input:not([type="checkbox"], [type="radio"]), select, textarea)[aria-invalid="true"],
.flw-form .hs-form .hs-input.error:not([type="checkbox"], [type="radio"]) { border-color: var(--err); box-shadow: inset 0 0 0 1px var(--err); }
.form :is(input:not([type="checkbox"], [type="radio"]), select, textarea):disabled,
.flw-form .hs-form .hs-input:not([type="checkbox"], [type="radio"]):disabled {
  border-color: var(--line); background: var(--surface-2); color: var(--ink-soft);
  -webkit-text-fill-color: var(--ink-soft); opacity: 1; cursor: not-allowed;
}
/* Autofilled fields keep the theme instead of the browser's yellow */
.form input:-webkit-autofill, .flw-form .hs-input:-webkit-autofill {
  -webkit-text-fill-color: var(--ink); box-shadow: inset 0 0 0 40px var(--field-sky);
}

/* Select chevron: a drawn shape (two borders turned 45deg), so only its position follows the direction.
   HubSpot's .input wrapper gets it only where :has() can find the select; otherwise the native arrow stays. */
.form .field-select, .flw-form .hs-form .input { position: relative; display: block; }
.form .field-select::after {
  content: ""; position: absolute; inset-inline-end: 18px; top: 50%;
  width: 8px; height: 8px;
  border-right: 2.5px solid var(--ink-soft); border-bottom: 2.5px solid var(--ink-soft);
  translate: 0 -70%; rotate: 45deg; pointer-events: none;
}
.form select { appearance: none; -webkit-appearance: none; }
@supports selector(:has(*)) {
  .flw-form .hs-form select.hs-input { appearance: none; -webkit-appearance: none; }
  .flw-form .hs-form .input:has(> select.hs-input)::after {
    content: ""; position: absolute; inset-inline-end: 18px; top: 50%;
    width: 8px; height: 8px;
    border-right: 2.5px solid var(--ink-soft); border-bottom: 2.5px solid var(--ink-soft);
    translate: 0 -70%; rotate: 45deg; pointer-events: none;
  }
}

/* Choice rows: full-width labels with the native input drawn as a 22px ring (a rounded square for
   checkboxes). Checked rows turn Green Field with a Reply Green border, as the mini Flow does. */
.form .choice,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) {
  position: relative;
  display: flex; align-items: center; gap: 12px;
  min-height: 52px; margin: 0; padding: 12px 14px;
  border: 2px solid var(--line); border-radius: 16px;
  background: var(--sheet-bg); color: var(--ink);
  font: 700 16px/1.35 var(--text);
  cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.form .choice > span,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) > span { min-width: 0; overflow-wrap: anywhere; }
.form .choice input,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input {
  appearance: none; -webkit-appearance: none;
  order: 2; flex: none; display: grid; place-content: center;
  width: 22px; height: 22px; margin: 0; margin-inline-start: auto;
  border: 2px solid var(--field-line); border-radius: 50%;
  background: var(--sheet-bg);
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease;
}
.form .choice input[type="checkbox"],
.flw-form .hs-form .hs-input[type="checkbox"] { border-radius: 7px; }
.form .choice input:checked,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input:checked { border-color: var(--green); background: var(--green); }
.form .choice input[type="radio"]:checked,
.flw-form .hs-form .hs-input[type="radio"]:checked { box-shadow: inset 0 0 0 4px var(--field-green); }
/* The tick: masked, so it takes the ink token */
.form .choice input[type="checkbox"]::before,
.flw-form .hs-form .hs-input[type="checkbox"]::before {
  content: ""; width: 14px; height: 14px;
  background: var(--on-bright);
  -webkit-mask: var(--mask-check) center / contain no-repeat; mask: var(--mask-check) center / contain no-repeat;
  opacity: 0; scale: 0.6;
  transition: opacity 120ms ease, scale 200ms var(--ease-pop);
}
.form .choice input[type="checkbox"]:checked::before,
.flw-form .hs-form .hs-input[type="checkbox"]:checked::before { opacity: 1; scale: 1; }
.form .choice input:focus-visible,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Where :has() works, the whole row carries the checked, focus, error and disabled states */
@supports selector(:has(*)) {
  .form .choice:has(input:checked),
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display):has(input:checked) { border-color: var(--green); background: var(--field-green); }
  .form .choice input:focus-visible,
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input:focus-visible { outline: none; }
  .form .choice:has(input:focus-visible),
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display):has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
  .form .choice:has(input[aria-invalid="true"]),
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display):has(input.error) { border-color: var(--err); box-shadow: inset 0 0 0 1px var(--err); }
  .form .choice:has(input:disabled),
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display):has(input:disabled) {
    border-color: var(--line); background: var(--surface-2); color: var(--ink-soft); cursor: not-allowed;
  }
}
.form .choice input:disabled,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input:disabled { border-color: var(--line); background: var(--surface-2); cursor: not-allowed; }
.form .choice input:disabled:checked,
.flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display) input:disabled:checked { border-color: var(--line-strong); background: var(--line-strong); box-shadow: none; }
@media (hover: hover) and (pointer: fine) {
  .form .choice:not(:has(input:checked, input:disabled, input[aria-invalid="true"])):hover,
  .flw-form .hs-form :is(.hs-form-radio-display, .hs-form-checkbox-display, .hs-form-booleancheckbox-display):not(:has(input:checked, input:disabled, input.error)):hover { border-color: var(--line-strong); }
}

/* HubSpot legacy embedded forms: wrap the form's output in <div class="flw-form">. Field layout mirrors
   .form; controls, rings and errors share the rules above. HubSpot can also inject its own default form CSS,
   so render the form unstyled (raw HTML) where it allows. */
.flw-form .hs-form { display: grid; gap: 22px; min-width: 0; max-inline-size: var(--form-max, 40rem); }
.flw-form .hs-form fieldset { min-width: 0; max-width: none; margin: 0; padding: 0; border: 0; display: grid; gap: 22px; }
.flw-form .hs-form fieldset.form-columns-2,
.flw-form .hs-form fieldset.form-columns-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: 22px 16px; }
.flw-form .hs-form fieldset[class*="form-columns"] .hs-form-field { float: none; width: auto; }
.flw-form .hs-form .hs-form-field { display: grid; gap: 8px; min-width: 0; margin: 0; }
.flw-form .hs-form .hs-form-field > label { display: block; font: 700 13px/1.3 var(--text); color: var(--ink); }
.flw-form .hs-form .hs-form-field:has(.inputs-list) > label { font: 800 16px/1.3 var(--text); }
.flw-form .hs-form .hs-form-required { margin-inline-start: 3px; color: var(--err); }
.flw-form .hs-form .hs-field-desc { display: block; margin: 0; padding: 0; font-size: 14px; line-height: 1.45; color: var(--ink-soft); }
.flw-form .hs-form .input { margin: 0; }
.flw-form .hs-form .inputs-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.flw-form .hs-form .inputs-list > li { margin: 0; padding: 0; }
.flw-form .hs-main-font-element { font-family: inherit; }
.flw-form .hs-form .hs-error-msgs { margin: 0; padding: 0; list-style: none; }
.flw-form .hs-form .hs-error-msg {
  display: flex; align-items: flex-start; gap: 6px;
  font: 700 13px/1.4 var(--text); color: var(--err);
}
.flw-form .hs-form .hs-error-msg::before {
  content: ""; flex: none; width: 16px; height: 16px; margin-top: 1px;
  background: currentColor;
  -webkit-mask: var(--mask-alert) center / contain no-repeat; mask: var(--mask-alert) center / contain no-repeat;
}
.flw-form .hs-form .legal-consent-container { display: grid; gap: 12px; }
.flw-form .hs-form .hs-richtext { max-width: 62ch; font-size: 14px; line-height: 1.5; color: var(--ink-soft); }
.flw-form .hs-form .hs-richtext > * + * { margin-top: 8px; }
.flw-form .hs-form .hs-richtext a { color: var(--accent-ink); font-weight: 700; }
.flw-form .hs-form :is(.hs_submit, .actions) { margin: 0; padding: 0; }
.flw-form .hs-form .actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
/* The submit is the primary pill button (.btn .btn-primary in base.css) */
.flw-form .hs-form .hs-button,
.flw-form .hs-form input[type="submit"].hs-button.primary {
  appearance: none; -webkit-appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 52px; max-width: 100%; margin: 0; padding: 0 26px;
  border: 0; border-radius: 999px;
  background: var(--btn-bg); color: var(--btn-ink);
  font: 700 17px/1.1 var(--text); text-shadow: none;
  cursor: pointer;
  box-shadow: var(--shadow-sm);
  transition: transform 160ms var(--ease-out), background-color 200ms ease;
  -webkit-tap-highlight-color: transparent;
}
.flw-form .hs-form .hs-button:active { transform: scale(0.97); }
.flw-form .hs-form .hs-button:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .flw-form .hs-form .hs-button:hover { background: var(--btn-bg-hover); }
}
/* Shown in place of the form once it is sent: a Green Field note with the tick disc */
.flw-form .submitted-message {
  position: relative; max-inline-size: var(--form-max, 40rem);
  padding: 20px 22px; padding-inline-start: 66px;
  border-radius: 22px;
  background: var(--field-green); color: var(--ink);
  font: 700 17px/1.45 var(--text);
}
.flw-form .submitted-message::before,
.flw-form .submitted-message::after { content: ""; position: absolute; top: 19px; border-radius: 50%; }
.flw-form .submitted-message::before { inset-inline-start: 22px; width: 28px; height: 28px; background: var(--green); }
.flw-form .submitted-message::after {
  inset-inline-start: 28px; top: 25px; width: 16px; height: 16px;
  background: var(--on-bright);
  -webkit-mask: var(--mask-check) center / contain no-repeat; mask: var(--mask-check) center / contain no-repeat;
}

/* Status pills: tag modifiers (DESIGN.md, Tags, Pills and Stickers). "New" Lagoon Mint, "Coming soon"
   outlined, "live" Reply Green, outlined coral for the old-way panel, and a process pill that moves
   Mist, Sky Field, Green Field through data-state="idle" | "running" | "done". */
.tag-new { background: var(--mint); color: var(--on-bright); }
.tag-soon { background: var(--surface); color: var(--ink-soft); box-shadow: inset 0 0 0 1px var(--line); }
.tag-live { background: var(--green); color: var(--on-bright); }
.tag-coral { background: transparent; box-shadow: inset 0 0 0 2px var(--coral); }
.tag[data-state] { transition: background-color 200ms ease, color 200ms ease; }
.tag[data-state="idle"] { background: var(--surface-2); color: var(--ink-soft); }
.tag[data-state="running"] { background: var(--field-sky); color: var(--ink); }
.tag[data-state="done"] { background: var(--field-green); color: var(--ink); }
.tag .i { width: 15px; height: 15px; }

/* Fact chips: dl.fact-chips > div.fact-chip (dt term, dd value). White chips with Press shadow, four across
   on wide screens and two below 960px, as along the bottom of the hero. */
.fact-chips { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
.fact-chip {
  min-width: 0; display: flex; flex-direction: column; gap: 6px;
  padding: 14px 20px 16px; border-radius: 24px;
  background: var(--chip-bg); color: var(--ink);
  box-shadow: var(--shadow-sm);
}
.fact-chip dt { font: 500 13px/1.25 var(--text); color: var(--ink-soft); }
.fact-chip dd { margin: 0; font: 700 17px/1.25 var(--text); overflow-wrap: anywhere; }

/* Comparison pages (templates/compare.hubl.html and its compare-* modules), shared by several of those modules:
   .cmp-ref, a numbered source pill after the fact it supports, linking to its entry in the sources list
   (<a class="cmp-ref" href="#cmp-src-4" aria-label="Source 4">4</a>); .cmp-logo, a logo tile that stays white in
   both themes so dark wordmarks stay legible (.is-wide for a wordmark); .cmp-head, a section's headline and lede. */
.cmp-ref {
  display: inline-grid; place-items: center;
  min-width: 24px; height: 24px; margin-inline-start: 6px; padding-inline: 6px;
  border-radius: 999px;
  background: var(--surface-2); color: var(--ink-soft);
  font: 700 12px/1 var(--text); font-variant-numeric: tabular-nums;
  text-decoration: none; vertical-align: 1px;
  transition: background-color 160ms ease, color 160ms ease;
}
.cmp-ref + .cmp-ref { margin-inline-start: 3px; }
.cmp-ref:focus-visible { outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .cmp-ref:hover { background: var(--field-sky); color: var(--ink); }
}
/* On a whole-card link the title's overlay covers the card; a source pill stays clickable above it */
.card-link .cmp-ref { position: relative; z-index: 1; }
.cmp-logo {
  flex: none; display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: 14px;
  background: var(--logo-bg); box-shadow: inset 0 0 0 1px var(--line);
}
.cmp-logo img { display: block; width: 26px; height: 26px; object-fit: contain; }
.cmp-logo.is-wide { width: auto; min-width: 72px; padding-inline: 10px; }
.cmp-logo.is-wide img { width: 52px; height: 18px; }
.cmp-head { display: grid; gap: 18px; max-width: 860px; }
.cmp-head .lede a { color: var(--accent-ink); font-weight: 700; }

/* Flo's speech bubble band (phase 2 batch 2, shared by the landing pages' booking and setup sections): her bubble,
   light in both themes, its tail pointing down at her head. It sits in a band above her picture (.flo-band) that
   also holds every other line she can say, invisible (.flo-ghost), in the same grid cell: the band is always as tall
   as her longest line, at any width and in any language, so a new line never moves anything and never reaches her
   head. --head is how far across the band her head sits; the bubble's end edge stops 38px past it, so the tail, 30px
   in from that edge, points at her head, and the bubble never reaches past the band's start edge. Placed against the
   artwork, which never mirrors, so the band stays physical (direction: ltr) in right-to-left pages, while the words
   read in the page's direction. One owner, one timer: the section script swaps the live line (it dips out, takes
   the new line, comes back). Markup:
     <figure class="flo-art" style="--head: 55%">
       <div class="flo-band" aria-hidden="true"><p class="flo-say">(live line)</p><span class="flo-ghost">(each line)</span>...</div>
       <img ...>
     </figure> */
.flo-art { --head: 50%; position: relative; margin: 0; }
.flo-art > img { display: block; width: 100%; height: auto; }
.flo-band {
  display: grid; grid-template-columns: minmax(0, calc(var(--head) + 38px)) minmax(0, 1fr);
  padding-bottom: 18px;  /* the tail hangs 13px below the bubble; the rest keeps it clear of her hair */
  direction: ltr;
}
.flo-say, .flo-ghost {
  grid-area: 1 / 1; justify-self: right; align-self: end;
  width: max-content; max-width: min(15em, 100%);
  margin: 0; padding: 12px 16px 13px; border-radius: 22px;
  font: 700 16px/1.35 var(--text); text-align: left; text-wrap: balance;
}
[dir="rtl"] .flo-say, [dir="rtl"] .flo-ghost { direction: rtl; text-align: right; }
.flo-ghost { visibility: hidden; }
.flo-say {
  position: relative; z-index: 3;
  overflow-anchor: none;  /* never the scroll anchor: a new line must not scroll the page */
  background: var(--speech-bg); color: var(--speech-ink);
  box-shadow: var(--shadow-sm);
  transform-origin: calc(100% - 38px) 100%;
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.flo-say::after {
  content: ""; position: absolute; right: 30px; bottom: -13px;
  width: 16px; height: 14px; background: var(--speech-bg);
  clip-path: polygon(0 0, 100% 0, 100% 100%);
}
.flo-say.is-out { opacity: 0; transform: scale(0.96); }
@media (max-width: 479px) {
  .flo-say, .flo-ghost { padding: 10px 13px 11px; font-size: 15px; }
}
@media (prefers-reduced-motion: reduce) {
  .flo-say { transition: opacity 160ms ease; }
  .flo-say.is-out { transform: none; }
}

/* Wayfinding tab (DESIGN.md, Navigation): the breadcrumb above the h1 on every page except home. Navigation, not an
   eyebrow: one per page, in the hero only. A compact white pill holding the section's icon disc and an ordered list:
     <nav class="crumbs" aria-label="(Breadcrumb, in the page's language)">
       <span class="crumbs-disc" aria-hidden="true"><svg class="i"><use href="#i-chats"/></svg></span>
       <ol><li><span class="crumbs-item">Product</span></li>
           <li><span class="crumbs-item" aria-current="page">WhatsApp Flows</span></li></ol>
     </nav>
   A parent with a page of its own is <a class="crumbs-link" href="..."><span class="crumbs-item">...</span></a>, with
   a 44px tall target that leaves the pill's size alone; the current page comes last, with aria-current="page". The
   separators are drawn here and point the reading way, so they mirror in right to left. Each item truncates rather
   than wraps, so the pill keeps one line on a phone and never moves the h1. The hero sets the disc's colours, the
   section's bright: --crumbs-disc and --crumbs-disc-ink. The section icons are in the sprite: Product #i-chats
   (Lagoon Mint, navy icon), Solutions #i-route (Open Sky), Get started and Pricing #i-flag (Harbour Blue, white
   icon), Integrations #i-link (Sunset Coral), Resources #i-pages (Open Sky, as Solutions). The only motion is the link's 160ms colour and underline change, on
   fine pointers. */
.crumbs {
  display: inline-flex; align-items: center; gap: 10px;
  max-width: 100%; min-height: 36px;
  padding-block: 4px; padding-inline: 4px 16px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--ink-soft);
  box-shadow: var(--shadow-sm);
  font: 600 15px/1.3 var(--text);
}
.crumbs-disc {
  flex: none; display: grid; place-items: center;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--crumbs-disc, var(--sky)); color: var(--crumbs-disc-ink, var(--on-bright));
}
.crumbs-disc .i { width: 15px; height: 15px; }
.crumbs ol { display: flex; align-items: center; min-width: 0; margin: 0; padding: 0; list-style: none; }
.crumbs li { display: flex; align-items: center; min-width: 0; }
.crumbs li + li::before {
  content: ""; flex: none;
  width: 6px; height: 6px; margin-inline: 7px 11px;
  border-block-start: 2px solid; border-inline-end: 2px solid;
  border-color: color-mix(in srgb, var(--ink-soft) 70%, transparent);
  rotate: 45deg;
}
[dir="rtl"] .crumbs li + li::before { rotate: -45deg; }
.crumbs-item { display: block; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The section is the signal (the h1 already names the page): when the pill runs out of room the current page gives
   way first, and a parent step only shortens once the current page has no room left. Shrink weights rather than a
   percentage cap, because a percentage of a shrink-to-fit trail cut short parents like "Integrations" beside "n8n"
   even when there was room. */
.crumbs li:not(:last-child) { flex-shrink: 1; }
.crumbs li:last-child { flex-shrink: 1000; }
.crumbs [aria-current="page"] { color: var(--ink); }
.crumbs-link {
  position: relative; display: flex; min-width: 0; border-radius: 6px;
  color: inherit;
  text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 0.22em;
  text-decoration-color: color-mix(in srgb, currentColor 40%, transparent);
  transition: color 160ms ease, text-decoration-color 160ms ease;
}
.crumbs-link::before { content: ""; position: absolute; inset: -12px 0; }
.crumbs-link:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  .crumbs-link:hover { color: var(--ink); text-decoration-color: currentColor; }
}
@media (max-width: 479px) {
  .crumbs { gap: 8px; padding-inline-end: 14px; font-size: 14px; }
}

/* Section motif (DESIGN.md, The Section Signature Rule): the flat shape behind Flo in a section hero. The drawings live
   once in partials/motifs.hubl.html (included by the base layout); a hero places its section's with
     <svg class="motif" viewBox="0 0 1440 300" preserveAspectRatio="xMaxYMax meet" aria-hidden="true"
       focusable="false"><use href="#motif-stones"/></svg>
   as the first child of its field, and sets --motif (the section's tint: --stone, --hill, --road or --chain) and
   --motif-cut (its field, for the details cut back into the shape). The field needs position: relative and
   isolation: isolate, so z-index -1 keeps the motif under everything inside it. The drawing scales evenly from the
   bottom end corner and never stretches; it mirrors with the layout, so it always rises behind Flo. No text ever
   sits on it. Below 960px it is hidden, and the panel behind Flo takes --motif instead. */
.motif { position: absolute; z-index: -1; inset-inline: 0; bottom: 0; width: 100%; height: 300px; overflow: visible; pointer-events: none; }
[dir="rtl"] .motif { transform: scaleX(-1); }
@media (max-width: 959px) {
  .motif { display: none; }
}

/* Responsive */
@media (max-width: 959px) {
  .fact-chips { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
}
@media (max-width: 719px) {
  .card-link { rotate: calc(var(--tilt, 0deg) * var(--tilt-dir, 1) / 2); }
  .table { font-size: 15px; }
  /* Part of the next column always shows, with a soft edge on the sticky column, so the table reads as scrollable */
  .table :is(th, td) { min-width: 6rem; padding: 12px; }
  .table :is(th, td):first-child { min-width: 7rem; box-shadow: 10px 0 12px -12px var(--edge-shadow); }
  .table thead .is-recommended .tag { min-height: 26px; padding: 3px 9px; font-size: 12px; }
  [dir="rtl"] .table :is(th, td):first-child { box-shadow: -10px 0 12px -12px var(--edge-shadow); }
  .flw-form .hs-form .actions .hs-button { width: 100%; }
}
@media (max-width: 479px) {
  .fact-chip { padding: 12px 12px 14px; border-radius: 20px; }
  .fact-chip dd { font-size: 15px; }
  .screen-bar, .screen-body { padding-inline: 14px; }
  .bubble { max-width: 90%; }
}

/* Video dialog (site.js): a 16:9 player over the dimmed page, with a close pill above it. It opens with a
   short fade and a scale from 0.96 and closes at once; under reduced motion it only fades. Markup: a button
   with data-video-dialog="<id>", and <dialog class="video-dialog" id="<id>"> holding .video-dialog-bar,
   .video-dialog-stage and a <template> with the player. */
.video-dialog {
  width: min(100% - 2 * var(--gutter), 1100px); max-width: none; max-height: none;
  margin: auto; padding: 0; border: 0; overflow: visible;
  background: transparent; color: var(--band-ink);
}
.video-dialog::backdrop { background: rgb(8 20 32 / 0.8); }
.video-dialog-bar { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.video-dialog-close { --b-bg: var(--sticker-bg); --b-ink: var(--sticker-ink); }
.video-dialog-close .i { width: 18px; height: 18px; }
.video-dialog-stage {
  aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: 26px; background: var(--band);
  box-shadow: var(--shadow-lift);
}
.video-dialog-stage > * { width: 100%; height: 100%; }
@media (prefers-reduced-motion: no-preference) {
  .video-dialog[open] { animation: video-dialog-in 220ms var(--ease-out); }
  .video-dialog[open]::backdrop { animation: fade-in 220ms var(--ease-out); }
}
@media (prefers-reduced-motion: reduce) {
  .video-dialog[open], .video-dialog[open]::backdrop { animation: fade-in 150ms ease-out; }
}
@keyframes video-dialog-in { from { opacity: 0; scale: 0.96; } }

/* Reduced motion: no press scale, no tick pop, the chevron turns instantly (the FAQ answer is gated above) */
@media (prefers-reduced-motion: reduce) {
  .faq summary .i { transition: color 160ms ease; }
  .flw-form .hs-form .hs-button:active { transform: none; }
  .form .choice input[type="checkbox"]::before,
  .flw-form .hs-form .hs-input[type="checkbox"]::before { scale: 1; transition: opacity 120ms ease; }
}

/* WhatsApp Flow sheet and CRM record card (phase 2 product page, shared by its modules): the product mocks
   several sections draw, the way modules already share .screen and .bubble.
   .wa-flow: a WhatsApp Flow sheet. A bar (lead button, Flow name, a count or tag), a body (.wa-flow-hi intro,
   .wa-flow-title question, .wa-flow-field with .wa-flow-label, option rows .wa-flow-opt with .wa-flow-dot,
   chips .wa-flow-chip, .wa-flow-select, .wa-flow-input, the .wa-flow-optin checkbox, .wa-flow-help and
   .wa-flow-err), and a footer with the green .wa-flow-btn. .wa-flow-fake draws a select or field value in a
   static illustration; .is-on marks a chosen row or chip there.
   .crm-rec: a CRM contact record. A head (initials, name, source), rows pairing a .crm-chip property name with
   the value that lands (.is-wait, .is-set, .is-new flash), and a footer.
   Mock screens keep the softer Hairline edges: they illustrate a form rather than ask for input. */
.wa-flow {
  position: relative; min-width: 0;
  display: flex; flex-direction: column;
  border-radius: 26px; overflow: hidden;
  background: var(--sheet-bg); color: var(--ink);
  box-shadow: var(--shadow);
}
.wa-flow-bar {
  display: grid; grid-template-columns: minmax(44px, auto) minmax(0, 1fr) minmax(44px, auto); align-items: center; gap: 6px;
  min-height: 56px; padding: 6px 10px;
  border-bottom: 1px solid var(--line);
}
.wa-flow-lead {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 0; border-radius: 50%; background: transparent; color: var(--ink-soft);
}
.wa-flow-lead .i { width: 20px; height: 20px; }
button.wa-flow-lead { cursor: pointer; transition: background-color 160ms ease; -webkit-tap-highlight-color: transparent; }
button.wa-flow-lead:focus-visible { outline-offset: -2px; }
button.wa-flow-lead:active { background: var(--surface-2); transition-duration: 0ms; }
.wa-flow-name { min-width: 0; text-align: center; font: 800 16px/1.25 var(--text); overflow-wrap: anywhere; }
.wa-flow-bar > :last-child { justify-self: end; }
.wa-flow-count { padding-inline-end: 8px; font: 600 13px/1.2 var(--text); color: var(--ink-soft); font-variant-numeric: tabular-nums; white-space: nowrap; }
.wa-flow-body { flex: 1; display: flex; flex-direction: column; gap: 16px; padding: 18px; }
.wa-flow-hi { font-size: 16px; line-height: 1.45; text-wrap: pretty; }
.wa-flow-title { padding: 0; font: 800 19px/1.25 var(--text); text-wrap: balance; border-radius: 8px; }
.wa-flow-title:focus-visible { outline-offset: 4px; }
.wa-flow-field { display: grid; gap: 8px; min-width: 0; margin: 0; padding: 0; border: 0; }
.wa-flow-label { padding: 0; font: 800 15px/1.3 var(--text); }
legend.wa-flow-label { margin-bottom: 8px; }
legend.wa-flow-title { margin-bottom: 12px; }
.wa-flow-opts { display: grid; gap: 8px; }
.wa-flow-opt {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  min-height: 48px; padding: 8px 14px;
  border-radius: 14px; border: 2px solid var(--line);
  background: var(--sheet-bg); color: var(--ink);
  font: 700 16px/1.3 var(--text); cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.wa-flow-opt > span:first-of-type { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.wa-flow-opt input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.wa-flow-dot {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--line-strong); color: transparent;
  transition: background-color 160ms ease, border-color 160ms ease;
}
.wa-flow-dot .i { width: 14px; height: 14px; }
.wa-flow-opt.is-check .wa-flow-dot { border-radius: 7px; }
.wa-flow-opt:has(input:checked), .wa-flow-opt.is-on { border-color: var(--green); background: var(--field-green); }
.wa-flow-opt:has(input:checked) .wa-flow-dot, .wa-flow-opt.is-on .wa-flow-dot { border-color: var(--green); background: var(--green); box-shadow: inset 0 0 0 4px var(--field-green); }
.wa-flow-opt.is-check:has(input:checked) .wa-flow-dot, .wa-flow-opt.is-check.is-on .wa-flow-dot { box-shadow: none; color: var(--on-bright); }
.wa-flow-opt:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
/* Chips: short answers (a day, a time, a count) as a wrapping row of pills */
.wa-flow-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.wa-flow-chip {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 0 16px;
  border-radius: 999px; border: 2px solid var(--line);
  background: var(--sheet-bg); color: var(--ink);
  font: 700 15px/1.2 var(--text); white-space: nowrap; cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease, color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.wa-flow-chip input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.wa-flow-chip:has(input:checked), .wa-flow-chip.is-on { border-color: var(--green); background: var(--green); color: var(--on-bright); }
.wa-flow-chip:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .wa-flow-opt:hover, .wa-flow-chip:hover { border-color: var(--line-strong); }
  .wa-flow-opt:has(input:checked):hover, .wa-flow-chip:has(input:checked):hover { border-color: var(--green); }
  button.wa-flow-lead:hover { background: var(--surface-2); color: var(--ink); }
}
/* Select and text input (and their drawn stand-ins, .wa-flow-fake, in illustrations) */
.wa-flow-select { position: relative; display: block; }
.wa-flow-select select, .wa-flow-input, .wa-flow-fake {
  display: flex; align-items: center;
  width: 100%; min-height: 48px; margin: 0; padding-block: 0; padding-inline: 14px;
  border-radius: 14px; border: 2px solid var(--line);
  background: var(--sheet-bg); color: var(--ink);
  font: 700 16px/1.2 var(--text);
  transition: border-color 160ms ease;
}
.wa-flow-select select { padding-inline-end: 42px; text-overflow: ellipsis; appearance: none; -webkit-appearance: none; cursor: pointer; }
.wa-flow-select::after {
  content: ""; position: absolute; inset-inline-end: 18px; top: 50%;
  width: 8px; height: 8px;
  border-right: 2.5px solid var(--ink-soft); border-bottom: 2.5px solid var(--ink-soft);
  translate: 0 -70%; rotate: 45deg; pointer-events: none;
}
.wa-flow-fake { justify-content: space-between; gap: 10px; }
.wa-flow-fake .i { width: 18px; height: 18px; color: var(--ink-soft); }
.wa-flow-input::placeholder { color: var(--ph); opacity: 1; }
.wa-flow-input[type="email"] { direction: ltr; }
[dir="rtl"] .wa-flow-input[type="email"] { text-align: right; }
.wa-flow-input[aria-invalid="true"] { border-color: var(--err); box-shadow: inset 0 0 0 1px var(--err); }
.wa-flow-select select:focus-visible, .wa-flow-input:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .wa-flow-select select:hover, .wa-flow-input:not([aria-invalid="true"]):hover { border-color: var(--line-strong); }
}
/* Opt-in: a single checkbox with its wording beside it */
.wa-flow-optin {
  --wa-flow-tick: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.6l4.4 4.4L19 7.4' fill='none' stroke='black' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  position: relative;
  display: grid; grid-template-columns: 22px minmax(0, 1fr); gap: 12px; align-items: start;
  padding: 12px 14px; border-radius: 14px; border: 2px solid var(--line);
  font: 600 15px/1.45 var(--text); cursor: pointer;
  transition: border-color 160ms ease, background-color 160ms ease;
  -webkit-tap-highlight-color: transparent;
}
.wa-flow-optin input {
  appearance: none; -webkit-appearance: none;
  display: grid; place-content: center;
  width: 22px; height: 22px; margin: 1px 0 0;
  border: 2px solid var(--line-strong); border-radius: 7px;
  background: var(--sheet-bg); cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease;
}
.wa-flow-optin input::before {
  content: ""; width: 14px; height: 14px; background: var(--on-bright);
  -webkit-mask: var(--wa-flow-tick) center / contain no-repeat; mask: var(--wa-flow-tick) center / contain no-repeat;
  opacity: 0; transition: opacity 120ms ease;
}
.wa-flow-optin input:checked { border-color: var(--green); background: var(--green); }
.wa-flow-optin input:checked::before { opacity: 1; }
.wa-flow-optin:has(input:checked) { border-color: var(--green); background: var(--field-green); }
.wa-flow-optin input:focus-visible { outline: none; }
.wa-flow-optin:has(input:focus-visible) { outline: 3px solid var(--focus); outline-offset: 2px; }
@media (hover: hover) and (pointer: fine) {
  .wa-flow-optin:not(:has(input:checked)):hover { border-color: var(--line-strong); }
}
.wa-flow-help { font-size: 13px; line-height: 1.45; color: var(--ink-soft); }
.wa-flow-err { display: flex; align-items: flex-start; gap: 6px; font: 700 13px/1.4 var(--text); color: var(--err); }
.wa-flow-err .i { width: 16px; height: 16px; margin-top: 1px; }
/* The footer action, a full-width green pill (Navy On Bright: ink text on the green) */
.wa-flow-foot { padding: 12px 18px 16px; border-top: 1px solid var(--line); background: var(--sheet-bg); }
.wa-flow-btn {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 50px; padding: 0 18px;
  border: 0; border-radius: 999px;
  background: var(--green); color: var(--wa-ink);
  font: 800 16px/1.15 var(--text); text-align: center; cursor: pointer;
  transition: transform 160ms var(--ease-out), background-color 200ms ease;
  -webkit-tap-highlight-color: transparent;
}
span.wa-flow-btn { cursor: default; }
button.wa-flow-btn:active { transform: scale(0.97); }
.wa-flow-btn:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; }
@media (hover: hover) and (pointer: fine) {
  button.wa-flow-btn:hover { background: var(--wa-bg-hover); }
}
.wa-flow-tick { flex: none; width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: var(--green); color: var(--on-bright); }
.wa-flow-tick .i { width: 18px; height: 18px; }
.wa-flow-done { display: flex; align-items: center; gap: 12px; font: 800 18px/1.3 var(--text); text-wrap: balance; }
.wa-flow-again {
  align-self: center;
  min-height: 44px; padding: 0 14px;
  border: 0; border-radius: 999px; background: transparent;
  color: var(--accent-ink); font: 700 15px/1.2 var(--text);
  text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.25em; cursor: pointer;
}

/* CRM contact record: a head (initials, name, source), rows of property chip and value, a footer */
.crm-rec { min-width: 0; border-radius: 26px; overflow: hidden; background: var(--sheet-bg); color: var(--ink); box-shadow: var(--shadow); }
.crm-rec-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; padding: 14px 18px; border-bottom: 1px solid var(--line); }
.crm-rec-ava {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--btn-bg); color: var(--btn-ink);
  font: 800 15px/1 var(--display);
}
.crm-rec-who { min-width: 0; flex: 1 1 150px; }
.crm-rec-who b { display: block; font-size: 17px; line-height: 1.2; }
.crm-rec-who small { display: flex; align-items: center; gap: 6px; margin-top: 2px; font-size: 13px; line-height: 1.3; color: var(--ink-soft); }
.crm-rec-who small img { flex: none; width: 14px; height: 14px; }
.crm-rec-rows { padding: 2px 18px; }
.crm-rec-row {
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); gap: 4px 12px; align-items: center;
  margin-inline: -18px; padding: 10px 18px;
  border-bottom: 1px solid var(--line);
  transition: background-color 200ms ease;
}
.crm-rec-row:last-child { border-bottom: 0; }
.crm-rec-row::after { content: ""; position: absolute; z-index: -1; inset: 0; background: var(--flash); opacity: 0; pointer-events: none; }
.crm-rec-row.is-new::after { animation: crm-flash 1300ms ease-out; }
@keyframes crm-flash { from { opacity: 1; } to { opacity: 0; } }
.crm-rec-row dt { display: grid; gap: 4px; justify-items: start; min-width: 0; }
.crm-rec-label { font-size: 13px; line-height: 1.3; color: var(--ink-soft); }
.crm-rec-row dd { display: grid; gap: 2px; min-width: 0; margin: 0; }
.crm-rec-val { font: 700 14px/1.35 var(--mono); font-variant-numeric: tabular-nums; overflow-wrap: break-word; unicode-bidi: plaintext; text-align: match-parent; }
.crm-rec-row dd small { font: 500 12px/1.35 var(--text); color: var(--ink-soft); }
.crm-rec-row.is-wait .crm-rec-val { font: 500 14px/1.35 var(--text); color: var(--ink-soft); }
.crm-chip {
  justify-self: start; max-width: 100%; overflow-wrap: anywhere;
  padding: 3px 8px; border-radius: 8px;
  background: var(--crm-bg); color: var(--crm-ink);
  font: 600 12px/1.35 var(--mono);
}
.crm-rec-tick {
  width: 20px; height: 20px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2px solid var(--line-strong); color: transparent;
  transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}
.crm-rec-tick .i { width: 12px; height: 12px; }
.crm-rec-row.is-set .crm-rec-tick { background: var(--green); border-color: var(--green); color: var(--on-bright); }
.crm-rec-foot {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 6px 12px;
  padding: 12px 18px 14px; background: var(--surface-2);
  font-size: 13px; line-height: 1.4; color: var(--ink-soft);
}
@media (prefers-reduced-motion: no-preference) {
  .crm-rec-row.is-set .crm-rec-tick { animation: crm-fill 360ms var(--ease-pop) both; }
}
/* The ring is already on screen, so the tick fills it with a small pop and never fades out first */
@keyframes crm-fill { from { scale: 0.8; } to { scale: 1; } }
@media (prefers-reduced-motion: reduce) {
  button.wa-flow-btn:active { transform: none; }
  .crm-rec-row.is-new::after { animation-duration: 600ms; }
}
