/* ============================================================================
   SIForm — rendered form (runtime) responsive system.

   Loaded after app.css and owns everything the *end user* sees: the form
   shell, grid, fields, controls, wizard chrome and modals.

   Design decisions
   ----------------
   1. Layout responds to the FORM'S OWN WIDTH via container queries, not the
      viewport. A form can live in a 320px sidebar on a 4K monitor; only its
      container width is meaningful. This also makes the builder's device
      preview genuine — resizing the frame re-runs the same rules a real phone
      would, with no JS and no re-render.
   2. Field/column widths are declared once as custom properties
      (--ff-col-d/t/m, --ff-w-d/t/m) and *selected* by CSS per breakpoint.
      Previously JS picked one value at render time, so an embedded form was
      frozen at its desktop layout.
   3. Sizes are fluid (clamp) and spacing comes from one scale, so nothing has
      to be re-tuned per breakpoint.

   Breakpoints (container width)
     >=1200  desktop        992-1199 laptop      768-991 tablet landscape
     600-767 tablet portrait 480-599 mobile large   <480 mobile small
   ========================================================================== */

/* ---------------------------------------------------------------- tokens -- */

.ff-form-root {
  /* The container everything below queries. */
  container-type: inline-size;
  container-name: ffform;

  /* Fluid type scale — grows with the container, clamped at both ends. */
  --ff-fs-title: clamp(1.35rem, 1.05rem + 1.4cqi, 1.9rem);
  --ff-fs-desc: clamp(0.875rem, 0.83rem + 0.22cqi, 1rem);
  --ff-fs-label: clamp(0.875rem, 0.85rem + 0.15cqi, 0.95rem);
  --ff-fs-input: clamp(0.95rem, 0.9rem + 0.2cqi, 1rem);
  --ff-fs-help: clamp(0.78rem, 0.76rem + 0.1cqi, 0.83rem);
  --ff-fs-btn: clamp(0.9rem, 0.87rem + 0.15cqi, 0.98rem);

  /* Fluid spacing scale. */
  --ff-sp-1: clamp(0.25rem, 0.22rem + 0.15cqi, 0.4rem);
  --ff-sp-2: clamp(0.45rem, 0.4rem + 0.25cqi, 0.65rem);
  --ff-sp-3: clamp(0.7rem, 0.6rem + 0.4cqi, 1rem);
  --ff-sp-4: clamp(1rem, 0.85rem + 0.6cqi, 1.5rem);
  --ff-sp-5: clamp(1.4rem, 1.15rem + 1cqi, 2.25rem);

  --ff-pad: clamp(1rem, 0.5rem + 3cqi, 2.4rem);   /* form shell padding      */
  --ff-gap: clamp(0.65rem, 0.5rem + 0.7cqi, 1.1rem); /* grid gutter          */
  --ff-radius: 10px;
  --ff-touch: 44px;                                /* WCAG 2.5.8 target size */
  --ff-label-col: clamp(7.5rem, 26cqi, 12rem);     /* left-label column      */

  font-size: 16px;   /* never inherit a shrunken host font size */
  line-height: 1.55;
}

/* ------------------------------------------------------------------ shell -- */

.ff-form-root * { box-sizing: border-box; }

.ff-form-root .pv-form-head { margin-bottom: var(--ff-sp-4); }
.ff-form-root .pv-form-head h1 {
  font-size: var(--ff-fs-title);
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin: 0 0 var(--ff-sp-2);
  /* Long unbroken words (URLs, IDs) must never widen the form. */
  overflow-wrap: anywhere;
}
.ff-form-root .pv-form-head p {
  font-size: var(--ff-fs-desc);
  color: var(--muted);
  margin: 0;
  overflow-wrap: anywhere;
}

/* ------------------------------------------------------------------- grid -- */

.ff-form-root .pv-fields { display: flex; flex-direction: column; gap: var(--ff-sp-1); }

.ff-form-root .pv-row {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--ff-gap);
  margin-bottom: var(--ff-sp-2);
}

/* Column span is chosen per breakpoint from custom properties.
   `minmax(0,1fr)` + `min-width:0` is what stops a wide child (a table, a long
   word) from forcing the track — the classic CSS-grid overflow trap. */
.ff-form-root .pv-col {
  grid-column: span var(--ff-col-d, 12);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--ff-sp-1);
}

/* Field width within its column (12-based, like the columns). */
.ff-form-root .pv-field {
  width: calc(var(--ff-w-d, 12) / 12 * 100%);
  min-width: 0;
  margin-bottom: var(--ff-sp-2);
}
.ff-form-root .pv-field.is-logic-hidden { display: none; }
/* A row whose every field is hidden by logic takes no room, so it leaves no gap. */
.ff-form-root .pv-row:has(> .pv-col > .pv-field):not(:has(> .pv-col > .pv-field:not(.is-logic-hidden))) { display: none; }

/* Per-breakpoint visibility (field settings → Appearance → Responsive). */
.ff-form-root .ff-hide-d { display: none; }

/* --------------------------------------------------------------- controls -- */

.ff-form-root .pv-label {
  display: flex;
  align-items: baseline;
  gap: 0.35em;
  flex-wrap: wrap;                 /* long labels wrap instead of overflowing */
  font-size: var(--ff-fs-label);
  font-weight: 600;
  margin-bottom: var(--ff-sp-1);
  overflow-wrap: anywhere;
}
.ff-form-root .pv-help,
.ff-form-root .pv-error {
  font-size: var(--ff-fs-help);
  margin-top: var(--ff-sp-1);
  overflow-wrap: anywhere;
}
.ff-form-root .pv-error { color: var(--danger); font-weight: 500; }

.ff-form-root .ff-input {
  width: 100%;
  max-width: 100%;
  min-height: var(--ff-touch);
  padding: var(--ff-sp-2) var(--ff-sp-3);
  font-size: var(--ff-fs-input);
  border-radius: var(--ff-radius);
  /* 16px minimum prevents iOS Safari from zooming on focus. */
}
.ff-form-root textarea.ff-input { min-height: calc(var(--ff-touch) * 2); resize: vertical; }
.ff-form-root select.ff-input {
  /* Native select on touch devices = native picker, correct z-order, no clipping. */
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1.15em top 50%, right 0.85em top 50%;
  background-size: 0.32em 0.32em, 0.32em 0.32em;
  background-repeat: no-repeat;
  padding-inline-end: 2.4em;   /* logical: the arrow follows the text direction */
  text-overflow: ellipsis;          /* long option labels never widen the box */
}
.ff-form-root input[type="date"].ff-input,
.ff-form-root input[type="time"].ff-input {
  /* iOS renders date inputs with intrinsic width; force them to the grid. */
  min-width: 0;
  width: 100%;
  appearance: none;
}
.ff-form-root .fb-control { min-width: 0; }
.ff-form-root .fb-control.has-affix { flex-wrap: wrap; gap: var(--ff-sp-2); }
.ff-form-root .fb-affix { flex: 0 0 auto; }

/* Choices: generous, unambiguous touch targets. */
.ff-form-root .ff-choices { gap: var(--ff-sp-2); }
.ff-form-root .ff-choice {
  min-height: var(--ff-touch);
  align-items: center;
  padding: var(--ff-sp-1) 0;
  gap: 0.6em;
  overflow-wrap: anywhere;
}
.ff-form-root .ff-choice input[type="checkbox"],
.ff-form-root .ff-choice input[type="radio"] { width: 1.25em; height: 1.25em; flex: 0 0 auto; }
.ff-form-root .ff-choices.ff-inline { flex-wrap: wrap; column-gap: var(--ff-sp-4); }

.ff-form-root .ff-toggle { min-height: var(--ff-touch); }
.ff-form-root .ff-star { font-size: clamp(1.6rem, 1.3rem + 1.2cqi, 2rem); min-width: 1.4em; }
.ff-form-root .ff-rating { flex-wrap: wrap; gap: var(--ff-sp-1); }

