/* ============================================================
   FABBRUCCIO: BASE + SHARED PRIMITIVES (layer 2 of 3)

   Always enqueued, depends on fab-tokens.css.

   Everything here appears on EVERY surface and is therefore not a
   section. Sections (nav, hero, pdp, shop-grid...) live in their own
   conditionally-enqueued files and must not redefine anything here.

   CLASS NAMING, and why it is not beta2's
   ---------------------------------------
   The approved build uses bare utility names: .wrap, .card, .grid, .cta,
   .press, .more. Those cannot ship inside WordPress: .grid, .card and
   .press collide with core block classes, WooCommerce templates and the
   parent's utility layer. design-language/components.md is explicit that
   "what is contractual is the structure, the token bindings and the rules
   that must hold, not the literal class strings", so every beta2 class is
   carried over with a fab- prefix and the beta2 name is named in a comment
   beside it. The mapping is 1:1 and the CSS is otherwise the same CSS.

   Contents:
     1. Page base + reduced motion
     2. fab-wrap        · beta2 .wrap, the one container
     3. fab-page        · beta2 .page, the nav-height top pad
     4. fab-eyebrow     · beta2 .eyebrow, the only uppercase moment
     5. fab-reveal      · beta2 [data-reveal], the motion hook
     6. fab-cta         · beta2 .cta, the ONE primary button
     7. fab-opt         · beta2 secondary buttons (.sizes/.filters button)
     8. fab-more        · beta2 .more, the quiet entry link
     9. fab-rule-link   · beta2 inline hairline underline
    10. fab-stars       · beta2 .stars
    11. fab-news-line   · beta2 .news-line (footer + newsletter band)
    12. Core-button guard
    13. Legacy component shims (routes this pass does not own)
   ============================================================ */

/* 1. PAGE BASE ----------------------------------------------

   The parent already ships the reset (layout.css:8) and sets the body
   font from --font / --text-base, both of which fab-tokens.css has
   re-pointed at the brand. What is left is the things the parent has no
   opinion about: the brand's tracking, the 15px body size as built, and
   the antialiasing. Values from beta2 site.css:30-35. */
body {
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-body);
  font-weight: var(--fab-weight-regular);
  line-height: var(--fab-leading-body);
  letter-spacing: var(--fab-track-body);
  color: var(--fab-ink);
  background: var(--fab-ground);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* THE BASE LINK. beta2's reset is `a{color:inherit;text-decoration:none}`,
   and leaving it out is not harmless: theme.json's link element does not
   reach an <a> that only wraps an image, so the four press anchors computed
   to the UA's rgb(0, 0, 238). Nothing painted blue because the child is an
   <img>, but the focus ring and any text child would have. Inherit is also
   the right default for this system: a link is drawn with a hairline
   underline (.fab-rule-link), never with a colour. */
a {
  color: inherit;
  text-decoration: none;
}

/* Weight 500 on every heading, whatever route rendered it. theme.json
   re-declares all six levels (the parent sets h1 800 / h2-h3 700 /
   h4-h6 600 and anything not re-declared SURVIVES), and this is the
   belt-and-braces for markup carrying heading CLASSES rather than
   semantic h1-h6. There is no weight above 500 in this system. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--fab-font-sans);
  font-weight: var(--fab-weight-medium);
}

/* The wordmark sprite holder. The <symbol> is injected once per page at
   wp_body_open (see functions.php) so both the nav and the footer can
   <use> it and control its colour with currentColor from one asset. */
.fab-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

