/* Vivly Living — shared WPForms embed styling (Phase 7 extraction).
   EVERY rule below was MOVED property-for-property identical from
   css/contact.css v0.7.1 Block 4 (+ its responsive form rules), rescoped
   .vl-contact-form-embed → .vl-form-embed — provenance comments (frame node
   reads, specificity battles, the Themes-tab !important guard) moved with
   their rules and still say "contact"/form 56 where that is where the
   evidence came from. Consumers: template-contact.php, template-land.php
   (Phase 6's enquiry/newsletter forms are the intended next ones). Wrap any
   WPForms shortcode in <div class="vl-form-embed"> and enqueue this file.
   Page-level layout (columns, headings, band padding) stays with each page's
   own stylesheet — only WPForms-scoped rules belong here. */

/* ── Block 4: WPForms scoping ─────────────────────────────────────────────
   RECONCILED (Task 7, 2026-07-29) against the REAL rendered markup, pulled
   from the live /contact/ page (form id 56) and saved locally to
   .superpowers/sdd/2026-07-28-phase4d-contact-page/rendered-form.html while
   doing this work. That path is gitignored scratch, not a repo artefact —
   it won't exist for a future reader, so it is cited here only as
   provenance for WHEN/HOW this was checked; the markup that actually
   matters is restated inline in the comments below (real class names,
   nesting, specificity numbers), which is what to trust instead. Task 4's
   blind guess had
   one load-bearing structural error: the five `.wpforms-field` divs are NOT
   direct children of `form.wpforms-form` — WPForms wraps all of them in one
   intermediate `.wpforms-field-container` div, with `.wpforms-submit-container`
   as its SIBLING (not a grid item), both direct children of the form. Task
   4's grid was applied to `form.wpforms-form` itself, whose only two visible
   children are those two wrapper divs — so the grid had exactly two
   auto-placed cells (field-container | submit-container) side by side, and
   every field then stacked full-width *inside* the half-width field
   container. That is the actual mechanism behind Liam's "two-up grid not
   applying, everything stacks full width" report. Fixed below by moving the
   grid onto `.wpforms-field-container`.

   Real classes confirmed present: wpforms-container, wpforms-container-full,
   wpforms-render-modern, wpforms-field-container, wpforms-field
   wpforms-field-text|email|phone|textarea, wpforms-field-label,
   wpforms-required-label, wpforms-field-medium, wpforms-field-required,
   wpforms-submit-container, wpforms-submit (the button's OWN class — used
   below in place of Task 4's generic `button[type="submit"]` guess; both
   match the same element, but see the specificity note on the button rules).

   WPForms serves its own opinionated CSS on top of all this
   (wpforms-modern-full-css: .../wpforms/assets/css/frontend/modern/
   wpforms-full.min.css?ver=2.0.0.2 — confirmed active via
   wpforms_settings.isModernMarkupEnabled:"1" and disable-css left at its
   default, 3/full; a second, pro-tier stylesheet at .../pro/css/frontend/
   modern/wpforms-full.min.css was also inspected on the server and adds
   nothing that touches plain text/email/phone/textarea/submit markup — its
   extra rules all target the Layout/Repeater/Password/Signature/Richtext
   field types, none of which this form uses). Two different problems fight
   our rules there, handled two different ways:

   (1) Colour/type/spacing on labels, fields and the button is driven by CSS
       custom properties WPForms itself defines on `:root` (its inline
       #wpforms-modern-full-inline-css block) and reads back via var() in its
       own rules, e.g. `div.wpforms-container-full .wpforms-field-label{
       font-size:var(--wpforms-label-size-font-size);...}` and
       `div.wpforms-container-full button[type=submit]{background-color:
       var(--wpforms-button-background-color-alt,
       var(--wpforms-button-background-color));...}`. A custom property's
       value for a given element resolves by CASCADE-ON-THAT-ELEMENT-OR-
       INHERITANCE, not by the specificity of whichever rule later reads it
       with var() — so redeclaring the variable once on `.wpforms-container`
       here beats the `:root` default for every descendant, regardless of
       stylesheet load order. (Order does matter for a same-specificity
       LITERAL-property fight, and WPForms' two <link> tags render at the
       very end of body on the live page — i.e. AFTER contact.css — so it
       would win most ties; the variable route sidesteps that fight
       entirely, which is why it's used everywhere a --wpforms-* var exists
       for the property in question.) Confirmed default values read from the
       live inline block: --wpforms-label-color: rgba(0,0,0,.85);
       --wpforms-label-size-font-size: 16px; --wpforms-button-background-
       color: #066aab (WPForms blue — this IS the reported button-colour
       bug); --wpforms-button-border-radius: 3px; --wpforms-button-size-
       height: 41px; --wpforms-field-border-color: rgba(0,0,0,.25);
       --wpforms-field-border-radius: 3px.
   (2) Wherever WPForms hardcodes a literal (no variable) at a specificity a
       flat theme selector can't beat, the selector below is deepened using
       the REAL ancestor classes confirmed in the rendered markup
       (.wpforms-field-container, .wpforms-submit-container,
       .wpforms-field-medium) until it wins on its own merits — e.g.
       WPForms' `.wpforms-container .wpforms-field{padding:15px 0}` is
       (0,2,0); nesting our reset under the real `.wpforms-field-container`
       ancestor makes ours (0,3,0), an outright win. No blanket !important
       anywhere in this block — the ONE justified exception (textarea
       height) is commented at its own declaration. */
