/**
 * ab-base.css — Art Binaire base layer for Impreza / WPBakery child themes
 *
 * Project-independent tokens and layout utilities. Nothing in here is
 * client-specific: no colours, no fonts, no component styles.
 *
 * INSTALL
 *   1. Drop this file in the child theme. Put it next to the theme's other
 *      assets rather than inventing a location: if the theme already has
 *      /assets/js, this belongs at /assets/css/ab-base.css. Older projects
 *      use a bare /css/ab-base.css. The snippet below probes both, so the
 *      same code works either way — do not hardcode one path.
 *   2. Enqueue it and push the child stylesheet behind it, so project
 *      rules win without !important:
 *
 *      add_action( 'wp_enqueue_scripts', function () {
 *          $dir = get_stylesheet_directory();
 *          $uri = get_stylesheet_directory_uri();
 *
 *          $rel = false;
 *          foreach ( array( '/assets/css/ab-base.css', '/css/ab-base.css',
 *                           '/ab-base.css' ) as $candidate ) {
 *              if ( file_exists( $dir . $candidate ) ) {
 *                  $rel = $candidate;
 *                  break;
 *              }
 *          }
 *          if ( ! $rel ) { return; }
 *
 *          $deps = wp_style_is( 'us-style', 'registered' )
 *              ? array( 'us-style' )
 *              : array();
 *
 *          wp_enqueue_style( 'ab-base', $uri . $rel, $deps,
 *              filemtime( $dir . $rel ) );
 *
 *          $styles = wp_styles();
 *          if ( isset( $styles->registered['theme-style'] )
 *              && ! in_array( 'ab-base', $styles->registered['theme-style']->deps, true ) ) {
 *              $styles->registered['theme-style']->deps[] = 'ab-base';
 *          }
 *      }, 20 );
 *
 *      Handles on Impreza are "us-style" (parent) and "theme-style"
 *      (child). wp_enqueue_style() prints nothing at all when a handle in
 *      $deps was never registered, so resolve them at runtime with
 *      wp_style_is() rather than guessing.
 *
 *      The file_exists() probe also means the site degrades quietly to
 *      "base layer absent" instead of printing a 404 <link> while the file
 *      is still being deployed.
 *
 *   3. Per project, override only what differs — usually just --grid-gutter
 *      and the radius scale — in the child theme's own :root block.
 *
 * NAMING
 *   Tokens:    --{category}-{modifier}     --fs-lg, --space-lg, --radius-lg
 *   Utilities: {scope}-{property}-{side}-{amount}
 *              col-pad-l-1, col-mar-x-0-5, col-bleed-r-2
 *   Fractions in class names use a hyphen for the decimal point: 0-5 = 0.5
 *
 * THE LAYER ABOVE THIS ONE
 *   This file is the part that is identical across projects BY VALUE. The project
 *   stylesheet on top of it is identical across projects BY NAME: same vocabulary,
 *   per-project values. A project's style.css is expected to define, at minimum:
 *
 *     roles       h2-style h3-style h4-style h5-style eyebrow handwriting-style
 *                 + the `is-accent` modifier.  Body copy gets NO class: set it in
 *                 Theme Options -> Typography -> Global Text and let it inherit.
 *     components  eyebrow-pill media-card quote-block check-list icon-card
 *                 step-item badge-row offer-panel section-mark image-band cta-band
 *
 *   Nothing here depends on those existing — the list is a contract so the next
 *   project starts with the same words instead of inventing `-lede`, `-title` and
 *   `-quote` classes per section. Full reasoning in the project file's header.
 *
 *   Two conventions that belong to that layer but are worth repeating here,
 *   because both are about beating Impreza rather than about taste:
 *     - compound the Impreza element class onto component/section classes
 *       (`.w-hwrapper.footer-offer-hwrapper`). The bare form is 0-1-0 and merely
 *       TIES with Impreza's own `.w-hwrapper`, winning on enqueue order alone.
 *       Role and utility classes are exempt — they must stay element-agnostic.
 *     - style a component's children through what Impreza emits (`.step-item h3`,
 *       `.media-card > .wpb_text_column`) instead of adding a class per child.
 *       That selector assumes the third convention: prose is authored as
 *       `vc_column_text` (real <p> in `.wpb_text_column`), not `us_text` (which
 *       holds its text in an attribute and suits single lines and headings).
 *
 * DEPENDS ON (provided by Impreza, do not redefine)
 *   --site-content-width, --color-content-*, --color-alt-content-*,
 *   --h1-font-size … --h6-text-transform
 *
 * CUSTOM GLOBAL COLORS — MIND THE SLUG → VARIABLE TRANSFORM
 *   Theme Options → Colors → Custom Global Colors DOES publish a real :root
 *   variable, usable from any hand-written rule. But the name is not the slug:
 *   underscores become hyphens, and the slug's forced leading underscore becomes
 *   the separator. Slug `_grey_lightest` is emitted as:
 *
 *       --color-grey-lightest        NOT --color_grey_lightest
 *
 *   Verified by counting :root custom properties before and after saving one
 *   colour: 195 → 196, the new one being --color-grey-lightest. The underscore
 *   form resolves to an empty string, so the declaration silently does nothing.
 *
 *   Name these by what the colour IS, matching the design system's own colour
 *   names — never by where it is used. `_grey_lightest`, not `_card_grey`.
 *
 *   Two related gotchas, same family, both verified here:
 *     - `_slug` tokens do NOT resolve inside the predefined Colors pickers —
 *       setting a picker to `_alt_content_primary` emits that string as a literal
 *       CSS value and breaks every rule reading the variable. Pickers take hex.
 *     - after any palette write, RELOAD before measuring. The page carries the
 *       generated CSS from its own render; checking a tab that was loaded before
 *       the write reports the old state and invites exactly the wrong conclusion.
 */

/* ============================================================
   1. TOKENS
   ============================================================ */

