/* ==========================================================================
   w10x.css - Vantix website-10X - scope A - Sprint 0, wave 1 (2026-09-14)
   Owner: builder A. Class prefix w10x-a-.
   This file deliberately creates NO classes: every rule targets a selector
   that already exists in the live site sheet
   (vantix-13c22e.webflow.shared.b2d489d69.css, read 2026-09-14).
   Implements MOBILE-SPEC.md M3 (A1), M2 (A2), M1 (A3).
   All values are ratified design.md section 3 token values (D-005,
   2026-09-14). No new colour, radius, spacing step or type step.
   Loaded once from the site head via a labelled <link> block
   (<!-- w10x-a-stylesheet -->), after the Webflow sheet, so equal-
   specificity rules win on order; "html body" is used where the site
   declares its mobile token mode on bare "body".
   ========================================================================== */

/* --------------------------------------------------------------------------
   A1 - M3: body and paragraph text >= 16px at <= 479px
   design.md 3.2: the role "Body 2" is the most-common <p> rendering
   (212 of 260 sampled nodes). It resolves 16px/24px at 1440 but 14px/20px
   at 390 - the mobile value is below the M3 floor by design, in the token.
   Live consumers of Size/Body 2: body, p, .text-body, .promo-card-sub
   (plus the form controls, handled by A2 at every width).
   Values: Size/Body 2 base = 16px; Line Height/Body 2 base = 24px.
   Scoped to <= 479px, so desktop and tablet are untouched.
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body,
  html body p,
  html body .text-body,
  html body .promo-card-sub {
    font-size: 1rem;   /* 16px - Size/Body 2, base mode */
    line-height: 24px; /* Line Height/Body 2, base mode */
  }
}

/* --------------------------------------------------------------------------
   A2 - M2: lead-form controls >= 16px font and >= 48px tall
   Applied at EVERY width, not just mobile: iOS Safari zooms on focus for any
   control under 16px whatever the viewport. The reused Webflow form renders
   id="email-form"; second and later instances on one page render
   id="email-form-2", "-3", so the id-prefix selector is included too.
   Exclusions, on purpose:
     [type=submit]   - .cta-submit-invisible is position:absolute; inset:0;
                       height:100%. A min-height there would push an invisible
                       hit area outside its visible CTA parent.
     checkbox/radio  - tap targets (A3), not text fields; a 48px box would
                       break the consent row.
     [type=hidden]   - not rendered.
   .text-field is height:auto, so min-height governs; .text-field.textarea
   keeps its explicit height:104px (> 48px, no conflict).
   -------------------------------------------------------------------------- */
#email-form input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="hidden"]),
#email-form select,
#email-form textarea,
form[id^="email-form"] input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="hidden"]),
form[id^="email-form"] select,
form[id^="email-form"] textarea {
  font-size: 1rem; /* 16px */
  min-height: 48px;
}

