/* ============================================================
   Forms — the Gravity Forms restyle layer, plus the modal body
   and the inline assessment_form block.

   inc/forms.php disables GF's own stylesheets (gform_disable_css),
   so this file is a REPLACEMENT, not an override. Nothing here
   needs !important and nothing should acquire it: if a rule is not
   landing, GF's CSS has been re-enabled somewhere.

   VERIFIED against the real DOM that Gravity Forms 3.0.2 emits for
   the assessment form (curl of / , reading the markup inside
   #m434-modal), not against a guess at GF's markup. GF 3.x differs
   from earlier majors in ways that matter here:

     - .gform_fields and .gfield are DIVs, not ul/li.
     - the fields sit under an extra .gform-body.gform_body wrapper,
       so every rule below is a DESCENDANT selector, never a child one.
     - each input is wrapped in .ginput_container.
     - label text is wrapped in <span class="gform-field-label__text">
       and the label carries .gform-field-label alongside .gfield_label.
     - the submit button is a real <button class="gform_button button">,
       and inc/forms.php prepends .btn .btn-primary to it — the design's
       button styling is therefore inherited from global.css, NOT
       duplicated here. Only sizing lives in this file.
     - the AJAX spinner is NO LONGER .gform_ajax_spinner. GF appends
       <span class="gform-loader"> inside the button and adds
       .gform-has-spinner to it. See the Submit section.
     - GF still prints an inline <style> of --gf-* custom properties
       inside .gform_wrapper even with gform_disable_css on. It is
       display:none per the UA sheet, we consume none of those
       properties, and it is harmless — do not try to remove it.

   DECISIONS D3 constraints that are NOT cosmetic:
     - inputs are height 48px, font-size 16px. 16px is the floor
       that stops iOS Safari zooming the viewport on focus; 15px
       triggers it and looks like a layout bug.
     - the submit button is 56px inside the modal.
   ============================================================ */

.m434-assessment-wrap { max-width: var(--m434-measure-wide); }

.m434-assessment-head { margin-bottom: 26px; }

.m434-assessment-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.08;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 10px 0 0;
}

/* --m434-muted-ink: this intro sits directly on the section ground and
   assessment_form clones section_settings like every other block, so
   Navy and Accent are selectable. A flat --m434-slate-strong is 2.00:1
   on --navy and 1.16:1 on --m434-crimson. */
.m434-assessment-intro {
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--m434-muted-ink);
  margin: 12px 0 0;
}

/* ---------- Gravity Forms: shell ---------- */
.m434-gf .gform_wrapper { margin: 0; }

.m434-gf .gform_wrapper form { margin: 0; }

/* GF renders .gform_heading whenever `requiredIndicator` is anything other than
   'text' — the assessment form uses 'asterisk' so the design's `Full name*` label
   reads correctly, which means this block ships the required-fields legend even
   though the form's title and description are both suppressed. The legend is a real
   accessibility affordance (it is what explains the asterisk), so it is styled
   rather than hidden. */
.m434-gf .gform_heading { margin: 0 0 18px; }

.m434-gf .gform_required_legend {
  font-family: var(--body);
  font-size: 12px;
  line-height: 1.5;
  /* Surface-tracking: --m434-slate-strong is 6.93:1 on --bg-soft but
     2.00:1 on --navy and 1.16:1 on crimson. */
  color: var(--m434-muted-ink);
  margin: 0;
}

/* ---------- Fields ---------- */
.m434-gf .gform_fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
  margin: 0;
  padding: 0;
}

.m434-gf .gfield {
  min-width: 0;
  /* The validation summary links to #field_1_1 etc. Inside the modal that scroll
     happens within .m434-modal__body, whose header is position:sticky — without a
     scroll margin the field being corrected lands underneath it. */
  scroll-margin-top: 76px;
}

.m434-gf .gfield_label {
  display: block;
  font-family: var(--body);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* --m434-muted-ink, not --slate. In the MODAL these labels sit on
     #ffffff and #6b7280 measures 4.83:1, which is why the failure was
     easy to miss — but the INLINE assessment_form block is seeded onto
     the Soft band, where the same color is 4.43:1 at 11px and fails
     AA. The token is --m434-slate-strong on any light ground (7.56:1 /
     6.93:1 / 6.67:1 on white / --bg-soft / --bg-cool) and
     rgba(255,255,255,.8) on the Navy and Accent bands the block can
     also be set to, where a flat #6b7280 is 3.13:1 / 1.81:1. */
  color: var(--m434-muted-ink);
  margin-bottom: 7px;
}

/* GF nests this twice: <span class="gfield_required"><span
   class="gfield_required gfield_required_asterisk">*</span></span>. No margin —
   templates.md 4.2 shows the marker set tight against the label as `Full name*`.
   The asterisk is the only thing distinguishing a required field, so it is
   meaningful text: --m434-accent-ink so it follows the band (a flat
   #a34f0e is 2.65:1 on --navy and 1.54:1 on crimson). */