/* REDUCED MOTION, hard cut-offs. fab-tokens.css collapses the duration
   constants; this stops anything that is not driven by a constant.
   Verbatim from design-language/motion.md. No section may re-enable
   itself inside this query. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-fab-reveal] { opacity: 1; transform: none; }
}

/* 1b. THE MAIN ELEMENT ---------------------------------------

   Two jobs, and both are about making the classic and FSE paths agree.

   a) The parent gives .site-main up to 72px of padding-block
      (instawhew/assets/css/layout.css:139). Every Fabbruccio route owns
      its own vertical rhythm through the band scale, so that is zeroed.

   b) THE DOUBLE-GUTTER FIX. On an FSE route (/shop/, the PDP, cart, 404)
      WordPress wraps the page in .wp-site-blocks and the parent pays it
      `padding-inline: var(--gutter)` (layout.css:65). On a classic route
      (the front page, /contact/, search) that wrapper does not exist and
      nobody pays anything. Without this line, .fab-wrap would add its own
      gutter ON TOP of the wrapper's on FSE routes only, so the shop and
      the PDP would sit at ~136px of inset while the home page sat at 68,
      and the same design would measure differently on two routes.

      So main escapes the wrapper's padding, exactly and only when there
      is padding to escape, and .fab-wrap is then the single payer of the
      gutter on every route. --fab-chrome-bleed is defined ONLY on
      .wp-site-blocks (fab-tokens.css section 5) and falls back to 0px,
      which is what makes it conditional. NO 100vw, ever. */
.fab-main {
  padding-block: 0;
  margin-inline: calc(-1 * var(--fab-chrome-bleed, 0px));
}

/* 2. THE CONTAINER (beta2 .wrap) ----------------------------
   ONE container in the built system: 1360px, gutter-padded. It never
   uses a negative margin to escape a parent gutter; the sections that
   genuinely need to bleed read --fab-chrome-bleed instead. */
/* NORMAL FLOW, RECLAIMED FROM Automatic.css
   ------------------------------------------------------------
   ACSS (the utility framework left over from the Bricks build, still an
   active plugin on www) ships these two opinionated defaults:

     section:where(:not(.bricks-shape-divider))       { display:flex; flex-direction:column }
     section > div:where(:not(.bricks-shape-divider)) { display:flex }

   Every band in this theme is a <section> whose first child is
   div.fab-wrap, so on that site the wrap became a horizontal FLEX
   container and each grid inside it shrank to content width instead of
   filling the column. Measured on www: .fab-grid was 402px inside a
   1360px wrap, against 1224px on staging. The cards looked like
   thumbnails and the page read as "everything is tiny".

   `:where()` contributes ZERO specificity, so those rules are effectively
   `section` (0,0,1) and `section > div` (0,0,2). A single class selector
   beats both, which is why this needs no `!important`. Declared
   explicitly rather than left to chance, so the theme renders the same
   whether or not ACSS is present. Components that genuinely want flex
   (.fab-sec-head, .fab-nav, .fab-assure) set it themselves further down
   the cascade and are unaffected. */
.fab-sec, .fab-story, .fab-press, .fab-clips, .fab-macro,
.fab-faq, .fab-newsletter, .fab-crosssell, .fab-editorial, .fab-hero {
  display: block;
}

.fab-wrap {
  display: block;
  width: 100%;
  max-width: var(--fab-wrap);
  margin-inline: auto;
  padding-inline: var(--fab-gutter);
}
.fab-wrap--narrow { max-width: var(--fab-wrap-narrow); }

/* 3. PAGE TOP PAD (beta2 .page) -----------------------------
   beta2's .page pays `calc(nav-height + clamp(18px,4vw,44px))` because
   the static site had no spacer element. Here .fab-nav__spacer already
   pays the nav's height (see fab-nav.css, and it is the proven fix for
   the parent's unconditional full-bleed escape), so this pays ONLY the
   breathing room on top of it. Adding the nav height again here is the
   obvious mistake and it would show as a 62px hole under the bar. */
.fab-page { padding-top: clamp(18px, 4vw, 44px); }

/* 4. EYEBROW (beta2 .eyebrow) -------------------------------
   The only uppercase moment in the system. Names a section without
   adding a heading level. .66rem, .2em tracking, weight 500, secondary
   ink. Sentence case everywhere else: uppercase is for micro-labels
   only, never for a heading and never for body copy. */
