/* vb-form.v3.css — the main-site lead form.
 *
 * Styles ONE form: the shared include at includes/lead-form.php. Edit that file
 * for markup, this one for looks, and all 472 instances on 301 pages follow.
 *
 * LAYOUT is the wa-ppc landing-page "Book Your Consultation" form, geometry
 * copied from its stylesheet rather than re-guessed — 1fr/1fr grid, 10px/13px
 * control padding, 1.5px borders, 11px/700 uppercase labels, 84px min textarea,
 * 16px checkboxes at an 8px gap with 12px consent wording.
 *
 * v3 (2026-08-25) TIGHTENS THE CARD VERTICALLY and nothing else. Every change is
 * a vertical margin or a block padding; no font-size, no card width, no
 * horizontal padding, no control height, no textarea width and no button size is
 * touched, so the tap targets and the type scale are byte-for-byte v1's. The
 * `<p class="vb-lf-note">` ("By appointment. No obligation.") is deleted from the
 * include, so its rule is deliberately absent here too.
 *
 * MEASURED, not estimated: 938.3px -> 779.0px at 1366 (-17.0%), 1194.9px ->
 * 1025.5px at 390 (-14.2%). v2's gentler cut got -10.0%; this is the aggressive
 * variant Bar picked. It is -17.0% and not -19.3% because v3 also lengthened the
 * intro line, which wraps to 3 rows instead of 2 = exactly +21.7px of COPY, not
 * spacing.
 *
 * WHY A BIGGER NUMBER IS NOT AVAILABLE: only 275px of the original 938.3px card
 * was vertical spacing at all. The other ~663px is control heights, the 71px
 * Turnstile widget, the button and text line-boxes, every one frozen. Zeroing
 * EVERY remaining gap and both card paddings is a ceiling of -29.3%.
 *
 * The 42.3px single-line controls are under the 44px tap guideline. That is
 * pre-existing and DELIBERATE: Bar chose the "no input-height changes" rule over
 * the guideline. `padding: 11px 13px` would make it 44.3px. Do not apply it
 * without asking.
 *
 * Full per-gap table and the probe scripts: _tools/README.md, "v1 -> v2 -> v3".
 *
 * COLOR is the main site's own navy, NOT the LP's gold. Every place the LP puts
 * --gold (#FFC132) — card top rule, focus ring, checkbox accent, submit button —
 * this puts --vb-navy (#0F1E2E), which is what the captured production form used
 * (background-color: var(--e-global-color-84d7b45) -> #0F1E2E, hover #16293CE3).
 * The muted #BFA15A is kept for the required-marker only. No LP hue enters here.
 *
 * Loaded on every page that has a form, via _tools/inject_form_css.py.
 *
 * Two notes on specificity:
 *  - The `vb-lf-*` class names mean Elementor's per-page inline <style> blocks
 *    (4-class selectors against .elementor-field-group / .elementor-field /
 *    .elementor-button) no longer match anything in the form, so most of the
 *    !important that the previous revision needed is gone.
 *  - What is still !important is only where leftover WordPress theme CSS styles
 *    bare `input` / `select` / `textarea` / `button` inside a widget container.
 *
 * Touches presentation only: no field name, key, option value, form action,
 * Turnstile node or checkbox default state is referenced anywhere in this file.
 */

.elementor-widget-form {
  --vb-navy: #0F1E2E;
  --vb-navy-hover: #16293C;
  --vb-gold: #BFA15A;   /* muted gold; required-marker accent only */
  --vb-border: #E6E6E6;
  --vb-radius: 3px;
  --vb-ink: #1a1a1a;
  --vb-ink-lt: #666;
}

/* ---------------------------------------------------------------- 1. card */
/* The "Book Your Consultation" heading is a sibling Elementor widget ABOVE the
 * form widget, so carding the form widget alone leaves the heading outside the
 * border. Card the shared column wrapper instead — measured: heading and form
 * widget are both 455px wide inside .elementor-widget-wrap, i.e. it holds just
 * these two.
 *
 * LITERALS, not var(). The --vb-* properties are declared on
 * .elementor-widget-form, which is this element's CHILD; a parent cannot inherit
 * from a child, so every var() here resolved to invalid and the whole
 * declaration was dropped — that is why the card once had no top border and no
 * radius while the literal background and padding applied fine. */