.m434-gf .gfield_required { color: var(--m434-accent-ink); }

.m434-gf .ginput_container { min-width: 0; }

.m434-gf input[type="text"],
.m434-gf input[type="email"],
.m434-gf input[type="tel"],
.m434-gf input[type="url"],
.m434-gf input[type="number"],
.m434-gf select,
.m434-gf textarea {
  width: 100%;
  /* See the header note: 16px is an iOS constraint, not a taste call. */
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--white);
  border: 1px solid var(--m434-input-border);
  border-radius: 0;
  padding: 0 14px;
  height: 48px;
  transition: border-color 0.16s var(--m434-ease), box-shadow 0.16s var(--m434-ease);
}

.m434-gf input[type="text"],
.m434-gf input[type="email"],
.m434-gf input[type="tel"],
.m434-gf input[type="url"],
.m434-gf input[type="number"],
.m434-gf textarea {
  -webkit-appearance: none;
  appearance: none;
}

/* A select needs its own caret once the native appearance is dropped, otherwise it
   is indistinguishable from a text input. The assessment form has no select, but a
   Drop Down is one click away in GF's editor and this layer is the only stylesheet
   that would ever style it. */
.m434-gf select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23303030' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
}

/* GF hard-codes rows='10' on every textarea (class-gf-field-textarea.php) where
   templates.md 4.2 asks for three. `rows` is not reachable from CSS and GF's
   textareaHeight setting only swaps a size class that GF's own — disabled —
   stylesheet would have interpreted, so an explicit height is the only lever.
   104px is 3 lines at 16px/1.4 plus the 12px vertical padding and the border. */
.m434-gf textarea {
  height: 104px;
  min-height: 104px;
  padding: 12px 14px;
  resize: vertical;
}

.m434-gf input:focus,
.m434-gf select:focus,
.m434-gf textarea:focus {
  border-color: var(--red);
  /* A ring rather than a 2px border swap, so focus does not reflow
     the field by a pixel. 3px per templates.md 4.2, which records the added ring as
     a deliberate WCAG 2.4.7 fix over the design's border-color-only focus. */
  box-shadow: 0 0 0 3px rgba(var(--vaccent), 0.28);
  /* Transparent rather than `outline: none`: forced-colors modes repaint a
     transparent outline as a visible one, so the indicator survives there. A bare
     `none` would remove focus entirely for high-contrast users. */
  outline: 2px solid transparent;
  outline-offset: 0;
}

.m434-gf ::placeholder { color: var(--m434-slate-mute); opacity: 1; }

/* ---------- Validation ---------- */
/* GF adds .gfield_error to the WRAPPER, not to the control, and the control sits
   two levels down inside .ginput_container. */
.m434-gf .gfield_error input,
.m434-gf .gfield_error select,
.m434-gf .gfield_error textarea { border-color: var(--m434-crimson); }

/* One element, three classes:
   <div class="gfield_description validation_message gfield_validation_message">.
   Matched on the two GF-specific ones so a field DESCRIPTION, which shares only
   .gfield_description, is not swept up. */
.m434-gf .gfield_validation_message,
.m434-gf .validation_message {
  font-family: var(--body);
  font-size: 13px;
  line-height: 1.5;
  color: var(--m434-crimson);
  margin-top: 6px;
}

/* The summary box above the form. Present because the form sets
   validationSummary — without it GF prints the heading and no list. */
.m434-gf .gform_validation_errors {
  background: rgba(139, 36, 51, 0.06);
  box-shadow: inset 0 0 0 1px var(--m434-crimson);
  padding: 14px 16px;
  margin-bottom: 20px;
}

/* The heading is an <h2 class="gform_submission_error">; matching the class alone is
   enough and avoids depending on the tag, which GF has changed between majors. */
.m434-gf .gform_submission_error {
  font-family: var(--body);
  font-weight: 700;
  font-size: 14px;
  line-height: 1.5;
  color: var(--m434-crimson);
  margin: 0;
  text-transform: none;
}

/* GF opens that heading with <span class="gform-icon gform-icon--circle-error">,
   which is an empty element fed by GF's icon font — and that font ships in the
   stylesheet inc/forms.php disables. Hidden rather than left as a zero-width span so
   it cannot contribute a stray word-space before the message. */
.m434-gf .gform-icon { display: none; }

/* The per-field error list GF appends inside the box, as
   <ol><li><a class="gform_validation_error_link" href="#field_1_1">. Unstyled it
   inherits the UA's decimal markers and 40px indent inside a bordered panel. */
.m434-gf .gform_validation_errors ol {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
}

.m434-gf .gform_validation_errors li + li { margin-top: 4px; }