.fab-eyebrow {
  display: block;
  margin: 0;
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-label);
  font-weight: var(--fab-weight-medium);
  letter-spacing: var(--fab-track-eyebrow);
  line-height: 1.4;
  text-transform: uppercase;
  color: var(--fab-ink-secondary);
}

/* 5. REVEAL-AND-STAGGER (beta2 [data-reveal]) ---------------

   One shared IntersectionObserver adds .is-in as an element enters view,
   then unobserves it. Reveal-once, never re-hidden. CSS runs the motion,
   JS only toggles the class. Constants from design-language/motion.md:
   22px travel, .6s on both properties, the house curve, 70ms stagger off
   --fab-i.

   THE .fab-js GATE IS LOAD-BEARING. The hidden state is scoped to
   html.fab-js, and that class is set by a one-line inline script in
   wp_head (functions.php). With JavaScript switched off entirely the
   class is never added, so this rule never matches and the content is
   simply visible. Without the gate, a reader with JS off, or with a JS
   error anywhere above the observer, would get permanently invisible
   sections: CSS would have hidden content that only JS could reveal.
   Same reasoning the previous build used, achieved without the flash of
   unstyled content that arming from a deferred script causes. */
.fab-js [data-fab-reveal] {
  opacity: 0;
  transform: translateY(var(--fab-reveal-distance));
  transition: opacity var(--fab-reveal-duration) var(--fab-ease),
              transform var(--fab-reveal-duration) var(--fab-ease);
  transition-delay: calc(var(--fab-i, 0) * var(--fab-reveal-stagger));
}
.fab-js [data-fab-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* 6. THE PRIMARY BUTTON (beta2 .cta) ------------------------

   The single colour moment on a page: the add-to-bag CTA and nothing
   else by default. AT MOST ONE OF THESE IN A VIEWPORT. Two oxblood fills
   on one screen breaks the one-accent-mark rule.

   Background AND border are both oxblood, so the button has a defined
   edge that survives on any ground. :disabled keeps opacity 1 on
   purpose: the disabled state is the CONFIRMATION state ("In your bag,
   US 8") and must stay fully legible, not dimmed. */
.fab-cta {
  display: block;
  width: 100%;
  margin: 0;
  padding: 17px;
  border: 1px solid var(--fab-accent-oxblood);
  border-radius: var(--fab-radius);
  background: var(--fab-accent-oxblood);
  color: var(--fab-accent-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-compact);
  font-weight: var(--fab-weight-medium);
  /* `normal`, NOT a number. instawhew/assets/css/layout.css:11 sets
     `input, button, textarea, select { font: inherit }`, which drags the
     body's 1.62 leading onto every button. beta2's buttons never inherit a
     line-height, so they sit at the UA's `normal`, and the difference is
     visible: at 1.2 this button measured 52.5px against beta2's 54, and the
     size cells 42.5 against 44. Restating `normal` is how the UA value is
     reached once the parent has taken it away. */
  line-height: normal;
  letter-spacing: var(--fab-track-cta);
  text-align: center;
  text-decoration: none;
  box-shadow: none;
  cursor: pointer;
  transition: background var(--fab-hover-duration) var(--fab-ease),
              border-color var(--fab-hover-duration) var(--fab-ease);
}
.fab-cta:hover,
.fab-cta:focus-visible {
  background: var(--fab-accent-pressed);
  border-color: var(--fab-accent-pressed);
  color: var(--fab-accent-ink);
}
.fab-cta:focus-visible { outline: 2px solid var(--fab-ink); outline-offset: 2px; }
.fab-cta:disabled { opacity: 1; cursor: default; }

/* 7. THE SECONDARY BUTTON (beta2 .sizes button) -------------

   Selection and quiet actions. Transparent, 1px hairline, ink text,
   radius 0. Hover takes the border to ink: no fill, no lift, no shadow.
   The SELECTED state is INK, not oxblood, because oxblood is reserved
   for the CTA. */
.fab-opt {
  padding: 12px 4px;
  border: 1px solid var(--fab-hairline);
  border-radius: var(--fab-radius);
  background: transparent;
  color: var(--fab-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-compact);
  font-weight: var(--fab-weight-regular);
  line-height: normal; /* see the note on .fab-cta */
  box-shadow: none;
  cursor: pointer;
  transition: border-color var(--fab-hover-duration) var(--fab-ease),
              background var(--fab-hover-duration) var(--fab-ease),
              color var(--fab-hover-duration) var(--fab-ease);
}
.fab-opt:hover { border-color: var(--fab-ink); }
.fab-opt:focus-visible { outline: 2px solid var(--fab-ink); outline-offset: 2px; }
.fab-opt.is-selected {
  background: var(--fab-ink);
  border-color: var(--fab-ink);
  color: var(--fab-ground);
}

/* 8. THE QUIET ENTRY LINK (beta2 .more) ---------------------
   Reused everywhere a section hands off to another page. */
.fab-more {
  display: inline-block;
  padding-bottom: 3px;
  border-bottom: 1px solid var(--fab-ink);
  color: var(--fab-ink);
  font-size: var(--fab-size-caption);
  letter-spacing: var(--fab-track-upper);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity var(--fab-hover-duration) var(--fab-ease);
}
.fab-more:hover { opacity: .6; }

/* 9. THE INLINE HAIRLINE LINK -------------------------------
   How every inline link in the system is drawn: hairline at rest, ink on
   hover, 1px of padding under the text. This is the only link decoration
   there is. There is no underline-on-hover and no colour change. */
.fab-rule-link {
  padding-bottom: 1px;
  border-bottom: 1px solid var(--fab-hairline);
  color: inherit;
  letter-spacing: var(--fab-track-link-underline);
  text-decoration: none;
  transition: border-color var(--fab-hover-duration) var(--fab-ease),
              color var(--fab-hover-duration) var(--fab-ease);
}
.fab-rule-link:hover {
  border-color: var(--fab-ink);
  color: var(--fab-ink);
}

/* 10. STARS (beta2 .stars) ----------------------------------
   A text glyph run, ink, aria-hidden. The accessible rating is always
   the sentence next to it, never a graphic badge and never a seal. */
.fab-stars {
  color: var(--fab-ink);
  font-size: .8rem;
  letter-spacing: 1px;
}

/* 11. THE NEWSLETTER LINE (beta2 .news-line) ----------------
   One primitive, two placements: the quiet newsletter band and the
   footer column. The input has NO box: transparent, no border except a
   hairline underneath, going to ink on focus. The submit is a
   bottom-ruled uppercase micro-label with no box at all. */
.fab-news-line {
  display: flex;
  gap: var(--fab-space-xs);
  max-width: 320px;
}
.fab-news-line__input {
  flex: 1;
  min-width: 0;
  padding: 8px 2px;
  border: 0;
  border-bottom: 1px solid var(--fab-hairline);
  border-radius: 0;
  background: transparent;
  color: var(--fab-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-compact);
  /* `normal`, for the reason spelled out on .fab-cta: the parent forces
     `font: inherit` on inputs and buttons (layout.css:11), which drags the
     body's 1.62 leading in, and beta2's field sits at the UA's normal. */
  line-height: normal;
  box-shadow: none;
}
.fab-news-line__input::placeholder { color: var(--fab-ink-secondary); opacity: 1; }
.fab-news-line__input:focus {
  outline: 0;
  border-color: var(--fab-ink);
}
.fab-news-line__submit {
  padding: 8px 2px;
  border: 0;
  border-bottom: 1px solid var(--fab-ink);
  border-radius: 0;
  background: none;
  color: var(--fab-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-caption);
  font-weight: var(--fab-weight-regular);
  line-height: normal; /* see .fab-cta */
  letter-spacing: var(--fab-track-upper-news);
  text-transform: uppercase;
  box-shadow: none;
  cursor: pointer;
  white-space: nowrap;
}
.fab-news-line__submit:hover { opacity: .7; }
.fab-news-line__note {
  margin: 10px 0 0;
  font-size: var(--fab-size-detail);
  color: var(--fab-ink-secondary);
}
/* The honeypot. Hidden here rather than with an inline style or
   type="hidden": a bot fills what it can see in the markup, and a
   type=hidden field is exactly what it skips. Kept in the layout at zero
   size rather than display:none, because some bots do read computed
   styles, and out of the a11y tree via aria-hidden in the markup. */
.fab-news-line__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* The screen-reader-only label. The parent may or may not ship this class
   depending on which stylesheet a route loads, so the child declares it:
   an unstyled .screen-reader-text prints a visible stray "Your email"
   above the newsletter input. */
.screen-reader-text {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* 12. CORE-BUTTON GUARD ------------------------------------

   Brand templates render their own .fab-cta / .fab-opt and carry no core
   button classes, so core's paint has nothing to match: that is the
   structural fix, done in the markup. This is the safety net for what we
   do not author by hand (an editor dropping a core Button block in, a
   pattern, a plugin).

   Two failure modes are closed:

   a) THE PAINTED WRAPPER. A wrapper is layout, never paint. Any
      background, border or radius on .wp-block-button is stripped
      unconditionally.

   b) CORE'S #32373c PILL. Core ships
      `:where(.wp-block-button__link){background-color:#32373c;
      border-radius:9999px}`. :where() has ZERO specificity, so any real
      selector beats it. theme.json now declares styles.elements.button,
      so core emits the brand values instead of that hex in the first
      place; this rule is what stops any remaining default PAINTING.

   IT PAINTS THE SECONDARY BUTTON, NOT THE CTA, AND THAT IS DELIBERATE.
   The obvious move is to re-clothe a stray core button as .fab-cta, and
   it is wrong: oxblood is a MARK with a hard budget of one per viewport
   (design-language/rules.md section 2). A core button can appear
   anywhere, including next to the real add-to-bag CTA, and the moment
   two oxblood fills share a screen the accent has become a field. So an
   unknown button degrades to the hairline outline, which is always safe
   and never claims the accent moment. theme.json still declares the
   button element in oxblood, because that declaration governs buttons an
   editor DELIBERATELY places as the page's primary action. */
.wp-block-button,
.wp-block-buttons > .wp-block-button {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
}
.wp-block-button__link,
.wp-element-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 15px 26px;
  border: 1px solid var(--fab-hairline);
  border-radius: var(--fab-radius);
  background: transparent;
  color: var(--fab-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-compact);
  font-weight: var(--fab-weight-medium);
  line-height: 1.2;
  letter-spacing: var(--fab-track-cta);
  text-decoration: none;
  box-shadow: none;
  transition: border-color var(--fab-hover-duration) var(--fab-ease);
}
.wp-block-button__link:hover,
.wp-element-button:hover {
  border-color: var(--fab-ink);
  background: transparent;
  color: var(--fab-ink);
}