:root {
	/* ---- Grid ----------------------------------------------
	   --grid-gutter is the ONLY number to change per project.
	   It must equal 2 × the horizontal padding Impreza puts on
	   .vc_column-inner. Check the theme's actual output:
	     .g-cols.via_flex.type_default { margin: 0 -15px }   → 30px
	     .g-cols.via_flex.type_default { margin: 0 -10px }   → 20px
	   -------------------------------------------------------- */
	--grid-gutter: 30px;
	--grid-columns: 12;

	/* Width of one 1/12 grid unit, gutters excluded.
	   col = (content-width − 11 gutters) / 12
	   Equivalent to the older (W + g)/12 − g notation. */
	--col-width: calc(
		(var(--site-content-width) - (var(--grid-columns) - 1) * var(--grid-gutter))
		/ var(--grid-columns)
	);

	/* One column measured from column edge to column edge, i.e. including
	   the gutter that follows it. This is what you want when shifting an
	   element "one column over". */
	--col-step: calc(var(--col-width) + var(--grid-gutter));

	/* NOTE: --site-content-width is deliberately NOT declared here. Impreza
	   emits it inline, from Theme Options → Site Content Width, and that
	   inline block beats any :root in the child stylesheet. Redeclaring it in
	   a project file is dead code at best and, if it ever did win, a silent
	   miscalculation of every narrow-* / col-* utility — Impreza's value is
	   not the Theme Options number verbatim (measured on one build: 1260px
	   set, 1280px emitted). Read it, never write it. */

	/* ---- Spacing scale ----
	   Vertical rhythm and generic padding. Kept as a fixed px ramp on
	   purpose: fluid spacing makes section heights unpredictable when
	   rows are stacked. Use --space-fluid-* below when you do want it. */
	--space-3xs: 4px;
	--space-2xs: 8px;
	--space-xs: 12px;

	/* 16px earns its own step: 12 → 20 is a 1.67x jump, the widest in the fine
	   end of the ramp, and 16 is where component-level gaps keep landing (the
	   testimonial avatar gap, the header menu cell, the alt-background box).
	   Named `s` because the t-shirt sequence already skips it — 3xs, 2xs, xs,
	   then straight to sm — so it slots in without renumbering anything.
	   MIND THE ADJACENCY: --space-s is 16px, --space-sm is 20px. One letter,
	   4px. A typo here fails silently. */
	--space-s: 16px;

	--space-sm: 20px;
	--space-md: 30px;
	--space-lg: 40px;
	--space-xl: 50px;
	--space-2xl: 60px;
	--space-3xl: 80px;
	--space-4xl: 120px;

	/* ---- Section height ladder ----
	   The vertical padding behind a row's `height` param. Impreza hardcodes
	   these at 2 / 4 / 6 / 8rem on .l-section itself (0-2-0) with NO media
	   queries — the ladder is flat at every viewport. Exposing it as tokens
	   lets a project retune one step from :root instead of restating the
	   rule, and lets it go responsive by overriding the token in a media
	   query. Defaults reproduce Impreza exactly, so adopting this file
	   changes nothing until a project overrides a step.

	   Impreza sets its own precedent here: height_custom already reads
	   var(--section-custom-padding, 5vmax). */
	--section-pad-small: 2rem;
	--section-pad-medium: 4rem;
	--section-pad-large: 6rem;
	--section-pad-huge: 8rem;

	/* Fluid alternatives for section padding that should breathe with the
	   viewport. Floor is the mobile value, cap is the desktop value. */
	--space-fluid-md: clamp(20px, 1rem + 1.5vw, 30px);
	--space-fluid-lg: clamp(28px, 1.25rem + 2vw, 40px);
	--space-fluid-xl: clamp(32px, 1.5rem + 3vw, 60px);
	--space-fluid-2xl: clamp(40px, 2rem + 4vw, 80px);
	--space-fluid-3xl: clamp(48px, 2.5rem + 5vw, 120px);

	/* ---- Column bleed ----
	   Horizontal inset/outset steps expressed as fractions of the gutter,
	   so they stay in tune when --grid-gutter changes.
	   At a 30px gutter these resolve to 15 / 30 / 45 / 60 / 75px;
	   at 20px, to 10 / 20 / 30 / 40 / 50px.

	   Consumed by the t-shirt-scale `.col-extend-*` utilities. Mind the two
	   scales that share the `col-` prefix: a NUMBER means whole columns
	   (--col-step), a T-SHIRT SIZE means gutters (--col-bleed-*). So
	   `.col-extend-x-1` grows by a column and `.col-extend-x-md` by a
	   gutter. */
	--col-bleed-sm: calc(var(--grid-gutter) * 0.5);
	--col-bleed-md: calc(var(--grid-gutter) * 1);
	--col-bleed-lg: calc(var(--grid-gutter) * 1.5);
	--col-bleed-xl: calc(var(--grid-gutter) * 2);
	--col-bleed-2xl: calc(var(--grid-gutter) * 2.5);

	/* ---- Radius ---- */
	--radius-xs: 4px;
	--radius-sm: 8px;
	--radius-md: 12px;
	--radius-lg: 16px;
	--radius-xl: 24px;
	--radius-pill: 999px;
	--radius-circle: 50%;

	/* Semantic aliases — point these at the scale above per project rather
	   than hardcoding a px value at the call site. */
	--radius-img: var(--radius-md);
	--radius-box: var(--radius-sm);
	--radius-row: var(--radius-lg);

	/* ---- Small text sizes ----
	   Only sizes BELOW body copy live here. Everything from body upward is
	   owned by Theme Options → Typography (--h1-font-size … --h6-font-size)
	   and must not be duplicated.

	   NAMING TRAP: Impreza emits the body typography tokens UNPREFIXED. The full
	   set at `:root` is

	     --font-family  --font-size  --line-height  --font-weight
	     --bold-font-weight  --text-transform  --font-style  --letter-spacing

	   and the headings are the prefixed ones (`--h1-font-size`,
	   `--h3-line-height`, `--h5-letter-spacing`, `--h*-margin-bottom`,
	   `--h6-color`, …). There is NO `--body-font-size`: writing it produces the
	   guaranteed-invalid value, the declaration is dropped, and the element
	   silently inherits instead — which looks correct until the base moves.

	   THE LADDER HAS A DELIBERATE HOLE AT BODY SIZE. There is no `--fs-body` and
	   no `--fs-xl`, because `var(--font-size)` is already exactly that — Impreza
	   emits it from Theme Options → Typography → Global Text, and it is the one
	   value in this ladder the theme owns. A step here at 1rem would be a second
	   name for the same number, which is how two sources of truth start. When you
	   want body size, write `var(--font-size)`.

	   (An earlier version did define `--fs-xl: 1rem` and its own comment admitted
	   it was "the same 16px as var(--font-size), by construction". Do not put it
	   back.)

	   The steps run 11-12-13-14-15 below the hole and 17 above it, so `md` is one
	   step under body and `lg` one step over. Named by position relative to body,
	   which is what makes the names readable: `--fs-lg` is LARGER than body copy,
	   not "large for small text".

	   The ladder is in REM, not px, and that is the whole point: Impreza puts the
	   Global Text size on `html`, so the root em IS the body size. Every step is
	   therefore a ratio against body copy, and moving Global Text moves the entire
	   scale with it. Do NOT write px here — a px value silently stops tracking the
	   base.

	   Same reason the builder's own rem inputs (`inner_items_gap="1.6rem"`,
	   separator sizes) already scale: they are rem against that same root.

	   Sizes ABOVE `--fs-lg` are not in this ladder on purpose. Everything bigger
	   is either a heading (fluid clamp() in Theme Options) or a one-off display
	   treatment that belongs to its own component — a 135px step numeral is not a
	   scale step. Add `--fs-xl` only when a NON-heading size above 17px turns up
	   in two different components. */
	--fs-3xs: 0.6875rem;   /* 11px */
	--fs-2xs: 0.75rem;     /* 12px */
	--fs-xs: 0.8125rem;    /* 13px */
	--fs-sm: 0.875rem;     /* 14px */
	--fs-md: 0.9375rem;    /* 15px */
	/*        1rem            16px — var(--font-size), Theme Options owns it */
	--fs-lg: 1.0625rem;    /* 17px */

	/* ---- Elevation ---- */
	--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, .05);
	--shadow-md: 0 4px 4px 0 rgba(0, 0, 0, .07);
	--shadow-lg: 0 8px 24px 0 rgba(0, 0, 0, .10);

	/* ---- Misc ---- */
	--anchor-offset: 2rem;
	--transition-fast: .15s ease;
	--transition-base: .25s ease;

	/* Bold weight for <strong> inside body copy. Impreza exposes
	   --body-bold-font-weight; this alias exists because several older
	   projects referenced a bare --bold-font-weight that was never defined. */
	--bold-font-weight: var(--body-bold-font-weight, 700);
}

