FORM SECTION RULES:
- Forms must be clean, minimal, and conversion-optimized.
- LEAD CAPTURE FORM ROUTING: If the user requests an opt-in, capture, or contact form, you MUST output the Lead Capture Form.
- Phone and Message fields MUST ALWAYS be included unless the user explicitly asks to remove them.

NO LOGO NEAR THE FORM — NON-NEGOTIABLE: Never place the brand logo inside, behind, or beside the form card/wrapper — not as a background image, not as decorative filler in empty space next to the form, not oversized, not at any size. A confirmed real-world failure: the model rendered the logo at a massive scale directly behind/overlapping a registration form's fields and submit button. The logo's only legitimate appearances anywhere on the page are nav, hero (small badge only), and footer — this section is never one of them, regardless of how much empty space the layout leaves beside the form. See LOGO PLACEMENT RESTRICTION in non_negotiable_rules.md for the full rule.

FORM REQUIREMENTS:
- form name: capture-form
- form method: post
- form action: /leadcapture

────────────────────────────
FORM CARD HEADLINE & SUBHEADING
────────────────────────────
- The form card's headline (e.g. "Claim Your Spot Now") and subheading (e.g. "Enter your details below...") must ALWAYS be center-aligned — never left-aligned, regardless of how the rest of the page is laid out.
- Both the headline and the subheading must use `text-wrap: balance` so multi-line text breaks evenly across lines rather than leaving one line much shorter/longer than the other.
- EQUAL GAP RULE — IF ANYTHING SITS BETWEEN THE SUBHEADING AND THE FORM FIELDS, NON-NEGOTIABLE: If you add any additional line below the subheading (e.g. a scarcity/urgency line like "🔥 Only 5 Spots Available at This Price"), that extra line is also centered. In this case there are TWO gaps to get right: the gap between the subheading and this extra line, and the gap between this extra line and the form fields below it — these two gaps MUST be the exact same size. Do NOT let one gap (e.g. subhead-to-extra-line) end up visibly tighter or looser than the other (extra-line-to-form) — pick one consistent spacing value (a single `margin-bottom` on each element, or a `gap` on a shared flex/grid wrapper holding the headline/subhead/extra-line stack) and apply it uniformly so the whole stack reads as evenly, deliberately spaced rather than uneven. A confirmed real-world failure: an extra urgency line sat much closer to the subheading above it than to the form fields below it, making the spacing look unintentional and lopsided rather than evenly designed.

────────────────────────────
HONEYPOT FIELDS
────────────────────────────
- Honeypot fields (hidden with CSS opacity:0;position:absolute;left:-9999px;height:0;width:0): name="hp_name" and name="hp_email"

────────────────────────────
HIDDEN FIELDS
────────────────────────────
MEMBER TRACKING:
- hidden input:
  id="memberid"
  name="memberid"
  value="%memberid%"

HIDDEN CSRF:
- Insert a CSS hidden div with the text %csrf%
- The %csrf% token div MUST be hidden with: style="display:none !important;visibility:hidden !important;height:0 !important;overflow:hidden !important;" — it must NEVER be visible on the page

────────────────────────────
REAL INPUT FIELDS
────────────────────────────
1. NAME FIELD
- input type="text" name="realname" id="realname-input"
- Label: "First Name"
- Placeholder: "Your First Name"
- Font Awesome icon:
  <i class="fas fa-user form-icon"></i>

2. EMAIL FIELD (REQUIRED)
- input type="email" name="realemail" id="realemail-input" required
- Label: "Email Address" with red asterisk
- Placeholder: "Your Email Address"
- Font Awesome icon:
  <i class="fas fa-envelope form-icon"></i>

EMAIL VALIDATION RULES:
- MUST block submit if empty or invalid
- If invalid:
  - prevent submission
  - add class .field-error
  - set border: 2px solid red !important
- If valid:
  - remove .field-error immediately

3. PHONE FIELD
- input type="tel" name="phone" id="phone-input"
- Label: "Phone Number"
- Placeholder: "Your Phone Number"
- Font Awesome icon:
  <i class="fas fa-mobile-alt form-icon"></i>
  .iti__country-container { margin-left: 7.5px !important; }

