/* =========================================================================
   SKP MATERIAL — SITEWIDE DESIGN SYSTEM
   v1 (2026-08-24)

   One normalization layer so every page reads as the same site.

   WHY THIS EXISTS
   A design-coherence audit across 14 product/tool pages found three
   divergent families sharing only a typeface:

     modern (5)   1354px content · hero photo · 18px cards · H1 60-70px
     mid    (4)   1180px content · no hero photo · 16px cards · H1 50px
     legacy (3)   1336px content · no cards · H1 78px
     outliers     tools hub/calculators (900px, off-palette lavender),
                  products directory (yellow buttons, 50px radius)

   The values below ARE the modern family's values, so this layer is a
   no-op on the five pages already correct and pulls the other nine onto
   the same grid, palette and type scale.

   LAYOUT CONTRACT (CLAUDE.md §Deployment UX defaults)
     1440 -> content ~1354px    1920 -> content 1600px CAPPED    390 -> ~354px
   Never flat padding: that lets content grow unbounded on wide screens.

   SPECIFICITY
   Deliberately moderate. Page-specific stylesheets that make an intentional,
   documented choice should still be able to win. This sets the floor, not a
   ceiling.
   ========================================================================= */

:root {
  /* ---- colour: one blue, one signal, a neutral ramp ---- */
  --skp-accent:        #0056A7;
  --skp-accent-dark:   #0f4c81;
  --skp-accent-wash:   rgba(0, 86, 167, 0.10);
  --skp-signal:        #FFCD57;   /* header quote CTA only — never body text */
  --skp-ink:           #102033;
  --skp-text:          #334155;
  --skp-muted:         #5b6b7d;
  --skp-surface:       #f2f5f8;
  --skp-surface-2:     #e9eff6;
  --skp-card:          #ffffff;
  --skp-line:          rgba(16, 32, 51, 0.10);
  --skp-shadow:        0 18px 42px rgba(15, 23, 42, 0.08);
  --skp-shadow-lift:   0 22px 50px rgba(16, 32, 51, 0.14);

  /* ---- geometry ---- */
  --skp-radius-card:   18px;
  --skp-radius-media:  20px;
  --skp-radius-pill:   999px;
  --skp-gutter:        max(18px, 3vw, calc((100vw - 1600px) / 2));
  --skp-inner-cap:     min(94%, 1600px);

  /* ---- type ---- */
  --skp-font:          "Barlow Semi Condensed", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --skp-h1:            clamp(2.4rem, 4.4vw, 3.9rem);
  --skp-h2:            clamp(1.7rem, 2.7vw, 2.5rem);
  --skp-h3:            clamp(1.15rem, 1.5vw, 1.4rem);
  --skp-body:          clamp(1rem, 1.08vw, 1.12rem);
  --skp-lede:          clamp(1.05rem, 1.32vw, 1.3rem);
}

/* =========================================================================
   1. CONTENT WIDTH — the single most visible inconsistency
   ========================================================================= */

/* Pattern A: pages that expose a real inner wrapper.
   `body` prefix + !important is required, not stylistic: four pages carry an
   inline <style> block inside post_content, which sits after this enqueued
   file in document order and therefore wins every specificity tie. !important
   is confined to the layout-critical properties so page stylesheets keep
   control of everything else. */