/* Kill the container's own 24px outer margins. WPForms' modern sheet sets
   `div.wpforms-container-full:not(:empty) { margin: 24px auto; … }` — with
   the :not(:empty) pseudo-class that is (0,2,1), which outguns the (0,2,0)
   `margin: 0` in the main rule below (and WPForms' stylesheet renders at the
   end of <body>, after theme CSS, so even a tie would lose). Invisible on
   Contact — its form heading's 70px margin-bottom collapses over the top
   24px and the band padding hides the bottom — but the Land page's
   headingless form column exposed both edges (Liam live review 2026-07-31:
   "gap above the form… at the bottom as well"). Three classes = (0,3,0),
   an outright win. The rule's `padding: var(--wpforms-container-padding)`
   needs no counter — the variable's own :root default is 0px. */
.vl-form-embed .wpforms-container.wpforms-container-full {
    margin: 0;
}

.vl-form-embed .wpforms-container {
    margin: 0;
    max-width: none; /* WPForms' own stylesheet caps this — the frame's width rules here, not theirs */

    /* Route (a): redeclare every --wpforms-* custom property this form's
       field/label/button rules read, per the evidence above.

       WHY !IMPORTANT HERE, AND ONLY HERE (cold-review fix, Important 1,
       2026-07-29): WPForms renders a PER-FORM id-scoped block for these same
       custom properties — `#wpforms-{$form_id} { --wpforms-label-color: …; }`
       etc. — from `$form_data['settings']['themes']` (CSSVars.php:399-406).
       Today that block is empty (`#wpforms-56 { }` on the live page) only
       because form 56 was created by a direct `post_content` write that never
       populated `settings.themes` (see tools/README.md). The moment anyone
       opens the form in the WPForms builder and touches its Themes/Style tab,
       WPForms writes real values into that block at ID specificity (1,0,0) —
       which beats this rule's (0,2,0) outright, with no error: the brick
       button silently reverts to WPForms blue, labels 24px -> 16px, radii
       10px -> 3px. Custom properties honour !important, and an !important
       NORMAL declaration beats a non-important ID-specificity one, so adding
       it here lets the styling survive that trap WITHOUT coupling this
       stylesheet to form id 56 (an ID-selector override here would only work
       for THIS form). This is a targeted, load-bearing exception, not the
       blanket-!important antipattern — do not add !important to anything
       else in this file on the strength of this comment; see tools/README.md
       for the companion warning against ever using that builder tab on this
       form. */
    --wpforms-label-color: var(--vl-black) !important;
    --wpforms-label-size-font-size: var(--vl-text-card-title) !important; /* 24px, node-exact */
    --wpforms-label-size-line-height: 28px !important; /* node-exact, 24/28 */
    --wpforms-field-size-input-spacing: 5px !important; /* node: label sits 5px above its input — this is the ONLY variable WPForms uses for the label's own margin-bottom; its other consumers (error-label margin-top, icon-choices spacing) are either harmless side effects or not triggered by this field set */
    --wpforms-field-border-color: var(--vl-brick) !important;
    --wpforms-field-border-style: solid !important;
    --wpforms-field-border-size: 1px !important;
    --wpforms-field-border-radius: 10px !important; /* node-exact */
    --wpforms-field-background-color: var(--vl-white) !important;
    --wpforms-field-text-color: var(--vl-black) !important;
    --wpforms-field-size-font-size: var(--vl-text-body) !important; /* 18px */
    --wpforms-field-size-padding-h: 20px !important; /* derived horizontal inset, matches the sitewide field convention */
    --wpforms-button-background-color: var(--vl-brick) !important;
    --wpforms-button-border-color: var(--vl-brick) !important;
    --wpforms-button-border-style: solid !important;
    --wpforms-button-border-size: 1px !important;
    --wpforms-button-border-radius: var(--vl-radius-pill) !important;
    --wpforms-button-text-color: var(--vl-white) !important;
    --wpforms-button-size-height: 50px !important;
    --wpforms-button-size-font-size: var(--vl-text-nav) !important; /* 18px, node-exact */
    --wpforms-button-size-margin-top: 30px !important; /* gap between the last field row
        and the Send button — 25 -> 30px (Liam, 2026-07-29), matching the
        field grid's own row gap so the button sits on the same rhythm. This
        var's only consumer in this stylesheet is .wpforms-submit-container's
        margin-top, so repurposing it is safe. */
}