4. MESSAGE FIELD
- textarea name="messagebox" id="messagebox-input"
- Label: "Message"
- Placeholder: "Your message..."
- rows="4"
- Font Awesome icon:
  <i class="fas fa-comment form-icon"></i>

────────────────────────────
STRUCTURE RULES
────────────────────────────
- Each field MUST be wrapped as:
  <div class="form-group form-group--icon">
- Label MUST be first child inside wrapper:
  <label>Field Label</label>
- The input and its icon MUST share an inner wrapper div:
  <div class="input-icon-wrap">
    <input ... />
    <i class="fas fa-... form-icon" aria-hidden="true"></i>
  </div>
  This inner wrapper is what the icon's top:50% is relative to — NOT the outer form-group which includes the label. This is mandatory for correct vertical centering.
- Form section MUST be centered:
  display: flex;
  flex-direction: column;
  align-items: center;

────────────────────────────
CONTAINER WIDTH/CENTERING — NOW FULLY PLATFORM-OWNED, DO NOT WRITE YOUR OWN
────────────────────────────
REQUIRED CLASS NAME — THE FORM'S OUTER CARD WRAPPER MUST ALWAYS BE EXACTLY `.form-card`, NEVER A PAGE-TYPE-SPECIFIC VARIANT: Regardless of what page type you're building (optin, registration, webinar, squeeze, sales, etc.), the div that wraps the form's badge/header content, the `<form>` itself, and the submit button must carry the exact class `form-card` — never an invented variant like `.optin-card`, `.optin2-card`, `.registration-card`, `.webinar-form-card`, or any other page-type-prefixed name. A CONFIRMED REAL-WORLD FAILURE: an optin page used `.optin2-card` as this wrapper's class instead of `.form-card` — since the platform's centering rule (see below) is keyed to the exact class `.form-card`, the wrapper fell completely outside that platform-owned system, with no width/centering rule applying to it at all, and it rendered off-center within its section. Using the exact, consistent `.form-card` class every time — never a per-page-type rename — is what keeps this wrapper inside the platform-owned system described below. If you need to distinguish multiple forms on the same page (e.g. two optin forms), vary the `id` (as you already do, e.g. `id="capture-form-2"`), never the class.

ANY CONTAINER THAT WRAPS `.form-card` MUST NEVER BE NARROWER THAN 464px — IN EVERY CONTEXT, NOT JUST THE SPLIT HERO — NON-NEGOTIABLE: The form itself has a platform-owned `min-width: 400px` (see landing-base.css), and `.form-card` has its own `padding: 2rem` (32px each side = 64px total) — 400 + 64 = 464px is the absolute floor the form's own column/cell/wrapper can ever be, in ANY layout you place it in: a split hero column (see the dedicated 464px rule in hero.md for that specific case), a multi-column section, a sidebar, a popup, or any other context. Before placing `.form-card` inside any column, grid cell, or flex item, check the actual width that container will resolve to at every breakpoint down to the smallest desktop/tablet width you're designing for — if it could ever be narrower than 464px, you MUST either widen that specific column (at the expense of others, if it's a multi-column layout), or restructure the layout so the form gets its own full-width row instead of a cramped column. Never place `.form-card` into a column you haven't verified is wide enough — the form's hard `min-width:400px` cannot shrink to compensate for a container that's too narrow, and the form will overflow/bleed past the container's edge instead of resizing to fit.

The form's width, min-width, max-width, centering, and display are now entirely owned by landing-base.css for these selectors: `#capture-form`, `form[name="capture-form"]`, `.form-card`, `.form-wrap`, `.form-wrapper`, `.form-container`, `.capture-form-wrap`. Do NOT write `width`, `min-width`, `max-width`, `margin`, or `display` rules of your own for any of these selectors, on desktop, tablet, or mobile — at any breakpoint. This was previously a model-authored rule duplicated against a conflicting platform rule, which produced inconsistent results (sometimes the form rendered correctly centered at the intended width, sometimes it didn't, depending on which of the two competing rules won the cascade on a given page). It is now a single platform-owned rule with nothing to conflict with — you do not need to, and must not, redeclare any of these four properties on these selectors yourself.

