/**
 * HERO Blocks — presentation for the finite controls.
 *
 * Every declaration reads an Elementor Kit variable with a NEUTRAL literal
 * fallback. The fallback is deliberately grey: one that looked like a brand
 * would hide a broken or unpopulated Kit, and the site would ship looking
 * plausible and wrong.
 *
 * Layout is driven entirely by the data attributes the widgets emit, so a
 * variant is a named value in saved settings rather than a pile of inline CSS.
 */

.hero-block {
  --hero-primary:    var(--e-global-color-primary,   #4a4a4a);
  --hero-secondary:  var(--e-global-color-secondary, #2e2e2e);
  --hero-text:       var(--e-global-color-text,      #333333);
  --hero-accent:     var(--e-global-color-accent,    #6b6b6b);

  /* The program's pinned custom globals. Ids are fixed across every program
     site so a preset harvested from the master resolves on a client site. */
  --hero-on-primary:    var(--e-global-color-53a5b1e, #ffffff);
  --hero-on-secondary:  var(--e-global-color-22f69d7, #ffffff);
  --hero-dark-heading:  var(--e-global-color-d5a0c60, #ffffff);
  --hero-dark-text:     var(--e-global-color-a16ac04, #f2f2f2);
  --hero-dark-bg:       var(--e-global-color-0794945, #2e2e2e);
  --hero-dark-cta-bg:   var(--e-global-color-896d929, #ffffff);
  --hero-dark-cta-text: var(--e-global-color-755f66e, #2e2e2e);
  --hero-surface-muted: var(--e-global-color-e0d3a3f, #f1f1f1);

  /* ── Geometry: the design language a style pack swaps ──────────────────
     These were literals until now, which meant two client sites could differ
     in colour and typeface and still share identical proportions, corners and
     shadows - the thing a competitor comparing two of our sites would notice.
     Every value here is what the library already looked like, so declaring
     them changes nothing on its own; a pack overrides the block and every
     widget follows. Token NAMES are frozen like control names: rename one and
     every site carrying a pack silently loses that part of its styling. */
  /* Families, from the Kit globals; a client with no faces gets the pack's. */
  --hero-font-heading: var(--e-global-typography-primary-font-family, system-ui), system-ui, sans-serif;
  --hero-font-body: var(--e-global-typography-text-font-family, system-ui), system-ui, sans-serif;

  --hero-gap: clamp(1.5rem, 4vw, 3.5rem);
  --hero-pad: clamp(3rem, 6vw, 5rem);
  --hero-card-pad: clamp(1.25rem, 2.5vw, 1.75rem);

  --hero-radius-card: 12px;
  --hero-radius-button: 6px;
  --hero-radius-pill: 999px;
  --hero-radius-frame: 16px;
  --hero-radius-panel: 14px;
  --hero-radius-media: 8px;

  --hero-shadow-card: 0 10px 30px rgba(0, 0, 0, .10);
  --hero-shadow-panel: 0 18px 50px rgba(0, 0, 0, .18);
  --hero-shadow-float: 0 24px 60px rgba(0, 0, 0, .20);

  --hero-width-boxed: 1140px;
  --hero-width-wide: 1440px;
  --hero-width-full: 1680px;
  --hero-measure: 46rem;

  --hero-button-pad-y: .85em;
  --hero-button-pad-x: 1.75em;
  --hero-button-border: 2px;
  --hero-button-weight: 600;

  /* Texture. `surface` is the white a light band paints; `hairline` is every
     rule, divider and chip border in the library. They were four slightly
     different greys before, which no pack could have moved together. */
  --hero-surface: #ffffff;
  --hero-hairline: rgba(128, 128, 128, .28);
  /* The hairline on a dark, primary or secondary band. One token, so a pack
     that wants harder rules on dark bands moves them everywhere at once. */
  --hero-hairline-dark: rgba(255, 255, 255, .14);
  /* Copy on a photo scrim. Always light, whatever the brand - the scrim is
     what makes it readable, so this follows the scrim and not the palette. */
  --hero-on-scrim: #ffffff;
  /* Review stars. A token so a pack can warm or cool the gold, NOT a brand
     colour: stars tinted to the client read as decoration, not as a rating. */
  --hero-star: #E8A317;

  /* Type.

     THE KIT OWNS FAMILY. THE PACK OWNS SCALE. That division is the whole rule,
     and it was got wrong first time round: this comment used to read "the Kit
     supplies family, size and weight for headings", which left headline size
     as the one thing a style pack could not touch. Three design options then
     rendered at identical type sizes no matter which pack they carried, which
     is most of why they read as one website.

     So headline scale, leading, tracking and case are tokens here, and the
     program Kit carries NO font sizes on its typography globals - a size on a
     Kit global becomes a font-size Elementor writes onto the element itself,
     at a specificity a token cannot reach, and the pack silently loses.
     `elementor-kit.ts` strips sizes on merge for program sites so this cannot
     drift back in by hand. */
  --hero-eyebrow-size: .8125rem;
  --hero-eyebrow-weight: 700;
  --hero-eyebrow-tracking: .08em;
  --hero-eyebrow-transform: none;

  --hero-h1: clamp(2.25rem, 5vw, 3.5rem);
  --hero-h2: clamp(1.75rem, 3.5vw, 2.5rem);
  --hero-h3: clamp(1.25rem, 2vw, 1.5rem);
  --hero-body: 1rem;

  --hero-heading-weight: 700;
  --hero-heading-leading: 1.15;
  --hero-heading-tracking: -.01em;
  --hero-heading-transform: none;
  --hero-body-leading: 1.6;

  --hero-text-small: .875rem;
  --hero-text-label: .9375rem;
  --hero-text-card-title: 1.0625rem;
  --hero-text-lead: 1.25rem;

  /* The tinted tile an icon sits in (cards, steps, stats). A pack lever: a
     chunky tile and a fine one read as different products. */
  --hero-icon-tile: 3.25rem;

  /* Room a transparent site header needs above the first block. A token
     because a pack with a taller header needs a taller offset. */
  --hero-header-offset: 6rem;

  /* How dark a photo scrim is. A pack lever: how heavily a design language
     leans on photography is part of how it reads, and these were duplicated
     literals in two widget files before. */
  --hero-scrim-light: .25;
  --hero-scrim-medium: .45;
  --hero-scrim-heavy: .65;

  --hero-stat-medium: clamp(1.75rem, 4vw, 2.25rem);
  --hero-stat-large: clamp(2.25rem, 5vw, 3rem);
  --hero-stat-xl: clamp(2.75rem, 7vw, 4.25rem);

  color: var(--hero-text);
  font-family: var(--hero-font-body);
  font-size: var(--hero-body);
  line-height: var(--hero-body-leading);
  box-sizing: border-box;
}

/*
 * Typefaces, set by the block and not left to the page.
 *
 * The widgets print a family only on their heading and body elements (the
 * Elementor typography controls, bound to the Kit globals). Every other text
 * element - card titles, eyebrows, buttons, the menu, reviews, the footer -
 * inherited from body, and the render site's Kit sets no body typography (the
 * Kit sync strips it on purpose, so the scale stays with the tokens). Those
 * elements fell to the browser default serif on every built page (EXEC,
 * 2026-09-11: "those cards are fucked everywhere"). The Kit globals are on the
 * page as custom properties, so the block reads them itself; a per-instance
 * typography override still wins on specificity, as before.
 */
.hero-block h1, .hero-block h2, .hero-block h3, .hero-block h4,
.hero-block [class*="__heading"], .hero-block [class*="__title"],
.hero-block [class*="__eyebrow"], .hero-block [class*="__wordmark"],
.hero-block [class*="__value"], .hero-block [class*="__stat"] {
  font-family: var(--hero-font-heading);
}

.hero-block *,
.hero-block *::before,
.hero-block *::after { box-sizing: inherit; }

/* The heading scale.

   Selected by tag rather than by class: every widget emits a real h1, h2 or h3
   through its `heading_tag` control, so the size follows the semantics the page
   already declares and a heading demoted to h3 for outline reasons gets the h3
   size without a second control to keep in step.

   Specificity is deliberately low (0,1,1). A widget that has a reason to size a
   heading itself - `hero-cta[data-hero-format="bar"]`, where the heading sits
   inline on a bar and cannot be a headline - keeps winning. */
.hero-block h1 { font-size: var(--hero-h1); }
.hero-block h2 { font-size: var(--hero-h2); }
.hero-block h3 { font-size: var(--hero-h3); }

.hero-block h1,
.hero-block h2,
.hero-block h3 {
  font-weight: var(--hero-heading-weight);
  line-height: var(--hero-heading-leading);
  letter-spacing: var(--hero-heading-tracking);
  text-transform: var(--hero-heading-transform);
}

/* An eyebrow that is a heading (the hero's H1 line) keeps the eyebrow's size
   and weight: the tag is for the outline, the role sets the type. The banner
   already does this with its own rule; this covers every other widget whose
   eyebrow selector is a single class and would lose to the tag rule above. */
.hero-block [class*="__eyebrow"]:is(h1, h2, h3) {
  font-size: var(--hero-eyebrow-size); font-weight: var(--hero-eyebrow-weight);
  line-height: 1.3; letter-spacing: var(--hero-eyebrow-tracking); text-transform: var(--hero-eyebrow-transform);
}

/* ── Item detail ─────────────────────────────────────────────────────────── */
/* The third level of a repeater item. Under the short copy: the first two
   lines of the detail, fading, then a "Read more" line with a glyph (a
   chevron on cards and steps, a plus on plain lists, an arrow for a modal),
   the way a news site does it. The whole item is the click target. Open, the
   copy shows in full above a "Show less" line. */
/* Pinned to the bottom of its item: `margin-top: auto` takes the item's spare
   height, so every Read more in a row of equal-height cards sits on one
   baseline whatever the copy above it runs to (EXEC, 2026-09-11: "cards have
   to be aligned"). In an item that is not a flex column the auto margin is
   zero and the padding keeps the gap. */
.hero-detail { margin-top: auto; padding-top: .5rem; font-size: var(--hero-text-small); display: flex; flex-direction: column; }
.hero-detail__toggle {
  display: flex; flex-direction: column; gap: .35rem; padding: 0; margin: 0; border: 0; background: none; cursor: pointer; text-align: left; width: 100%;
  font: inherit; color: inherit; list-style: none; order: 1;
}
.hero-detail__body { order: 0; }
.hero-detail__toggle::-webkit-details-marker { display: none; }
/* The click target is the whole item: the summary paints a layer over its
   nearest positioned ancestor, the card. A linked title sits above it. */
.hero-detail__toggle::before { content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; }
a.hero-cards__title, a.hero-tiles__title { position: relative; z-index: 2; }
/* The preview: two lines of the detail, fading out, gone once it is open. */
.hero-detail__preview {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  line-height: var(--hero-body-leading); opacity: .75;
  -webkit-mask-image: linear-gradient(#000 40%, transparent); mask-image: linear-gradient(#000 40%, transparent);
}
.hero-detail[open] .hero-detail__preview { display: none; }
/* The label line, in the brand colour, with the glyph after it. */
.hero-detail__label { display: inline-flex; align-items: center; gap: .35em; font-weight: 600; color: var(--hero-primary); }
.hero-detail__label::after {
  content: ""; width: 1em; height: 1em; background: currentColor; transition: transform .18s ease;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") center / contain no-repeat;
}
.hero-detail__less { display: none; }
.hero-detail[open] .hero-detail__more { display: none; }
.hero-detail[open] .hero-detail__less { display: inline; }
.hero-detail[open] .hero-detail__label::after { transform: rotate(180deg); }
/* A plain list uses plus, and a cross when open. */
[data-hero-presentation="list"] .hero-detail__label::after, [data-hero-presentation="columns"] .hero-detail__label::after, [data-hero-presentation="checklist"] .hero-detail__label::after {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M12 5v14M5 12h14'/%3E%3C/svg%3E") center / contain no-repeat;
}
[data-hero-presentation="list"] .hero-detail[open] .hero-detail__label::after, [data-hero-presentation="columns"] .hero-detail[open] .hero-detail__label::after, [data-hero-presentation="checklist"] .hero-detail[open] .hero-detail__label::after { transform: rotate(45deg); }
/* A modal uses an arrow that does not turn. */
.hero-detail[data-hero-detail="modal"] .hero-detail__label::after {
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17L17 7M9 7h8v8'/%3E%3C/svg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M7 17L17 7M9 7h8v8'/%3E%3C/svg%3E") center / contain no-repeat;
}
/* Hover and focus land on the label line, never as a box around the item. */
.hero-cards__card:hover .hero-detail__label, .hero-tiles__tile:hover .hero-detail__label, .hero-steps__item:hover .hero-detail__label { text-decoration: underline; text-underline-offset: .2em; }
.hero-detail__toggle:focus { outline: none; }
.hero-detail__toggle:focus-visible .hero-detail__label { outline: 2px solid currentColor; outline-offset: 3px; border-radius: 2px; }
.hero-detail__body { margin-top: 0; margin-bottom: .5rem; font-size: var(--hero-text-label); line-height: var(--hero-body-leading); color: inherit; }
.hero-detail__body > :first-child { margin-top: 0; }
.hero-detail__body > :last-child { margin-bottom: 0; }
.hero-detail__body p { margin: 0 0 .75em; }
.hero-block[data-hero-bg="dark"] .hero-detail__label, .hero-block[data-hero-bg="primary"] .hero-detail__label, .hero-block[data-hero-bg="secondary"] .hero-detail__label { color: inherit; }
@media (prefers-reduced-motion: reduce) { .hero-detail__label::after { transition: none; } }

/* The dialog: a panel that fits a phone with a gutter, scrolls when long. */
.hero-detail__dialog { border: 0; padding: 0; background: transparent; max-width: none; max-height: none; width: auto; margin: auto; }
.hero-detail__dialog::backdrop { background: rgba(0, 0, 0, .55); }
.hero-detail__panel {
  position: relative; box-sizing: border-box; width: min(40rem, calc(100vw - 2rem)); max-height: min(calc(100vh - 2rem), 60rem); overflow: auto;
  padding: clamp(1.5rem, 4vw, 2.5rem); border-radius: var(--hero-radius-panel); background: var(--hero-surface); color: var(--hero-text);
  box-shadow: var(--hero-shadow-float); font-size: var(--hero-body); text-align: left;
}
.hero-detail__title { margin: 0 2.5rem .75rem 0; font-size: var(--hero-h3); font-weight: var(--hero-heading-weight); line-height: var(--hero-heading-leading); color: var(--hero-secondary); }
.hero-detail__panel .hero-detail__body { margin-top: 0; font-size: var(--hero-body); }
.hero-detail__close {
  position: absolute; top: .75rem; right: .75rem; width: 2.25rem; height: 2.25rem; border: 0; border-radius: var(--hero-radius-pill);
  background: var(--hero-surface-muted); color: var(--hero-text); font: inherit; font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.hero-detail__close:hover { background: var(--hero-primary); color: var(--hero-on-primary); }
/* ── Bands ───────────────────────────────────────────────────────────────── */
.hero-block[data-hero-bg="surface"]   { background: var(--hero-surface); }
.hero-block[data-hero-bg="muted"]     { background: var(--hero-surface-muted); }
.hero-block[data-hero-bg="none"]      { background: transparent; }

.hero-block[data-hero-bg="dark"] {
  background: var(--hero-dark-bg);
  color: var(--hero-dark-text);
}
.hero-block[data-hero-bg="primary"] {
  background: var(--hero-primary);
  color: var(--hero-on-primary);
}
.hero-block[data-hero-bg="secondary"] {
  background: var(--hero-secondary);
  color: var(--hero-on-secondary);
}

/* Body copy inherits the band, always. A theme or Kit rule on `p` (Hello
   Elementor paints paragraphs in the Kit text colour) was overriding the
   band's colour on every dark card and photo overlay, so the heading was
   white and the paragraph under it was dark on dark. EXEC, 2026-09-10. */
.hero-block .hero-block__inner :is(p, li, .hero-block__body) { color: inherit; }

/* A dark band needs its own heading colour, or the heading keeps the light-band
   colour and disappears. This is why dark-heading is a pinned global. */
.hero-block[data-hero-bg="dark"] :is(h1,h2,h3,h4,h5,h6),
.hero-block[data-hero-bg="dark"] .hero-split__heading   { color: var(--hero-dark-heading); }
.hero-block[data-hero-bg="primary"] :is(h1,h2,h3,h4,h5,h6),
.hero-block[data-hero-bg="primary"] .hero-split__heading { color: var(--hero-on-primary); }
.hero-block[data-hero-bg="secondary"] :is(h1,h2,h3,h4,h5,h6),
.hero-block[data-hero-bg="secondary"] .hero-split__heading { color: var(--hero-on-secondary); }

/* ── Vertical rhythm ─────────────────────────────────────────────────────── */
.hero-block[data-hero-pad="none"]     { padding-block: 0; }
.hero-block[data-hero-pad="compact"]  { padding-block: calc(var(--hero-pad) * 0.5); }
.hero-block[data-hero-pad="standard"] { padding-block: var(--hero-pad); }
.hero-block[data-hero-pad="roomy"]    { padding-block: calc(var(--hero-pad) * 1.6); }

/* ── Measure ─────────────────────────────────────────────────────────────── */
.hero-block__inner {
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 2.5rem);
}
.hero-block[data-hero-width="boxed"] .hero-block__inner { max-width: var(--hero-width-boxed); }
.hero-block[data-hero-width="wide"]  .hero-block__inner { max-width: var(--hero-width-wide); }
/* `full` is the band edge to edge and the content to a wide cap. Now that the
   section is no longer clipped by a boxed Elementor container, an uncapped
   inner ran to the edge of a 1920px screen while its neighbours sat in a
   1140px column (EXEC, 2026-09-11). */
.hero-block[data-hero-width="full"]  .hero-block__inner { max-width: var(--hero-width-full); }

.hero-block[data-hero-align="center"] { text-align: center; }
.hero-block[data-hero-align="right"]  { text-align: right; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.hero-block__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}
.hero-block[data-hero-align="center"] .hero-block__actions { justify-content: center; }
.hero-block[data-hero-align="right"]  .hero-block__actions { justify-content: flex-end; }

.hero-block__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.85em 1.75em;
  font-weight: var(--hero-button-weight);
  line-height: 1.2;
  text-decoration: none;
  border: var(--hero-button-border) solid transparent;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.hero-block__button[data-hero-shape="square"]  { border-radius: 0; }
.hero-block__button[data-hero-shape="rounded"] { border-radius: var(--hero-radius-button); }
.hero-block__button[data-hero-shape="pill"]    { border-radius: var(--hero-radius-pill); }

.hero-block__button[data-hero-style="solid"] {
  background: var(--hero-primary);
  color: var(--hero-on-primary);
  border-color: var(--hero-primary);
}
.hero-block__button[data-hero-style="solid"]:hover {
  background: var(--hero-secondary);
  border-color: var(--hero-secondary);
  color: var(--hero-on-secondary);
}
.hero-block__button[data-hero-style="outline"] {
  background: transparent;
  color: var(--hero-primary);
  border-color: currentColor;
}
.hero-block__button[data-hero-style="outline"]:hover {
  background: var(--hero-primary);
  color: var(--hero-on-primary);
}
.hero-block__button[data-hero-style="ghost"] {
  background: transparent;
  color: currentColor;
  border-color: transparent;
}
.hero-block__button[data-hero-style="ghost"]:hover { text-decoration: underline; }
.hero-block__button[data-hero-style="link"] {
  padding: 0;
  background: transparent;
  border-color: transparent;
  color: var(--hero-primary);
  text-decoration: underline;
}

/* On a dark, primary or secondary band the solid button reads the dark-band
   button colours. The Kit sets them to Primary and its label, so the button is
   one colour on every band; the white fallback applies only without a Kit. */
.hero-block[data-hero-bg="dark"] .hero-block__button[data-hero-style="solid"],
.hero-block[data-hero-bg="primary"] .hero-block__button[data-hero-style="solid"],
.hero-block[data-hero-bg="secondary"] .hero-block__button[data-hero-style="solid"] {
  background: var(--hero-dark-cta-bg);
  border-color: var(--hero-dark-cta-bg);
  color: var(--hero-dark-cta-text);
}
.hero-block[data-hero-bg="dark"] .hero-block__button[data-hero-style="outline"],
.hero-block[data-hero-bg="primary"] .hero-block__button[data-hero-style="outline"],
.hero-block[data-hero-bg="secondary"] .hero-block__button[data-hero-style="outline"] {
  color: currentColor;
}

/* ── Shared section head ─────────────────────────────────────────────────── */
.hero-block__head { margin-bottom: clamp(1.5rem, 3vw, 2.5rem); }
/* One rule for the eyebrow-to-heading gap on every widget. The cards, steps,
   tiles and gallery headings kept the browser's own H2 margin, so their
   heading sat a line lower under its eyebrow than the hero's or the split's
   (EXEC, 2026-09-13: "is that not enforced throughout?"). It is now: every
   heading starts flush, and the eyebrow alone sets the gap. */
.hero-block [class*="__heading"] { margin-top: 0; }
.hero-block [class*="__eyebrow"] + [class*="__heading"] { margin-top: 0; }
.hero-block__eyebrow {
  margin: 0 0 .6rem;
  font-size: var(--hero-eyebrow-size);
  font-weight: var(--hero-eyebrow-weight);
  letter-spacing: var(--hero-eyebrow-tracking);
  text-transform: var(--hero-eyebrow-transform);
  color: var(--hero-accent);
}
.hero-block[data-hero-align="center"] .hero-block__head { max-width: var(--hero-measure); margin-inline: auto; }

/* On a brand or dark band the accent-coloured eyebrow can vanish into the
   band; it follows the band's text colour instead, a step quieter. */
.hero-block[data-hero-bg="dark"] [class*="__eyebrow"],
.hero-block[data-hero-bg="primary"] [class*="__eyebrow"],
.hero-block[data-hero-bg="secondary"] [class*="__eyebrow"] { color: inherit; opacity: .8; }

/* ── Eyebrow styles ──────────────────────────────────────────────────────── */
/* `data-hero-eyebrow` is stamped by section_attrs for every widget with
   heading controls. The widgets name their eyebrow element differently
   (`hero-banner__eyebrow`, `hero-split__eyebrow`, `hero-block__eyebrow`), so the
   selector matches the suffix. Plain is the base rule each widget already has.

   `rule` is the quiet label: sentence case, regular weight, a step larger,
   no glyph. It was a rule line, then a square marker; EXEC named both as AI
   design tells (2026-09-10). The option's name stays for the contract and the
   variants that carry it; what it draws is type only. */
.hero-block[data-hero-eyebrow="rule"] [class*="__eyebrow"] {
  font-size: calc(var(--hero-eyebrow-size) * 1.2); font-weight: 500; letter-spacing: .01em; text-transform: none;
}

.hero-block[data-hero-eyebrow="bracket"] [class*="__eyebrow"] { letter-spacing: .06em; }
.hero-block[data-hero-eyebrow="bracket"] [class*="__eyebrow"]::before { content: "[ "; opacity: .55; }
.hero-block[data-hero-eyebrow="bracket"] [class*="__eyebrow"]::after  { content: " ]"; opacity: .55; }

.hero-block[data-hero-eyebrow="pill"] [class*="__eyebrow"] {
  display: inline-block; padding: .35em .9em; border-radius: var(--hero-radius-pill);
  background: var(--hero-surface-muted); color: var(--hero-primary);
}
.hero-block[data-hero-eyebrow="pill"][data-hero-bg="dark"] [class*="__eyebrow"],
.hero-block[data-hero-eyebrow="pill"][data-hero-bg="primary"] [class*="__eyebrow"],
.hero-block[data-hero-eyebrow="pill"][data-hero-bg="secondary"] [class*="__eyebrow"],
.hero-block[data-hero-eyebrow="pill"].hero-banner:not([data-hero-layout="minimal"]) [class*="__eyebrow"],
/* The interior masthead over a photograph: the same translucent pill in the
   on-scrim colour, so the H1 line reads like every other eyebrow on a scrim
   and not white on a pale pill (EXEC, 2026-09-12, Forger). */
.hero-block[data-hero-eyebrow="pill"].hero-masthead:is([data-hero-layout="photo"], [data-hero-layout="transparent"]) [class*="__eyebrow"] {
  background: rgba(255, 255, 255, .16); color: inherit;
}

/* Card chrome, shared by cards and reviews so the same word looks the same. */
.hero-block[data-hero-card="bordered"] .hero-cards__card,
.hero-block[data-hero-card="bordered"] .hero-reviews__card {
  padding: var(--hero-card-pad); border: 1px solid var(--hero-hairline); border-radius: var(--hero-radius-card);
}
.hero-block[data-hero-card="elevated"] .hero-cards__card,
.hero-block[data-hero-card="elevated"] .hero-reviews__card {
  padding: var(--hero-card-pad); border-radius: var(--hero-radius-card); background: var(--hero-surface);
  box-shadow: var(--hero-shadow-card);
}
.hero-block[data-hero-card="filled"] .hero-cards__card,
.hero-block[data-hero-card="filled"] .hero-reviews__card {
  padding: var(--hero-card-pad); border-radius: var(--hero-radius-card); background: var(--hero-surface-muted);
}

/* ── Shared: hero-masthead and hero-banner, hero-site-header ──────────── */

/*
 * Room for a transparent site header, given only when there IS one.
 *
 * The offset used to hang off `hero-masthead[layout="transparent"]` alone, on
 * the assumption that the variant is only ever chosen under a transparent
 * header. It is not: no seeded header variant sets `transparent`, yet the Fleet
 * look picks this masthead - so every Fleet interior page reserved 6rem for a
 * header that is not floating, and the home page's banner, which needs the room
 * whenever the header IS transparent, never got it.
 *
 * Keyed on the header instead, which is the thing that actually decides. The
 * site header renders once per page, so `:has()` on the page root answers the
 * question for every block below it. `minimal` is the one banner layout with no
 * photo behind it; a transparent header over it is the pairing the engine
 * refuses, so it is not styled for here.
 */
/* Set on the blocks, not on the root: `--hero-header-offset` is a block token,
   and a var() the root cannot resolve is invalid there and inherits as nothing. */
:root:has(.hero-site-header[data-hero-transparent="yes"]) .hero-block {
  --hero-header-present: var(--hero-header-offset);
}

/*
 * Sticky is decided one level up from the widget.
 *
 * On a built site the header is its own Elementor document, printed by the
 * theme as a direct child of body, and that document's root is exactly as
 * tall as the header. `position: sticky` on the widget therefore had a scroll
 * range of zero: every header in the library was marked sticky and every one
 * scrolled away (EXEC, 2026-09-11). The element whose containing block is the
 * page is the document root, so that is what sticks. The widget keeps its own
 * rule for the static sheet, where there is no root.
 *
 * A transparent sticky header is absolutely positioned inside a root of no
 * height, so the root sticks at the top without taking room, the hero runs
 * under the header, and the offset above reserves the space.
 */
body > .elementor:has(.hero-site-header[data-hero-sticky="sticky"]) {
  position: sticky; top: 0; z-index: 50;
}
.hero-masthead[data-hero-layout="transparent"],
.hero-banner:not([data-hero-layout="minimal"]) {
  padding-top: var(--hero-header-present, 0px);
}

/* ── Scrim depth ─────────────────────────────────────────────────────────── */
/*
 * Core, and keyed on `.hero-block`, because two widgets declare the same scale
 * and a third reads it. Declared per widget it was duplicated, unpackable, and
 * invisible on any page the declaring widget was absent from.
 */
.hero-block[data-hero-scrim="none"]   { --hero-scrim-alpha: 0; }
.hero-block[data-hero-scrim="light"]  { --hero-scrim-alpha: var(--hero-scrim-light); }
.hero-block[data-hero-scrim="medium"] { --hero-scrim-alpha: var(--hero-scrim-medium); }
.hero-block[data-hero-scrim="heavy"]  { --hero-scrim-alpha: var(--hero-scrim-heavy); }

/* colour-roles:tokens:start
   The colour-roles standard (docs/specs/site-program/colour-roles-standard.md).
   Generated from lib/site-program/colour-roles-css.ts; a test holds the two equal. */
.hero-block {
  --hero-mark:       var(--e-global-color-b7e2d40, var(--hero-accent));
  --hero-on-mark:    var(--e-global-color-3c9f5a1, #ffffff);
  --hero-dark-phone: var(--e-global-color-c4a91f2, var(--hero-dark-text));
  --hero-action-text:    var(--e-global-color-9d4e1b7, var(--hero-primary));
  --hero-accent-fill:    var(--e-global-color-a4e7c21, var(--hero-mark));
  --hero-on-accent-fill: var(--e-global-color-e6a9d15, var(--hero-on-mark));
  --hero-accent-bar:     var(--e-global-color-d8c1e47, transparent);
  --hero-on-accent-bar:  var(--e-global-color-c7f2b38, var(--hero-text));
  --hero-accent-tile:    var(--e-global-color-b2d8e64, transparent);
  --hero-on-accent-tile: var(--e-global-color-f3b6a02, var(--hero-mark));
}
/* Rule 5: no band is ever Action. The "primary" band paints Brand, and every
   widget rule written for it follows, because the tokens it reads move. */
.hero-block[data-hero-bg="primary"] {
  --hero-primary:    var(--e-global-color-secondary, #2e2e2e);
  --hero-on-primary: var(--e-global-color-22f69d7, #ffffff);
}
/* colour-roles:tokens:end */