.ff-form-root .ff-slider-wrap { flex-wrap: wrap; gap: var(--ff-sp-3); }
.ff-form-root .ff-slider-wrap input[type="range"] { flex: 1 1 12ch; min-width: 0; height: var(--ff-touch); }

.ff-form-root .ff-qty { flex-wrap: wrap; }
.ff-form-root .ff-qty-btn { min-width: var(--ff-touch); min-height: var(--ff-touch); }
.ff-form-root .ff-qty input { min-height: var(--ff-touch); }

.ff-form-root .ff-color input[type="color"] { min-width: 3.4rem; min-height: var(--ff-touch); }

/* Address sub-grid collapses with the container, not the viewport. */
.ff-form-root .ff-address { gap: var(--ff-sp-2); }
.ff-form-root .ff-address-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(10rem, 100%), 1fr));
  gap: var(--ff-sp-2);
}

/* Uploads: the drop zone shrinks gracefully and stays tappable. */
.ff-form-root .ff-upload-drop {
  padding: var(--ff-sp-4) var(--ff-sp-3);
  min-height: calc(var(--ff-touch) * 1.8);
  gap: var(--ff-sp-1);
}
.ff-form-root .ff-upload-drop small { overflow-wrap: anywhere; }
.ff-form-root .ff-up-act { min-width: var(--ff-touch); min-height: var(--ff-touch); }

/* Below roughly a phone's width the actions no longer fit beside the name, so
   the row becomes two: file on top, controls underneath at full tap size. */
@container (max-width: 26rem) {
  .ff-form-root .ff-up-item { flex-wrap: wrap; }
  .ff-form-root .ff-up-main { flex: 1 1 100%; order: 2; }
  .ff-form-root .ff-up-actions { order: 3; margin-inline-start: auto; }
}
@supports not (container-type: inline-size) {
  @media (max-width: 26rem) {
    .ff-form-root .ff-up-item { flex-wrap: wrap; }
    .ff-form-root .ff-up-main { flex: 1 1 100%; order: 2; }
    .ff-form-root .ff-up-actions { order: 3; margin-inline-start: auto; }
  }
}

/* Signature pad scales with the container and never overflows. */
.ff-form-root .ff-signature { position: relative; }
.ff-form-root .ff-signature-pad {
  width: 100%;
  max-width: 100%;
  height: clamp(6rem, 4rem + 14cqi, 9rem);
  touch-action: none;              /* drawing must not scroll the page */
}
.ff-form-root .fx-sign-modes { flex-wrap: wrap; gap: var(--ff-sp-1); }
.ff-form-root .fx-sign-mode { min-height: var(--ff-touch); }

/* Media blocks. */
.ff-form-root img,
.ff-form-root .ff-image { max-width: 100%; height: auto; }
.ff-form-root .ff-map-canvas:not(.ff-map-live) { min-height: 7rem; }
.ff-form-root .ff-richtext-area { min-height: clamp(5rem, 4rem + 10cqi, 8rem); }
.ff-form-root .ff-richtext-bar { flex-wrap: wrap; }
.ff-form-root .ff-richtext-bar button { min-width: 2.2rem; min-height: 2.2rem; }
.ff-form-root .ff-code textarea { font-size: max(0.85rem, 13px); }

/* Payment blocks. */
.ff-form-root .ff-product { flex-wrap: wrap; gap: var(--ff-sp-2); }
.ff-form-root .ff-product-amount .ff-input { width: min(8rem, 100%); }
.ff-form-root .ff-money { flex-wrap: wrap; gap: var(--ff-sp-2); }
.ff-form-root .ff-coupon { flex-wrap: wrap; }
.ff-form-root .ff-coupon input { flex: 1 1 10rem; min-width: 0; }
.ff-form-root .ff-gateway-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(8rem, 100%), 1fr)); gap: var(--ff-sp-2); }
.ff-form-root .ff-nps-scale { display: flex; flex-wrap: wrap; gap: var(--ff-sp-1); }
.ff-form-root .ff-nps-btn { flex: 1 1 2.5rem; min-width: var(--ff-touch); min-height: var(--ff-touch); }
.ff-form-root .ff-likert { gap: var(--ff-sp-2); }
.ff-form-root .ff-likert-opt { min-height: var(--ff-touch); flex: 1 1 6rem; }
.ff-form-root .ff-captcha { flex-wrap: wrap; gap: var(--ff-sp-2); min-height: var(--ff-touch); }

/* --------------------------------------------------------------- tables --- */

/* Wide data (matrix, table builder, calculation tables) scrolls inside its own
   box — the page itself must never scroll sideways. */
.ff-form-root .ff-matrix-wrap,
.ff-form-root .fx-table,
.ff-form-root .pv-table-scroll {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.ff-form-root .ff-matrix { min-width: 22rem; border-collapse: collapse; }
.ff-form-root .ff-matrix th,
.ff-form-root .ff-matrix td { padding: var(--ff-sp-1) var(--ff-sp-2); }
.ff-form-root .ff-matrix input[type="radio"] { width: 1.25em; height: 1.25em; }
/* The label is the activation target, so it — not the 16px radio — must meet
   the touch minimum. */
.ff-form-root .ff-matrix-hit {
  display: flex; align-items: center; justify-content: center;
  min-height: var(--ff-touch); min-width: var(--ff-touch);
  margin: 0; cursor: pointer;
}

/* Card conversion: under 480px a grid of radios is unusable, so each matrix row
   becomes a labelled card and the horizontal scroll disappears entirely. */
@container ffform (max-width: 479px) {
  .ff-form-root .ff-matrix-wrap { overflow-x: visible; }
  .ff-form-root .ff-matrix { min-width: 0; width: 100%; }
  .ff-form-root .ff-matrix thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .ff-form-root .ff-matrix tbody,
  .ff-form-root .ff-matrix tr,
  .ff-form-root .ff-matrix th,
  .ff-form-root .ff-matrix td { display: block; width: 100%; }
  .ff-form-root .ff-matrix tr {
    border: 1px solid var(--border); border-radius: var(--ff-radius);
    padding: var(--ff-sp-2) var(--ff-sp-3); margin-bottom: var(--ff-sp-2);
  }
  .ff-form-root .ff-matrix tbody th {
    font-weight: 700; padding: 0 0 var(--ff-sp-1); border: 0; text-align: start;
  }
  .ff-form-root .ff-matrix td {
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--ff-sp-3); min-height: var(--ff-touch); padding: 0; border: 0;
  }
  .ff-form-root .ff-matrix td::before {
    content: attr(data-label);
    flex: 1 1 auto; min-width: 0;
    font-size: var(--ff-fs-help); color: var(--muted);
    overflow-wrap: anywhere;
  }
  .ff-form-root .ff-matrix-hit { flex: 0 0 auto; justify-content: flex-end; }
}

/* ------------------------------------------------------------- containers -- */

.ff-form-root .pv-section { padding: var(--ff-sp-4); border-radius: var(--ff-radius); }
.ff-form-root .pv-section-inner { min-width: 0; }
.ff-form-root .pv-repeater { padding: var(--ff-sp-3); }
.ff-form-root .pv-repeat-group { padding-bottom: var(--ff-sp-3); }
.ff-form-root .fx-tabbar { overflow-x: auto; flex-wrap: nowrap; scrollbar-width: thin; }
.ff-form-root .fx-tabbtn { white-space: nowrap; min-height: var(--ff-touch); }
.ff-form-root .fx-acc-head { min-height: var(--ff-touch); text-align: start; }

/* ---------------------------------------------------------------- wizard -- */

.ff-form-root .pv-footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--ff-sp-3);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--ff-sp-5);
}
.ff-form-root .pv-footer-right { display: flex; flex-wrap: wrap; gap: var(--ff-sp-2); }
.ff-form-root .ff-btn {
  min-height: var(--ff-touch);
  font-size: var(--ff-fs-btn);
  padding: var(--ff-sp-2) var(--ff-sp-4);
  max-width: 100%;
  overflow-wrap: anywhere;         /* long button text wraps, never overflows */
  text-align: center;
}
.ff-form-root .ff-btn[disabled],
.ff-form-root .ff-btn.is-loading { opacity: .6; pointer-events: none; }
.ff-form-root .ff-btn.is-loading::before {
  content: '';
  width: 0.9em; height: 0.9em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  margin-inline-end: 0.5em;
  animation: ff-spin .7s linear infinite;
}
@keyframes ff-spin { to { transform: rotate(360deg); } }