────────────────────────────
🔥 ICON SYSTEM (FINAL — GUARANTEED CENTERING)
────────────────────────────
.form-group--icon {
  position: relative;
}
/* INNER WRAP — the icon positions relative to this, not the outer form-group */
.input-icon-wrap {
  position: relative;
  width: 100%;
  display: block;
}
/* INPUTS */
.form-group--icon input,
.form-group--icon textarea {
  width: 100%;
  box-sizing: border-box;
  font-size: 16px;
  line-height: normal;
  padding-left: 12px;
  padding-right: 44px;
}
/* FIXED INPUT HEIGHT */
.form-group--icon input {
  height: 48px !important;
}
/* TEXTAREA */
.form-group--icon textarea {
  height: auto;
  padding-top: 12px;
  padding-bottom: 12px;
}
/* ICON — ANCHORED TO INPUT, PERFECTLY CENTERED VERTICALLY */
/* top:50% + translateY(-50%) centers on the input height, not the label+input block */
.form-icon {
  position: absolute;
  right: 0.65rem !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  width: 1.5rem;
  height: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem !important;
  line-height: 1;
  pointer-events: none;
}
/* Textarea icon anchors to the top of the textarea instead of its midpoint */
.input-icon-wrap:has(textarea) .form-icon {
  top: 1rem !important;
  transform: none !important;
}
/* SAFETY RESET */
input,
textarea {
  line-height: normal !important;
}
/* ICON COLOR RULE */
.form-icon {
  opacity: 0.6;
  color: var(--color-accent);
}

────────────────────────────
BUTTON RULE
────────────────────────────
- ALWAYS use <button>
- Submit button: <button type="submit" class="btn btn--primary btn--pulse">
- Submit button must be full width on mobile, auto width on desktop

- Privacy microcopy below submit: small text (var(--text-xs)) with lock icon: "🔒 Your information is 100% secure and will never be shared." Must carry the exact class "form-note" — not "form-disclaimer" or any other variant. Per DO NOT DOUBLE UP THE GAP BETWEEN A BUTTON AND TEXT DIRECTLY BELOW IT in non_negotiable_rules.md, never give this element its own margin-top. EXCEPTION: if the submit button itself is left-aligned (not centered/full-width), do not include this note at all — see the BUTTON ITSELF IS LEFT-ALIGNED exception under TEXT IMMEDIATELY UNDER A BUTTON MUST BE CENTERED AND BALANCED in non_negotiable_rules.md.

- PLACEMENT — `.form-note` MUST BE INSIDE THE `<form>` TAG, AS THE SUBMIT BUTTON'S DIRECT NEXT SIBLING, NON-NEGOTIABLE: Place `.form-note` immediately after the submit button, still inside the same `<form>` element (or inside the same wrapping div as the button, e.g. `.btn-submit-wrap`/`.submit-btn-wrap`, if you use one) — never as a sibling of the `<form>` tag itself, outside its closing `</form>`. A CONFIRMED REAL-WORLD FAILURE: the submit button was the last element inside `<form>`, and `.form-note` was placed as a sibling of the `<form>` element instead of the button — since the button then had no next sibling at all (the form closed immediately after it), the platform's button-to-text gap CSS never matched, and the note rendered with zero gap directly under the button instead of the intended 10px. CSS adjacent-sibling rules can only see true direct siblings; placing the note one DOM level higher breaks that relationship even though it looks identical visually in your own markup review. Keep the button and its note as direct siblings, both inside the form.