/* Two-up grid, on the REAL wrapper (see header comment). Node read: 489px ×
   2 + 30px gap = 1008px, an 8px overshoot of the SAME kind as Block 1's
   outer overshoot (the .vl-contact__form column here is 1000px, matching
   Block 1's adjusted width). Using `repeat(2, 1fr)` with the node's 30px
   column-gap resolves to (1000−30)/2 = 485px per field — two of those + the
   30px gap land on exactly 1000px, no overshoot. Row rhythm (input bottom ->
   next label top = 25px) becomes the grid's row-gap, since each `.wpforms-field`
   div is one row (label + input stacked inside it). No competing `display`
   rule exists on `.wpforms-field-container` outside WPForms' `.inline-fields`/
   AMP-success variants (neither present here), so this applies at normal,
   uncontested specificity. */
.vl-form-embed .wpforms-field-container {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    column-gap: 30px; /* node-exact, 39:2116 */
    row-gap: 30px; /* 25px was the node read (input bottom -> next label top);
                       Liam set it to 30px live (2026-07-29) to match the
                       column gap, so the field grid is evenly spaced */
}

.vl-form-embed .wpforms-field-container .wpforms-field {
    margin: 0;
    padding: 0; /* Beats the load-bearing top/bottom padding: WPForms' `.wpforms-container
                   .wpforms-field{padding:15px 0}` is (0,2,0), and nesting under the real
                   .wpforms-field-container ancestor gives this rule (0,3,0), an outright
                   win there. NOT a full win, though — WPForms also has `div.wpforms-
                   container .wpforms-form .wpforms-field{padding-right:1px;padding-left:1px}`
                   at (0,3,1), which beats this rule's (0,3,0), so 1px of lateral padding
                   survives per field. Visually irrelevant (swallowed by the field's own
                   border/radius), noted here so the comment doesn't overstate what this
                   rule actually wins. */
}

/* Message spans both columns (full 1000px width per the node). Confirmed
   against the real markup: WPForms wraps the Paragraph Text field exactly
   as `<div class="wpforms-field wpforms-field-textarea">`. */
.vl-form-embed .wpforms-field-textarea {
    grid-column: 1 / -1;
}

/* Label: every property (font-size, line-height, colour, margin-bottom) is
   already supplied by WPForms' own rule via the --wpforms-label-* /
   --wpforms-field-size-input-spacing variables redeclared above — nothing
   left to restate here. font-weight:700 is WPForms' own hardcoded default
   (not variable-driven) and already equals --vl-weight-semibold, so that
   needs no override either. (Task 4's old flat `.vl-form-embed
   .wpforms-field-label{...}` rule is removed here: its font-size/line-
   height/colour/margin all lost to WPForms' higher-specificity
   `div.wpforms-container-full .wpforms-field-label` rule anyway, so it was
   dead weight that happened to still look right once the variables above
   made WPForms' own rule agree with it.) */