.ff-form-root .pv-progress { margin: var(--ff-sp-3) 0 var(--ff-sp-2); }
.ff-form-root .pv-steps { display: flex; flex-wrap: wrap; gap: var(--ff-sp-2); align-items: center; }
.ff-form-root .pv-step { gap: var(--ff-sp-2); min-width: 0; }
.ff-form-root .pv-step-label { overflow-wrap: anywhere; }
.ff-form-root .pv-step-line { flex: 1 1 1rem; min-width: 0.75rem; }
.ff-form-root .pv-breadcrumb { overflow-wrap: anywhere; }
.ff-form-root .pv-page-title { font-size: clamp(1rem, 0.92rem + 0.5cqi, 1.2rem); overflow-wrap: anywhere; }

.ff-form-root .pv-success { padding: var(--ff-sp-5) var(--ff-sp-3); }

/* ===========================================================================
   Breakpoints — container queries.
   Each block only *re-selects* which custom property drives the layout.
   ========================================================================= */

/* Laptop 992–1199: identical columns, slightly tighter shell. */
@container ffform (max-width: 1199px) {
  .ff-form-root { --ff-pad: clamp(1rem, 0.6rem + 2.4cqi, 2rem); }
}

/* Tablet landscape + portrait: switch to the tablet width set. */
@container ffform (max-width: 991px) {
  .ff-form-root .pv-col { grid-column: span var(--ff-col-t, var(--ff-col-d, 12)); }
  .ff-form-root .pv-field { width: calc(var(--ff-w-t, var(--ff-w-d, 12)) / 12 * 100%); }
  .ff-form-root .ff-hide-d { display: revert; }
  .ff-form-root .ff-hide-t { display: none; }
}

/* Tablet portrait: left labels become top labels — a 160px label column
   leaves too little room for the control below ~768px. */
@container ffform (max-width: 767px) {
  .ff-form-root .ff-labels-left .pv-field,
  .ff-form-root.ff-labels-left .pv-field { grid-template-columns: 1fr; }
  .ff-form-root .ff-labels-left .pv-label { margin-top: 0; }
  .ff-form-root .ff-labels-left .pv-help,
  .ff-form-root .ff-labels-left .pv-error { grid-column: 1; }
}

/* Honeypot: hidden with zero layout footprint. Off-screen positioning
   (left:-9999px) still occupies a box and can provoke horizontal scrolling in
   some hosts; clipping does not, while remaining fillable by bots. */
.ff-form-root .pv-hp-wrap,
.pv-hp-wrap {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  pointer-events: none;
}

/* Mobile: single column, full-width actions, larger targets. */
@container ffform (max-width: 599px) {
  /* A narrow container is a phone in practice — apply touch minimums even when
     the pointer reports as fine (desktop emulation, hybrid devices). */
  .ff-form-root .ff-signature-clear,
  .ff-form-root .pv-repeat-del,
  .ff-form-root .ff-richtext-bar button,
  .ff-form-root .fx-tabbtn,
  .ff-form-root .ff-qty-btn,
  .ff-form-root .ff-nps-btn,
  .ff-form-root .ff-matrix-hit,
  .ff-form-root .pv-dev { min-height: var(--ff-touch); min-width: var(--ff-touch); }
  .ff-form-root .ff-star { min-height: var(--ff-touch); min-width: var(--ff-touch); font-size: 1.9rem; }
  .ff-form-root .ff-signature-clear { position: static; align-self: flex-start; padding-inline: var(--ff-sp-3); }
  .ff-form-root .pv-repeat-del { position: static; align-self: flex-end; }
  /* Table-builder row controls are real form controls, not builder chrome. */
  .ff-form-root .fx-table [data-table-del],
  .ff-form-root .fx-table [data-table-add] { min-height: var(--ff-touch); min-width: var(--ff-touch); }
  .ff-form-root .pv-col { grid-column: span 12; }
  .ff-form-root .pv-field { width: calc(var(--ff-w-m, 12) / 12 * 100%); }
  .ff-form-root .ff-hide-t { display: revert; }
  .ff-form-root .ff-hide-m { display: none; }

  .ff-form-root .pv-footer { flex-direction: column-reverse; align-items: stretch; }
  .ff-form-root .pv-footer-right { flex-direction: column-reverse; align-items: stretch; }
  .ff-form-root .pv-footer .ff-btn,
  .ff-form-root .pv-footer-right .ff-btn { width: 100%; }

  .ff-form-root .ff-choices.ff-inline { flex-direction: column; align-items: stretch; }
  .ff-form-root .ff-product,
  .ff-form-root .ff-money { justify-content: space-between; }
  .ff-form-root .pv-steps { gap: var(--ff-sp-1); }
  .ff-form-root .pv-step-label { font-size: 0.75rem; }
}

/* Mobile small: reclaim every pixel. */
@container ffform (max-width: 479px) {
  .ff-form-root { --ff-pad: clamp(0.85rem, 0.6rem + 2cqi, 1.15rem); }
  .ff-form-root .pv-field { width: 100%; }   /* fractional widths stop paying off */
  .ff-form-root .pv-section { padding: var(--ff-sp-3); }
  .ff-form-root .pv-steps .pv-step-label { display: none; }  /* dots stay, text goes */
  .ff-form-root .pv-steps .pv-step.is-active .pv-step-label { display: inline; }
  .ff-form-root .ff-nps-btn { flex: 1 1 2.1rem; }
  .ff-form-root .ff-likert-opt { flex: 1 1 100%; }
}

/* ---------------------------------------------------------------------------
   Fallback for engines without container queries: the same rules keyed to the
   viewport. Correct for full-width embeds, which is the common case.
   ------------------------------------------------------------------------- */
@supports not (container-type: inline-size) {
  @media (max-width: 991px) {
    .ff-form-root .pv-col { grid-column: span var(--ff-col-t, var(--ff-col-d, 12)); }
    .ff-form-root .pv-field { width: calc(var(--ff-w-t, var(--ff-w-d, 12)) / 12 * 100%); }
    .ff-form-root .ff-hide-d { display: revert; }
    .ff-form-root .ff-hide-t { display: none; }
  }
  @media (max-width: 767px) {
    .ff-form-root .ff-labels-left .pv-field { grid-template-columns: 1fr; }
  }
  @media (max-width: 599px) {
    .ff-form-root .pv-col { grid-column: span 12; }
    .ff-form-root .pv-field { width: calc(var(--ff-w-m, 12) / 12 * 100%); }
    .ff-form-root .ff-hide-t { display: revert; }
    .ff-form-root .ff-hide-m { display: none; }
    .ff-form-root .pv-footer { flex-direction: column-reverse; align-items: stretch; }
    .ff-form-root .pv-footer .ff-btn { width: 100%; }
  }
  @media (max-width: 479px) {
    .ff-form-root .pv-field { width: 100%; }
  }
}

/* ------------------------------------------------------- input modality --- */

/* Coarse pointers (touch) get the full target size everywhere, independent of
   width — a tablet in landscape is still a touch device. */
@media (pointer: coarse) {
  .ff-form-root .ff-input,
  .ff-form-root .ff-btn,
  .ff-form-root .ff-choice,
  .ff-form-root .ff-qty-btn,
  .ff-form-root .ff-nps-btn { min-height: var(--ff-touch); }
  .ff-form-root .ff-choices { gap: var(--ff-sp-3); }
  .ff-form-root .ff-input { font-size: max(16px, var(--ff-fs-input)); } /* no iOS zoom */
}

/* --------------------------------------------------- label positioning ---- */

/* Left labels: a real two-column field. Collapses to top labels under 768px
   (see the container query above) because a label column starves the control. */