/* ============================================================
   2. GRID NORMALISATION
   ============================================================
   Impreza's flex grid needs its negative margin and the matching column
   padding to agree with --grid-gutter, or every column-fraction utility
   below drifts. This ties all three together.
   ------------------------------------------------------------ */

/* Contains right-side bleed so it cannot open a horizontal scrollbar.
   `clip` rather than `hidden`: hidden makes this a scroll container, and a
   scroll container between a sticky element and its scrollport kills
   position: sticky — which Impreza's sticky columns (.vc_column-inner
   .type_sticky) rely on. clip does the same visual job without that side
   effect. The hidden line stays as a fallback for Safari below 16. */
.l-canvas.type_wide {
	overflow-x: hidden;
	overflow-x: clip;
}

.g-cols.via_flex.type_default {
	margin-inline: calc(var(--grid-gutter) / -2);
}

/* Impreza pads a stretched column away from the viewport edge:
     .g-cols.via_flex.type_default > .wpb_column.stretched:first-of-type
       { margin-inline-start: calc(var(--margin-inline-stretch) + 1.5rem) }
   The `+ 1.5rem` leaves a seam between the screen edge and a full-bleed
   column — measured 2px on one build, because --margin-inline-stretch already
   overshoots by about that much and the 1.5rem claws it back. Dropping the
   addend lets the column run past the edge instead, where .l-canvas clips it.
   Same selector as the parent's, so it wins on load order rather than on a
   specificity arms race (both are 0-6-0). */
.g-cols.via_flex.type_default > .wpb_column.stretched:first-of-type {
	margin-inline-start: var(--margin-inline-stretch);
}

.g-cols.via_flex.type_default > .wpb_column.stretched:last-of-type {
	margin-inline-end: var(--margin-inline-stretch);
}

.g-cols.via_flex.type_default > div > .vc_column-inner {
	padding-inline: calc(var(--grid-gutter) / 2);
}

/* ============================================================
   3. WIDTH CONSTRAINTS
   ============================================================ */

/* ---- Narrow SECTION: constrains a vc_row's inner container ----
   A vc_row renders as .l-section, so this is a section-level constraint.
   Deliberately NOT called narrow-row-*: that would read as a sibling of
   narrow-inner-row-* below, which constrains a column inside a
   vc_row_inner — a different element at a different depth.
   Applied as el_class on the row itself. narrow-section-8 → 8 columns. */
.narrow-section-4 .l-section-h  { max-width: calc(var(--col-step) * 4  - var(--grid-gutter)); }
.narrow-section-5 .l-section-h  { max-width: calc(var(--col-step) * 5  - var(--grid-gutter)); }
.narrow-section-6 .l-section-h  { max-width: calc(var(--col-step) * 6  - var(--grid-gutter)); }
.narrow-section-7 .l-section-h  { max-width: calc(var(--col-step) * 7  - var(--grid-gutter)); }
.narrow-section-8 .l-section-h  { max-width: calc(var(--col-step) * 8  - var(--grid-gutter)); }
.narrow-section-9 .l-section-h  { max-width: calc(var(--col-step) * 9  - var(--grid-gutter)); }
.narrow-section-10 .l-section-h { max-width: calc(var(--col-step) * 10 - var(--grid-gutter)); }