/* 13. LEGACY COMPONENT SHIMS ------------------------------

   The routes this pass does NOT own (cart, contact, search, 404,
   minicart, the calf pre-lander) paint through .fab-btn, .fab-container,
   .fab-section, .fab-section-head and .fab-textlink. Those class names
   are kept alive here and re-pointed at the beta2 system, for the same
   reason the token aliases exist in fab-tokens.css section 3: deleting
   the name would leave those pages with unstyled buttons and no
   container, and re-pointing it is how the serif display face and the
   gold accent are removed from files this pass does not rewrite.

   When a route is rebuilt to beta2 it should stop using these. When the
   last consumer is gone, delete this block. */
.fab-container {
  width: 100%;
  max-width: var(--fab-wrap);
  margin-inline: auto;
  padding-inline: var(--fab-gutter);
}
.fab-section { padding-block: var(--fab-band-md); }
.fab-surface--dark,
.fab-surface--muted { background: var(--fab-stage-grey); color: var(--fab-ink); }

.fab-section-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 20px 40px;
  margin-bottom: clamp(26px, 4vw, 46px);
}
.fab-section-head__title {
  margin: 0;
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-heading-s);
  font-weight: var(--fab-weight-medium);
  line-height: var(--fab-leading-heading);
  letter-spacing: var(--fab-track-heading-m);
}
/* The old design italicised a word inside a heading and coloured it
   gold. Both are gone: no gold, and no italic display type. */
