diff --git a/www/.env.example b/www/.env.example index e514425..2942d30 100644 --- a/www/.env.example +++ b/www/.env.example @@ -5,4 +5,6 @@ PUBLIC_COUNTERS_MOCK_RESULT=success PUBLIC_AIA_FORMS_MODE=off PUBLIC_AIA_FORMS_LIVE_APPROVED=false PUBLIC_AIA_FORMS_MOCK_RESULT=success +# Explicit, local-only Form A meeting preview; requires PUBLIC_AIA_FORMS_MODE=mock. +PUBLIC_AIA_FORM_A_PREVIEW=false PUBLIC_ALLOW_INDEXING=false diff --git a/www/integrations/jotform/README.md b/www/integrations/jotform/README.md new file mode 100644 index 0000000..d4c0920 --- /dev/null +++ b/www/integrations/jotform/README.md @@ -0,0 +1,46 @@ +# AIA Form A Jotform styling and conditional-button guide + +This directory contains the nonproduction visual handoff for the new AIA Form A. [`aia-form-a.css`](./aia-form-a.css) is intended for Jotform Classic Forms' **Form Designer → Styles → Inject Custom CSS** after the form is created and its settings are approved. + +The CSS translates the existing AIA form treatment: Rubik typography, blue labels and text, `#fcf9f5` inputs with `#edeef3` borders, the `#ffbd59` filled button, the `#ff914d` hover/focus border, four-pixel corners, visible validation errors, and strong keyboard focus. The Astro page supplies the heading, introduction, privacy-policy link, and surrounding card. The stylesheet therefore removes the Jotform surface rather than adding another header, footer, or nested card. + +The selectors target Jotform Classic Forms identifiers such as `#form`, `.form-all`, `.form-line`, `.form-label`, `.form-sub-label`, `.form-required`, `.form-textbox`, `.form-dropdown`, `.form-textarea`, `.form-error-message`, and `.form-submit-button`. Jotform's final generated DOM must be checked in the account before relying on pixel-level parity. The stylesheet does not hide required indicators, error messages, honeypots, or focus outlines, and it does not request fonts or other external assets. + +## Installation and comparison + +1. Create or open the approved blank Form A in AIA's HIPAA-enabled Jotform account. +2. Keep the form disabled while field, PHI, notification, conditional-logic, and language review is pending. +3. Paste the contents of `aia-form-a.css` into Jotform's custom CSS area. +4. Compare the Jotform preview with the Astro Form A mock at 390px and 1440px. Check the form surface, label rhythm, input height, button fill, outlined hover/focus state, error state, and mobile reflow. +5. Check both English and Spanish configurations. Confirm translated labels, required indicators, validation messages, confirmation copy, and the accessible iframe title supplied by the parent Astro integration. +6. Test the form in a real embedded iframe and on the direct hosted-form fallback. Confirm the iframe has a practical mobile height, does not create horizontal overflow, and does not trap keyboard focus. + +The current Astro meeting preview remains `off` by default and can only be shown in a non-indexing mock build. It does not load Jotform and is not a live submission test. + +## Form context and button labels + +The current Form A design uses a hidden `formContext` value with fixed, approved values such as `contact` and `landing`. Jotform does not provide a native conditional rule that changes one Submit button's accessible label safely in every context. If owner-approved context-specific labels are required, use multiple native Jotform Submit buttons and Jotform's conditional visibility rules: + +- Add one native Submit button for each approved context/language label. +- Show exactly one intended Submit button for the current, validated `formContext`. +- Keep every button a real Jotform Submit control; do not use CSS `::before`/`::after` text as a label. +- Verify that every visible variant submits through the same approved form and preserves the honeypot and validation behavior. +- Make the no-context and invalid-context states fail closed: no ambiguous extra button and no unintended submission path. +- Verify keyboard order, focus visibility, screen-reader names, English/Spanish labels, and mobile layout for every variant. + +The four campaign pages remain mapped to Form B in the production architecture. Their current Form A mock override is temporary meeting-preview behavior only. Do not add an external Astro button that attempts to submit a cross-origin iframe. + +## Verification checklist + +- [ ] Form A is disabled while configuration is reviewed. +- [ ] Exact question types, required flags, choices, conditional logic, and `formContext` values are approved. +- [ ] English and Spanish labels, validation, confirmation, and button variants are reviewed by fluent-language owners. +- [ ] The hidden honeypot remains present, effective, and excluded from user-facing visual changes. +- [ ] Exactly one native Submit button is visible for every valid context. +- [ ] Invalid or missing context does not expose an unintended submission path. +- [ ] No PHI-bearing answer, PDF, recipient, redirect, webhook, or HTTP POST forwarding is inherited without privacy/security approval. +- [ ] The iframe title, loading/error state, keyboard behavior, and mobile height are accepted. +- [ ] Synthetic testing uses only approved synthetic values and a separately authorized test form. +- [ ] No Jotform, Contabo, analytics, advertising, or production API request is made by off/mock builds. + +JF-01 through JF-09, privacy/security review, operations approval, fluent-language review, and production activation remain pending. This guide does not authorize Jotform account changes or live integration. diff --git a/www/integrations/jotform/aia-form-a.css b/www/integrations/jotform/aia-form-a.css new file mode 100644 index 0000000..a2d9ca1 --- /dev/null +++ b/www/integrations/jotform/aia-form-a.css @@ -0,0 +1,192 @@ +/* + * AIA Form A — Jotform Classic Forms custom CSS + * + * Paste into Jotform Form Designer > Styles > Inject Custom CSS after + * creating the approved Form A. These selectors are scoped to Jotform's + * Classic Forms structure and do not replace Jotform validation or controls. + * Validate the final generated form DOM before activation; no account access + * or pixel-perfect Jotform comparison was performed for this artifact. + */ + +/* The Astro page supplies the surrounding heading, copy, privacy link and + card. Keep the iframe's own surface quiet so it does not create a second + card inside the page's existing form container. */ +#form, +#form .form-all { + background: #fff; + border: 0; + box-shadow: none; + color: #254080; + font-family: Rubik, Arial, sans-serif; + max-width: 100%; +} + +#form .form-all { + margin: 0; + padding: 0; +} + +#form .form-line { + background: transparent; + border: 0; + margin: 0; + padding: 0 0 1rem; +} + +#form .form-label, +#form .form-label-left, +#form .form-label-right, +#form .form-label-top { + color: #254080; + font-size: .9rem; + font-weight: 700; + line-height: 1.5; + margin: 0 0 .4rem; + padding: 0; +} + +#form .form-sub-label { + color: #254080; + font-size: .78rem; + line-height: 1.5; +} + +#form .form-required { + color: #a21c28; + margin-left: .2rem; +} + +#form input.form-textbox, +#form input.form-textbox.form-phone, +#form input.form-textbox.form-email, +#form select.form-dropdown, +#form textarea.form-textarea { + background: #fcf9f5; + border: 1px solid #edeef3; + border-radius: 4px; + box-sizing: border-box; + color: #254080; + font: inherit; + line-height: 1.5; + min-height: 2.9rem; + padding: .7rem .8rem; + width: 100%; +} + +#form textarea.form-textarea { + min-height: 7rem; + resize: vertical; +} + +#form input.form-textbox:focus-visible, +#form select.form-dropdown:focus-visible, +#form textarea.form-textarea:focus-visible, +#form input[type='radio']:focus-visible + label, +#form input[type='checkbox']:focus-visible + label, +#form .form-submit-button:focus-visible { + outline: 3px solid #115bbd; + outline-offset: 3px; +} + +#form .form-line.form-line-error input.form-textbox, +#form .form-line.form-line-error select.form-dropdown, +#form .form-line.form-line-error textarea.form-textarea { + border-color: #a21c28; + outline: 2px solid #a21c28; + outline-offset: 1px; +} + +#form .form-error-message, +#form .form-line-error .form-error-message { + color: #a21c28; + font-size: .85rem; + font-weight: 700; + line-height: 1.5; + margin: .45rem 0 0; +} + +#form .form-radio-item, +#form .form-checkbox-item { + color: #254080; + line-height: 1.5; + margin: 0 1rem .5rem 0; +} + +#form .form-radio, +#form .form-checkbox { + accent-color: #254080; +} + +#form .form-buttons-wrapper { + background: transparent; + border: 0; + margin: .25rem 0 0; + padding: 0; + text-align: left; +} + +#form .form-submit-button, +#form button[type='submit'] { + background: #ffbd59; + border: 2px solid #ffbd59; + border-radius: 4px; + box-shadow: none; + color: #254080; + cursor: pointer; + font: inherit; + font-weight: 400; + line-height: 1.5; + min-height: 3rem; + padding: .65rem 1.2rem; + transition: .3s linear all; + width: 100%; +} + +#form .form-submit-button:hover, +#form .form-submit-button:focus-visible, +#form button[type='submit']:hover, +#form button[type='submit']:focus-visible { + background: transparent; + border-color: #ff914d; + color: #254080; +} + +#form .form-submit-button:disabled, +#form button[type='submit']:disabled { + cursor: not-allowed; + opacity: .65; +} + +/* Jotform error and required content must remain visible. Do not hide these + classes in a campaign-specific override. */ +#form .form-validation-error, +#form .form-required, +#form .form-error-message { + visibility: visible; +} + +@media (max-width: 640px) { + #form .form-line, + #form .form-label, + #form .form-label-left, + #form .form-label-right, + #form .form-label-top { + width: 100%; + } + + #form .form-all { + width: 100%; + } + + #form .form-submit-button, + #form button[type='submit'] { + min-height: 3rem; + } +} + +@media (prefers-reduced-motion: reduce) { + #form .form-submit-button, + #form button[type='submit'] { + transition: none; + } +} diff --git a/www/reports/phase-9-form-a-meeting-preview-2026-10-22.md b/www/reports/phase-9-form-a-meeting-preview-2026-10-22.md new file mode 100644 index 0000000..00d6129 --- /dev/null +++ b/www/reports/phase-9-form-a-meeting-preview-2026-10-22.md @@ -0,0 +1,121 @@ +# Phase 9 Form A Meeting Preview — 2026-10-22 + +## Scope and baseline + +This report records a local, non-submitting preview of the new Jotform Form A visitor journey. The repository remained on `faithful-astro-migration` at `ce17728e0b9a0e148941cfa47b2d074859b24456` when this work began. The Git index was empty, and no production configuration or Jotform account setting was changed. + +The preview is available only when all of the following are true: + +```text +PUBLIC_AIA_FORMS_MODE=mock +PUBLIC_AIA_FORM_A_PREVIEW=true +PUBLIC_ALLOW_INDEXING is not true +``` + +Default builds remain `off`. `live` remains fail-closed because no approved live adapter or production form identifier is present. Indexing-enabled builds omit the preview and retain the ordinary inactive fallback. + +## Placements and fields + +The full Form A preview is rendered on `/contact` and `/es/contact`. It contains the required name, required phone, conditionally required email, preferred contact method, optional message, sensitive-information caution, and a local demonstration control. It intentionally does not include an enquiry-category field. Spanish labels, including the dynamic email-requirement text and internal-preview label, are supplied through the existing locale message architecture. + +The compact preview is rendered on `/lp/aba-therapy`, `/lp/aba-insurance`, `/lp/aba-ahcccs`, and `/lp/aba-private-pay`. It contains only name, phone, conditional email, and preferred contact method. It has no message, enquiry-category, or sensitive-information notice. `/lp/early-intervention` was not changed and remains outside this meeting-preview override. + +The contact buttons use `Submit` and `Enviar`. Campaign buttons use the approved page CTA: `Request a Free Consultation`, `Request Insurance Verification`, `Request a Benefits Check`, or `Discuss Private-Pay Options`. The production route contract still assigns all four campaign pages to Form B; Form A is a temporary mock-only review override. + +Final copy cleanup was verified on 2026-10-23 UTC. In mock mode, each compact campaign preview has one short status line beneath its controls: “Preview only — nothing is submitted.” The same line retains the telephone and privacy-policy links. In off mode, the four campaign panels contain no form-availability notice; a plain support line retains the telephone and privacy-policy links. The compact panels contain no free-text field and therefore contain no sensitive-information disclaimer. Early Intervention likewise contains no free-text field, disclaimer, or unavailable-form notice; its existing telephone CTAs, hours, clinic address, and directions remain available. The hero and separate clinic-contact block retain their contact information without repeating form status. + +## Visual fidelity + +The mock now uses the established AIA form values from the existing Astro components and tokens: `#ffbd59` button fill and border, transparent hover/focus fill, `#ff914d` hover/focus border, `#254080` text, four-pixel corners, `#fcf9f5` input backgrounds, and `#edeef3` input borders. Keyboard focus retains a separate three-pixel outline. The compact variant relies on the campaign page's existing white form container instead of introducing a nested card surface. + +`integrations/jotform/aia-form-a.css` translates these values to narrowly scoped Jotform Classic Forms selectors. `integrations/jotform/README.md` documents installation, iframe/mobile comparison, multilingual verification, honeypot checks, and the multiple-native-Submit-button pattern needed for context-specific accessible labels. The Jotform selectors still require verification against the form's actual generated DOM. + +The component does not contain a form element, action, iframe, Jotform URL, form ID, fetch call, persistence mechanism, logging call, email operation, analytics event, or advertising event. The control is `type="button"`; its success state explicitly says that no information was sent or saved. The preview's fields are disabled in the ordinary/off build. + +## Validation behavior + +Chromium verifies that: + +- Name, phone, and preferred contact are required. +- Selecting Email makes the email field required and validates its format. +- Phone preference permits the optional email field to remain empty. +- The local success state is shown only after the local checks pass. +- English and Spanish labels render in their respective pages. +- Every placement uses its approved contextual button text as actual accessible text. +- The rendered button begins with `#ffbd59` fill and border, changes to a transparent fill with `#ff914d` border on hover/focus, retains `#254080` text, and keeps a visible focus outline. +- The sensitive-information caution appears only with the contact-page message field. +- No native `