.vl-form-embed .wpforms-field-container input[type="text"],
.vl-form-embed .wpforms-field-container input[type="email"],
.vl-form-embed .wpforms-field-container input[type="tel"],
.vl-form-embed .wpforms-field-container textarea {
    display: block;
    width: 100%;
    max-width: 100%; /* neutralises WPForms' `.wpforms-container input.wpforms-field-medium{max-width:60%}` (every field in the real markup carries wpforms-field-medium) — nesting under .wpforms-field-container bumps this rule to (0,3,1), beating WPForms' (0,2,1) outright */
    margin: 0;
    padding: 0 20px; /* matches the sitewide field convention (dev-listing.css select padding); also mirrored via --wpforms-field-size-padding-h above */
    border: 1px solid var(--vl-brick); /* node-exact, 39:2099; also mirrored via --wpforms-field-border-color above so WPForms' own rule agrees independently */
    border-radius: 10px; /* node-exact */
    background: var(--vl-white);
    color: var(--vl-black);
    font-family: inherit; /* reset WPForms' own font stack */
    font-size: var(--vl-text-body); /* 18px */
    resize: none;
}

.vl-form-embed .wpforms-field-container input[type="text"],
.vl-form-embed .wpforms-field-container input[type="email"],
.vl-form-embed .wpforms-field-container input[type="tel"] {
    height: 50px; /* node-exact, 39:2099 — WPForms' own height rule for plain inputs (`div.wpforms-container-full input,select{height:var(--wpforms-field-size-input-height)}`) is only (0,1,2), so this already wins without needing the .wpforms-field-container nesting; kept for consistency with the shared selector above */
}

/* Invalid-state border: an explicit, theme-owned statement of WPForms' own
   red on `.wpforms-error`/`.user-invalid` fields — belt-and-braces, not a
   required override. Corrected arithmetic (review round 1, 2026-07-29):
   WPForms' rule for this (`.wpforms-container .wpforms-field
   input.wpforms-error{border:1px solid #D63637}`, hardcoded, not
   variable-driven) is 3 classes (`.wpforms-container`, `.wpforms-field`,
   `.wpforms-error`) + 1 element (`input`) = **(0,3,1)** — a TIE with our own
   base border rule above (also (0,3,1)), not lower as an earlier draft of
   this comment wrongly claimed. Per this file's own Block 4 header note,
   WPForms' `<link>` renders at the very end of `<body>` on the live page —
   i.e. AFTER contact.css — so on a genuine tie like this one, WPForms'
   native red already wins by page load order, WITH OR WITHOUT this rule.
   In other words: this rule is not what makes the invalid border show; it
   is kept so the intended behaviour is legible in this file and doesn't
   quietly depend on WPForms' internal selector depth or asset-load order,
   either of which could change in a future plugin update without notice.
   It happens to be harmless either way because both rules resolve to the
   identical `#D63637`. No design-frame read for this state (not shown in
   the static frame) — matching WPForms' own native invalid colour rather
   than inventing one keeps the browser's built-in :invalid/required-field
   affordances consistent with whatever text WPForms itself renders.

   (Task 4's old `.vl-form-embed .wpforms-error{...}` message-TEXT
   rule, styling the error label itself, is deleted rather than reconciled:
   WPForms' own `div.wpforms-container-full .wpforms-form label.wpforms-error,
   em.wpforms-error{...color:var(--wpforms-label-error-color);...}` is
   (0,3,2), which already beat Task 4's flat `.vl-form-embed
   .wpforms-error` selector — (0,2,0), two classes — outright. Same
   "already dead, deletion is a no-op" situation as the `.wpforms-field-label`
   deletion noted above.) */
.vl-form-embed .wpforms-field-container input.wpforms-error,
.vl-form-embed .wpforms-field-container input.user-invalid,
.vl-form-embed .wpforms-field-container textarea.wpforms-error,
.vl-form-embed .wpforms-field-container textarea.user-invalid {
    border-color: #D63637;
}