/* --------------------------------------------------------------------------
   A3 - M1: tap targets >= 44px at <= 479px
   Offender sizes below are computed from the live sheet's own declarations at
   the <= 479px mode (spacing--8 = 8px, spacing--12 = 10px, icon-size--large
   = 20px, line-height--button-2 = 12px), not estimated:
     a.cta-small      CTA / Small            8+12+8  + border   ~= 37px tall
     .nav-link        Navbar dropdown        8+12+8  + 2 border ~= 39px tall
     .button-slider   Button / Circle        8+20+8  + 2 border ~= 38px box
     a.link-social    footer social links    20px icon, no pad  ~= 20px box
     a.footer-link    footer links           20px line box      ~= 20px tall
     a.nav-column-item  nav links (already display:flex, column)
   min-height / min-width only. No font, colour or padding change, and no
   display change on anything that is already a flex container - so nothing
   moves above 479px (the whole block is inside the media query).
   NOT enlarged, deliberately: div.button-circle is the 8px accent dot with
   pointer-events:none, and .icon-slider-button is the icon inside
   .button-slider. Both are decorative children, not tap targets; growing
   them to 44px would break the button interiors.
   a.footer-link is scoped to its flex-column parent, so the rule can never
   blockify a footer link used inline inside a sentence (e.g. a legal line).
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body a.cta-small,
  html body .nav-link,
  html body a.nav-column-item,
  html body .footer-links-column > a.footer-link {
    min-height: 44px;
  }

  html body .button-slider,
  html body a.link-social {
    min-width: 44px;
    min-height: 44px;
  }

  html body .footer-links-column > a.footer-link,
  html body a.link-social {
    display: flex;
    align-items: center;
  }

  html body a.link-social {
    justify-content: center;
  }
}

/* --------------------------------------------------------------------------
   A4 - Body 3 roles lifted to the Size/Body 2 MOBILE token values (head
   decision, batch 2, 2026-09-14). At <= 479px these roles resolve
   Size/Body 3 = 12px / Line Height/Body 3 = 16px, below the M3 floor and
   below the 15px absolute floor noted in design.md 3.2. They are raised to
   the live mobile values of the next step up, Size/Body 2 = 14px and
   Line Height/Body 2 = 20px - an existing token value, not a new type step,
   and a smaller move than the 16px A1 floor because these classes mix
   paragraph utility with label roles.
   .promo-eyebrow is excluded by the head's decision (label role).
   Live consumers of Size/Body 3: .text-small, .checkbox-text,
   .list-wrapper, .promo-eyebrow.
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body .text-small,
  html body .checkbox-text,
  html body .list-wrapper {
    font-size: 14px;   /* Size/Body 2, mobile mode */
    line-height: 20px; /* Line Height/Body 2, mobile mode */
  }
}

/* --------------------------------------------------------------------------
   A5 - CTA / Small text at its own DESKTOP token value (head decision,
   batch 2). .cta-small resolves Size/Button 2, which is 12px at base and
   10px in the mobile mode; 10px button text is the smallest type on the
   site. It is set to the base value, 12px. Font size only - the paired
   Line Height/Button 2 is 16px in BOTH modes, so nothing else changes, and
   the A3 min-height:44px above already gives the control its tap area.
   Every .cta-small in the staged HTML is an <a> (10/10 sampled), so the
   anchor-qualified selector is complete.
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body a.cta-small {
    font-size: 12px; /* Size/Button 2, base mode */
  }
}

/* --------------------------------------------------------------------------
   A6 - M1 on the PRIMARY CTA (batch 3). C measured a 165x36 element whose
   text is "Book a Welding Demo"; resolved from the served welding page to
   the CTA / Main root, a.cta-main (265 instances sitewide, 13/13 sampled
   instances on the two staged pages are <a>). At <= 479px it computes
   padding 8px + line-height--button-2 16px + 8px + border ~= 36px, under the
   44px floor. This is the site's primary conversion control.
   min-height only; .cta-main already declares justify-content/align-items
   center, so the content self-centres and nothing above 479px moves.
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body a.cta-main {
    min-height: 44px;
  }
}

/* --------------------------------------------------------------------------
   A7 - M1 on the navigation brand link (batch 3). Reconciling C's
   ".master-navigation a" request: a depth-correct parse of the served
   .master-navigation subtree (12,655 chars) returns 67 anchors -
   a.nav-column-item (26), a.footer-link (38, inside .footer-links-column so
   already covered by A3), a.nav-link (1), a.cta-small (1) and a.brand-nav
   (1). Every one of those is already covered by A3 EXCEPT a.brand-nav, so a
   blanket ".master-navigation a" rule would be redundant for 66 of 67
   anchors. Only the brand link is added here.
   Confirmed computed height at <= 479px = 24px: .brand-nav declares no
   height and no padding (padding-left:0 at <= 767px); its tallest child is
   .logo-mark at an explicit height:24px, and the wordmark is capped by
   .logo-text max-width:96px against an intrinsic 1501x320 (aspect 4.69),
   rendering 20.5px tall. 24px < 44px.
   -------------------------------------------------------------------------- */