/* Full-width rows need the constraint forced past Impreza's own rule. */
.width_full.narrow-section-6 .l-section-h  { max-width: calc(var(--col-step) * 6  - var(--grid-gutter)) !important; }
.width_full.narrow-section-8 .l-section-h  { max-width: calc(var(--col-step) * 8  - var(--grid-gutter)) !important; }
.width_full.narrow-section-10 .l-section-h { max-width: calc(var(--col-step) * 10 - var(--grid-gutter)) !important; }

/* ---- Narrow INNER ROW: constrains a vc_row_inner's columns ---- */
.narrow-inner-row-6 > .wpb_column,
.narrow-inner-row-8 > .wpb_column,
.narrow-inner-row-10 > .wpb_column {
	margin-inline: auto;
}

.narrow-inner-row-6 > .wpb_column  { max-width: calc(var(--col-step) * 6  - var(--grid-gutter)); }
.narrow-inner-row-8 > .wpb_column  { max-width: calc(var(--col-step) * 8  - var(--grid-gutter)); }
.narrow-inner-row-10 > .wpb_column { max-width: calc(var(--col-step) * 10 - var(--grid-gutter)); }

/* ---- Narrow ELEMENT: constrains any single element, centred ---- */
.narrow-el-4,
.narrow-el-5,
.narrow-el-6,
.narrow-el-7,
.narrow-el-8,
.narrow-el-9,
.narrow-el-10 {
	margin-inline: auto;
}

.narrow-el-4  { max-width: calc(var(--col-step) * 4  - var(--grid-gutter)); }
.narrow-el-5  { max-width: calc(var(--col-step) * 5  - var(--grid-gutter)); }
.narrow-el-6  { max-width: calc(var(--col-step) * 6  - var(--grid-gutter)); }
.narrow-el-7  { max-width: calc(var(--col-step) * 7  - var(--grid-gutter)); }
.narrow-el-8  { max-width: calc(var(--col-step) * 8  - var(--grid-gutter)); }
.narrow-el-9  { max-width: calc(var(--col-step) * 9  - var(--grid-gutter)); }
.narrow-el-10 { max-width: calc(var(--col-step) * 10 - var(--grid-gutter)); }

/* Left/right aligned variants — same width, no auto-centring. */
.narrow-el-4.align-l,  .narrow-el-5.align-l,  .narrow-el-6.align-l,
.narrow-el-7.align-l,  .narrow-el-8.align-l,  .narrow-el-9.align-l,
.narrow-el-10.align-l { margin-inline: 0 auto; }

.narrow-el-4.align-r,  .narrow-el-5.align-r,  .narrow-el-6.align-r,
.narrow-el-7.align-r,  .narrow-el-8.align-r,  .narrow-el-9.align-r,
.narrow-el-10.align-r { margin-inline: auto 0; }

/* ============================================================
   4. COLUMN-FRACTION SPACING
   ============================================================
   Push content inward (pad), move the box itself (mar), or pull it
   outward past its container (bleed) — always by whole grid columns,
   so an element optically lines up with the column above it.

   Pattern: col-{pad|mar|bleed}-{l|r|x}-{columns}
   Fractions: 0-5 = half a column.
   ------------------------------------------------------------ */

/* ---- Padding, GUTTER scale ----
   The t-shirt half of the convention stated in the tokens block: number =
   columns, t-shirt = gutters. `col-pad-l-md` indents by exactly one gutter,
   which is the size most "nudge this column off its neighbour" moments want —
   a whole column (`col-pad-l-1`) is far too much for that job.

   Neutralised at ≤1024 by the `[class*="col-pad-l-"]` reset at the bottom of
   this file, so these are desktop-only without needing their own media query. */
.col-pad-l-sm { padding-left: var(--col-bleed-sm); }
.col-pad-r-sm { padding-right: var(--col-bleed-sm); }
.col-pad-x-sm { padding-inline: var(--col-bleed-sm); }

.col-pad-l-md { padding-left: var(--col-bleed-md); }
.col-pad-r-md { padding-right: var(--col-bleed-md); }
.col-pad-x-md { padding-inline: var(--col-bleed-md); }

.col-pad-l-lg { padding-left: var(--col-bleed-lg); }
.col-pad-r-lg { padding-right: var(--col-bleed-lg); }
.col-pad-x-lg { padding-inline: var(--col-bleed-lg); }

.col-pad-l-xl { padding-left: var(--col-bleed-xl); }
.col-pad-r-xl { padding-right: var(--col-bleed-xl); }
.col-pad-x-xl { padding-inline: var(--col-bleed-xl); }

.col-pad-l-2xl { padding-left: var(--col-bleed-2xl); }
.col-pad-r-2xl { padding-right: var(--col-bleed-2xl); }
.col-pad-x-2xl { padding-inline: var(--col-bleed-2xl); }

/* ---- Padding, COLUMN scale ---- */
.col-pad-l-0-5 { padding-left: calc(var(--col-step) * 0.5); }
.col-pad-r-0-5 { padding-right: calc(var(--col-step) * 0.5); }
.col-pad-x-0-5 { padding-inline: calc(var(--col-step) * 0.5); }

.col-pad-l-1 { padding-left: var(--col-step); }
.col-pad-r-1 { padding-right: var(--col-step); }
.col-pad-x-1 { padding-inline: var(--col-step); }

.col-pad-l-1-5 { padding-left: calc(var(--col-step) * 1.5); }
.col-pad-r-1-5 { padding-right: calc(var(--col-step) * 1.5); }
.col-pad-x-1-5 { padding-inline: calc(var(--col-step) * 1.5); }

.col-pad-l-2 { padding-left: calc(var(--col-step) * 2); }
.col-pad-r-2 { padding-right: calc(var(--col-step) * 2); }
.col-pad-x-2 { padding-inline: calc(var(--col-step) * 2); }