.vl-form-embed .wpforms-field-container textarea {
    /* WPForms chains FOUR selector levels specifically to make its field-size
       height formula resist overrides: the active rule is
       `div.wpforms-container-full .wpforms-form textarea.wpforms-field-medium
       {height:calc(var(--wpforms-field-size-input-height)*2.8)}` — 2 elements
       (div, textarea) + 3 classes (wpforms-container-full, wpforms-form,
       wpforms-field-medium) = (0,3,2). This selector, `.vl-form-embed
       .wpforms-field-container textarea`, is only 2 classes + 1 element =
       (0,2,1) — it has no attribute selector to draw on the way the input
       lines above do (there's no `[type=...]` on a textarea), so it's
       further behind here than the input/max-width case, not closer.
       Matching WPForms' selector depth would mean mirroring their internal
       DOM structure directly, which is fragile against any future WPForms
       markup change; !important is the honest, single-purpose tool here
       instead — the ONLY use of it in this file. */
    height: 150px !important; /* node-exact, 39:2114 */
    padding-block: 15px; /* vertical breathing room a single-line input doesn't need — derived */
}

.vl-form-embed input:focus-visible,
.vl-form-embed textarea:focus-visible {
    outline: 2px solid var(--vl-cornflower); /* sitewide focus treatment; no competing WPForms :focus/outline rule exists for plain text/email/tel/textarea fields (only for submit buttons and checkbox/radio) */
    outline-offset: 2px;
}

/* Send button (39:2117/39:2118): same solid-brick pill construction used
   sitewide for CTAs (header.css .vl-nav__contact-pill; plot-floorplans.css
   .vl-plot-floorplans__brochure). Real markup: the button's OWN class is
   `wpforms-submit` (`<button type="submit" class="wpforms-submit" ...>Send
   </button>`), a child of `.wpforms-submit-container`. WPForms' base button
   rule (`div.wpforms-container-full button[type=submit]{...}`) is (0,2,2);
   nesting the real `.wpforms-submit` class under the real
   `.wpforms-submit-container` ancestor gives (0,3,0), an outright win — used
   below for the one hardcoded (non-variable) property WPForms sets on this
   rule, font-weight:500. Every colour/size property besides that is
   variable-driven and already resolved by the --wpforms-button-* overrides
   above, so only font-weight, width and flex-alignment need restating. */
.vl-form-embed .wpforms-submit-container {
    display: flex;
    justify-content: flex-end;
    margin: 0; /* margin-top comes from --wpforms-button-size-margin-top, redeclared above to 30px */
}

.vl-form-embed .wpforms-submit-container .wpforms-submit {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 200px; /* node-exact, 39:2118 — WPForms sets no width of its own on this button */
    font-weight: var(--vl-weight-semibold); /* WPForms hardcodes font-weight:500 here; the only non-variable property on its base button rule */
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

.vl-form-embed .wpforms-submit-container .wpforms-submit:hover {
    /* WPForms' own :hover rule darkens via a 20%-opacity black overlay on
       top of --wpforms-button-background-color (i.e. our brick) — visually
       close to the sitewide brick-hover convention but not the exact token,
       so this restates --vl-brick-dark explicitly for consistency with
       header.css/plot-floorplans.css. WPForms' :hover rule is (0,3,2); the
       real-class chain + :hover here is (0,4,0), an outright win. */
    background: var(--vl-brick-dark);
    border-color: var(--vl-brick-dark);
}

.vl-form-embed .wpforms-submit-container .wpforms-submit:focus-visible {
    /* WPForms sets `outline:none` on the button's own :focus at (0,3,2);
       the real-class chain + :focus-visible here is (0,4,0), an outright win. */
    outline: 2px solid var(--vl-cornflower);
    outline-offset: 2px;
}

/* The grid tracks' minmax(0,…) lets the TRACKS shrink; these let the embed's
   ITEMS shrink inside them — the WPForms min-size-auto trap, both directions
   (see the consuming page's own `__cols > *` copy of this guard). */
.vl-form-embed,
.vl-form-embed .wpforms-container {
    min-width: 0;
}

@media (max-width: 1024px) {
    .vl-form-embed .wpforms-field-container {
        grid-template-columns: 1fr; /* fields stack — derived */
    }

    .vl-form-embed .wpforms-field-textarea {
        grid-column: 1 / -1; /* inert at 1 column but harmless to restate */
    }
}

@media (max-width: 767px) {
    .vl-form-embed .wpforms-submit-container {
        justify-content: flex-start; /* `stretch` is not a valid flex main-axis
            value (computes to flex-start) — corrected here to say what
            actually happens. Harmless either way: the button below is
            width: 100%, so main-axis alignment has nothing left to do. */
    }

    .vl-form-embed .wpforms-submit-container .wpforms-submit {
        width: 100%; /* derived: Send button goes full-width on mobile */
    }
}