- SCHEDULER WIDGET: If a scheduling/booking form is requested, use this exact structure:
  <div class="scheduler-widget" id="scheduler-widget">
    <div class="scheduler-widget__calendar">
      <div class="scheduler-widget__header">
        <button class="scheduler-nav-btn" id="prev-month" aria-label="Previous month"><i class="fas fa-chevron-left" aria-hidden="true"></i></button>
        <span class="scheduler-widget__month" id="calendar-month-label">Month Year</span>
        <button class="scheduler-nav-btn" id="next-month" aria-label="Next month"><i class="fas fa-chevron-right" aria-hidden="true"></i></button>
      </div>
      <div class="scheduler-widget__days-grid" id="calendar-days"></div>
    </div>
    <div class="scheduler-widget__times" id="time-slots" style="display:none;">
      <h4 class="scheduler-widget__times-title">Select a time</h4>
      <div class="scheduler-widget__time-grid" id="time-grid"></div>
    </div>
    <div class="scheduler-widget__confirm" id="booking-confirm" style="display:none;">
      <p>You selected: <strong id="selected-datetime"></strong></p>
      <button type="submit" class="btn btn--primary">Confirm Booking <i class="fas fa-check" aria-hidden="true" style="margin-left:0.4em;"></i></button>
    </div>
  </div>

FORM SUBMISSION SCRIPT — MANDATORY:
Every page that contains a form MUST include this exact script in the javascript field. It makes every button[type="submit"] submit its closest parent form, validates the email field before submitting, and adds accessible keyboard support:
document.querySelectorAll('button[type="submit"]').forEach(function(btn){btn.setAttribute('role','button');if(!btn.getAttribute('tabindex'))btn.setAttribute('tabindex','0');btn.addEventListener('click',function(){var f=btn.closest('form');if(!f)return;var emailEl=f.querySelector('[name="realemail"],[name="registeremail"]');if(emailEl){var v=emailEl.value.trim();if(!v||!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v)){emailEl.style.border='2px solid red';emailEl.focus();return;}else{emailEl.style.border='';}}f.dispatchEvent(new Event('submit',{bubbles:true,cancelable:true}));});btn.addEventListener('keydown',function(e){if(e.key==='Enter'||e.key===' '){e.preventDefault();btn.click();}});});
});


MOBILE HORIZONTAL SPACING REMINDER: This section is subject to the MOBILE HORIZONTAL SPACING rule in non_negotiable_rules.md — on mobile (max-width:767px), no element you write for this section (outer wrapper, inner container, cards, headings, paragraphs, buttons, icons, anything) may have padding-left, padding-right, margin-left, or margin-right greater than 10px, and this section's outermost div must have at least 10px. Check this section's mobile CSS against that rule before finalizing.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
GRAPESJS MOBILE CHECKS — FORMS
[GRAPESJS BUILDER ONLY — page generator: ignore this section]
Run these checks after adding or modifying the form section in GrapesJS.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

VERIFY AND FIX with editor.addStyle() or editor.Css.setRule():

1. SECTION WRAPPER 10px edge — outermost form section div must have 10px horizontal padding on mobile:
   editor.Css.setRule('.your-form-section-class', {'padding-left':'10px','padding-right':'10px'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

2. FORM CARD full width — .form-card must not be narrower than the screen:
   editor.Css.setRule('#capture-form, form[name="capture-form"], .form-card, .form-wrap, .capture-form-wrap', {'min-width':'100%','max-width':'100%','padding':'1rem'}, {atRuleType:'media',atRuleParams:'(max-width:767px)'});

3. INPUT font-size 16px — prevents iOS auto-zoom on focus (any font-size below 16px triggers zoom):
   editor.addStyle('@media (max-width:767px) { .form-group--icon input, .form-group--icon textarea, .form-group input, .form-group textarea { font-size: 16px; } }');

4. SUBMIT BUTTON full width on mobile:
   editor.addStyle('@media (max-width:767px) { .form-card button[type="submit"], .form-card tempbutton[type="submit"] { width: 100%; display: block; } }');

5. FORM GROUP horizontal padding — inner wrappers must be 0 horizontal (10px is already on outer wrapper):
   editor.addStyle('@media (max-width:767px) { .form-group, .form-group--icon, .input-icon-wrap { padding-left: 0; padding-right: 0; } }');

6. FORM NOTE text wraps:
   editor.addStyle('@media (max-width:767px) { .form-note { font-size: var(--text-xs); white-space: normal; text-align: center; } }');

QUICK CHECK CODE — run in editor console to spot overflow:
   editor.Canvas.getDocument().querySelectorAll('[class*="form"]').forEach(el => { if(el.scrollWidth > el.clientWidth) console.warn('OVERFLOW:', el.className); });