body .skp-product-page .skp-inner,
body .skp-resource-page .skp-resource-inner,
body .skp-section > .skp-inner,
body.page-id-2632 .skp-inner,
body.page-id-2397 .skp-inner,
body.page-id-2398 .skp-inner,
body.page-id-2399 .skp-inner {
  max-width: var(--skp-inner-cap) !important;
  width: 100% !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* Pattern B: Spectra/UAGB strips inner wrappers, so cap on the section via
   padding-inline. max() is mathematically equivalent to Pattern A: the 3vw
   arm holds a ~3% gutter up to 1700px, then the (100vw-1600px)/2 arm caps
   content at 1600px, and the 18px arm floors the mobile gutter. */
/* Scoped BY PAGE ID to the pages that genuinely have no inner wrapper.
   Applying this globally double-applied on pages that already cap via
   .skp-inner and widened industrial-pvc-curtains from 1354 to 1400 —
   a regression on a page that was already correct. */
body.page-id-1472 .entry-content > .wp-block-uagb-container.alignfull,
body.page-id-1738 .entry-content > .wp-block-uagb-container.alignfull,
body.page-id-1092 .entry-content > .wp-block-uagb-container.alignfull,
body.page-id-732  .entry-content > .wp-block-uagb-container.alignfull,
body.page-id-126  .entry-content > .wp-block-uagb-container.alignfull {
  padding-left: var(--skp-gutter) !important;
  padding-right: var(--skp-gutter) !important;
}

/* UAGB's own inner wrapper must then fill, not re-cap. */
.entry-content > .wp-block-uagb-container.alignfull > .uagb-container-inner-blocks-wrap {
  max-width: 100%;
  width: 100%;
}

/* =========================================================================
   2. TYPE SCALE — 38px to 78px H1s across the site collapsed to one ramp
   ========================================================================= */

.skp-product-page h1, .skp-resource-page h1, .tools-hero h1,
.skp-product-page h2, .skp-resource-page h2,
.skp-product-page h3, .skp-resource-page h3 {
  font-family: var(--skp-font);
  line-height: 1.1;
  letter-spacing: -0.015em;
}

body .skp-product-page h1,
body .skp-resource-page h1,
body .skp-hero h1,
body .entry-content > .wp-block-uagb-container h1 { font-size: var(--skp-h1) !important; font-weight: 700; }
.skp-product-page h2, .skp-resource-page h2 { font-size: var(--skp-h2); font-weight: 600; }
.skp-product-page h3, .skp-resource-page h3 { font-size: var(--skp-h3); font-weight: 600; }

.skp-product-page p, .skp-resource-page p { font-size: var(--skp-body); line-height: 1.68; }
.skp-product-page .skp-lede, .skp-resource-page .skp-lede {
  font-size: var(--skp-lede);
  line-height: 1.6;
  color: var(--skp-muted);
}

/* =========================================================================
   3. BUTTONS — pill everywhere, 48px touch target, explicit colour
   An implicit colour lets high-specificity theme link rules produce
   same-colour text on background. Verified failure; keep these explicit.
   ========================================================================= */

.skp-btn,
.skp-resource-cta,
.tools-cta-btn,
.uagb-buttons-repeater,
.wp-block-button__link {
  border-radius: var(--skp-radius-pill);
  min-height: 48px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease;
}

/* COLOUR IS NOT OWNED HERE — deliberately.
   Pages invert their button palette over dark heroes (white pill on navy).
   An earlier revision set `color: ... !important` without `background:
   !important`, so this file's text colour won while the page's background
   won — producing white-on-white on a live conversion CTA. The design system
   owns GEOMETRY and TYPE; each page owns its own contextual colour. */

/* =========================================================================
   4. CARDS & MEDIA — 8px/16px/0 radii unified to 18px, images to 20px
   ========================================================================= */

body .skp-card,
body .skp-resource-card,
body .skp-note,
body .skp-quote-box,
body .tools-dir-card,
body .tool-card,
body .skp-feature-grid > *,
body .skp-faq-grid > *,
body .wp-block-uagb-info-box {
  border-radius: var(--skp-radius-card) !important;
}
.skp-card,
.skp-resource-card,
.skp-note,
.skp-quote-box,
.tools-dir-card,
.tool-card {
  background: var(--skp-card);
  border: 1px solid var(--skp-line);
}

.skp-product-page figure img,
.skp-resource-page figure img,
.skp-product-page .wp-block-image img {
  border-radius: var(--skp-radius-media);
}

/* =========================================================================
   5. SECTION RHYTHM — vertical spacing was 48px to 96px arbitrarily
   ========================================================================= */

.skp-product-page .skp-section,
.skp-resource-page .skp-resource-section {
  padding-top: clamp(48px, 6vw, 88px);
  padding-bottom: clamp(48px, 6vw, 88px);
}

.skp-product-page .skp-soft,
.skp-resource-page .skp-soft,
.skp-section--tint { background: var(--skp-surface); }

/* =========================================================================
   6. ALIGNMENT — a heading and its lede must share a left edge
   Capping children individually (`> *`) makes each centre independently
   against the theme's auto margins, so they drift apart. Verified on the
   tools hub, where the H1 sat 40px right of its own lede.
   ========================================================================= */

.tools-hero > *,
.tools-section > *,
.tools-cta > * {
  margin-left: 0;
  margin-right: 0;
  max-width: 100%;
}

/* =========================================================================
   7. OVERFLOW GUARD — no page may scroll horizontally at any width
   ========================================================================= */

.skp-product-page,
.skp-resource-page { overflow-x: hidden; }

@media (max-width: 900px) {
  /* mobile keeps its own gutter; content must never touch the screen edge */
  .skp-product-page .skp-inner,
  .skp-resource-page .skp-resource-inner {
    width: calc(100% - 36px);
    max-width: calc(100% - 36px);
  }
  .skp-btn, .skp-resource-cta, .tools-cta-btn { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .skp-btn, .skp-card, .tools-dir-card, .wp-block-button__link { transition: none !important; }
  .skp-btn:hover, .skp-card:hover, .tools-dir-card:hover { transform: none !important; }
}


/* =========================================================================
   8. RESIDUAL OUTLIERS — traced individually, each with a distinct cause
   ========================================================================= */

/* (a) PIL family (car-wash, 500gsm, rolls, oem): .skp-inner already caps at
   min(94%,1600px), but its parent .skp-section carries 40px side padding, so
   the cap computes against 1360 not 1440 and lands at 1278 instead of 1354.
   The modern family's sections are horizontally flush and let the inner
   wrapper alone govern — match that. */
body .skp-product-page > .skp-section,
body .skp-product-page > .skp-quick-strip,
body .skp-product-page > .uagb-block-pil-hero {
  padding-left: 0 !important;
  padding-right: 0 !important;
}

/* (b) sound-barrier: content sits as a DIRECT child of <main> with no wrapper
   at all, so it runs the full 1440 with no gutter. Give the children the same
   cap the rest of the site gets from .skp-inner. */
body.page-id-1092 .skp-product-page > *,
body .skp-legacy-product > * {
  max-width: var(--skp-inner-cap) !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* (c) products directory: containers carry a flat 32px pad, which lets content
   grow unbounded on wide screens. Flat padding is exactly what the layout
   contract forbids — swap for the gutter formula so 1920 caps at 1600. */
body.page-id-732 .skp-product-page > .wp-block-uagb-container {
  padding-left: var(--skp-gutter) !important;
  padding-right: var(--skp-gutter) !important;
}

/* (d) directory CTA buttons sat at 50px — neither pill nor the family radius. */
body.page-id-732 .wp-block-button__link,
body.page-id-732 .uagb-buttons-repeater {
  border-radius: var(--skp-radius-pill) !important;
}

/* (e) pvc-tarpaulin H1 renders at 48px against the family's ~63px. It is the
   highest-impression commercial page and should not read as the smallest. */
body.page-id-126 .entry-content h1 {
  font-size: var(--skp-h1) !important;
  line-height: 1.1;
  letter-spacing: -0.015em;
}


/* =========================================================================
   9. ASTRA BREAKOUT — the wrapper must actually reach both viewport edges
   .entry-content is 1390 wide and centred, so a child set to width:100vw
   inherits its parent's left offset (25px) and runs 25px past the right
   edge, producing horizontal scroll. The negative margin pulls it back.
   Documented in CLAUDE.md; idempotent on pages that already have it.
   ========================================================================= */

body .skp-product-page,
body .skp-resource-page {
  width: 100vw !important;
  max-width: 100vw !important;
  margin-left: calc(50% - 50vw) !important;
  margin-right: calc(50% - 50vw) !important;
  overflow-x: hidden;
}


/* =========================================================================
   10. LEGACY PAGES — cap on the container, whatever its block class
   The legacy pages mark their wrapper .skp-legacy-product-page, which is a
   cleaner hook than a list of page IDs. Their UAGB containers are direct
   children of <main> (not .entry-content) and often lack .alignfull, so the
   earlier selectors missed them and content ran to 1816px at 1920 — an
   uncapped layout, which the contract forbids.
   ========================================================================= */

body .skp-legacy-product-page > .wp-block-uagb-container,
body .skp-legacy-product-page > .wp-block-group,
body .skp-legacy-product-page > section,
body .skp-products-directory > .wp-block-uagb-container {
  padding-left: var(--skp-gutter) !important;
  padding-right: var(--skp-gutter) !important;
}

/* their inner wrappers must fill, not re-cap against the padded box */
body .skp-legacy-product-page > .wp-block-uagb-container > .uagb-container-inner-blocks-wrap,
body .skp-products-directory > .wp-block-uagb-container > .uagb-container-inner-blocks-wrap {
  max-width: 100% !important;
  width: 100% !important;
}


/* =========================================================================
   11. CONTRAST FLOOR — a CTA must never fall below 3:1
   car-wash's hero secondary button renders dark blue (#0f4c81) on bright
   blue (#2563eb) at 2.83:1. Both values are the page's own; the pairing is
   simply wrong. Set the text white against that specific solid-blue fill —
   the smallest change that clears the floor without touching the palette.
   ========================================================================= */

body.page-id-2632 .skp-hero a.skp-btn-secondary,
body.page-id-2632 .skp-hero a.skp-btn-secondary:visited {
  color: #ffffff !important;
}


/* =========================================================================
   12. SITEWIDE SWEEP FIXES — from the 87-URL audit, 2026-08-24
   ========================================================================= */

/* (a) Header search overflow — FIXED, narrowly.
   Mechanism: .search-form is absolutely positioned and correctly collapses to
   18px, but its 198px <label> child spills right because the form is
   overflow:visible — producing ~174px of horizontal scroll on every page.
   Clip ONLY while collapsed, so Astra's slide-open still works. An earlier
   attempt set max-width on .search-form itself and broke the expand
   behaviour, taking overflow from 2 pages to 33. */

.ast-search-menu-icon.slide-search:not(.ast-dropdown-active):not(.ast-inline-search) .search-form {
  overflow: hidden;
}

/* superseded note kept for context:
   Two factory pages showed the header search field running past the right
   edge. Constraining .search-form with max-width/box-sizing interfered with
   Astra's collapse-and-expand behaviour and took overflow from 2 pages to 33.
   Reverted. This is theme chrome; it needs a fix inside the theme's own
   search widget, not a blanket override from the design system. */

/* (b) Flat side padding lets content grow unbounded with the viewport, which
   the layout contract forbids: /certifications/ used 80px and /about/ 60px,
   so /about/ still measured 1800px at a 1920 viewport. Swap both for the
   gutter formula so they cap at 1600 like everything else. */
body.page-id-2115 .entry-content > .wp-block-uagb-container,
body.page-id-2114 .entry-content > .wp-block-uagb-container,
body.page-id-912  .entry-content > .wp-block-uagb-container,
body.page-id-146  .entry-content > .wp-block-uagb-container {
  padding-left: var(--skp-gutter) !important;
  padding-right: var(--skp-gutter) !important;
}

/* (c) Factory pages capped their inner wrapper at 860px, well under the
   1354px the rest of the site uses at 1440. */
body.parent-pageid-146 .uagb-container-inner-blocks-wrap,
body[class*="factories"] .uagb-container-inner-blocks-wrap,
.skp-factory-page .uagb-container-inner-blocks-wrap {
  max-width: min(100%, 1600px) !important;
}

/* (d) /privacy-policy/ rendered its H1 at 32px against the site's ~63px.
   Legal pages keep a narrow reading measure, but the heading should still
   belong to the same type ramp. */
body.page-id-487 .entry-content h1,
body[class*="privacy"] .entry-content h1 {
  font-size: var(--skp-h1) !important;
  line-height: 1.1;
  letter-spacing: -0.015em;
}

/* NOTE — deliberately NOT normalized:
   · Resource-page paragraphs cap near 725px. That is a ~72-character reading
     measure on a 1354px container, which is correct typography. Widening
     prose to full container width would hurt legibility.
   · Blog posts sit at a uniform 982px article measure, internally consistent
     and appropriate for long-form reading.
   Coherence means consistent WITHIN a template family plus shared tokens
   across families — not one width for every page regardless of purpose. */


/* (e) Factory CHILD pages (/factories/<name>/) measured 1840px at a 1920
   viewport. WordPress adds `parent-pageid-912` to their body, which is a
   more durable hook than listing each child's ID. */
body.parent-pageid-912 .entry-content > .wp-block-uagb-container,
body.parent-pageid-912 .entry-content > .wp-block-group {
  padding-left: var(--skp-gutter) !important;
  padding-right: var(--skp-gutter) !important;
}
body.parent-pageid-912 .entry-content > .wp-block-uagb-container > .uagb-container-inner-blocks-wrap {
  max-width: 100% !important;
  width: 100% !important;
}

/* (f) /privacy-policy/ H1 renders at 32px. Its narrow measure is right for a
   legal page, but the heading should share the site's type ramp. Scoped to
   the heading only — the reading width is left alone deliberately. */
body.page-id-487 h1,
body.page-id-487 .entry-title {
  font-size: var(--skp-h1) !important;
  line-height: 1.1;
  letter-spacing: -0.015em;
}


/* =========================================================================
   13. CONTRAST FAILURES FOUND IN FUNCTIONAL AUDIT — 2026-08-24
   Both pre-existing, both genuinely unreadable, both on Alibaba CTAs.
   Fixing text colour only; the brand fill on each button is untouched.
   ========================================================================= */

/* /tools/ — white text on the yellow signal fill measured 1.49:1, effectively
   unreadable. Yellow is a light surface: it needs dark ink. The button carries
   only generic block classes, so scope by page id + href. */
/* Every button on the tools pages that takes the yellow signal fill needs
   dark ink. Yellow is a light surface; white on it measured 1.49:1 —
   effectively unreadable. Scoped to the tools pages so nothing else moves. */
body.page-id-2130 .wp-block-button.is-style-outline > a.wp-block-button__link,
body.page-id-2131 .wp-block-button.is-style-outline > a.wp-block-button__link,
body.page-id-2132 .wp-block-button.is-style-outline > a.wp-block-button__link,
body.page-id-2130 a.wp-block-button__link[href*="alibaba"],
body.page-id-2131 a.wp-block-button__link[href*="alibaba"],
body.page-id-2132 a.wp-block-button__link[href*="alibaba"] {
  color: var(--skp-ink) !important;
}

/* /resource/ secondary button — NO CHANGE, deliberately.
   An audit flagged it as 1.00:1 "invisible". Screenshot proved otherwise: it
   is a white outline button on a dark teal gradient and reads clearly. The
   checker could not resolve GRADIENT backgrounds and fell back to white,
   comparing white text against white. Fixing the tool, not the button. */

/* /contact-us/ — dark navy text on a deep-blue fill measured ~1.5:1.
   Deep blue is a dark surface: it needs white. */
body.page-id-1192 a[href*="alibaba"],
body.page-id-1192 .wp-block-button__link[href*="alibaba"] {
  color: #ffffff !important;
}


/* =========================================================================
   14. LINKS ON DARK RESOURCE BANDS — verified by screenshot, genuinely unreadable
   The closing CTA band on resource pages uses a dark navy gradient, but plain
   <a> elements inside it inherit the theme's link blue (#1d4ed8) — dark blue
   on dark navy, effectively invisible. Only bare links are affected; buttons
   with their own fill already read correctly.
   ========================================================================= */

/* The intended design is a YELLOW PILL with dark ink — ~11:1, perfectly
   readable. An earlier revision of this file set background:transparent here,
   which stripped the fill and left dark text on a dark gradient: invisible.
   That was self-inflicted. Re-assert the fill so the pill cannot be lost to
   another rule (or to RUCSS dropping part of the page stylesheet). */
body .skp-resource-page .skp-resource-cta {
  background: var(--skp-signal) !important;
  color: #0f172a !important;
  border: none;
}
body .skp-resource-page .skp-resource-cta:hover,
body .skp-resource-page .skp-resource-cta:focus-visible {
  background: #ffd97a !important;
}