.ff-form-root.ff-labels-left .pv-field,
.ff-form-root .ff-labels-left .pv-field {
  display: grid;
  grid-template-columns: var(--ff-label-col) minmax(0, 1fr);
  gap: var(--ff-sp-1) var(--ff-sp-3);
  align-items: start;
}
.ff-form-root .ff-labels-left .pv-label { margin-top: 0.6em; margin-bottom: 0; }
.ff-form-root .ff-labels-left .pv-help,
.ff-form-root .ff-labels-left .pv-error { grid-column: 2; }
/* Bare content (headings, HTML, dividers) never gets a label column. */
.ff-form-root .ff-labels-left .pv-type-heading,
.ff-form-root .ff-labels-left .pv-type-paragraph,
.ff-form-root .ff-labels-left .pv-type-html,
.ff-form-root .ff-labels-left .pv-type-divider,
.ff-form-root .ff-labels-left .pv-type-spacer,
.ff-form-root .ff-labels-left .pv-type-image { display: block; }

/* Per-field override of the form default. */
.ff-form-root .pv-field.ff-label-left {
  display: grid;
  grid-template-columns: var(--ff-label-col) minmax(0, 1fr);
  gap: var(--ff-sp-1) var(--ff-sp-3);
  align-items: start;
}
.ff-form-root .pv-field.ff-label-left > .pv-label { margin-top: 0.6em; margin-bottom: 0; }
.ff-form-root .pv-field.ff-label-left > .pv-help,
.ff-form-root .pv-field.ff-label-left > .pv-error { grid-column: 2; }
@container ffform (max-width: 767px) {
  .ff-form-root .pv-field.ff-label-left { grid-template-columns: 1fr; }
  .ff-form-root .pv-field.ff-label-left > .pv-label { margin-top: 0; }
  .ff-form-root .pv-field.ff-label-left > .pv-help,
  .ff-form-root .pv-field.ff-label-left > .pv-error { grid-column: 1; }
}
.ff-form-root .pv-field.ff-label-inline {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--ff-sp-1) var(--ff-sp-3);
}
.ff-form-root .pv-field.ff-label-inline > .pv-label { margin-bottom: 0; flex: 0 1 auto; }
.ff-form-root .pv-field.ff-label-inline > .fb-control { flex: 1 1 12rem; min-width: 0; }
.ff-form-root .pv-field.ff-label-inline > .pv-help,
.ff-form-root .pv-field.ff-label-inline > .pv-error { flex: 1 1 100%; }

/* Inline labels: label and control share a line, wrapping when tight. */
.ff-form-root .ff-labels-inline .pv-field {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--ff-sp-1) var(--ff-sp-3);
}
.ff-form-root .ff-labels-inline .pv-label { margin-bottom: 0; flex: 0 1 auto; }
.ff-form-root .ff-labels-inline .fb-control { flex: 1 1 12rem; min-width: 0; }
.ff-form-root .ff-labels-inline .pv-help,
.ff-form-root .ff-labels-inline .pv-error { flex: 1 1 100%; }

/* Floating labels: the label sits in the control and lifts on focus/fill.
   Requires a non-empty placeholder, which the renderer guarantees (" "). */