.fab-section-head__title em { font-style: normal; color: inherit; }

.fab-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--fab-space-xs);
  margin: 0;
  padding: 15px 26px;
  border: 1px solid var(--fab-hairline);
  border-radius: var(--fab-radius);
  background: transparent;
  color: var(--fab-ink);
  font-family: var(--fab-font-sans);
  font-size: var(--fab-size-compact);
  font-weight: var(--fab-weight-medium);
  line-height: 1.2;
  letter-spacing: var(--fab-track-cta);
  text-transform: none;
  text-decoration: none;
  text-align: center;
  box-shadow: none;
  cursor: pointer;
  transition: background var(--fab-hover-duration) var(--fab-ease),
              color var(--fab-hover-duration) var(--fab-ease),
              border-color var(--fab-hover-duration) var(--fab-ease);
}
.fab-btn:focus-visible { outline: 2px solid var(--fab-ink); outline-offset: 3px; }
/* --solid keeps its job (the page's primary action on a legacy route) but
   in INK, not oxblood: those routes are not the buy box, and the accent
   budget belongs to the CTA. */
.fab-btn--solid {
  background: var(--fab-ink);
  border-color: var(--fab-ink);
  color: var(--fab-ground);
}
.fab-btn--solid:hover {
  background: var(--fab-accent-pressed);
  border-color: var(--fab-accent-pressed);
  color: var(--fab-accent-ink);
}
.fab-btn--ghost {
  background: transparent;
  border-color: var(--fab-hairline);
  color: var(--fab-ink);
}
.fab-btn--ghost:hover { border-color: var(--fab-ink); background: transparent; }