.col-pad-l-3 { padding-left: calc(var(--col-step) * 3); }
.col-pad-r-3 { padding-right: calc(var(--col-step) * 3); }
.col-pad-x-3 { padding-inline: calc(var(--col-step) * 3); }

/* ---- Margin ---- */
.col-mar-l-0-5 { margin-left: calc(var(--col-step) * 0.5); }
.col-mar-r-0-5 { margin-right: calc(var(--col-step) * 0.5); }
.col-mar-x-0-5 { margin-inline: calc(var(--col-step) * 0.5); }

.col-mar-l-1 { margin-left: var(--col-step); }
.col-mar-r-1 { margin-right: var(--col-step); }
.col-mar-x-1 { margin-inline: var(--col-step); }

.col-mar-l-1-5 { margin-left: calc(var(--col-step) * 1.5); }
.col-mar-r-1-5 { margin-right: calc(var(--col-step) * 1.5); }
.col-mar-x-1-5 { margin-inline: calc(var(--col-step) * 1.5); }

.col-mar-l-2 { margin-left: calc(var(--col-step) * 2); }
.col-mar-r-2 { margin-right: calc(var(--col-step) * 2); }
.col-mar-x-2 { margin-inline: calc(var(--col-step) * 2); }

.col-mar-l-3 { margin-left: calc(var(--col-step) * 3); }
.col-mar-r-3 { margin-right: calc(var(--col-step) * 3); }
.col-mar-x-3 { margin-inline: calc(var(--col-step) * 3); }

/* ---- Bleed, GUTTER scale ----
   The t-shirt half of the bleed scale, mirroring the padding scale above.
   `col-bleed-l-sm` pulls an element out by exactly half a gutter, which is the
   distance from a column's CONTENT edge to its BOX edge — i.e. what you want
   when a panel inside a column should reach the column's edge rather than sit
   inside its gutter. A whole column (`col-bleed-l-1`) is a different job.

   Neutralised at <=1024 by the `[class*="col-bleed-"]` reset at the foot of this
   file, like the rest of the grid utilities. */
.col-bleed-l-sm { margin-left: calc(var(--col-bleed-sm) * -1); }
.col-bleed-r-sm { margin-right: calc(var(--col-bleed-sm) * -1); }
.col-bleed-x-sm { margin-inline: calc(var(--col-bleed-sm) * -1); }

.col-bleed-l-md { margin-left: calc(var(--col-bleed-md) * -1); }
.col-bleed-r-md { margin-right: calc(var(--col-bleed-md) * -1); }
.col-bleed-x-md { margin-inline: calc(var(--col-bleed-md) * -1); }

.col-bleed-l-lg { margin-left: calc(var(--col-bleed-lg) * -1); }
.col-bleed-r-lg { margin-right: calc(var(--col-bleed-lg) * -1); }
.col-bleed-x-lg { margin-inline: calc(var(--col-bleed-lg) * -1); }

.col-bleed-l-xl { margin-left: calc(var(--col-bleed-xl) * -1); }
.col-bleed-r-xl { margin-right: calc(var(--col-bleed-xl) * -1); }
.col-bleed-x-xl { margin-inline: calc(var(--col-bleed-xl) * -1); }

.col-bleed-l-2xl { margin-left: calc(var(--col-bleed-2xl) * -1); }
.col-bleed-r-2xl { margin-right: calc(var(--col-bleed-2xl) * -1); }
.col-bleed-x-2xl { margin-inline: calc(var(--col-bleed-2xl) * -1); }

/* ---- Bleed, COLUMN scale ----
   Negative margin. Pair with overflow-x:hidden on .l-canvas (set above)
   so a right-side bleed cannot create a horizontal scrollbar. */
.col-bleed-l-0-5 { margin-left: calc(var(--col-step) * -0.5); }
.col-bleed-r-0-5 { margin-right: calc(var(--col-step) * -0.5); }
.col-bleed-x-0-5 { margin-inline: calc(var(--col-step) * -0.5); }

.col-bleed-l-1 { margin-left: calc(var(--col-step) * -1); }
.col-bleed-r-1 { margin-right: calc(var(--col-step) * -1); }
.col-bleed-x-1 { margin-inline: calc(var(--col-step) * -1); }

.col-bleed-l-1-5 { margin-left: calc(var(--col-step) * -1.5); }
.col-bleed-r-1-5 { margin-right: calc(var(--col-step) * -1.5); }
.col-bleed-x-1-5 { margin-inline: calc(var(--col-step) * -1.5); }

.col-bleed-l-2 { margin-left: calc(var(--col-step) * -2); }
.col-bleed-r-2 { margin-right: calc(var(--col-step) * -2); }
.col-bleed-x-2 { margin-inline: calc(var(--col-step) * -2); }

/* Bleed all the way to the viewport edge, from inside a constrained row. */
.col-bleed-l-full {
	margin-left: calc((100vw - var(--site-content-width)) / -2);
}

.col-bleed-r-full {
	margin-right: calc((100vw - var(--site-content-width)) / -2);
}

.col-bleed-x-full {
	margin-inline: calc((100vw - var(--site-content-width)) / -2);
}

/* ---- Extend: grow the element by N columns on one side ----
   Unlike bleed, this also widens the box instead of only shifting it. */
.col-extend-l-1 {
	margin-left: calc(var(--col-step) * -1);
	width: calc(100% + var(--col-step));
	max-width: none;
}

.col-extend-r-1 {
	margin-right: calc(var(--col-step) * -1);
	width: calc(100% + var(--col-step));
	max-width: none;
}

.col-extend-x-1 {
	margin-inline: calc(var(--col-step) * -1);
	width: calc(100% + var(--col-step) * 2);
	max-width: none;
}

.col-extend-l-2 {
	margin-left: calc(var(--col-step) * -2);
	width: calc(100% + var(--col-step) * 2);
	max-width: none;
}

.col-extend-r-2 {
	margin-right: calc(var(--col-step) * -2);
	width: calc(100% + var(--col-step) * 2);
	max-width: none;
}