.ff-form-root .pv-field.ff-label-floating { position: relative; padding-top: 0; }
.ff-form-root .ff-label-floating .pv-label {
  position: absolute;
  top: 0.95em;
  inset-inline-start: calc(var(--ff-sp-3) + 1px);
  margin: 0;
  padding: 0 0.3em;
  font-weight: 500;
  color: var(--muted);
  pointer-events: none;
  transform-origin: left top;
  transition: transform .14s ease, color .14s ease;
  max-width: calc(100% - var(--ff-sp-4));
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: linear-gradient(to bottom, transparent 45%, var(--panel, #fff) 45%);
}
.ff-form-root .ff-label-floating .ff-input { padding-top: 1.35em; padding-bottom: 0.5em; }
.ff-form-root .ff-label-floating:focus-within .pv-label,
.ff-form-root .ff-label-floating .ff-input:not(:placeholder-shown) ~ .pv-label,
.ff-form-root .ff-label-floating.is-filled .pv-label {
  transform: translateY(-1.45em) scale(.82);
  color: var(--accent, #6366f1);
}
@media (prefers-reduced-motion: reduce) {
  .ff-form-root .ff-label-floating .pv-label { transition: none; }
}

/* --------------------------------------------------------- accessibility -- */

.ff-form-root :focus-visible {
  outline: 3px solid var(--accent, #6366f1);
  outline-offset: 2px;
  border-radius: 4px;
}
.ff-form-root .pv-field.has-error .ff-input { border-color: var(--danger); }
.ff-form-root .pv-error:not([hidden]) { display: block; }

/* Errors must be reachable under a sticky host header when scrolled to. */
.ff-form-root .pv-field { scroll-margin-top: 5rem; scroll-margin-bottom: 2rem; }

@media (prefers-reduced-motion: reduce) {
  .ff-form-root *,
  .ff-form-root *::before { animation-duration: .001ms !important; transition-duration: .001ms !important; scroll-behavior: auto !important; }
}

@media (prefers-contrast: more) {
  .ff-form-root .ff-input { border-width: 2px; }
  .ff-form-root .pv-help { color: var(--text); }
}

@media (forced-colors: active) {
  .ff-form-root .ff-input,
  .ff-form-root .ff-btn { border: 1px solid ButtonBorder; }
  .ff-form-root .pv-progress-bar span { background: Highlight; }
}

/* Landscape phones: short viewports shouldn't waste height on chrome. */
@media (max-height: 460px) and (orientation: landscape) {
  .ff-form-root { --ff-pad: clamp(0.75rem, 0.5rem + 1.5cqi, 1.25rem); }
  .ff-form-root .pv-form-head { margin-bottom: var(--ff-sp-2); }
}

/* ------------------------------------------------------------ standalone -- */

/* Render/embed mode: the form owns the page. `dvh` tracks mobile browser
   chrome; safe-area insets clear notches and home indicators. */
body.ff-kiosk .ff-form-root {
  width: 100%;
  /* Container queries measure the CONTENT box, so the shell's padding (~77px at
     this size) counts against the 992px desktop threshold. 70rem (=1120px)
     leaves ~1043px of content, which clears it — otherwise a form authored with
     three desktop columns would never actually render three columns. */
  max-width: min(70rem, 100%);
  margin-inline: auto;
  padding:
    max(var(--ff-pad), env(safe-area-inset-top))
    max(var(--ff-pad), env(safe-area-inset-right))
    max(var(--ff-pad), env(safe-area-inset-bottom))
    max(var(--ff-pad), env(safe-area-inset-left));
}
body.ff-kiosk { min-height: 100dvh; }

/* Password gate shown before a protected form loads. */
.ff-kiosk-msg { padding: var(--ff-sp-5, 2rem) 1rem; }

/* ----------------------------------------------------------- pv chrome ---- */

/* Preview overlay (builder only): full-height, scrollable, safe on mobile. */
.pv-overlay { padding: clamp(0px, 2vw, 18px); }
.pv-chrome { max-height: 100dvh; }
.pv-bar { flex-wrap: wrap; row-gap: 8px; }
.pv-bar-center { flex-wrap: wrap; }
.pv-stage { padding: clamp(10px, 2.5vw, 26px) clamp(6px, 2vw, 16px); }

/* The device frame is a width constraint only — the form inside adapts itself. */
.pv-frame {
  width: 100%;
  max-width: var(--pv-w, 46rem);
  transition: max-width .22s ease;
}
@media (prefers-reduced-motion: reduce) { .pv-frame { transition: none; } }

@media (max-width: 700px) {
  .pv-overlay { padding: 0; }
  .pv-chrome { border-radius: 0; }
  .pv-bar .pv-title { flex: 1 1 100%; }
}


/* ==========================================================================
   Right-to-left
   The layout is built from flex/grid and logical properties, so direction is
   inherited from the document's `dir`. These rules cover the few places where
   a glyph or a gradient is direction-bound and cannot flip on its own.
   ========================================================================== */

[dir="rtl"] .ff-form-root .ff-select,
[dir="rtl"] .ff-form-root select {
  /* The chevron is painted with a background gradient anchored to one side. */
  background-position: left 0.9em top 55%, left 0.55em top 55%;
}
[dir="ltr"] .ff-form-root .ff-select,
[dir="ltr"] .ff-form-root select {
  background-position: right 0.9em top 55%, right 0.55em top 55%;
}

/* Progress steps and wizard navigation read in the writing direction. */
[dir="rtl"] .ff-form-root .ff-steps,
[dir="rtl"] .ff-form-root .ff-actions { flex-direction: row-reverse; }

/* Directional icons inside buttons (next/previous chevrons) mirror. */
[dir="rtl"] .ff-form-root .ff-btn svg.ff-dir-icon,
[dir="rtl"] .ff-form-root .ff-nav-icon { transform: scaleX(-1); }

/* Numbers, dates, emails, URLs and phone numbers stay left-to-right even in an
   RTL sentence, which is what users expect when typing them. */
[dir="rtl"] .ff-form-root input[type="email"],
[dir="rtl"] .ff-form-root input[type="url"],
[dir="rtl"] .ff-form-root input[type="tel"],
[dir="rtl"] .ff-form-root input[type="number"],
[dir="rtl"] .ff-form-root input[type="date"],
[dir="rtl"] .ff-form-root input[type="time"] {
  direction: ltr;
  text-align: right;
}

/* CAPTCHA widget slot, above the submit button. */
.pv-captcha { margin-block: 14px 4px; min-height: 0; }
.pv-captcha:empty { display: none; }
.pv-captcha-note, .pv-captcha-error {
  display: flex; align-items: center; gap: 8px; margin: 0;
  padding: 10px 12px; border: 1px dashed currentColor; border-radius: 8px;
  font-size: 12.5px; opacity: .75;
}
.pv-captcha-note svg { width: 16px; height: 16px; flex-shrink: 0; }
.pv-captcha-error { border-style: solid; color: #b42318; opacity: 1; }

/* ---------- Searchable dropdown ---------- */
.ff-ss-native { position: absolute !important; width: 1px !important; height: 1px !important; opacity: 0 !important; pointer-events: none !important; overflow: hidden; }
.ff-ss { position: relative; }
.ff-ss-control { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.ff-ss-input { padding-inline-end: 32px; cursor: pointer; }
.ff-ss.is-open .ff-ss-input { cursor: text; }
.ff-ss-caret {
  position: absolute; inset-inline-end: 12px; top: 50%; width: 8px; height: 8px; margin-top: -6px; pointer-events: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg); opacity: .5; transition: transform .15s;
}
.ff-ss.is-open .ff-ss-caret { transform: rotate(-135deg); margin-top: -2px; }
.ff-ss.is-multiple .ff-ss-chips { display: contents; }
.ff-ss-chip {
  display: inline-flex; align-items: center; gap: 4px; padding: 2px 4px 2px 8px; border-radius: 6px;
  background: color-mix(in srgb, var(--ff-primary, var(--accent, #6366f1)) 12%, transparent); font-size: .875em;
}
.ff-ss-chip button { border: 0; background: none; cursor: pointer; padding: 0 4px; font-size: 1.1em; line-height: 1; color: inherit; opacity: .7; }
.ff-ss-chip button:hover { opacity: 1; }
.ff-ss-list {
  position: absolute; z-index: 50; inset-inline: 0; top: calc(100% + 4px); max-height: 240px; overflow: auto;
  margin: 0; padding: 4px; list-style: none; border-radius: 10px;
  background: var(--panel, #fff); color: var(--text, inherit); border: 1px solid var(--border, #e2e8f0); box-shadow: 0 10px 30px rgba(15, 23, 42, .14);
}
.ff-ss-list[hidden] { display: none; }
.ff-ss-opt { padding: 8px 10px; border-radius: 7px; cursor: pointer; }
.ff-ss-opt.is-active { background: color-mix(in srgb, var(--ff-primary, var(--accent, #6366f1)) 10%, transparent); }
.ff-ss-opt.is-selected { font-weight: 600; color: var(--ff-primary, var(--accent, #6366f1)); }
.ff-ss.is-multiple .ff-ss-opt.is-selected::after { content: '✓'; float: inline-end; }
.ff-ss-none { padding: 8px 10px; opacity: .6; }

/* ---------- In-form card payment (Braintree Drop-in) ---------- */
.pv-pay-overlay { position: fixed; inset: 0; z-index: 1000; display: flex; align-items: flex-start; justify-content: center; padding: 6vh 16px 16px; background: rgba(15, 23, 42, .45); overflow-y: auto; }
.pv-pay-box { width: 100%; max-width: 460px; padding: 20px; border-radius: 14px; background: var(--panel, #fff); color: var(--text, #0f172a); box-shadow: 0 24px 60px rgba(15, 23, 42, .3); }
.pv-pay-box h2 { margin: 0 0 12px; font-size: 1.15rem; }
.pv-pay-dropin { min-height: 120px; display: flex; flex-direction: column; justify-content: center; gap: 8px; color: var(--muted, #64748b); font-size: .9rem; }
.pv-pay-error { margin: 10px 0 0; padding: 8px 10px; border-radius: 8px; background: #fef2f2; color: #b91c1c; font-size: .875rem; }
.pv-pay-error[hidden] { display: none; }
.pv-pay-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

/* ---------- Image / icon choices ---------- */
.ff-vchoices { display: grid; grid-template-columns: repeat(var(--ff-vc-cols, 3), minmax(0, 1fr)); gap: 10px; }
@container (max-width: 480px) { .ff-vchoices { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.ff-vchoice { position: relative; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 10px; border: 1.5px solid var(--ffs-input-border, var(--border, #d0d5dd)); border-radius: var(--ffs-input-radius, 10px); background: var(--ffs-input-bg, #fff); cursor: pointer; text-align: center; transition: border-color .15s, box-shadow .15s; }
.ff-vchoice:hover { border-color: var(--ffs-accent, var(--accent, #6366f1)); }
.ff-vchoice input { position: absolute; opacity: 0; pointer-events: none; }
.ff-vchoice:has(input:checked) { border-color: var(--ffs-accent, var(--accent, #6366f1)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ffs-accent, var(--accent, #6366f1)) 18%, transparent); }
.ff-vchoice:has(input:focus-visible) { outline: 2px solid var(--ffs-accent, var(--accent, #6366f1)); outline-offset: 2px; }
.ff-vchoice-media { display: flex; align-items: center; justify-content: center; width: 100%; }
.ff-vchoices-image .ff-vchoice-media { aspect-ratio: 4 / 3; border-radius: 6px; overflow: hidden; background: #f2f4f7; }
.ff-vchoices-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ff-vchoice-ph svg { width: 28px; height: 28px; color: #98a2b3; }
.ff-vchoice-icon svg { width: 34px; height: 34px; color: var(--ffs-accent, var(--accent, #6366f1)); }
.ff-vchoice-label { font-size: .92em; font-weight: 500; }

/* ---------- Number spinner ---------- */
.ff-spinner { display: inline-flex; max-width: 220px; }

/* ---------- Tags ---------- */
.ff-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: var(--ffs-input-h, 44px); height: auto !important; padding: 6px 8px; cursor: text; }
.ff-tag { display: inline-flex; align-items: center; gap: 4px; padding: 3px 4px 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--ffs-accent, var(--accent, #6366f1)) 12%, transparent); color: inherit; font-size: .88em; line-height: 1.3; }
.ff-tag-x { display: inline-flex; align-items: center; justify-content: center; width: 18px; height: 18px; border: 0; border-radius: 50%; background: transparent; color: inherit; cursor: pointer; font-size: 14px; line-height: 1; opacity: .65; }
.ff-tag-x:hover { opacity: 1; background: rgba(0, 0, 0, .08); }
.ff-tags-input { flex: 1 1 120px; min-width: 100px; border: 0; outline: 0; background: transparent; font: inherit; color: inherit; padding: 4px 2px; }

/* ---------- Icon element and page buttons ---------- */
.ff-icon-el svg { width: var(--ff-icon-size, 40px); height: var(--ff-icon-size, 40px); }
.ff-pagebtn .ff-btn-block { width: 100%; justify-content: center; }
/* Spinner and quantity: − [value] + always on one line. */
.ff-form-root .ff-qty, .ff-qty.ff-spinner { flex-wrap: nowrap; }
.ff-form-root .ff-qty input.ff-input, .ff-qty input.ff-input { width: 96px; min-width: 64px; flex: 0 1 96px; text-align: center; }
/* Tags: the typing area is a full touch target. */
.ff-form-root .ff-tags-input { min-height: var(--ff-touch, 44px); }
.ff-form-root .ff-tags { padding-block: 0; }

/* ---------- Field icons (inside the box, before or after the text) ---------- */
.ff-iconbox { position: relative; flex: 1 1 auto; min-width: 0; }
.ff-iconbox > .ff-input, .ff-iconbox > select, .ff-iconbox > textarea, .ff-iconbox > input { width: 100%; }
.ff-iconbox.is-left > .ff-input, .ff-iconbox.is-left > select, .ff-iconbox.is-left > textarea { padding-inline-start: 2.6em !important; }
.ff-iconbox.is-right > .ff-input, .ff-iconbox.is-right > select, .ff-iconbox.is-right > textarea { padding-inline-end: 2.6em !important; }
.ff-iconbox.is-right > select { padding-inline-end: 3.4em !important; }
.ff-field-icon {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 1; pointer-events: none;
  display: inline-flex; width: 1.1em; height: 1.1em; font-size: 1.05em;
  color: var(--ffs-placeholder-color, var(--faint, #98a2b3));
}
.ff-field-icon svg { width: 100%; height: 100%; }
.ff-iconbox.is-left > .ff-field-icon { inset-inline-start: .85em; }
.ff-iconbox.is-right > .ff-field-icon { inset-inline-end: .85em; }
.ff-iconbox.is-right:has(> select) > .ff-field-icon { inset-inline-end: 2.1em; }
.ff-iconbox.is-area > .ff-field-icon { top: .85em; transform: none; }
.ff-iconbox:focus-within > .ff-field-icon { color: var(--ffs-accent, var(--accent, #6366f1)); }

/* ---------- Payment method ---------- */
.ff-paymethod { display: grid; gap: 8px; }
.ff-paymethod-opt {
  position: relative; display: flex; align-items: center; gap: 12px; padding: 12px 14px; cursor: pointer;
  border: 1.5px solid var(--ffs-input-border, var(--border, #d0d5dd)); border-radius: var(--ffs-input-radius, 10px);
  background: var(--ffs-input-bg, #fff); transition: border-color .15s, box-shadow .15s;
}
.ff-paymethod-opt:hover { border-color: var(--ffs-accent, var(--accent, #6366f1)); }
.ff-paymethod-opt input { position: absolute; opacity: 0; pointer-events: none; }
.ff-paymethod-opt:has(input:checked) { border-color: var(--ffs-accent, var(--accent, #6366f1)); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ffs-accent, var(--accent, #6366f1)) 16%, transparent); }
.ff-paymethod-opt:has(input:focus-visible) { outline: 2px solid var(--ffs-accent, var(--accent, #6366f1)); outline-offset: 2px; }
.ff-paymethod-dot { flex: 0 0 18px; width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--ffs-input-border, #d0d5dd); }
.ff-paymethod-opt:has(input:checked) .ff-paymethod-dot { border-color: var(--ffs-accent, var(--accent, #6366f1)); background: radial-gradient(circle, var(--ffs-accent, var(--accent, #6366f1)) 45%, transparent 50%); }
.ff-paymethod-text, .ff-paymethod-single > span:not(.ff-paymethod-lock) { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ff-paymethod small { color: var(--ffs-help-color, var(--muted, #667085)); font-size: .85em; }
.ff-paymethod-note { display: flex; align-items: center; gap: 6px; margin-top: 2px; }
.ff-paymethod-note svg, .ff-paymethod-lock svg { width: 14px; height: 14px; flex-shrink: 0; }
.ff-paymethod-single { display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--ffs-input-radius, 10px); background: color-mix(in srgb, currentColor 5%, transparent); }
.ff-paymethod-lock { display: inline-flex; color: var(--ffs-accent, var(--accent, #6366f1)); }
.ff-paymethod-lock svg { width: 18px; height: 18px; }
.ff-paymethod-empty { display: flex; align-items: center; gap: 8px; padding: 12px 14px; border: 1.5px dashed var(--border-strong, #d0d5dd); border-radius: 10px; color: var(--muted, #667085); font-size: 12.5px; }
.ff-paymethod-empty svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ---------- WooCommerce Product field ---------- */
.ff-woo { display: grid; gap: 10px; }
.ff-woo-cards { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
.ff-woo-item { position: relative; display: flex; align-items: center; gap: 10px; padding: 10px 12px; border: 1px solid var(--ffs-input-border, #d0d5dd); border-radius: var(--ffs-input-radius, 10px); background: var(--ffs-input-bg, #fff); cursor: pointer; transition: border-color .12s, box-shadow .12s; }
.ff-woo-cards .ff-woo-item { flex-direction: column; align-items: stretch; text-align: start; padding: 10px; }
.ff-woo-item:hover { border-color: var(--_primary, #6366f1); }
.ff-woo-item input { position: absolute; opacity: 0; pointer-events: none; }
.ff-woo-item:has(input:checked) { border-color: var(--_primary, #6366f1); box-shadow: 0 0 0 2px color-mix(in srgb, var(--_primary, #6366f1) 25%, transparent); }
.ff-woo-item:has(input:focus-visible) { outline: 2px solid var(--_primary, #6366f1); outline-offset: 2px; }
.ff-woo-item.is-off { opacity: .55; cursor: not-allowed; }
.ff-woo-img { display: flex; align-items: center; justify-content: center; aspect-ratio: 1; border-radius: 8px; background: color-mix(in srgb, currentColor 6%, transparent); overflow: hidden; }
.ff-woo-img img { width: 100%; height: 100%; object-fit: cover; }
.ff-woo-img svg { width: 28px; height: 28px; opacity: .45; }
.ff-woo-text { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.ff-woo-name { font-weight: 600; line-height: 1.3; }
.ff-woo-stock { font-size: .8em; color: var(--ffs-danger, #d92d20); }
.ff-woo-price { font-weight: 600; white-space: nowrap; }
.ff-woo-price del { font-weight: 400; opacity: .55; }
.ff-woo-price ins { text-decoration: none; color: var(--ffs-danger, #d92d20); }
.ff-woo-list .ff-woo-item::before { content: ""; flex: 0 0 18px; height: 18px; border: 1.5px solid var(--ffs-input-border, #d0d5dd); border-radius: 50%; }
.ff-woo-list .ff-woo-item:has(input[type="checkbox"])::before { border-radius: 5px; }
.ff-woo-list .ff-woo-item:has(input:checked)::before { border-color: var(--_primary, #6366f1); background: radial-gradient(circle, var(--_primary, #6366f1) 45%, transparent 50%); }
.ff-woo-empty { display: flex; align-items: center; gap: 8px; padding: 14px; border: 1px dashed var(--ffs-input-border, #d0d5dd); border-radius: 10px; opacity: .75; font-size: .9em; }
.ff-woo-empty svg { width: 18px; height: 18px; }

/* A form's own page (?siform=<id>): a quiet page background around the form. */
html.ff-direct body.ff-kiosk { background: #f4f5f7; }

/* Save & resume (ui/saveResume.js) */
.pv-saved { display: grid; gap: 12px; margin: 0 0 18px; padding: 16px 18px; border: 1px solid color-mix(in srgb, var(--ffs-primary, #6366f1) 30%, #e5e7eb); border-radius: 12px; background: color-mix(in srgb, var(--ffs-primary, #6366f1) 6%, #fff); }
.pv-saved-head { display: flex; gap: 10px; align-items: flex-start; }
.pv-saved-head > svg { flex-shrink: 0; width: 22px; height: 22px; color: var(--ffs-primary, #6366f1); }
.pv-saved-head strong { display: block; font-size: 15px; }
.pv-saved-head p { margin: 2px 0 0; font-size: 13px; opacity: .8; }
.pv-saved-link, .pv-saved-email > div { display: flex; gap: 8px; }
.pv-saved-link .ff-input, .pv-saved-email .ff-input { flex: 1; min-width: 0; }
.pv-saved-link .ff-input { font-size: 12.5px; }
.pv-saved-email label { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 600; }
.pv-saved-msg { min-height: 1em; margin: 4px 0 0; font-size: 12.5px; }
.pv-saved-msg.is-error { color: #b91c1c; }
.pv-saved-msg.is-ok { color: #047857; }
.pv-saved-close { justify-self: start; }
.pv-autosaved { align-self: center; font-size: 12px; opacity: .65; }
@media (max-width: 480px) { .pv-saved-link, .pv-saved-email > div { flex-wrap: wrap; } .pv-saved-link .ff-btn, .pv-saved-email .ff-btn { width: 100%; justify-content: center; } }

/* Changing an entry (ui/entryEdit.js) */
.pv-editing { display: flex; gap: 10px; align-items: flex-start; margin: 0 0 18px; padding: 14px 16px; border: 1px solid color-mix(in srgb, var(--ffs-primary, #6366f1) 30%, #e5e7eb); border-radius: 12px; background: color-mix(in srgb, var(--ffs-primary, #6366f1) 6%, #fff); }
.pv-editing > svg { flex-shrink: 0; width: 20px; height: 20px; color: var(--ffs-primary, #6366f1); }
.pv-editing strong { display: block; font-size: 15px; }
.pv-editing p { margin: 2px 0 0; font-size: 13px; opacity: .8; }
.pv-field.pv-locked { opacity: .65; }
.pv-field.pv-locked :is(input, select, textarea) { cursor: not-allowed; }
.pv-edit-link { display: grid; gap: 8px; justify-items: center; margin: 4px 0 14px; }
.pv-edit-link p { margin: 0; font-size: 13.5px; opacity: .8; }
.pv-edit-link a.ff-btn { text-decoration: none; }
.pv-edit-error { display: grid; gap: 6px; justify-items: center; text-align: center; }
.pv-edit-error > svg { width: 28px; height: 28px; opacity: .6; }
.pv-edit-error p { margin: 0; max-width: 420px; opacity: .8; }

/* ---------------- One question at a time (ui/conversation.js) ---------------- */
#pv-form.pv-convo { --cv-gap: clamp(20px, 5vh, 56px); }
/* Only top-level questions are hidden; fields inside a section stay with it. */
.pv-convo .pv-fields > .pv-row > .pv-col > .pv-field:not(.cv-on) { display: none; }
.pv-convo .pv-fields > .pv-row:not(:has(.cv-on, .cv-bar)) { display: none; }
.pv-convo .pv-fields > .pv-row > .pv-col:not(:has(.cv-on, .cv-bar)) { display: none; }
.pv-convo .pv-fields > .pv-row > .pv-col { flex-basis: 100%; max-width: 100%; }
.pv-convo :is(.pv-progress, .pv-steps, .pv-breadcrumb, .pv-page-title) { display: none; }
.pv-convo .pv-footer :is([data-pv-back], [data-pv-next], [type="submit"]) { display: none; }
.pv-convo .pv-captcha:not(.cv-on) { display: none; }
.pv-convo .pv-fields { padding-block: var(--cv-gap) 0; }
.pv-convo .pv-field.cv-on > .pv-label { font-size: 1.3em; line-height: 1.35; font-weight: 600; }
.pv-convo .pv-field.cv-on :is(.ff-input, select) { font-size: 1.05em; }
.pv-convo .cv-num { display: inline-flex; align-items: center; gap: 2px; margin-inline-end: 8px; font-size: .7em; font-weight: 700; color: var(--ffs-primary, var(--accent, #6366f1)); vertical-align: .15em; }
.pv-convo .cv-num svg { width: .9em; height: .9em; }
.pv-convo .cv-in { animation: cv-in .32s ease both; }
@keyframes cv-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .pv-convo .cv-in { animation: none; } }
.cv-bar { display: grid; gap: var(--cv-gap); margin: 18px 0 8px; }
.cv-act { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.cv-hint { font-size: 12px; opacity: .6; }
.cv-foot { display: flex; align-items: center; gap: 10px; padding-top: 14px; border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent); }
.cv-progress { flex: 1; height: 6px; border-radius: 99px; background: color-mix(in srgb, currentColor 10%, transparent); overflow: hidden; }
.cv-progress span { display: block; height: 100%; border-radius: inherit; background: var(--ffs-primary, var(--accent, #6366f1)); transition: width .3s ease; }
.cv-count { font-size: 12.5px; font-variant-numeric: tabular-nums; opacity: .7; white-space: nowrap; }
.cv-nav { width: 34px; height: 34px; border: 1px solid color-mix(in srgb, currentColor 16%, transparent); border-radius: 8px; }
.cv-nav[data-cv-prev] svg { transform: rotate(180deg); }
.cv-nav:disabled { opacity: .35; cursor: default; }
.pv-convo.cv-at-welcome > :not(.cv-welcome):not(.pv-hp-wrap) { display: none; } /* the welcome title stands in for the form title */
.cv-welcome { display: grid; justify-items: start; gap: 14px; padding-block: var(--cv-gap); }
.cv-welcome h2 { margin: 0; font-size: 1.7em; line-height: 1.2; }
.cv-welcome p { margin: 0; font-size: 1.05em; opacity: .8; white-space: pre-line; }
[dir="rtl"] .pv-convo .cv-num svg { transform: scaleX(-1); }
.cv-count { unicode-bidi: isolate; }

/* ---------------- Booking field (ui/bookingPicker.js) ---------------- */
.ff-booking { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 16px; align-items: start; }
.ff-bk-cal .ff-cal { max-width: none; box-shadow: none; }
.ff-bk-cal[aria-busy="true"] { opacity: .6; }
.ff-bk-times { display: grid; gap: 10px; align-content: start; }
.ff-bk-day { margin: 0; font-weight: 600; }
.ff-bk-slots { display: flex; flex-wrap: wrap; gap: 8px; }
.ff-bk-slot { min-width: 84px; padding: 8px 12px; border: 1px solid var(--ffs-input-border, var(--border-strong, #d1d5db)); border-radius: 8px; background: var(--ffs-input-bg, #fff); color: inherit; font: inherit; font-variant-numeric: tabular-nums; cursor: pointer; }
.ff-bk-slot:hover, .ff-bk-slot:focus-visible { border-color: var(--ffs-primary, var(--accent, #6366f1)); outline: none; }
.ff-bk-slot.is-picked { background: var(--ffs-primary, var(--accent, #6366f1)); border-color: var(--ffs-primary, var(--accent, #6366f1)); color: #fff; font-weight: 600; }
.ff-bk-slot small { opacity: .75; }
.ff-bk-hint, .ff-bk-zone { margin: 0; font-size: 13px; opacity: .7; }
.ff-bk-note { grid-column: 1 / -1; min-height: 1em; margin: 0; font-size: 13px; }
.ff-bk-note.is-ok { color: #047857; } .ff-bk-note.is-error { color: #b91c1c; }
.ff-bk-booked { display: flex; gap: 8px; align-items: center; margin: 0; font-weight: 600; }
.ff-bk-booked svg { width: 18px; height: 18px; }
@container (max-width: 560px) { .ff-booking { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .ff-booking { grid-template-columns: 1fr; } }

/* Choices: "Other" with its box; places left / full (includes/choices.php). */
.ff-choice-other { flex-wrap: wrap; align-items: center; }
.ff-choice-other .ff-other-text { flex: 1 1 160px; min-width: 0; max-width: 320px; margin-inline-start: 4px; padding: 4px 8px; min-height: 32px; }
.ff-choice-left { color: var(--ff-muted, #64748b); font-size: .85em; margin-inline-start: 4px; }
.ff-choice-full { color: var(--ff-muted, #64748b); font-size: .85em; margin-inline-start: 4px; }
.ff-choice.is-full { opacity: .6; cursor: not-allowed; }

/* Summary field (ui/summary.js). */
.ff-summary { border: 1px solid var(--ff-border, #e2e8f0); border-radius: var(--ff-radius, 8px); padding: 4px 14px; background: var(--ff-surface, transparent); }
.ff-summary-list { margin: 0; }
.ff-summary-row { display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr) auto; gap: 4px 12px; align-items: baseline; padding: 10px 0; border-bottom: 1px solid var(--ff-border, #e2e8f0); }
.ff-summary-row:last-child { border-bottom: 0; }
.ff-summary-row dt { font-weight: 600; margin: 0; overflow-wrap: anywhere; }
.ff-summary-row dd { margin: 0; overflow-wrap: anywhere; white-space: pre-line; }
.ff-summary-none, .ff-summary-empty, .ff-summary-note { color: var(--ff-muted, #64748b); }
.ff-summary-empty, .ff-summary-note { margin: 10px 0; font-size: .9em; }
.ff-summary-edit { display: inline-flex; align-items: center; gap: 4px; background: none; border: 0; padding: 2px 4px; color: var(--accent, #6366f1); font: inherit; font-size: .85em; cursor: pointer; border-radius: 4px; }
.ff-summary-edit:hover { text-decoration: underline; }
.ff-summary-edit:focus-visible { outline: 2px solid var(--accent, #6366f1); outline-offset: 1px; }
.ff-summary-edit svg { width: 13px; height: 13px; }
@container (max-width: 480px) { .ff-summary-row { grid-template-columns: minmax(0, 1fr) auto; } .ff-summary-row dd { grid-column: 1 / -1; grid-row: 2; } }

/* Quiz result (ui/quiz.js). */
.pv-quiz { margin: 16px auto 0; max-width: 520px; text-align: start; border: 1px solid var(--ff-border, #e2e8f0); border-radius: var(--ff-radius, 8px); padding: 14px 16px; }
.pv-quiz.is-pass { border-color: color-mix(in srgb, #16a34a 45%, transparent); }
.pv-quiz.is-fail { border-color: color-mix(in srgb, #dc2626 40%, transparent); }
.pv-quiz-score { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.pv-quiz-pct { font-size: 1.6em; font-weight: 700; color: var(--accent, #6366f1); }
.pv-quiz-verdict { margin: 6px 0 0; }
.pv-quiz-items { list-style: none; margin: 12px 0 0; padding: 0; display: grid; gap: 8px; }
.pv-quiz-items li { display: flex; gap: 8px; align-items: flex-start; }
.pv-quiz-items li svg { width: 16px; height: 16px; flex: none; margin-top: 2px; }
.pv-quiz-items li.is-right svg { color: #16a34a; }
.pv-quiz-items li.is-wrong svg { color: #dc2626; }
.pv-quiz-items small { display: block; color: var(--ff-muted, #64748b); }

/* Sign-in form: "Forgot your password?" (includes/accounts.php). */
.ff-login-links { margin: 4px 0 0; font-size: .9em; }
.ff-login-links a { color: var(--accent, #6366f1); }

/* Poll results (ui/poll.js). */
.ff-poll { margin: 18px auto 22px; max-width: 520px; text-align: start; }
.ff-poll figcaption { font-weight: 600; margin-bottom: 8px; }
.ff-poll-bars { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ff-poll-row { display: flex; justify-content: space-between; gap: 12px; font-size: .92em; margin-bottom: 4px; }
.ff-poll-label { overflow-wrap: anywhere; }
.ff-poll-pct { font-variant-numeric: tabular-nums; color: var(--ff-muted, #64748b); }
.ff-poll-track { height: 8px; border-radius: 999px; background: color-mix(in srgb, var(--accent, #6366f1) 12%, transparent); overflow: hidden; }
.ff-poll-track span { display: block; height: 100%; border-radius: inherit; background: color-mix(in srgb, var(--accent, #6366f1) 55%, transparent); transition: width .5s ease; }
.ff-poll li.is-top .ff-poll-track span, .ff-poll li.is-picked .ff-poll-track span { background: var(--accent, #6366f1); }
.ff-poll-you { display: inline-flex; align-items: center; gap: 3px; font-size: .82em; color: var(--accent, #6366f1); }
.ff-poll-you svg { width: 12px; height: 12px; }
.ff-poll-total { margin: 8px 0 0; font-size: .85em; color: var(--ff-muted, #64748b); }
.ff-poll-link { margin-top: 6px; }
.ff-link-btn { display: inline-flex; align-items: center; gap: 5px; background: none; border: 0; padding: 2px 0; color: var(--accent, #6366f1); font: inherit; font-size: .88em; cursor: pointer; }
.ff-link-btn:hover { text-decoration: underline; }
.ff-link-btn:focus-visible { outline: 2px solid var(--accent, #6366f1); outline-offset: 2px; border-radius: 3px; }
.ff-link-btn svg { width: 14px; height: 14px; }
.ff-poll-out { margin-top: 6px; font-size: .9em; }
.ff-poll-out .ff-poll { margin: 4px 0 0; }
@media (prefers-reduced-motion: reduce) { .ff-poll-track span { transition: none; } }

.pv-quiz-outcome { text-align: center; }
.pv-quiz-outcome small { display: block; color: var(--ff-muted, #64748b); text-transform: uppercase; letter-spacing: .06em; font-size: .75em; }
.pv-quiz-title { display: block; font-size: 1.4em; margin: 4px 0; color: var(--accent, #6366f1); }
.pv-quiz-outcome p { margin: 6px 0 0; white-space: pre-line; }

/* Email "type it again", text counters, international phone. */
.ff-confirm { margin-top: 8px; }
.ff-count { margin-top: 4px; font-size: .8em; color: var(--ff-muted, #64748b); text-align: end; font-variant-numeric: tabular-nums; }
.ff-count.is-over { color: var(--ff-error, #dc2626); }
.ff-phone { display: flex; gap: 6px; }
.ff-phone .ff-phone-cc { flex: 0 1 38%; min-width: 0; max-width: 220px; }
.ff-phone .ff-phone-num { flex: 1 1 auto; min-width: 0; }
@container (max-width: 380px) { .ff-phone { flex-direction: column; } .ff-phone .ff-phone-cc { max-width: none; } }

.pv-repeat-note { display: block; margin-top: 4px; color: var(--ff-muted, #64748b); font-size: .82em; }
[data-repeat-add]:disabled { opacity: .5; cursor: not-allowed; }

/* Poll pie chart; quiz explanations and sharing. */
.ff-pie-wrap { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.ff-pie { width: 132px; height: 132px; border-radius: 50%; flex: none; }
.ff-pie-legend { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; flex: 1 1 180px; min-width: 0; }
.ff-pie-legend li { display: flex; align-items: center; gap: 8px; font-size: .92em; }
.ff-pie-legend .ff-poll-label { flex: 1 1 auto; min-width: 0; overflow-wrap: anywhere; }
.ff-pie-dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.pv-quiz-why { display: block; margin-top: 2px; color: var(--ff-muted, #64748b); font-style: italic; }
.pv-quiz-share { display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center; justify-content: center; margin-top: 12px; font-size: .88em; }
.pv-quiz-share span { color: var(--ff-muted, #64748b); }
.pv-quiz-share a { color: var(--accent, #6366f1); font-weight: 600; text-decoration: none; }
.pv-quiz-share a:hover { text-decoration: underline; }
.pv-quiz { margin-bottom: 18px; }