/* --dark IS NOT A SECOND NAME FOR --ghost, WHICH IS WHAT IT USED TO BE.
   The two shared one rule and therefore one colour, ink, so --dark rendered
   ink type inside a hairline box. It is used in exactly one place: the buy
   button on the calf pre-lander's three .fab-calf-band--dark sections, whose
   background IS --fab-ink. Ink on ink. Measured contrast 1.00, on all three
   CTAs, at both widths: the page's only conversion action was invisible, and
   the hover made it worse by moving the border to ink as well.

   It never showed up in any audit because nothing reachable used it. The one
   template that does had no published page, so the variant shipped unrendered
   from the day it was written until that page went live.

   --dark is the INVERSE OF --solid, not a ghost: same job (the primary action
   in its band), same weight, on the opposite ground. Paper fill, ink type,
   and the hover lands on the same oxblood press state --solid uses, which is
   the accent doing the one thing the rules do allow it to do, marking the
   buy. The focus ring is restated because the base ring is ink and would be
   just as invisible on that band as the type was. */
.fab-btn--dark {
  background: var(--fab-on-dark);
  border-color: var(--fab-on-dark);
  color: var(--fab-dark);
}
.fab-btn--dark:hover {
  background: var(--fab-accent-pressed);
  border-color: var(--fab-accent-pressed);
  color: var(--fab-accent-ink);
}
.fab-btn--dark:focus-visible { outline-color: var(--fab-on-dark); }

.fab-textlink {
  color: var(--fab-ink);
  font-size: var(--fab-size-caption);
  letter-spacing: var(--fab-track-upper);
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid var(--fab-ink);
  padding-bottom: 3px;
  transition: opacity var(--fab-hover-duration) var(--fab-ease);
}
.fab-textlink:hover { opacity: .6; }