@media screen and (max-width: 479px) {
  html body a.brand-nav {
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

/* --------------------------------------------------------------------------
   A8 (REPLACED in v4, head D-014) - the welding first-screen spec table
   collapses to one column at <= 479px.
   The v3 form of this rule targeted the CONTAINER (.w10x-c-spec-first) and
   was therefore INERT: verified against the live sheet
   (vantix-13c22e.webflow.shared.c8a10f169.css, read 2026-09-14), where
   grid-template-columns is declared only on the inner ROWS -
   .pricing55_row and .pricing55_top-row (1fr 3fr), plus their .v-1 combos
   (1fr 2fr 2fr). No container carries a grid.
   Below is C's rule, verbatim. It also beats the .v-1 combos: both are
   two-class selectors (0,2,0) and this stylesheet loads after the Webflow
   sheet, so equal specificity resolves on source order in C's favour.
   NOTE: .pricing55_component.w10x-c-table-scroll is C's live overflow combo
   and is deliberately NOT touched or pruned here.
   -------------------------------------------------------------------------- */
@media (max-width:479px){.w10x-c-spec-first .pricing55_top-row,.w10x-c-spec-first .pricing55_row{grid-template-columns:1fr}}

/* --------------------------------------------------------------------------
   A9 - companion to A8 (head D-014): the service-proof strip's row/column
   gaps at <= 479px. C owns .w10x-c-proof-strip and has applied it (present
   in the live sheet). Written exactly as the head specified.
   8px and 16px are existing Layout token values (Spacing/8; Spacing/16 base)
   - no new spacing step is introduced.
   -------------------------------------------------------------------------- */
@media (max-width:479px){.w10x-c-proof-strip{gap:8px 16px}}

/* --------------------------------------------------------------------------
   A10 - M6 overflow on the 8 /comparisons/* pages at 390 (head D-030 section 4,
   from QA's rendered measurement: 195px of horizontal overflow, identical on
   production, i.e. PRE-EXISTING and not a regression from this engagement).
   A grid item's automatic minimum size is min-width:auto, which stops the
   1fr track shrinking below its content's min-content width. min-width:0
   releases it. Same root cause and same remedy as C's
   .pricing55_component.w10x-c-table-scroll fix on the welding page.
   Verified against the live sheet (shared.c8a10f169.css, 2026-09-14):
   .vx-cmp-split is `grid-template-columns: 260px 1fr` at base and `1fr` at
   <= 991px; .vx-cmp-split-aside declares only `position: relative`; and
   min-width is declared NOWHERE in the vx-cmp family - so `auto` here is the
   CSS default for grid items, not an authored value.
   Written exactly as the head specified.
   UPDATED in v6 (head D-037 section 2): Q's rendered measurement proved
   .vx-cmp-rich-col is the element that actually releases the track - the
   aside alone did not, and neither did relying on the 1fr track. Selector
   extended to cover both grid children, exactly as Q measured it. This is
   the second correction to this rule; the lesson recorded in v4's A8 note
   applies again - a selector is only a fix once something it matches owns
   the property that is breaking.
   -------------------------------------------------------------------------- */
@media (max-width:479px){.vx-cmp-split-aside,.vx-cmp-rich-col{min-width:0}}

/* --------------------------------------------------------------------------
   A11 - the service-tabs headline column is capped at 332px on DESKTOP
   (head D-044, from UI audit U.md section 1; pre-existing, identical on
   production - the operator spotted it on the welding page).
   Verified in the live sheet (shared.c8a10f169.css, 2026-09-15):
     .headline-service-tabs                        max-width: 332px
     @media (max-width:991px) .headline-service-tabs  max-width: none
   so the cap is live only at >= 992px; tablet and mobile already release it.
   That is why this rule is scoped min-width:992px and not applied globally.
   The descendant selector is two classes (0,2,0) against the site's single
   class (0,1,0), so it wins on specificity regardless of source order.
   Written exactly as the head specified.
   -------------------------------------------------------------------------- */
@media (min-width:992px){.service-a-tabs-section .headline-service-tabs{max-width:none}}

/* --------------------------------------------------------------------------
   A12 - companion that makes A8 effective (head D-044, U.md section 4).
   U measured A8 inert, and the live sheet shows why: the ROWS were already
   released by A8, but the box containing them is pinned wide -
     .pricing55_plans                            width: 100%
     @media (max-width:767px) .pricing55_plans   width: 75rem   (= 1200px)
   with .pricing55_plans-wrapper{overflow:auto} taking the scroll. At 390px
   that is the 858px of wrapper scroll U measured. Releasing the box to 100%
   is what collapses it; U simulated 858 -> 0.
   Scoped to C's .w10x-c-spec-first container only, so the other four
   .pricing55_plans instances keep their intended horizontal-scroll table.
   Two classes (0,2,0) beats .pricing55_plans (0,1,0) and the <=767 rule.
   Written exactly as the head specified.
   -------------------------------------------------------------------------- */
@media (max-width:479px){.w10x-c-spec-first .pricing55_plans{width:100%}}

/* --------------------------------------------------------------------------
   A13 - the one regression U's sweep attributed to this scope (head D-057).
   A4 raised .text-small to 14px at <= 479px, which widened bare citation
   URLs inside .career-list-item past its 342px container on two industry
   pages. min-width:0 lets the flex/grid child shrink; overflow-wrap:anywhere
   breaks the unbroken URL token. Applied to the wrap AND its descendants
   because the long token sits in a child, not the wrap itself.
   Verified in the live sheet (shared.a00f29807.css, 2026-09-15):
   .career-list-item is flex-flow:column at <= 479px and
   .text-wrap-feature-home-c is a flex column - neither declares min-width,
   so `auto` is the default that pins the track. U simulated the overflow
   to 0. Written exactly as the head specified.
   -------------------------------------------------------------------------- */
@media (max-width:479px){.career-list-item .text-wrap-feature-home-c, .career-list-item .text-wrap-feature-home-c *{min-width:0;overflow-wrap:anywhere}}

/* --------------------------------------------------------------------------
   A14 - un-crops the spec-sheet screenshot that A11 exposed (head D-057).
   The live sheet gives .image-wrap-column a FIXED height with
   overflow:hidden - 584px at base, 362px at <= 767px - so widening the
   column in A11 revealed a 33% vertical crop. Replacing the fixed height
   with the image's own ratio lets the box follow its width.
   CSS only: no image is replaced, resized or removed (D-003 holds).
   Two classes (0,2,0) beats .image-wrap-column (0,1,0) at every width,
   including the <= 767px override, so one rule covers all breakpoints -
   which is why the head scoped it without a media query.
   Written exactly as the head specified.
   -------------------------------------------------------------------------- */
.service-a-tabs-section .image-wrap-column{aspect-ratio:1440/843;height:auto}

/* --------------------------------------------------------------------------
   A15 - the booking-button avatar (head D-057). C2's combo
   .image-cover.w10x-c-btn-icon sizes the IMAGE to 49x36, but its wrap
   .book-button-avatar is 32px wide by icon-size--large (24px) with
   overflow:hidden - so the image overflowed its wrap and only 66.7% showed.
   Sizing the image to the wrap fixes it (U: 66.7% -> 100% visible).
   Specificity note: this selector and C2's combo are both two-class (0,2,0),
   so the tie breaks on source order and this stylesheet loads after the
   Webflow sheet. If C2 ever raises its own specificity this rule stops
   winning silently - the same failure mode as A8/A10.
   Written exactly as the head specified.
   -------------------------------------------------------------------------- */
.book-button-avatar > .w10x-c-btn-icon{width:100%;height:100%;object-fit:cover}
/* A17 - D-077 s3 r1 + D-101 s2: section.top-secton top spacing, <=991px.
   Head's strings verbatim. The class is the site's own misspelling
   ("top-secton"). (0,1,1) beats .top-secton and .section, both (0,1,0).
   Baseline --section-padding--large: 160px >767, 96px <=767.
   Net: 768-991 -60px; 480-767 +4px; <=479 -56px (companion, later in
   source, same specificity, wins at <=479).
   Reach, served staging #40 (150 URLs): 25 sections on 21 pages - 20 heroes
   plus 5 NON-hero sections (/about-us x4, the /laser-cleaning-systems case
   study). / , /fiber-laser-cutting and /fiber-laser-profile do NOT carry
   this class (hero-home-a/-b) and are untouched. See A.md s40.3. */
@media (max-width:991px){section.top-secton{padding-top:100px}}
@media (max-width:479px){section.top-secton{padding-top:96px}}
/* A18 - D-077 s3 r2 + D-101 s3: welding hero H1 48px/46px at <=991px
   (was <=767 in s39; 768 is the width U and W1-A measured failing).
   Selector read from the served page: section.section.top-secton >
   .main-container > .column-halves > div#w-node-_2a07f2e0-...-a5b096a7
   .content-column > h1.no-margins. Page-scoped: a5b096a7 is the tail of
   page id 697295bc93fc194ca5b096a7; 1 occurrence on
   /laser-welding-machines, 0 on the other 149 staged URLs.
   (1,0,1) beats the authored h1 (0,0,1): 64/60 >767, 44/44 <=767.
   Effect: 768-991 64/60 -> 48/46; <=767 44/44 -> 48/46. */
@media (max-width:991px){#w-node-_2a07f2e0-449e-195f-96df-4c668bc5d864-a5b096a7 h1{font-size:48px;line-height:46px}}
/* A19 - D-101 s4: mobile heroes text-first at <=991px.
   The authored sheet orders the hero TEXT column last at <=991
   ({order:9999} on page-scoped #w-node ids), so the hero image fills the
   first screen. This puts the IMAGE wrapper after it: 10000 > 9999, and
   > 0 where the text column carries no order. order only - no image is
   removed, resized or swapped (D-003).
   Hero only: :first-of-type = the first <section> child of <body>, which
   is the H1 hero on all 20 hero pages carrying section.top-secton and on
   none of the 5 non-hero ones. (0,4,1); no authored rule sets order on
   .image-wrap-column. If a page ever gains a <section> before its hero,
   this rule stops matching there and that hero stays image-first. */
@media (max-width:991px){section.top-secton:first-of-type .column-halves>.image-wrap-column{order:10000}}
/* A17 erratum (v10): the A17 comment above still says "<=479 -56px"; v9 shipped
   the ALT companion (D-107), so the net at <=479 is 0 (96px -> 96px). Comment only;
   the v9 bytes are kept verbatim so v10 starts with v9. */
/* A20 - D-129 s1: the GHL chat widget over Modal / Book. chat_widget_1_loader
   appends widgets.leadconnectorhq.com/loader.js, which renders a <chat-widget>
   custom element at runtime (not in the served HTML); G measured it above the
   modal (z 99999999 vs .modal-book 9999999) and covering the modal's submit
   (elementFromPoint = CHAT-WIDGET, #44). vx_form_attribution_fill 1.1.2 keeps
   html.w10x-a-modal-open present exactly while a .modal-book is displayed
   (computed, whichever path opened it). display:none on the host removes its
   whole shadow tree; !important beats an inline style the widget may set on
   its host. The widget returns when the modal closes. The legacy iframe form
   is the selector the site's /contact A2P block already uses. */
html.w10x-a-modal-open chat-widget,html.w10x-a-modal-open iframe[src*="leadconnectorhq.com/widget"]{display:none!important}
/* A21 - D-131: first-screen proof strip and CTA line (C's classes), served on
   /laser-welding-machines, /fiber-laser-cutting, /tube-profile-laser-cutting
   only. Structure read from the served pages: ul.w10x-c-proof-strip >
   li.text-small x4, then the SIBLING p.w10x-c-fs-cta.text-small ending in
   <a href="tel:+17789079796">. The tel link is not inside the strip, so the
   specified `.w10x-c-proof-strip a[href^="tel:"]` matches nothing; both
   selectors are kept. Tap target 44px tall at <=991 (touch widths; desktop
   untouched, like A1-A5). Type at <=479: 16px/24px (Size/Body 2 base, as A1).
   (0,1,3) beats A4's html body .text-small (0,1,2); the specified
   `.w10x-c-proof-strip *` (0,1,0) would lose to A4 and ship inert.
   Predicted from Geist advances read from the site's own TTF (content width
   = viewport - 48px; A9 gaps 8px/16px at <=479): strip 76 -> 120px at 360
   (3 -> 4 rows), 76 -> 88px at 390 and 430 (at 390 the third row fits with
   0.3px to spare - if rendering tips it, 120px); CTA line 40 -> 68px (2 lines,
   one of them 44px). Widest atom 305px (strip item 1) vs 312px at 360, so no
   horizontal overflow. */
@media (max-width:991px){.w10x-c-proof-strip a[href^="tel:"],.w10x-c-fs-cta a[href^="tel:"]{min-height:44px;display:inline-flex;align-items:center}}
@media (max-width:479px){html body .w10x-c-proof-strip li,html body p.w10x-c-fs-cta{font-size:16px;line-height:24px}}