.m434-gf .gform_validation_error_link {
  font-family: var(--body);
  font-size: 13px;
  line-height: 1.5;
  color: var(--m434-crimson);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* GF's honeypot must stay in the DOM and stay unreachable. Never
   display:none it — GF compares the submitted value, and some bots
   skip hidden inputs, which is the point.

   Both classes are real and both land on the same wrapper: GF 3.x builds the field
   with cssClass 'gform_validation_container' (GF_Honeypot_Handler::get_honeypot_field)
   and the wrapper picks up .gfield--type-honeypot from its field type. Either alone
   would work; keeping both means a rename of one does not silently expose the trap.

   No !important: GF's stylesheets are disabled, so nothing competes. */
.m434-gf .gform_validation_container,
.m434-gf .gfield--type-honeypot {
  position: absolute;
  top: 0;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* ---------- Submit ---------- */
.m434-gf .gform_footer {
  margin: 22px 0 0;
  padding: 0;
}

/* Color, type and hover come from .btn/.btn-primary in global.css, applied to the
   button by m434_gform_submit_button() in inc/forms.php. Only the sizing the design
   asks of a FORM submit lives here. */
.m434-gf .gform_button {
  width: 100%;
  min-height: 52px;
}

/* GF 3.x's submission spinner. There is no .gform_ajax_spinner any more: the theme
   scripts append <span class="gform-loader" aria-hidden="true"> INSIDE the button and
   add .gform-has-spinner plus aria-busy="true" to it.

   Left as a flex item next to the label rather than absolutely centered over it, the
   way GF's own CSS does it. GF's JS additionally sets an inline
   -webkit-text-fill-color:transparent on Safari, which no stylesheet can undo; so on
   Safari the label goes and only the ring shows, and everywhere else the label stays
   beside the ring. Both are coherent states, and neither is a blank button — which is
   what Safari would have given us with no .gform-loader styling at all. */
.m434-gf .gform-loader {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  border: 2px solid rgba(17, 17, 17, 0.28);
  border-top-color: currentColor;
  border-radius: 50%;
  /* global.css's prefers-reduced-motion block clamps every animation to .001ms and
     one iteration, so under reduced motion this settles as a STATIC two-tone ring.
     That is intentional: GF also sets aria-busy + aria-live on the button, so the
     pending state is still announced. */
  animation: m434-gf-spin 0.8s linear infinite;
}

.m434-gf .gform_button[aria-busy="true"] { cursor: progress; }

@keyframes m434-gf-spin {
  to { transform: rotate(360deg); }
}

/* ---------- Confirmation ---------- */
/* The assessment form confirms by REDIRECTING to /thank-you/ (DECISION D2), so these
   rules are dormant for it. They exist because a form's confirmation is an editor
   setting: switching it to "Text" in wp-admin must not produce unstyled output.
   GF wraps the message as
   <div class="gform_confirmation_wrapper"><div class="gform_confirmation_message">. */
.m434-gf .gform_confirmation_wrapper { margin: 0; }

.m434-gf .gform_confirmation_message {
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px rgba(var(--vaccent), 0.5);
  padding: 22px 24px;
}

/* ---------- The no-Gravity-Forms fallback ---------- */
.m434-form-fallback {
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--m434-slate-strong);
}

.m434-form-fallback p { margin: 0 0 12px; }
.m434-form-fallback .btn { margin-top: 6px; }

/* ---------- Modal-specific ---------- */
/* Scroll lock. position:fixed on body, because iOS Safari ignores
   overflow:hidden on body and scrolls the page behind the sheet.
   modal.js sets `top` to preserve the reading position.
   (The sheet's own scrolling — overflow/overscroll on .m434-modal__body — is
   global.css's, not repeated here.) */
body.m434-modal-open {
  position: fixed;
  width: 100%;
  overflow: hidden;
  /* Belt and braces for the overlay's own scroll chaining. */
  overscroll-behavior: contain;
}

.m434-modal__intro {
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.65;
  color: var(--m434-slate-strong);
  margin: 0 0 20px;
}

.m434-modal .m434-gf .gform_button { min-height: 56px; }
.m434-modal .m434-modal__close { min-width: 44px; min-height: 44px; }

/* ---------- sm: the two-column form ---------- */
@media (min-width: 480px) {
  .m434-gf .gform_fields { grid-template-columns: 1fr 1fr; }

  /* Anything that is not explicitly half-width spans both columns:
     textareas, consent checkboxes and single-select rows all read
     badly in a narrow half-column.
     GF derives these classes from the field's layoutGridColumnSpan — 6 gives
     .gfield--width-half, 12 gives .gfield--width-full — which is why
     migration/assessment-form.json sets 6 on name/company/email/phone and 12 on
     location/message. .gfield--width-half is declared after .gfield so it wins at
     equal specificity. */
  .m434-gf .gfield { grid-column: 1 / -1; }
  .m434-gf .gfield--width-half { grid-column: span 1; }

  .m434-gf .gform_button { width: auto; min-width: 220px; }
}

@media (min-width: 768px) {
  .m434-assessment-title { font-size: 34px; }
  .m434-assessment-head { margin-bottom: 32px; }
}

@media (min-width: 1024px) {
  .m434-assessment-title { font-size: 40px; }
}