/* ---- Extend by GUTTERS instead of columns ----
   The steps above move an element by whole columns; these nudge it out by a
   fraction of the gutter, which is the size most "let this panel breathe past
   its column" moments actually need.

   These target `> .vc_column-inner`, unlike the numeric steps, because they
   are meant for a WPBakery COLUMN: the percentage width lives on .wpb_column
   (via vc_col-sm-*), so growing that element fights the grid — the inner box
   is the one that can safely widen. On a plain element, use the numeric steps
   or a max-width calc instead.

   Scale reminder: number = columns, t-shirt = gutters. */
.col-extend-r-sm > .vc_column-inner { width: calc(100% + var(--col-bleed-sm)); }
.col-extend-r-md > .vc_column-inner { width: calc(100% + var(--col-bleed-md)); }
.col-extend-r-lg > .vc_column-inner { width: calc(100% + var(--col-bleed-lg)); }
.col-extend-r-xl > .vc_column-inner { width: calc(100% + var(--col-bleed-xl)); }
.col-extend-r-2xl > .vc_column-inner { width: calc(100% + var(--col-bleed-2xl)); }

.col-extend-l-sm > .vc_column-inner {
	width: calc(100% + var(--col-bleed-sm));
	margin-left: calc(var(--col-bleed-sm) * -1);
}

.col-extend-l-md > .vc_column-inner {
	width: calc(100% + var(--col-bleed-md));
	margin-left: calc(var(--col-bleed-md) * -1);
}

.col-extend-l-lg > .vc_column-inner {
	width: calc(100% + var(--col-bleed-lg));
	margin-left: calc(var(--col-bleed-lg) * -1);
}

.col-extend-l-xl > .vc_column-inner {
	width: calc(100% + var(--col-bleed-xl));
	margin-left: calc(var(--col-bleed-xl) * -1);
}

.col-extend-l-2xl > .vc_column-inner {
	width: calc(100% + var(--col-bleed-2xl));
	margin-left: calc(var(--col-bleed-2xl) * -1);
}

.col-extend-x-sm > .vc_column-inner {
	width: calc(100% + var(--col-bleed-sm) * 2);
	margin-left: calc(var(--col-bleed-sm) * -1);
}

.col-extend-x-md > .vc_column-inner {
	width: calc(100% + var(--col-bleed-md) * 2);
	margin-left: calc(var(--col-bleed-md) * -1);
}

.col-extend-x-lg > .vc_column-inner {
	width: calc(100% + var(--col-bleed-lg) * 2);
	margin-left: calc(var(--col-bleed-lg) * -1);
}

.col-extend-x-xl > .vc_column-inner {
	width: calc(100% + var(--col-bleed-xl) * 2);
	margin-left: calc(var(--col-bleed-xl) * -1);
}

.col-extend-x-2xl > .vc_column-inner {
	width: calc(100% + var(--col-bleed-2xl) * 2);
	margin-left: calc(var(--col-bleed-2xl) * -1);
}

/* ---- Close the gutter entirely: flush columns ----
   For rows whose columns must TOUCH — split panels, a photo half against a
   copy half, a video beside stacked cards. Goes on the ROW, not the columns.

   Do NOT reach for `.col-extend-*` to do this. Extending each column by half a
   gutter widens the inner box but leaves its padding in place, so the CONTENT
   box moves while the PADDING box does not. Anything in flow follows the
   content box; anything absolutely positioned (a filled video, an overlay)
   resolves against the padding box, and the two desync by half a gutter. Worse,
   `aspect-ratio` on the inner then measures the padded box, so the band comes
   out ~30px taller than the design (measured: 968.8px against the correct
   939.3px). Removing the gutter instead makes padding box == content box and
   every child, in flow or not, lands on the same edges.

   Impreza builds the gutter from a negative margin on the row plus matching
   padding on each `.vc_column-inner`, so both halves have to go. The selectors
   carry `.g-cols.via_flex.type_default` because that is the specificity of the
   rules being undone (0-3-0 and 0-4-1) — the plain class form silently loses.

   A deliberate per-column indent still wins: scope it to the row's own class
   (`.g-cols.via_flex.type_default.my-row > div.my-col > .vc_column-inner`,
   0-5-2) and it beats the 0-5-1 reset below.

   WARNING: do not combine with `stretch="1"` on a child column. Impreza derives
   the stretch bleed from the gutter, so with the gutter gone the maths breaks
   and the column overshoots the viewport (measured once at 266px). Use one or
   the other — a flush row does not need stretch, since its outer edges already
   sit on the container edges. */
.g-cols.via_flex.type_default.cols-flush {
	margin-inline: 0;
}

.g-cols.via_flex.type_default.cols-flush > .wpb_column > .vc_column-inner {
	padding-inline: 0;
}

/* ---- Icon-only button ----
   For a button whose design is just the icon. The label STAYS in the DOM — an
   unlabelled link is not navigable by a screen reader, and `display: none` /
   `visibility: hidden` would drop it out of the accessibility tree — so it is
   clipped to a 1px box instead.

   `flex: none` because these sit inside an hwrapper next to a long title: as a
   flex item the button would otherwise be squeezed out of shape. */
.w-btn.hide-btn-label {
	flex: none;
}

.w-btn.hide-btn-label .w-btn-label {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	white-space: nowrap;
	clip-path: inset(50%);
}

/* The clipped label is still a box, so Impreza's icon gap survives it and shoves
   the icon off centre. `.w-btn.icon_atright i` is (0,2,1); pairing the utility
   class with the position class gives (0,3,1) so this wins on specificity rather
   than on load order. `margin-inline` covers icon_atleft's margin-inline-end too.

   Measured on a 48px-high button: the icon sat 22.4px from the left edge against
   14.4px from the right — 8px of skew, exactly the .5em gap. With this it is
   14.4 / 14.4. */
.w-btn.hide-btn-label.icon_atright i,
.w-btn.hide-btn-label.icon_atright svg,
.w-btn.hide-btn-label.icon_atleft i,
.w-btn.hide-btn-label.icon_atleft svg {
	margin-inline: 0;
}