.elementor-widget-wrap:has(> .elementor-widget-form) {
  background: #fff !important;
  border-radius: 8px !important;
  border-top: 4px solid #0F1E2E !important;
  /* v3: 36px -> 12px top/bottom (-67%). v2's -25% was not enough to move the
   * card height meaningfully; Bar took the aggressive variant. The 36px
   * HORIZONTAL padding is still kept verbatim — card width and side padding are
   * frozen. */
  padding: 12px 36px !important;
  margin-top: 24px !important;
  /* MEASURED, not a padding guess: an anchor or CTA jump aligns the card to
   * scroll-margin-top. The sticky header is 122px, so 122 + 24 breathing room. */
  scroll-margin-top: 146px;
  box-shadow: 0 20px 50px rgba(15, 30, 46, .15) !important;
}
/* ...and stop carding the form widget itself, or you get a box inside a box. */
.elementor-widget-wrap:has(> .elementor-widget-form) > .elementor-widget-form > .elementor-widget-container {
  background: none !important; border: 0 !important; border-radius: 0 !important;
  padding: 0 !important; box-shadow: none !important;
}
/* Fallback for engines without :has() — keep the card on the form widget. */
@supports not selector(:has(*)) {
  .elementor-widget-form > .elementor-widget-container {
    background: #fff !important;
    border-radius: 8px !important;
    border-top: 4px solid #0F1E2E !important;
    padding: 12px 36px !important;
    box-shadow: 0 20px 50px rgba(15, 30, 46, .15) !important;
  }
}

/* ------------------------------------------------------------ 2. subtext */
/* Sits between the heading widget and the first row. The LP's equivalent line
 * is service-specific; this one is deliberately company-wide. */

/* The "Book Your Consultation" -> intro-paragraph gap is NOT ours: it is the
 * 20px Elementor puts between two sibling widgets, and the heading is a sibling
 * widget one level up from .vb-lf-sub. So it has to be cut on the heading
 * widget, matched by the card wrapper the same way the card itself is.
 * v3: 20px -> 6px (-70%). No :has() fallback is possible — you cannot select a
 * PREVIOUS sibling without :has() — so on a pre-2022 engine this gap stays 20px
 * and the card is 14px taller. Nothing breaks. */
.elementor-widget-wrap:has(> .elementor-widget-form) > .elementor-widget-heading {
  margin-bottom: 6px !important;
}

.elementor-widget-form .vb-lf-sub {
  /* v3: 16px -> 6px (-63%). Gap from the intro line to the first field row. */
  margin: 0 0 6px !important;
  font-size: 14px;
  line-height: 1.55;
  color: var(--vb-ink-lt);
  text-align: center;
}

/* --------------------------------------------------------------- 3. grid */
/* Straight from the LP: two equal columns at a 12px gutter, one column on
 * mobile. Rows the design pairs (Name|Email, Phone|Location, Interest|Budget)
 * are .vb-lf-row; Timeline, Message and the consent blocks are full width by
 * simply not being in one. */
.elementor-widget-form .vb-lf-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
/* v3: 12px -> 4px (-67%). This ONE declaration is the whole row-to-row rhythm:
 * a .vb-lf-group's bottom margin sits inside its .vb-lf-row's box, so the gap
 * between Name/Email and Phone/Location, and after Timeline and Message, is
 * this value and not the grid's row-gap. */
.elementor-widget-form .vb-lf-group { margin-bottom: 4px; }
/* ...except the last field before the consent blocks, which the brief wants cut
 * hardest as part of that area: 12px -> 3px (-75%).
 * :not(.vb-lf-group--cb) is load-bearing. Without it this also matches the FIRST
 * consent block (it too is followed by a .vb-lf-group--cb) and, at (0,3,0), beats
 * the (0,2,0) `.vb-lf-group--cb` rule below — so Email-Marketing-to-SMS-Marketing
 * came out looser than the consent area is supposed to get. */
.elementor-widget-form .vb-lf-group:not(.vb-lf-group--cb):has(+ .vb-lf-group--cb) { margin-bottom: 3px; }

/* -------------------------------------------------------------- 4. labels */
.elementor-widget-form .vb-lf-group > label,
.elementor-widget-form .vb-lf-cbhead {
  display: block !important;
  /* v3: 4px -> 2px (-50%). Also the .vb-lf-cbhead gap above each consent block.
   * 2px is the floor: at 1px the 11px/700 uppercase label starts reading as part
   * of the control's border rather than as its own line. */
  margin: 0 0 2px !important;
  padding: 0 !important;
  font-size: 11px !important;
  font-weight: 700 !important;
  line-height: 1.4 !important;
  letter-spacing: .3px;
  text-transform: uppercase;
  text-align: left !important;
  color: var(--vb-navy) !important;
  background: none !important;
  border: 0 !important;
}
/* Required marker. Only the four fields the design marks carry one, because it
 * is an element in the markup rather than a rule keyed off [required] — Interest
 * is also required and deliberately unmarked. */
.elementor-widget-form .vb-lf-req { color: var(--vb-gold); font-weight: 700; }

/* ------------------------------------------------------------ 5. controls */
.elementor-widget-form .vb-lf input[type="text"],
.elementor-widget-form .vb-lf input[type="email"],
.elementor-widget-form .vb-lf input[type="tel"],
.elementor-widget-form .vb-lf textarea,
.elementor-widget-form .vb-lf select {
  width: 100% !important;
  padding: 10px 13px !important;
  border: 1.5px solid var(--vb-border) !important;
  border-radius: var(--vb-radius) !important;
  background: #fff !important;
  font-family: inherit !important;
  font-size: 14px !important;
  line-height: 1.45 !important;
  color: var(--vb-ink) !important;
  box-shadow: none !important;
  outline: 0;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.elementor-widget-form .vb-lf input:focus,
.elementor-widget-form .vb-lf textarea:focus,
.elementor-widget-form .vb-lf select:focus {
  border-color: var(--vb-navy) !important;
  box-shadow: 0 0 0 3px rgba(15, 30, 46, .12) !important;
}
/* Keyboard focus stays visible for anyone not using a pointer. */
.elementor-widget-form .vb-lf input:focus-visible,
.elementor-widget-form .vb-lf select:focus-visible,
.elementor-widget-form .vb-lf textarea:focus-visible,
.elementor-widget-form .vb-lf button:focus-visible {
  outline: 2px solid var(--vb-navy);
  outline-offset: 2px;
}
.elementor-widget-form .vb-lf input::placeholder,
.elementor-widget-form .vb-lf textarea::placeholder {
  color: #bbb !important;
  opacity: 1;
}
.elementor-widget-form .vb-lf textarea {
  resize: vertical;
  min-height: 84px !important;
}

/* --------------------------------------------------------------- 6. selects */
/* Same caret treatment for all three (Interested in, Budget, Timeline): the
 * native arrow is suppressed and one chevron is drawn on the wrapper, so the
 * three controls cannot drift apart. */
.elementor-widget-form .vb-lf-select { position: relative; }
.elementor-widget-form .vb-lf-select select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 36px !important;
  cursor: pointer;
}
.elementor-widget-form .vb-lf-select::after {
  content: "";
  position: absolute;
  right: 13px;
  top: 50%;
  margin-top: 3px;
  transform: translateY(-50%);
  pointer-events: none;
  border: 5px solid transparent;
  border-top-color: #888;
}
/* An unchosen select reads as placeholder grey. :invalid only fires on the
 * required one, so Budget and Timeline are matched through their placeholder
 * option still being the selected one. */