/* ============================================================
   5. GENERIC SPACING UTILITIES
   ============================================================ */

.p-2xs { padding: var(--space-2xs); }
.p-xs  { padding: var(--space-xs); }
.p-s   { padding: var(--space-s); }
.p-sm  { padding: var(--space-sm); }
.p-md  { padding: var(--space-md); }
.p-lg  { padding: var(--space-lg); }
.p-xl  { padding: var(--space-xl); }
.p-2xl { padding: var(--space-2xl); }
.p-3xl { padding: var(--space-3xl); }

.px-s  { padding-inline: var(--space-s); }
.px-sm { padding-inline: var(--space-sm); }
.px-md { padding-inline: var(--space-md); }
.px-lg { padding-inline: var(--space-lg); }
.px-xl { padding-inline: var(--space-xl); }

.py-s  { padding-block: var(--space-s); }
.py-sm { padding-block: var(--space-sm); }
.py-md { padding-block: var(--space-md); }
.py-lg { padding-block: var(--space-lg); }
.py-xl { padding-block: var(--space-xl); }
.py-2xl { padding-block: var(--space-2xl); }
.py-3xl { padding-block: var(--space-3xl); }

/* Fluid section padding — preferred for full sections over fixed py-*. */
.py-fluid-lg  { padding-block: var(--space-fluid-lg); }
.py-fluid-xl  { padding-block: var(--space-fluid-xl); }
.py-fluid-2xl { padding-block: var(--space-fluid-2xl); }
.py-fluid-3xl { padding-block: var(--space-fluid-3xl); }

/* ---- Row vertical padding ----
   A section's vertical padding belongs to the row's own `height` param
   (auto / small / medium / large / huge → 0 / 2 / 4 / 6 / 8rem), not to a
   utility class.

   The ladder is restated here so each step reads its token (see
   --section-pad-* in section 1). Same 0-2-0 specificity as Impreza's own
   rule, and this file loads after us-style, so these win. Values are
   identical to Impreza's by default — retune a step from the project's
   :root, never by rewriting the rule:

     :root { --section-pad-huge: 7.2rem; }
     @media (max-width: 1024px) { :root { --section-pad-huge: 9vmax; } }

   height_auto (0) and height_custom (Impreza's own
   --section-custom-padding) are deliberately left alone. */
.l-section.height_small  { padding-block: var(--section-pad-small); }
.l-section.height_medium { padding-block: var(--section-pad-medium); }
.l-section.height_large  { padding-block: var(--section-pad-large); }
.l-section.height_huge   { padding-block: var(--section-pad-huge); }

/* pt-0 / pb-0 drop ONE side so two sections can sit flush without
   inventing a custom height. They follow the ladder above, so equal
   specificity resolves in their favour on source order. */
.l-section.pt-0 { padding-top: 0; }
.l-section.pb-0 { padding-bottom: 0; }
.l-section.py-0 { padding-block: 0; }

.mb-0  { margin-bottom: 0 !important; }
.mb-xs { margin-bottom: var(--space-xs); }
.mb-sm { margin-bottom: var(--space-sm); }
.mb-md { margin-bottom: var(--space-md); }
.mb-lg { margin-bottom: var(--space-lg); }
.mb-xl { margin-bottom: var(--space-xl); }

.mt-0  { margin-top: 0 !important; }
.mt-xs { margin-top: var(--space-xs); }
.mt-sm { margin-top: var(--space-sm); }
.mt-md { margin-top: var(--space-md); }
.mt-lg { margin-top: var(--space-lg); }
.mt-xl { margin-top: var(--space-xl); }

/* Pushes a flex child to the far end of its wrapper — the standard way to
   bottom-align a button so CTAs line up across a row of unequal cards. */
.push-end { margin-top: auto !important; }

/* ============================================================
   6. RADIUS UTILITIES
   ============================================================ */

.r-none   { border-radius: 0; }
.r-xs     { border-radius: var(--radius-xs); }
.r-sm     { border-radius: var(--radius-sm); }
.r-md     { border-radius: var(--radius-md); }
.r-lg     { border-radius: var(--radius-lg); }
.r-xl     { border-radius: var(--radius-xl); }
.r-pill   { border-radius: var(--radius-pill); }
.r-circle { border-radius: var(--radius-circle); }

/* Clip children to the radius — needed on any wrapper holding a full-bleed
   image, or the image's square corners punch through the rounded box. */
.r-clip { overflow: hidden; }

/* ============================================================
   7. FLEX ROWS
   ============================================================
   Equal-width flex rows independent of the WPBakery grid. Useful inside
   a single column, where vc_row_inner is unavailable or overkill.
   Override --gap per instance.
   ------------------------------------------------------------ */

.flex-row-1,
.flex-row-2,
.flex-row-3,
.flex-row-4,
.flex-row-5,
.flex-row-6 {
	--gap: var(--grid-gutter);
	display: flex;
	flex-wrap: wrap;
	gap: var(--gap);
}

.flex-row-1 > *,
.flex-row-2 > *,
.flex-row-3 > *,
.flex-row-4 > *,
.flex-row-5 > *,
.flex-row-6 > * {
	min-width: 0;
	margin-inline-end: 0 !important;
}

/* One per row. A vwrapper stacks too, but the scale reads as complete only if
   1 is in it — written as flex-row-1 and silently doing nothing is worse than
   a redundant utility. Also the honest choice when a row already carries an
   hwrapper and only the column count should change. */
.flex-row-1 > * { flex: 1 1 100%; }

.flex-row-2 > * { flex: 1 1 calc((100% - 1 * var(--gap)) / 2); }
.flex-row-3 > * { flex: 1 1 calc((100% - 2 * var(--gap)) / 3); }
.flex-row-4 > * { flex: 1 1 calc((100% - 3 * var(--gap)) / 4); }
.flex-row-5 > * { flex: 1 1 calc((100% - 4 * var(--gap)) / 5); }
.flex-row-6 > * { flex: 1 1 calc((100% - 5 * var(--gap)) / 6); }

/* ============================================================
   8. TYPOGRAPHY HELPERS
   ============================================================ */

/* Replay a heading level's tokens onto any element — for text that should
   LOOK like a heading without being one semantically. */
.h1-style { font: var(--h1-font-style) var(--h1-font-weight) var(--h1-font-size) / var(--h1-line-height) var(--h1-font-family); letter-spacing: var(--h1-letter-spacing); text-transform: var(--h1-text-transform); }
.h2-style { font: var(--h2-font-style) var(--h2-font-weight) var(--h2-font-size) / var(--h2-line-height) var(--h2-font-family); letter-spacing: var(--h2-letter-spacing); text-transform: var(--h2-text-transform); }
.h3-style { font: var(--h3-font-style) var(--h3-font-weight) var(--h3-font-size) / var(--h3-line-height) var(--h3-font-family); letter-spacing: var(--h3-letter-spacing); text-transform: var(--h3-text-transform); }
.h4-style { font: var(--h4-font-style) var(--h4-font-weight) var(--h4-font-size) / var(--h4-line-height) var(--h4-font-family); letter-spacing: var(--h4-letter-spacing); text-transform: var(--h4-text-transform); }
.h5-style { font: var(--h5-font-style) var(--h5-font-weight) var(--h5-font-size) / var(--h5-line-height) var(--h5-font-family); letter-spacing: var(--h5-letter-spacing); text-transform: var(--h5-text-transform); }
.h6-style { font: var(--h6-font-style) var(--h6-font-weight) var(--h6-font-size) / var(--h6-line-height) var(--h6-font-family); letter-spacing: var(--h6-letter-spacing); text-transform: var(--h6-text-transform); }

/* `.eyebrow` used to live here. It was moved to the project layer: its values are
   project-specific (Figma's Subheading token is Platypi SemiBold 13/22 with NO
   tracking on this build, where the old rule had Geist and .09em) and it carried a
   colour, which this file must not. The NAME stays part of the shared vocabulary —
   see the contract at the top. */

.fs-3xs { font-size: var(--fs-3xs); }
.fs-2xs { font-size: var(--fs-2xs); }
.fs-xs  { font-size: var(--fs-xs); }
.fs-sm  { font-size: var(--fs-sm); }
.fs-md  { font-size: var(--fs-md); }
.fs-lg  { font-size: var(--fs-lg); }

/* Avoid typographic orphans in headings and short intros. */
.text-balance { text-wrap: balance; }
.text-pretty  { text-wrap: pretty; }

/* ============================================================
   9. BASE RESETS
   ============================================================ */

/* DO NOT add `html { scroll-behavior: smooth }`.
 *
 * MEASURED on Impreza 9.1: it kills every in-page anchor. The theme handles
 * anchor clicks in its own JS — preventDefault, then step the scroll position
 * itself. With CSS smooth scrolling also on, each of those steps becomes a new
 * animation that the next step immediately supersedes, and the page never
 * moves at all. Verified both ways on the same click:
 *
 *   scroll-behavior: smooth   → click on [href="#consult"], scrollY 1000 → 1000
 *   scroll-behavior: auto     → same click,                 scrollY 1000 → 7630
 *
 * The theme already animates the jump. There is nothing to add, and adding it
 * silently breaks every on-page CTA — the one thing a landing page has to do.
 */

/* The serif display faces these projects use render heavy without this on
   macOS/Safari, and the ligature/kerning pass is what keeps a headline set
   in a text face from looking like it was typed rather than set. */
body {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	text-rendering: optimizeLegibility;
}

h1, h2, h3, h4, h5, h6 {
	padding-top: 0;
	text-wrap: pretty;
}

ul, ol {
	margin-left: 2rem;
}

.wpb_text_column a {
	text-decoration: underline;
}

/* Inside a coloured box the link must not fight the box's text colour. */
.has_text_color a {
	color: inherit;
}

/* Offset anchor targets so a jump link does not hide the heading under a
   sticky header. */
:target {
	scroll-margin-top: calc(var(--anchor-offset) + var(--sticky-header-height, 0px));
}

/* ============================================================
   10. RESPONSIVE
   ============================================================
   Impreza breakpoints: mobiles ≤600, tablets ≤1024, laptops ≤1380.
   Column-fraction utilities are meaningless once columns stack, so they
   are neutralised from the tablet breakpoint down.
   ------------------------------------------------------------ */

@media (max-width: 1024px) {

	[class*="col-pad-l-"] { padding-left: 0; }
	[class*="col-pad-r-"] { padding-right: 0; }
	[class*="col-pad-x-"] { padding-inline: 0; }

	[class*="col-mar-l-"] { margin-left: 0; }
	[class*="col-mar-r-"] { margin-right: 0; }
	[class*="col-mar-x-"] { margin-inline: 0; }

	[class*="col-bleed-"],
	[class*="col-extend-"] {
		margin-inline: 0;
		width: auto;
	}

	/* The gutter-scale extends act on the inner box, so the neutraliser has
	   to reach it too — otherwise they survive the stack and overflow. */
	[class*="col-extend-"] > .vc_column-inner {
		margin-inline: 0;
		width: auto;
	}

	/* Narrow constraints relax to the full container on tablet down. */
	[class*="narrow-section-"] .l-section-h,
	[class*="narrow-inner-row-"] > .wpb_column,
	[class*="narrow-el-"] {
		max-width: none;
	}
}

@media (max-width: 600px) {

	.flex-row-2 > *,
	.flex-row-3 > *,
	.flex-row-4 > *,
	.flex-row-5 > *,
	.flex-row-6 > * {
		flex-basis: 100%;
	}

	/* Halve the largest padding steps so small screens keep usable width. */
	.p-2xl { padding: var(--space-lg); }
	.p-3xl { padding: var(--space-xl); }
	.py-2xl { padding-block: var(--space-lg); }
	.py-3xl { padding-block: var(--space-xl); }
}