.elementor-widget-form .vb-lf-select select:required:invalid,
.elementor-widget-form .vb-lf-select:has(> select > option[value=""]:checked) select { color: #bbb !important; }
.elementor-widget-form .vb-lf-select select option { color: var(--vb-ink); }

/* -------------------------------------------------------- 7. consent block */
/* Wording, field names and the UNCHECKED default all live in the markup; this
 * only lays them out. */
/* v3: 10px -> 3px (-70%). Applies twice: Email-Marketing -> SMS-Marketing, and
 * SMS-Marketing -> .vb-lf-actions (i.e. the gap above the Turnstile widget). */
.elementor-widget-form .vb-lf-group--cb { margin-bottom: 3px; }
.elementor-widget-form .vb-lf-cb {
  display: flex;
  align-items: flex-start;
  gap: 8px;   /* HORIZONTAL: checkbox to wording. Not a vertical gap — untouched. */
  cursor: pointer;
  margin: 0 !important;
}
/* The `margin: 0 !important` above never actually applied. .vb-lf-cb IS a
 * <label> and a direct child of .vb-lf-group--cb, so section 4's
 * `.elementor-widget-form .vb-lf-group > label` (0,2,1) out-specifies
 * `.elementor-widget-form .vb-lf-cb` (0,2,0) and won even though both are
 * !important — leaving 4px of dead space under each block of consent wording,
 * which is most of why this area read as the loosest one. Restated at (0,3,1) so
 * the original intent holds. */
.elementor-widget-form .vb-lf-group--cb > label.vb-lf-cb { margin: 0 !important; }
.elementor-widget-form .vb-lf-cb input[type="checkbox"] {
  width: 16px !important;
  height: 16px !important;
  flex: 0 0 16px;
  margin: 2px 0 0 !important;
  accent-color: var(--vb-navy);
  cursor: pointer;
}
.elementor-widget-form .vb-lf-cb span {
  font-size: 12px !important;
  font-weight: 400 !important;
  line-height: 1.5 !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  color: var(--vb-ink) !important;
}

/* ------------------------------------------------- 8. Turnstile + actions */
/* The plugin injects .cf-turnstile in here, immediately above the button. It
 * ships its own `margin: 10px 0 15px` inline, so this only reins that in. */
.elementor-widget-form .vb-lf-actions { display: block; }
/* v3: the gap DIRECTLY ABOVE the button is this widget's bottom margin,
 * 8px -> 3px (-63%); top margin 4px -> 2px. When the plugin has not injected a
 * widget yet, the gap above the button is the consent block's 3px instead. */
.elementor-widget-form .vb-lf-actions .cf-turnstile { margin: 2px 0 3px !important; }

.elementor-widget-form .vb-lf-submit {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100% !important;
  padding: 14px 20px !important;
  border: 0 !important;
  border-radius: var(--vb-radius) !important;
  background-color: var(--vb-navy) !important;
  color: #fff !important;
  font-family: inherit;
  font-size: 15px !important;
  font-weight: 800 !important;
  letter-spacing: .6px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .15s ease, transform .15s ease;
}
.elementor-widget-form .vb-lf-submit:hover {
  background-color: var(--vb-navy-hover) !important;
  color: #fff !important;
  transform: translateY(-1px);
}
.elementor-widget-form .vb-lf-submit[disabled] { opacity: .65; cursor: default; transform: none; }

/* .vb-lf-note ("By appointment. No obligation.") was DELETED from
 * includes/lead-form.php in v2 — the element, not just its styling — so there is
 * deliberately no rule for it here. Do not re-add one without the copy. */
.elementor-widget-form .vb-lf-legal {
  /* v3: 8px -> 4px (-50%). Not in the brief's list, but it is pure vertical
   * spacing and it is part of the -19.3% that was measured and approved. */
  margin: 4px 0 0 !important;
  text-align: center;
  font-size: 11px;
  line-height: 1.5;
  color: var(--vb-ink-lt);
}
.elementor-widget-form .vb-lf-legal a { color: var(--vb-navy); text-decoration: underline; }

/* ------------------------------------------- 9. relay success/error message */
/* js/vb-lead.v1.js appends this; it borrows Elementor's message classes so it
 * looks native. Restated here because the Elementor sheet that styled them is
 * no longer guaranteed to be the winning rule now the form is ours. */
.elementor-widget-form .vb-lead-message {
  margin-top: 12px;
  padding: 11px 14px;
  border-radius: var(--vb-radius);
  font-size: 14px;
  line-height: 1.5;
}
.elementor-widget-form .vb-lead-message.elementor-message-success {
  background: #eef7f0; border: 1px solid #b6dcc0; color: #1e6b34;
}
.elementor-widget-form .vb-lead-message.elementor-message-danger {
  background: #fdf1f1; border: 1px solid #eabcbc; color: #96271f;
}

/* --------------------------------------------------------- 10. responsive */
@media (max-width: 767px) {
  /* v3: 22px -> 8px top/bottom, scaled proportionally to the desktop 36 -> 12
   * (x0.333 gives 7.3px; 8px is the nearest whole pixel). Horizontal stays 16px. */
  .elementor-widget-wrap:has(> .elementor-widget-form) { padding: 8px 16px !important; }
  /* One column, and row-gap zeroed. The LP's own sheet leaves its 12px grid gap
   * in place when the row collapses, which stacks on .vb-lf-group's margin-bottom
   * and makes every mobile gap the sum of the two — twice the desktop rhythm.
   * Only the margin should apply once the row is a single column. */
  .elementor-widget-form .vb-lf-row { grid-template-columns: 1fr; row-gap: 0; }
}
@supports not selector(:has(*)) {
  @media (max-width: 767px) {
    .elementor-widget-form > .elementor-widget-container { padding: 8px 16px !important; }
  }
}

@media (prefers-reduced-motion: reduce) {
  .elementor-widget-form .vb-lf-submit,
  .elementor-widget-form .vb-lf input,
  .elementor-widget-form .vb-lf select,
  .elementor-widget-form .vb-lf textarea { transition: none; }
  .elementor-widget-form .vb-lf-submit:hover { transform: none; }
}

/* Anything a link can jump to inside the form clears the sticky header. */
.elementor-widget-form,
.elementor-widget-form form.vb-lf,
.elementor-widget-form .vb-lf-group { scroll-margin-top: 146px; }
