/* ==========================================================================
   EctothermInc — Design System
   --------------------------------------------------------------------------
   ELEMENTOR REBUILD NOTES
   Every layout in this stylesheet is built with flexbox only. No CSS grid,
   no absolute-positioned layout tricks, no JS-driven layout. Each component
   below maps to a native Elementor widget — the mapping is named in the
   comment above each block.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. TOKENS
   Elementor: set these under Site Settings > Global Colors / Global Fonts
   -------------------------------------------------------------------------- */
:root {
  /* Brand */
  --purple-900: #120627;   /* deepest ground */
  --purple-800: #1a0d33;
  --purple-700: #211647;
  --purple-600: #2a2055;   /* wordmark purple / panels */
  --purple-500: #3b3070;
  --purple-400: #574a94;
  --purple-200: #b3a9d6;

  --orange-600: #d94700;
  --orange-500: #ff5500;   /* primary accent */
  --orange-400: #ff7a33;
  --orange-100: #ffe8dd;

  /* Neutrals */
  --white: #ffffff;
  --off-white: #f7f5fa;
  --grey-100: #ece9f2;
  --grey-300: #cdc7da;
  --grey-500: #7c7391;
  --grey-700: #4a4260;
  --ink: #1a1526;

  /* ---- DARK SURFACES -------------------------------------------------
     The site runs dark end to end. Everything that used to be a white
     card or an off-white band now resolves through these tokens, so the
     whole palette can be retuned from one place. */
  --bg-0: #130428;   /* page ground */
  --bg-1: #1b0838;   /* alternating band */
  --bg-2: #241046;   /* cards and panels */
  --bg-3: #2e1657;   /* raised / hover */

  --line:        rgba(255, 255, 255, 0.10);
  --line-strong: rgba(255, 255, 255, 0.20);

  --text-strong: #ffffff;
  --text-body:   #cbc0e4;
  --text-dim:    #9a8dba;

  --violet-500: #8b5cf6;   /* icon rings, secondary accent */
  --violet-400: #a78bfa;

  /* Glow used behind heroes and CTA bands */
  --glow-magenta: rgba(168, 40, 190, 0.30);
  --glow-violet:  rgba(99, 60, 200, 0.32);

  /* Semantic */
  --bg: var(--bg-0);
  --text: var(--text-body);
  --text-muted: var(--text-dim);
  --border: var(--line);

  /* Type */
  --font-head: 'Archivo', 'Archivo Black', 'Helvetica Neue', Arial, sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;

  /* Spacing scale */
  --s-1: 0.25rem;
  --s-2: 0.5rem;
  --s-3: 0.75rem;
  --s-4: 1rem;
  --s-5: 1.5rem;
  --s-6: 2rem;
  --s-7: 3rem;
  --s-8: 4rem;
  --s-9: 6rem;
  --s-10: 8rem;

  /* Layout */
  --container: 1200px;
  --container-narrow: 780px;
  --radius: 6px;
  --radius-lg: 14px;
  --header-h: 84px;

  /* On a dark ground, depth reads as a darker shadow plus a light top edge. */
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.30);
  --shadow-md: 0 10px 34px rgba(0, 0, 0, 0.42);
  --shadow-lg: 0 26px 70px rgba(0, 0, 0, 0.55);
  --glow-card: 0 0 0 1px rgba(167, 139, 250, 0.35), 0 14px 44px rgba(88, 40, 170, 0.35);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* --------------------------------------------------------------------------
   2. RESET / BASE
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* offset for the sticky header when jumping to in-page anchors */
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1.0625rem;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4, h5 {
  font-family: var(--font-head);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 var(--s-4);
  color: var(--text-strong);
}

/* Two-tone display headline: white line, orange line.
   Elementor: Heading widget, wrap the second line in <span class="hl-accent">. */
.hl-accent { color: var(--orange-500); display: block; }

h1 { font-size: clamp(2.4rem, 6vw, 4.2rem); letter-spacing: -0.035em; }
h2 { font-size: clamp(1.9rem, 4.2vw, 3rem); letter-spacing: -0.03em; }
h3 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); }
h4 { font-size: 1.15rem; letter-spacing: -0.01em; }

p { margin: 0 0 var(--s-4); }
p:last-child { margin-bottom: 0; }

a { color: var(--orange-600); text-decoration: none; transition: color 0.18s var(--ease); }
a:hover { color: var(--orange-500); text-decoration: underline; }

ul, ol { margin: 0 0 var(--s-4); padding-left: 1.35rem; }
li { margin-bottom: var(--s-2); }
li:last-child { margin-bottom: 0; }

strong { font-weight: 650; color: var(--text-strong); }

hr { border: 0; border-top: 1px solid var(--line); margin: var(--s-7) 0; }

:focus-visible {
  outline: 3px solid var(--orange-500);
  outline-offset: 3px;
  border-radius: 2px;
}

::selection { background: var(--orange-500); color: #fff; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; top: -100px; left: var(--s-4);
  background: var(--orange-500); color: #fff;
  padding: var(--s-3) var(--s-5); z-index: 2000;
  font-weight: 700; border-radius: 0 0 var(--radius) var(--radius);
}
.skip-link:focus { top: 0; text-decoration: none; }

/* --------------------------------------------------------------------------
   3. LAYOUT PRIMITIVES
   Elementor: Container widget (boxed / full width), flex direction row|column
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--s-5);
}
.container--narrow { max-width: var(--container-narrow); }

.section { padding-block: clamp(3.5rem, 8vw, 7rem); }
.section--tight { padding-block: clamp(2.5rem, 5vw, 4rem); }

/* An intro aside (.section--tight) sitting directly above a full section used
   to stack both paddings: 64px below the aside plus 102px above the next
   section, plus the callout's own 24px margin, came to 190px of dead space at
   1280px wide. Collapse the pair into a single deliberate gap. Applies to the
   7 pages that use this intro-then-content pattern. */
.section--tight + .section { padding-top: clamp(1.5rem, 3vw, 2.75rem); }

/* Same idea after a compact hero. The banner already separates the content, so
   a further 107px of section padding only pushes the first item off a laptop
   screen. Measured on the FAQ: it moved the first question from 672px to 530px
   from the top of the document. */
.page-hero--compact + .section { padding-top: clamp(1.5rem, 3vw, 3rem); }

/* A callout that ends its container should not add a trailing margin on top of
   the section padding below it. */
.callout:last-child { margin-bottom: 0; }

/* Elementor: Container > background type: classic, colour */
.section--dark {
  background: var(--purple-900);
  color: var(--purple-200);
}
.section--dark h1, .section--dark h2, .section--dark h3, .section--dark h4 { color: #fff; }
.section--dark strong { color: #fff; }
.section--dark a:not(.btn) { color: var(--orange-400); }

.section--mid { background: var(--purple-600); color: #e6e1f5; }
.section--mid h2, .section--mid h3 { color: #fff; }
.section--mid strong { color: #fff; }

/* `--light` is now simply the alternating band, one step up from the ground. */
.section--light { background: var(--bg-1); }

/* --------------------------------------------------------------------------
   SURFACE TEXTURES
   Every dark band gets a faint scale lattice plus a coloured bloom, so no
   section is ever a flat slab of colour. Delivered as layered background
   images on existing classes, which means NO markup changes and it applies
   to all 18 pages at once.

   The diamond lattice deliberately echoes two things already in the brand:
   chameleon scales, and the textured back panel of the 3D printed feeders.
   -------------------------------------------------------------------------- */
:root {
  /* Organic grain. feTurbulence generates real fractal noise, so there is no
     repeating motif to spot — it just removes the flatness from a solid fill.
     This does the heavy lifting; the foliage below is used sparingly. */
  /* Grain, dialled right back — at 16% it read as TV static. This is now just
     enough to stop a flat fill looking like plastic. */
  --tex-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E");

  /* ---- FOLIAGE ARTWORK -------------------------------------------------
     The jungle artwork lives in assets/img/ as section-art-1, section-art-2
     and band-art-2, all darkened at build time because the source is far too
     bright to sit behind body copy.

     There used to be --art-section / --art-section-alt / --art-band custom
     properties here holding those url() values. DO NOT REINTRODUCE THEM.
     A relative url() inside a custom property is resolved against the PAGE,
     not the stylesheet, so `../img/x.jpg` became /img/x.jpg and 404'd on every
     page. The artwork silently never rendered. Reference the files with a
     literal url() inside the rule that uses them; there it resolves against
     this stylesheet and is correct on both the static build and in the
     WordPress theme. See .section--art and .cta-band--art. */
}

/* Ground sections: a soft bloom at each corner over fractal grain. No motif,
   no pattern to notice — just depth. */
.section--dark {
  background-color: var(--bg-0);
  background-image:
    radial-gradient(65% 85% at 6% 0%, rgba(139, 92, 246, 0.13), transparent 64%),
    radial-gradient(55% 75% at 100% 100%, rgba(168, 40, 190, 0.10), transparent 62%),
    var(--tex-grain);
  background-repeat: no-repeat, no-repeat, repeat;
}

/* Mid sections: warm bloom over grain. --art-section drops jungle artwork in
   behind it when one exists; while it is `none` this renders as-is. */
.section--mid {
  background-color: var(--bg-2);
  background-image:
    url("../img/section-art-1.jpg"),
    radial-gradient(60% 80% at 0% 100%, rgba(255, 85, 0, 0.10), transparent 62%),
    var(--tex-grain);
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: center, left bottom, 0 0;
  background-size: cover, auto, auto;
  background-blend-mode: soft-light, normal, normal;
}

/* Alternating band: cool bloom over grain.

   The section-art photograph used to sit on top of this stack at soft-light.
   It was carrying 20 sections across 11 pages, which made it wallpaper rather
   than emphasis, and its varying luminance is what made small muted text sit
   on an inconsistent ground. The elaborate artwork now belongs to the genuine
   focal moments only: .hero--art and .cta-band--art, which have their own
   rules and are untouched. The bloom and grain stay: they are flat enough to
   add depth without moving the effective contrast under text. */
.section--light {
  background-color: var(--bg-1);
  background-image:
    radial-gradient(75% 65% at 100% 0%, rgba(139, 92, 246, 0.09), transparent 66%),
    var(--tex-grain);
  background-repeat: no-repeat, repeat;
  background-position: right top, 0 0;
  background-size: auto, auto;
}

/* Wholly flat, no image layers at all. For a band whose job is to be read
   rather than admired. */
.section--solid {
  background-color: var(--bg-1);
  background-image: none;
}

/* Opt-in artwork. This is the treatment that used to sit on every .section--light
   by default; it is now something a section has to ask for, so it reads as
   emphasis rather than wallpaper. Reserved for focal sections only.
   Literal url() rather than var() for the reason given on .cta-band--art. */
.section--art {
  background-color: var(--bg-0);
  background-image:
    url("../img/section-art-2.jpg"),
    radial-gradient(75% 65% at 100% 0%, rgba(139, 92, 246, 0.10), transparent 66%),
    var(--tex-grain);
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: center, right top, 0 0;
  background-size: cover, auto, auto;
  background-blend-mode: soft-light, normal, normal;
}

/* CTA bands already sit over a photograph. Where one carries only a heading
   and a button, the artwork can run at close to full strength instead. */
.cta-band--art .cta-band__bg { display: none; }
.cta-band--art {
  background-color: var(--bg-0);
  /* Literal url(), NOT var(--art-band). A relative url() inside a custom
     property is resolved against the PAGE, not the stylesheet, so
     `../img/band-art-2.jpg` became /img/band-art-2.jpg and 404'd. Written
     directly in the rule it resolves against this file, which is what we want
     on both the static build and inside the WordPress theme. */
  background-image: url("../img/band-art-2.jpg");
  background-size: cover;
  background-position: center;
}
.cta-band--art .cta-band__overlay {
  background: linear-gradient(180deg, rgba(19, 4, 40, 0.72) 0%, rgba(19, 4, 40, 0.58) 50%, rgba(19, 4, 40, 0.78) 100%);
}


/* Aurora wash — a soft magenta/violet bloom used behind heroes and CTA bands
   to lift them off the flat ground. Purely decorative, no markup needed. */
.glow-wrap { position: relative; isolation: isolate; overflow: hidden; }
.glow-wrap::before,
.glow-wrap::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
}
.glow-wrap::before {
  width: 46vw; height: 46vw; max-width: 640px; max-height: 640px;
  top: -18%; left: -10%;
  background: var(--glow-magenta);
}
.glow-wrap::after {
  width: 40vw; height: 40vw; max-width: 560px; max-height: 560px;
  bottom: -22%; right: -8%;
  background: var(--glow-violet);
}

/* Flex row that wraps into a column on small screens.
   Elementor: Container, direction row, wrap: wrap */
.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-6);
}
.row > * { flex: 1 1 260px; min-width: 0; }

.row--2 > * { flex: 1 1 calc(50% - var(--s-6)); }
.row--3 > * { flex: 1 1 calc(33.333% - var(--s-6)); }
.row--4 > * { flex: 1 1 calc(25% - var(--s-6)); }

.row--tight { gap: var(--s-4); }
.row--wide  { gap: var(--s-7); }
.row--middle { align-items: center; }
.row--stretch { align-items: stretch; }

.stack { display: flex; flex-direction: column; gap: var(--s-5); }
.stack--tight { gap: var(--s-3); }

.center { text-align: center; }
.center-x { margin-inline: auto; }

/* --------------------------------------------------------------------------
   4. TYPOGRAPHY HELPERS
   Elementor: Heading widget + Text Editor widget
   -------------------------------------------------------------------------- */

/* Small uppercase label above a heading. Elementor: Heading widget, HTML tag span */
.eyebrow {
  display: inline-block;
  font-family: var(--font-head);
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--orange-500);
  margin-bottom: var(--s-3);
}
.section--dark .eyebrow,
.section--mid .eyebrow { color: var(--orange-400); }

.lead {
  font-size: clamp(1.1rem, 1.7vw, 1.3rem);
  line-height: 1.6;
  color: var(--text-muted);
}
.section--dark .lead, .section--mid .lead { color: var(--purple-200); }

.section-head { max-width: 900px; margin-bottom: var(--s-7); }
.section-head.center { margin-inline: auto; }
/* The block is wide enough for the headings; the copy inside keeps the
   narrower measure so lines stay readable. */
.section-head > p { max-width: 720px; }
.section-head.center > p { margin-inline: auto; }

/* Accent rule under a heading. Elementor: Divider widget */
.rule {
  width: 64px; height: 4px;
  background: var(--orange-500);
  border-radius: 2px;
  margin-bottom: var(--s-5);
}
.center .rule, .rule.center-x { margin-inline: auto; }

.text-muted { color: var(--text-muted); }
.small { font-size: 0.9rem; }

/* --------------------------------------------------------------------------
   5. BUTTONS
   Elementor: Button widget
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  font-family: var(--font-head);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0.95rem 1.9rem;
  border: 2px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  text-align: center;
  transition: transform 0.16s var(--ease), background-color 0.16s var(--ease),
              color 0.16s var(--ease), border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--orange-500);
  color: #fff;
  box-shadow: 0 4px 16px rgba(255, 85, 0, 0.32);
}
.btn--primary:hover { background: var(--orange-600); color: #fff; box-shadow: 0 8px 24px rgba(255, 85, 0, 0.42); }

.btn--secondary {
  background: var(--purple-600);
  color: #fff;
}
.btn--secondary:hover { background: var(--purple-500); color: #fff; }

.btn--outline {
  background: transparent;
  color: var(--text-strong);
  border-color: var(--line-strong);
}
/* Dark purple panel with orange text and border. Keep this IDENTICAL to the
   `.elementor .btn--outline .elementor-button:hover` rule in the compat layer:
   the two drifted apart once, and the Elementor copy was left with dark purple
   TEXT on a dark purple panel at 1.16:1, which is effectively invisible. */
.btn--outline:hover { border-color: var(--orange-500); color: var(--orange-400); background: var(--bg-2); }

/* for use on dark backgrounds */
.btn--ghost {
  background: transparent;
  color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
}
.btn--ghost:hover { background: rgba(255, 255, 255, 0.1); color: #fff; border-color: #fff; }

.btn--lg { font-size: 1.05rem; padding: 1.15rem 2.4rem; }
.btn--block { display: flex; width: 100%; }

.btn-group { display: flex; flex-wrap: wrap; gap: var(--s-4); }
.center .btn-group, .btn-group.center-x { justify-content: center; }

/* --------------------------------------------------------------------------
   6. HEADER + NAVIGATION
   Elementor: Header template — Container (flex row) + Site Logo + Nav Menu
              + Button widget. The mobile panel below is Elementor's native
              Nav Menu "dropdown" breakpoint behaviour.
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 1000;
  background: rgba(18, 6, 39, 0.97);
  /* A defined edge for the sticky bar, so content scrolling up beneath it has
     something to stop against. Violet rather than orange: it is already the
     mid purple rather than orange, so the line reads as part of the palette
     rather than competing with the orange CTA sitting a few pixels above it.
     Applied to .site-header, not the Elementor wrapper, so the static build
     and WordPress match. */
  border-bottom: 2px solid var(--purple-400);
  backdrop-filter: blur(10px);
}

/* Brand and nav sit together on the left, CTA pushed to the far right by its
   own auto margin. `space-between` used to spread all three, which left the
   logo marooned in the corner well away from the first nav item. */
.header-inner {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: var(--s-5);
  min-height: var(--header-h);
  padding-block: var(--s-3);
}

.brand { display: flex; align-items: center; flex-shrink: 0; }
.brand:hover { text-decoration: none; }
.brand img { height: 52px; width: auto; }

/* The header carries the icon at every width now; the full logo lives in the
   footer and the hero. `.brand .brand__mark` has to out-specify `.brand img`
   above, which is (0,1,1). */
.brand__full { display: none; }
.brand .brand__mark { display: block; height: 52px; }

/* Desktop nav */
.nav { display: flex; align-items: center; gap: var(--s-2); }

/* The CTA lives twice in the markup: once inside the nav panel (for mobile,
   where the header button is hidden) and once in .header-cta (for desktop).
   Only ever show one. */
.nav__cta { display: none; }
.nav__list {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__item { position: relative; margin: 0; }

.nav__link {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-head);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #e8e4f5;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  white-space: nowrap;
  transition: color 0.16s var(--ease), background-color 0.16s var(--ease);
}
.nav__link:hover { color: #fff; background: rgba(255, 255, 255, 0.08); text-decoration: none; }
.nav__link[aria-current="page"] { color: var(--orange-400); }

.nav__caret { width: 9px; height: 9px; flex-shrink: 0; opacity: 0.7; transition: transform 0.2s var(--ease); }
.nav__item:hover .nav__caret, .nav__item:focus-within .nav__caret { transform: rotate(180deg); }

/* Dropdown — CSS hover/focus only, no JS. Elementor: Nav Menu submenu */
.nav__submenu {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 258px;
  background: var(--purple-700);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--s-2);
  margin: 0;
  list-style: none;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition: opacity 0.18s var(--ease), transform 0.18s var(--ease), visibility 0.18s;
}
.nav__item:hover > .nav__submenu,
.nav__item:focus-within > .nav__submenu {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__submenu li { margin: 0; }
.nav__submenu a {
  display: block;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 500;
  color: #ded8f0;
  padding: 0.62rem 0.9rem;
  border-radius: var(--radius);
}
.nav__submenu a:hover { background: var(--orange-500); color: #fff; text-decoration: none; }
.nav__submenu a[aria-current="page"] { color: var(--orange-400); }

.header-cta { flex-shrink: 0; margin-left: auto; }

/* Hamburger — the only layout-adjacent JS on the site.
   Elementor: replaced entirely by the Nav Menu widget's mobile toggle. */
.nav-toggle {
  display: none;
  /* Pushed right the same way the desktop CTA is. The CTA is hidden on mobile,
     so without this the toggle sits next to the logo instead of the far edge. */
  margin-left: auto;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 46px;
  height: 46px;
  padding: 0 10px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius);
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--bg-2);
  border-radius: 2px;
  transition: transform 0.22s var(--ease), opacity 0.18s var(--ease);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   7. HERO
   Elementor: Container, background image + background overlay, min-height
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: min(80vh, 720px);
  background: var(--purple-900);
  overflow: hidden;
}
.hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 72% 42%;
  /* Lift the animal's colour so it survives the purple grade over the top */
  filter: saturate(1.28) contrast(1.10) brightness(1.04);
}

/* Elementor: Container > Background Overlay, colour + gradient.
   Four stacked layers do the work of the mockup's painted background:
     1. tropical fronds bottom-left, orange
     2. tropical fronds top-right, violet
     3. a magenta bloom sitting behind the chameleon
     4. the purple wash that keeps the headline legible on the left */
.hero__overlay {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(42% 58% at 74% 46%, rgba(196, 52, 220, 0.34), transparent 70%),
    linear-gradient(100deg,
      rgba(19, 4, 40, 0.97) 0%,
      rgba(19, 4, 40, 0.90) 34%,
      rgba(28, 8, 58, 0.62) 58%,
      rgba(40, 10, 70, 0.34) 78%,
      rgba(19, 4, 40, 0.48) 100%),
    var(--tex-grain);
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: center, center, 0 0;
}

/* A second pass that pushes purple into the shadows and orange into the
   highlights, so a plain photograph reads as lit by the scene around it. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(115deg, rgba(120, 40, 200, 0.30), transparent 45%, rgba(255, 85, 0, 0.16));
  mix-blend-mode: soft-light;
}
.hero__inner { z-index: 2; }

/* --- Artwork hero ---------------------------------------------------------
   When the hero background is purpose-made artwork rather than a photograph,
   almost all of the treatment above has to come off: the art already carries
   its own dark left side, colour grade and foliage. Left in place, the wash
   turns it to mud.

   What remains is a light scrim on the left only, so the headline stays
   readable, and a floor gradient so the statement bar below joins cleanly. */
/* Measured from the artwork by brightness+saturation (an earlier green-only
   test missed the red-and-blue casque and read the head ~5% too low): the
   animal becomes solid at 15.9% of the source height and runs to 76.9%.
   The hero is a short band, so `cover` crops vertically. 16% keeps the casque
   framed even in the worst case — an ultrawide screen with a short browser
   window, where the crop is most severe. The tail crops instead. */
.hero--art .hero__bg { filter: none; object-position: 72% 20%; }
.hero--art::after { display: none; }

/* The logo adds real height, so the art hero runs slightly tighter padding to
   keep the whole block inside one screen on a laptop. */
.hero--art .hero__inner { padding-block: clamp(2.5rem, 6vw, 4.5rem); }
.hero--art .hero__overlay {
  background:
    /* Text plate. The artwork has a bright starburst around 45% across, which
       lands squarely under the headline and drops contrast to 1.7:1. This soft
       ellipse darkens just behind the copy instead of flattening the whole
       left half of the image. */
    radial-gradient(40% 75% at 26% 47%,
      rgba(19, 4, 40, 0.90) 0%,
      rgba(19, 4, 40, 0.74) 48%,
      rgba(19, 4, 40, 0.28) 78%,
      transparent 100%),
    linear-gradient(100deg,
      rgba(19, 4, 40, 0.88) 0%,
      rgba(19, 4, 40, 0.62) 28%,
      rgba(19, 4, 40, 0.26) 52%,
      rgba(19, 4, 40, 0.04) 70%,
      rgba(19, 4, 40, 0.00) 100%),
    /* Floor fade. Reaches FULL opacity at the very bottom so the hero dissolves
       into the solid section beneath it with no seam — 0.85 left a visible
       edge. Long, soft ramp so the transition is not a detectable band. */
    linear-gradient(to top,
      rgb(19, 4, 40) 0%,
      rgba(19, 4, 40, 0.92) 6%,
      rgba(19, 4, 40, 0.62) 15%,
      rgba(19, 4, 40, 0.28) 26%,
      rgba(19, 4, 40, 0.08) 36%,
      transparent 48%);
  background-repeat: no-repeat, no-repeat, no-repeat;
  background-position: center, center, center;
}

/* Belt and braces: a soft shadow rescues any bright pixel the scrim misses.
   Invisible against the dark ground, decisive over a hot spot. */
.hero--art h1,
.hero--art .hero__text { text-shadow: 0 2px 18px rgba(19, 4, 40, 0.75); }

/* Below the desktop breakpoint the artwork's chameleon crops out of frame, so
   the scrim goes full-width to keep the headline legible over whatever remains. */
@media (max-width: 900px) {
  /* Narrow viewports crop horizontally instead, so bias right to hold the head
     (which sits between 62% and 92% across) and slightly up to keep the casque. */
  .hero--art .hero__bg { object-position: 82% 22%; }
}

/* On the narrowest phones the horizontal crop clips the snout, so sit almost
   flush right — losing a sliver off the back of the head instead of the face. */
@media (max-width: 480px) {
  .hero--art .hero__bg { object-position: 88% 22%; }
  /* Ends on the solid section colour so the hero dissolves into what follows,
     exactly as the desktop floor fade does. */
  .hero--art .hero__overlay {
    background:
      linear-gradient(180deg,
        rgba(19, 4, 40, 0.86) 0%,
        rgba(19, 4, 40, 0.74) 42%,
        rgba(19, 4, 40, 0.84) 74%,
        rgba(19, 4, 40, 0.96) 92%,
        rgb(19, 4, 40) 100%);
  }
}
.hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  padding-block: clamp(4rem, 10vw, 7rem);
}
.hero__content { max-width: 680px; }

/* Brand mark above the headline. Drop-shadow rather than a panel, so the
   transparent PNG lifts off busy artwork without gaining a visible edge. */
.hero__logo {
  display: block;
  width: clamp(200px, 46vw, 360px);
  height: auto;
  margin-bottom: var(--s-4);
  filter: drop-shadow(0 6px 24px rgba(0, 0, 0, 0.55));
}

/* Smaller floor than the global h1 clamp. "Panther Chameleons." is held
   together by a non-breaking space in the markup, so at the global 2.4rem
   minimum it measured 388px inside a 343px box on a 375px phone and clipped.
   Scoped to .hero so page-hero headings keep the larger floor. */
.hero h1 { color: #fff; margin-bottom: var(--s-5); font-size: clamp(2rem, 6vw, 4.2rem); }
.hero__tagline {
  font-family: var(--font-head);
  font-size: clamp(1.05rem, 2vw, 1.4rem);
  font-weight: 700;
  letter-spacing: 0.01em;
  color: var(--orange-400);
  margin-bottom: var(--s-4);
}
.hero__text {
  font-size: clamp(1.05rem, 1.6vw, 1.22rem);
  color: #d9d2ee;
  margin-bottom: var(--s-6);
  max-width: 560px;
}

/* Compact hero for interior pages */
.page-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 380px;
  background: var(--purple-900);
  overflow: hidden;
}
.page-hero__bg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0.5;
}
.page-hero__overlay {
  position: absolute; inset: 0;
  background:
    radial-gradient(48% 68% at 82% 50%, rgba(196, 52, 220, 0.24), transparent 68%),
    linear-gradient(95deg, rgba(19, 4, 40, 0.96) 0%, rgba(19, 4, 40, 0.84) 48%, rgba(34, 10, 64, 0.60) 78%, rgba(19, 4, 40, 0.54) 100%),
    var(--tex-grain);
  background-repeat: no-repeat, no-repeat, repeat;
  background-position: center, center, 0 0;
}
.page-hero__inner {
  position: relative; z-index: 2;
  width: 100%;
  padding-block: clamp(3rem, 7vw, 5rem);
}
/* Compact variant. On a page whose job is to get people to an answer, a
   380px banner pushes the first question off a laptop screen: measured at
   672px from the top, against roughly 640px of viewport on a 1366x768. This
   trims the banner and lets the section links sit inside it, so they cost no
   height of their own. */
.page-hero--compact { min-height: 0; }
.page-hero--compact .page-hero__inner { padding-block: clamp(1.75rem, 3.5vw, 2.75rem); }
.page-hero--compact h1 { margin-bottom: var(--s-3); }
.page-hero--compact p { margin-bottom: var(--s-5); }

/* Section links. Pills rather than a list, so four of them fit on one line
   on a laptop and wrap tidily on a phone. */
.jump-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin: 0;
  padding: 0;
  list-style: none;
}
/* .jump-links sets margin:0 for use anywhere; inside a hero it sits directly
   under the intro paragraph, which itself has margin-bottom:0, so the pills
   would touch the text. Applies to the FAQ hero too, which had the same gap. */
.page-hero .jump-links { margin-top: var(--s-5); }

.jump-links a {
  display: inline-block;
  padding: 0.48rem 1rem;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.88rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: background 0.16s var(--ease), border-color 0.16s var(--ease);
}
.jump-links a:hover,
.jump-links a:focus-visible {
  background: var(--orange-500);
  border-color: var(--orange-500);
  color: #fff;
  text-decoration: none;
}

/* Three of the Our Story jump targets sit under an eyebrow label ("Who we are",
   "What we believe", "The facility"). html already sets scroll-padding-top for
   the sticky header, which stops exactly on the <h2> and leaves that eyebrow -
   the words the reader just clicked - hidden above the fold. These reserve
   enough extra room for the label to land on screen with its heading. */
.split__body > h2[id],
.section-head > h2[id] { scroll-margin-top: 2.4rem; }

.page-hero h1 { color: #fff; margin-bottom: var(--s-4); }
.page-hero p {
  color: #d3cbe9;
  font-size: clamp(1.02rem, 1.5vw, 1.18rem);
  max-width: 640px;
  margin-bottom: 0;
}

/* Breadcrumb. Elementor: Breadcrumbs widget */
.breadcrumb {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  list-style: none; margin: 0 0 var(--s-4); padding: 0;
  font-size: 0.85rem; color: var(--purple-200);
}
.breadcrumb li { margin: 0; }
.breadcrumb a { color: var(--purple-200); }
.breadcrumb a:hover { color: #fff; }
.breadcrumb__sep { opacity: 0.5; }
.breadcrumb [aria-current] { color: var(--orange-400); }

/* --------------------------------------------------------------------------
   8. CARDS
   Elementor: Image Box widget, or Container + Image + Heading + Text
   -------------------------------------------------------------------------- */
.card {
  display: flex;
  flex-direction: column;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform 0.22s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}
.card:hover { transform: translateY(-5px); box-shadow: var(--glow-card); border-color: transparent; }

.card__media { position: relative; overflow: hidden; background: var(--bg-3); }
.card__media img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 0.5s var(--ease);
}
.card:hover .card__media img { transform: scale(1.05); }

.card__body { display: flex; flex-direction: column; flex: 1; padding: var(--s-5); gap: var(--s-3); }
.card__body h3 { margin: 0; font-size: 1.28rem; }
.card__body p { margin: 0; color: var(--text-muted); font-size: 0.98rem; }

.card__link {
  margin-top: auto;
  padding-top: var(--s-2);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--orange-600);
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.card__link::after { content: "\2192"; transition: transform 0.2s var(--ease); }
.card:hover .card__link::after { transform: translateX(4px); }

/* Whole card clickable without JS */
.card--link { position: relative; }
.card--link .card__stretch::after { content: ""; position: absolute; inset: 0; }

/* Card on a dark section */
.section--dark .card, .section--mid .card {
  background: var(--purple-700);
  border-color: rgba(255, 255, 255, 0.11);
}
.section--dark .card h3, .section--mid .card h3 { color: #fff; }
.section--dark .card p, .section--mid .card p { color: var(--purple-200); }
.section--dark .card:hover, .section--mid .card:hover { border-color: var(--orange-500); }

/* --------------------------------------------------------------------------
   9. ICON BOX
   Elementor: Icon Box widget
   -------------------------------------------------------------------------- */
.icon-box { display: flex; flex-direction: column; gap: var(--s-3); }
.icon-box--center { text-align: center; align-items: center; }

/* Circular outlined badge — a thin violet ring on a faintly lit disc. */
.icon-box__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 62px;
  height: 62px;
  flex-shrink: 0;
  border-radius: 50%;
  background: radial-gradient(circle at 50% 40%, rgba(139, 92, 246, 0.28), rgba(139, 92, 246, 0.07));
  border: 1.5px solid rgba(167, 139, 250, 0.55);
  color: var(--violet-400);
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.icon-box__icon svg { width: 26px; height: 26px; }

.icon-box:hover .icon-box__icon,
.card:hover .icon-box__icon {
  border-color: var(--orange-500);
  color: var(--orange-400);
  box-shadow: 0 0 22px rgba(255, 85, 0, 0.30);
}

/* Accent variant for steps and anything that should read warm from the start */
.icon-box__icon--accent {
  background: radial-gradient(circle at 50% 40%, rgba(255, 85, 0, 0.30), rgba(255, 85, 0, 0.08));
  border-color: rgba(255, 122, 51, 0.6);
  color: var(--orange-400);
}

.icon-box h3, .icon-box h4 { margin: 0; font-size: 1.14rem; }
/* Body colour, not the muted one. These sit at 0.97rem in multi-column grids
   where the line is short and the eye is scanning, so the dimmer tone was
   costing more than it bought. */
.icon-box p { margin: 0; font-size: 0.97rem; color: var(--text-body); }
.section--dark .icon-box p, .section--mid .icon-box p { color: var(--purple-200); }

/* Horizontal variant */
.icon-box--row { flex-direction: row; align-items: flex-start; gap: var(--s-4); }
.icon-box--row .icon-box__content { display: flex; flex-direction: column; gap: var(--s-2); }

/* --------------------------------------------------------------------------
   10. NUMBERED STEPS  (How It Works)
   Elementor: Icon Box widget with a number in place of the icon, or Counter
   -------------------------------------------------------------------------- */
.step {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: var(--s-6) var(--s-5);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-top: 4px solid var(--orange-500);
  border-radius: var(--radius-lg);
  height: 100%;
}
.step__num {
  font-family: var(--font-head);
  font-size: 2.6rem;
  font-weight: 800;
  line-height: 1;
  color: var(--orange-500);
  letter-spacing: -0.04em;
}
.step h3 { margin: 0; font-size: 1.18rem; }
.step p { margin: 0; font-size: 0.96rem; color: var(--text-muted); }

.section--dark .step, .section--mid .step {
  background: var(--purple-700);
  border-color: rgba(255, 255, 255, 0.1);
  border-top-color: var(--orange-500);
}
.section--dark .step h3, .section--mid .step h3 { color: #fff; }
.section--dark .step p, .section--mid .step p { color: var(--purple-200); }

/* ---- Connected step timeline (homepage How It Works) --------------------
   A horizontal run of circular icons joined by a dashed rule. The connector
   is drawn on the row, behind the steps, so it never affects layout.
   Elementor: Container (row) + Icon Box widgets; add .steps-rail to the row. */
.steps-rail { position: relative; }
.steps-rail::before {
  content: "";
  position: absolute;
  top: 31px;                 /* centre of the 62px icon */
  left: 10%;                 /* centre of the first of five equal columns */
  right: 10%;                /* centre of the last */
  border-top: 2px dashed rgba(167, 139, 250, 0.35);
  z-index: 0;
}
.steps-rail > * { position: relative; z-index: 1; }

/* All five steps share one line on wide screens.
   The `.row` default is `flex: 1 1 260px`, and five 260px columns cannot fit a
   1200px container, so the run broke into an ugly 4 + 1. Equal flexible
   columns (basis 0) divide the row exactly five ways instead, which is also
   what lets the connector's 10%/90% endpoints land under the first and last
   icons.
   Elementor: `.step-mini` is a child CONTAINER of the row, not a widget, so
   the class is on the element itself and `> *` matches it directly.
   The selector is `.row.steps-rail`, not `.steps-rail`, because the compat
   layer late in this file carries `.elementor .row > * { flex: 1 1 260px }`.
   At EQUAL specificity that rule wins on document order, so the doubled
   class is load-bearing rather than decorative. Do not simplify it away. */
@media (min-width: 1024px) {
  .row.steps-rail > *,
  .elementor .row.steps-rail > * { flex: 1 1 0; min-width: 0; }
}

/* Below that, five across stops being legible. Drop to three and hide the
   connector rather than leave it pointing at nothing. */
@media (max-width: 1023px) {
  .steps-rail::before { display: none; }
  .row.steps-rail > *,
  .elementor .row.steps-rail > * { flex: 1 1 calc(33.333% - var(--s-4)); }
}
@media (max-width: 639px) {
  .row.steps-rail > *,
  .elementor .row.steps-rail > * { flex: 1 1 100%; }
}

.step-mini { display: flex; flex-direction: column; align-items: center; text-align: center; gap: var(--s-3); }
.step-mini__label {
  display: flex; align-items: baseline; gap: 0.45rem;
  font-family: var(--font-head); font-weight: 800; font-size: 1.05rem; color: var(--text-strong);
}
.step-mini__label b { color: var(--orange-500); font-size: 1.15rem; }
.step-mini p { margin: 0; font-size: 0.93rem; color: var(--text-dim); max-width: 24ch; }


/* ---- Statement bar ------------------------------------------------------
   The full-width claim strip that sits directly under the hero.
   Elementor: Container (row) + Image + Text Editor, class `statement`. */
.statement {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-5) var(--s-6);
  background: linear-gradient(90deg, rgba(46, 22, 87, 0.9), rgba(36, 16, 70, 0.75));
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.statement__mark { flex-shrink: 0; width: 64px; }
.statement__mark img { width: 100%; height: auto; }
.statement__rule { width: 2px; align-self: stretch; background: var(--orange-500); border-radius: 2px; flex-shrink: 0; }
.statement p {
  margin: 0;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: clamp(1rem, 1.5vw, 1.15rem);
  line-height: 1.5;
  color: var(--text-strong);
}
/* .statement is a flex row, so the two lines need a wrapper or they sit side
   by side next to the mark and rule. */
.statement__body { display: flex; flex-direction: column; gap: var(--s-2); }
/* Needs the extra class on the left to outrank `.statement p` above. */
.statement .statement__sub {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: 0.97rem;
  color: var(--text-body);
}
@media (max-width: 767px) {
  .statement { flex-direction: column; text-align: center; gap: var(--s-4); }
  .statement__rule { width: 48px; height: 2px; align-self: center; }
}

/* Large, alternating step blocks for the How It Works page */
.step-block {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-7);
  align-items: center;
  padding-block: var(--s-7);
  border-bottom: 1px solid var(--line);
}
.step-block:last-child { border-bottom: 0; }
.step-block__media { flex: 1 1 340px; min-width: 0; }
.step-block__media img { border-radius: var(--radius-lg); box-shadow: var(--shadow-md); width: 100%; aspect-ratio: 4/3; object-fit: cover; }
.step-block__body { flex: 1 1 380px; min-width: 0; }
.step-block--reverse { flex-direction: row-reverse; }

.step-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px; height: 52px;
  border-radius: 50%;
  background: var(--orange-500);
  color: #fff;
  font-family: var(--font-head);
  font-size: 1.4rem;
  font-weight: 800;
  margin-bottom: var(--s-4);
}

/* --------------------------------------------------------------------------
   11. MEDIA + TEXT SPLIT
   Elementor: Container (flex row) with two child Containers
   -------------------------------------------------------------------------- */
.split {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}
.split__media { flex: 1 1 400px; min-width: 0; }
.split__body { flex: 1 1 400px; min-width: 0; }
.split--reverse { flex-direction: row-reverse; }

.split__media img {
  width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.split__media--tall img { aspect-ratio: 3 / 4; object-fit: cover; }
.split__media--square img { aspect-ratio: 1 / 1; object-fit: cover; }
.split__media--wide img { aspect-ratio: 4 / 3; object-fit: cover; }

/* A run of .split cards, one per animal, on Our Breeders. .split itself only
   lays out a single row, so stacking several needs the gap declared here
   rather than as a margin on each card, which would collapse unpredictably
   against the section padding at the ends. */
.cham-list {
  display: flex;
  flex-direction: column;
  gap: clamp(3rem, 6vw, 5rem);
}
.cham-list .rule { margin-block: var(--s-4); }

/* Two stacked images offset for visual interest, still pure flex */
.media-pair { display: flex; gap: var(--s-4); align-items: flex-start; }
.media-pair > * { flex: 1 1 0; min-width: 0; }
.media-pair img { border-radius: var(--radius-lg); box-shadow: var(--shadow-md); aspect-ratio: 3/4; object-fit: cover; width: 100%; }
.media-pair__offset { margin-top: var(--s-7); }

/* Photo group: one tall portrait on the left, three frames stacked beside it.
   Lives inside a <figure>, which convert.js treats as a text-editor widget and
   passes through verbatim, so this one set of rules serves the static page and
   Elementor alike - no .elementor override needed.

   The column ratio is not arbitrary. Three 4:3 frames plus two gaps make the
   right column (2.25R + 2g) tall, so at 1.75fr against 1fr the left slot
   resolves to very close to 3:4, which is what don-reynaldo-portrait.jpg is
   cropped to. Changing either number without the other leaves the portrait
   being cover-cropped by the browser.

   The three frames are wrapped in their own flex column rather than being
   placed into three grid rows. Spanning one image across three implicitly
   sized rows makes the row height depend on the spanning item, which resolved
   805px tall instead of 613px and stretched the portrait. One row whose height
   comes from the stack removes the circularity. */
.photo-group {
  display: grid;
  grid-template-columns: 1.75fr 1fr;
  gap: var(--s-3);
  align-items: stretch;
}
.photo-group img {
  display: block;
  width: 100%;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  object-fit: cover;
}
/* .prose img carries margin-block: var(--s-6), which adds 64px to every frame
   in the group and inflated the row to 806px, stretching the portrait to 0.62
   instead of 0.75. It cannot be cancelled by a plain `.photo-group img` rule:
   both selectors score 0-0-1-1 and `.prose img` is declared several hundred
   lines later, so it wins the tie. Hence the two-class selector. The group
   spaces itself with gap. */
.prose .photo-group img { margin: 0; }
.photo-group__main { aspect-ratio: 3 / 4; }
.photo-group__stack {
  display: grid;
  grid-template-rows: repeat(3, auto);
  gap: var(--s-3);
}
.photo-group__stack img { aspect-ratio: 4 / 3; }

/* --------------------------------------------------------------------------
   12. GALLERY
   Elementor: Gallery widget (justified/grid) or Image Carousel
   -------------------------------------------------------------------------- */
.gallery { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.gallery__item {
  flex: 1 1 220px;
  min-width: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-3);
}
.gallery__item img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  transition: transform 0.45s var(--ease);
}
.gallery__item:hover img { transform: scale(1.07); }

.gallery--wide .gallery__item { flex: 1 1 300px; }
.gallery--wide .gallery__item img { aspect-ratio: 4 / 3; }

/* Four tiles in a 2x2. `flex: 1 1 300px` fits three across a 1200px container,
   so a four-tile gallery would strand the fourth on its own row and let
   flex-grow stretch it to the full width. Halves keep the block square.
   The .elementor variant is here because the compat layer late in this file
   repeats `.elementor .gallery__item { flex: 1 1 220px }` and would win. */
@media (min-width: 768px) {
  .gallery--quad > .gallery__item,
  .elementor .gallery--quad > .gallery__item {
    flex: 1 1 calc(50% - var(--s-3));
  }
}

/* Six tiles, one row.
   The default `flex: 1 1 220px` fits only five across a 1200px container, so
   the sixth landed alone on the next row, grew to the full 1152px, and with
   `aspect-ratio: 1/1` became a 1152px square that dwarfed everything above it.
   Equal sixths keep this strip reading as support for the feature gallery
   rather than competing with it.

   Two things the selector is carefully working around, both of which broke
   earlier attempts:
     1. `.gallery--wide` blocks on the other pages also carry `.gallery`, so a
        bare `.gallery > .gallery__item` would match and resize them too. The
        `:not()` keeps this to the plain homepage gallery.
     2. The Elementor compat layer late in this file repeats
        `.elementor .gallery__item { flex: 1 1 220px }`, so the `.elementor`
        variant here has to out-specify it. */
@media (min-width: 1024px) {
  .gallery:not(.gallery--wide) > .gallery__item,
  .elementor .gallery:not(.gallery--wide) > .gallery__item {
    flex: 1 1 calc(16.666% - var(--s-3));
  }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .gallery:not(.gallery--wide) > .gallery__item,
  .elementor .gallery:not(.gallery--wide) > .gallery__item {
    flex: 1 1 calc(33.333% - var(--s-3));
  }
}

/* Feature gallery: one large + others. Flex-only, no grid. */
.gallery-feature { display: flex; flex-wrap: wrap; gap: var(--s-3); }
.gallery-feature__main { flex: 4 1 0; min-width: 0; }
.gallery-feature__main img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-lg); }
.gallery-feature__side { flex: 3 1 0; display: flex; flex-wrap: wrap; align-content: flex-start; gap: var(--s-3); min-width: 0; }
.gallery-feature__side > * { flex: 1 1 calc(50% - var(--s-3)); min-width: 120px; }
.gallery-feature__side img { width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: var(--radius); }

/* --------------------------------------------------------------------------
   13. ACCORDION (FAQ)
   Elementor: Accordion / Toggle widget. Uses native <details> — no JS.
   -------------------------------------------------------------------------- */
.accordion { display: flex; flex-direction: column; gap: var(--s-3); }

.accordion__item {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
}
.accordion__item[open] { border-color: var(--purple-400); box-shadow: var(--shadow-sm); }

.accordion__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-5);
  cursor: pointer;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text-strong);
  list-style: none;
  transition: background-color 0.18s var(--ease);
}
.accordion__q::-webkit-details-marker { display: none; }
.accordion__q:hover { background: var(--bg-1); }

.accordion__icon {
  flex-shrink: 0;
  width: 22px; height: 22px;
  position: relative;
  transition: transform 0.24s var(--ease);
}
.accordion__icon::before, .accordion__icon::after {
  content: "";
  position: absolute;
  background: var(--orange-500);
  border-radius: 2px;
}
.accordion__icon::before { top: 10px; left: 0; width: 22px; height: 2.5px; }
.accordion__icon::after  { left: 10px; top: 0; width: 2.5px; height: 22px; transition: opacity 0.24s var(--ease); }
.accordion__item[open] .accordion__icon { transform: rotate(180deg); }
.accordion__item[open] .accordion__icon::after { opacity: 0; }

.accordion__a { padding: 0 var(--s-5) var(--s-5); color: var(--text-muted); }
.accordion__a > *:first-child { margin-top: 0; }

/* --------------------------------------------------------------------------
   14. TABLES  (care quick-reference specs)
   Elementor: Table widget or a styled Text Editor
   -------------------------------------------------------------------------- */
.table-wrap { overflow-x: auto; margin-bottom: var(--s-5); -webkit-overflow-scrolling: touch; }

.spec-table {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: 0.97rem;
  background: var(--bg-2);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.spec-table th, .spec-table td {
  padding: 0.9rem 1.15rem;
  text-align: left;
  border-bottom: 1px solid var(--line);
}
.spec-table thead th {
  background: var(--purple-600);
  color: #fff;
  font-family: var(--font-head);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.spec-table tbody tr:last-child td { border-bottom: 0; }
.spec-table tbody tr:nth-child(even) { background: var(--bg-1); }
.spec-table td:first-child { font-weight: 600; color: var(--text-strong); }

/* --------------------------------------------------------------------------
   15. CALLOUTS
   Elementor: Container with background + border, or Alert widget
   -------------------------------------------------------------------------- */
.callout {
  display: flex;
  gap: var(--s-4);
  padding: var(--s-5);
  border-radius: var(--radius-lg);
  border-left: 5px solid var(--purple-400);
  background: var(--bg-1);
  margin-bottom: var(--s-5);
}
.callout__icon { flex-shrink: 0; width: 26px; height: 26px; color: var(--purple-500); }
.callout__icon svg { width: 100%; height: 100%; }
.callout__body > *:first-child { margin-top: 0; }
.callout__body > *:last-child { margin-bottom: 0; }
/* Callout headings are h3 for correct document outline, but sized like an h4 */
.callout h3, .callout h4 {
  font-size: 1.15rem;
  letter-spacing: -0.01em;
  margin-bottom: var(--s-2);
}

/* Warning callouts were the last light-theme survivor: a near-white peach panel
   (--orange-100) inherited from before the dark redesign, with the dark theme's
   pale body text still on top. Measured 1.46:1 for body copy and 1.18:1 for the
   bold text, which is where the anti-scam warnings put the email domain. These
   boxes carry the highest-stakes content on the site, so they are now a warm
   tint over the dark page instead.
   `.callout.callout--warning` doubles the class deliberately: the plain
   `.section--dark .callout h3` rule below ties on specificity and would
   otherwise win on document order. */
.callout--warning { border-left-color: var(--orange-500); background: rgba(255, 85, 0, 0.10); }
.callout.callout--warning .callout__icon { color: var(--orange-400); }
.callout.callout--warning h3, .callout.callout--warning h4 { color: var(--orange-400); }

.callout--info { border-left-color: var(--purple-500); }

.section--dark .callout, .section--mid .callout {
  background: rgba(255, 255, 255, 0.06);
  border-left-color: var(--orange-500);
}
.section--dark .callout h3, .section--mid .callout h3,
.section--dark .callout h4, .section--mid .callout h4 { color: #fff; }
.section--dark .callout p, .section--mid .callout p { color: var(--purple-200); }

/* --------------------------------------------------------------------------
   16. BADGES / PILLS
   Elementor: Text Editor with styling, or an Icon List item
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-head);
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.35rem 0.75rem;
  border-radius: 100px;
}
.badge--available { background: #d8f3e0; color: #17663a; }
.badge--waitlist  { background: var(--orange-100); color: var(--orange-600); }
.badge--growing   { background: #e0e7fb; color: #2b3f8f; }
.badge--sold      { background: var(--bg-3); color: var(--text-dim); }

.pill-list { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; padding: 0; margin: 0; }
.pill-list li { margin: 0; }
.pill {
  display: inline-block;
  font-size: 0.87rem;
  font-weight: 500;
  padding: 0.4rem 0.9rem;
  border-radius: 100px;
  background: var(--bg-3);
  color: var(--text-dim);
}
.section--dark .pill, .section--mid .pill { background: rgba(255,255,255,0.1); color: #ded8f0; }

/* Pedigree chips on Our Breeders: a label and its value inside one pill, so
   five facts per animal stay scannable. The label carries the meaning here
   ("Sire" against "Dam Sire"), so it is dimmed but never below the contrast
   floor - it is not decoration. The value takes the brighter body colour so
   the eye lands on the name, not the field. */
/* Two deliberate rows: identity (locale, breeder) above lineage (sire, dam,
   dam's sire). A single wrapping list broke wherever the text happened to run
   out of room, so the split moved as soon as a real name was longer than the
   placeholder. Two lists put the break where it belongs and keep it there. */
/* Clutch reference code. Monospace so a code reads as an identifier rather than
   as prose, and quiet enough that it does not compete with the pairing above. */
.clutch__ref {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--text-dim);
  margin-top: calc(var(--s-2) * -1);
  margin-bottom: var(--s-4);
}

.pill-groups {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.pill--data { color: var(--text-body); }
.pill__label {
  color: var(--text-dim);
  font-size: 0.76rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-right: 0.45rem;
}
.section--dark .pill--data, .section--mid .pill--data { color: #fff; }
.section--dark .pill__label, .section--mid .pill__label { color: var(--purple-200); }

/* --------------------------------------------------------------------------
   17. STAT BAR
   Elementor: Counter widget inside a flex Container
   -------------------------------------------------------------------------- */
.stats { display: flex; flex-wrap: wrap; gap: var(--s-6); }
.stat { flex: 1 1 180px; min-width: 0; text-align: center; }
.stat__num {
  display: block;
  font-family: var(--font-head);
  font-size: clamp(2.2rem, 4.5vw, 3.2rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--orange-500);
  margin-bottom: var(--s-2);
}
.stat__label { font-size: 0.93rem; color: var(--purple-200); line-height: 1.4; }
.section--light .stat__label, .section:not(.section--dark):not(.section--mid) .stat__label { color: var(--text-muted); }

/* --------------------------------------------------------------------------
   18. CHECKLIST
   Elementor: Icon List widget
   -------------------------------------------------------------------------- */
.checklist { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.checklist li {
  display: flex;
  gap: var(--s-3);
  align-items: flex-start;
  margin: 0;
  padding-bottom: var(--s-3);
  border-bottom: 1px dashed var(--line);
}
.checklist li:last-child { border-bottom: 0; padding-bottom: 0; }

.checklist__box {
  flex-shrink: 0;
  width: 22px; height: 22px;
  margin-top: 3px;
  border: 2px solid var(--line-strong);
  border-radius: 5px;
  background: var(--bg-1);
}
/* Icon-led variant of .checklist, used on Contact. Same row rhythm as the tick
   box it replaces (22px, 3px down to sit on the label's cap height) so the two
   variants line up identically; only the mark changes. Orange picks the icons
   out against the card without competing with the link text. */
.checklist--icons .checklist__icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  margin-top: 3px;
  display: grid;
  place-items: center;
  color: var(--orange-500);
}
.checklist--icons .checklist__icon svg { width: 20px; height: 20px; display: block; }

.checklist__text { flex: 1; min-width: 0; }
.checklist__text strong { display: block; color: var(--text-strong); }
.checklist__text span { font-size: 0.93rem; color: var(--text-muted); }

.checklist-card {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-6);
  height: 100%;
}
.checklist-card__head {
  display: flex; align-items: center; gap: var(--s-3);
  margin-bottom: var(--s-5); padding-bottom: var(--s-4);
  border-bottom: 2px solid var(--orange-500);
}
.checklist-card__head h3 { margin: 0; font-size: 1.2rem; }
.checklist-card__head .icon-box__icon { width: 44px; height: 44px; }
.checklist-card__head .icon-box__icon svg { width: 21px; height: 21px; }

/* --------------------------------------------------------------------------
   19. CLUTCH CARD
   Elementor: Container + Image + Heading + Icon List + Button (duplicate per clutch)
   -------------------------------------------------------------------------- */
.clutch {
  display: flex;
  flex-wrap: wrap;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.clutch__media { flex: 1 1 320px; min-width: 0; }
.clutch__media img { width: 100%; height: 100%; min-height: 260px; object-fit: cover; }
.clutch__body { flex: 1.4 1 380px; min-width: 0; padding: var(--s-6); display: flex; flex-direction: column; gap: var(--s-4); }
.clutch__top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-3); justify-content: space-between; }
.clutch__body h3 { margin: 0; }

.clutch__meta { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6); list-style: none; padding: 0; margin: 0; }
.clutch__meta li { margin: 0; }
.clutch__meta dt, .clutch__meta .meta-label {
  font-family: var(--font-head);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 2px;
}
.clutch__meta dd, .clutch__meta .meta-value {
  margin: 0;
  font-weight: 600;
  color: var(--text-strong);
  font-size: 0.98rem;
}

/* --------------------------------------------------------------------------
   20. FORMS
   Elementor: Form widget (Elementor Pro). Field styling maps 1:1.
   -------------------------------------------------------------------------- */
.form { display: flex; flex-direction: column; gap: var(--s-5); }
.form__row { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.form__row > * { flex: 1 1 240px; min-width: 0; }

.field { display: flex; flex-direction: column; gap: var(--s-2); }
.field label {
  font-family: var(--font-head);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text-strong);
}
.field .req { color: var(--orange-500); }
.field__hint { font-size: 0.85rem; color: var(--text-dim); }

.field input,
.field select,
.field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--text-strong);
  background: var(--bg-1);
  padding: 0.85rem 1rem;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius);
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.field textarea { resize: vertical; min-height: 150px; line-height: 1.6; }
.field select { cursor: pointer; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%237c7391' d='M1 1l5 5 5-5'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 1rem center; padding-right: 2.6rem; }

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--orange-500);
  box-shadow: 0 0 0 3px rgba(255, 85, 0, 0.15);
}

.field-check { display: flex; align-items: flex-start; gap: var(--s-3); }
.field-check input { width: 20px; height: 20px; flex-shrink: 0; margin-top: 3px; accent-color: var(--orange-500); }
.field-check label { font-family: var(--font-body); font-weight: 400; font-size: 0.93rem; color: var(--text-muted); letter-spacing: 0; }

.form-card {
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  box-shadow: var(--shadow-md);
}

/* --------------------------------------------------------------------------
   21. CTA BAND
   Elementor: Container, dark background, centred Heading + Button
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  /* background-color, NOT the `background` shorthand. The shorthand resets
     every longhand it does not name, and this rule sits ~1200 lines after
     .cta-band--art, so it was silently wiping that rule's background-image and
     leaving the CTA band with no artwork at all. */
  background-color: var(--purple-900);
  overflow: hidden;
  text-align: center;
}
.cta-band__bg { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.22; }
.cta-band__overlay { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(18,6,39,0.86) 0%, rgba(18,6,39,0.94) 100%); }
.cta-band__inner { position: relative; z-index: 2; padding-block: clamp(3.5rem, 8vw, 6rem); }
.cta-band h2 { color: #fff; max-width: 900px; margin-inline: auto; }
/* White, not --purple-200. This is the closing pitch on sixteen pages, and on
   the home page it now sits over artwork, where the softer tone lost its hold
   on the background. */
.cta-band p { color: #fff; max-width: 600px; margin-inline: auto; margin-bottom: var(--s-6); font-size: 1.08rem; }

/* --------------------------------------------------------------------------
   22. PROSE  (long-form care copy)
   Elementor: Text Editor widget
   -------------------------------------------------------------------------- */
.prose > h2 { margin-top: var(--s-8); }
.prose > h2:first-child { margin-top: 0; }
.prose > h3 { margin-top: var(--s-6); }
.prose img { border-radius: var(--radius-lg); margin-block: var(--s-6); box-shadow: var(--shadow-md); }
.prose figure { margin: var(--s-6) 0; }
.prose figcaption { font-size: 0.88rem; color: var(--text-dim); margin-top: var(--s-3); text-align: center; }
.prose ul li::marker { color: var(--orange-500); }

/* Explanatory diagrams (inline SVG).
   Elementor: the SVG becomes an HTML widget, the caption a Text widget. */
.diagram {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  margin-block: var(--s-7);
}
.diagram__svg { display: block; width: 100%; height: auto; }
.diagram__caption {
  margin: var(--s-4) 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--text-dim);
  text-align: center;
  max-width: 60ch;
  margin-inline: auto;
}
.section--dark .diagram,
.section--mid .diagram { background: rgba(255, 255, 255, 0.05); border-color: rgba(255, 255, 255, 0.12); }

/* In-page contents. Elementor: Table of Contents widget */
.toc {
  background: var(--bg-1);
  border: 1px solid var(--line);
  border-left: 4px solid var(--orange-500);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  margin-bottom: var(--s-7);
}
.toc h2 {
  font-size: 0.8rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: var(--s-3);
}
.toc ol { margin: 0; padding-left: 1.2rem; }
.toc li { margin-bottom: var(--s-2); }
/* Same light-theme leftover as the outline button: --purple-600 on the dark
   --bg-1 panel measured 1.26:1, so every "On this page" link was invisible on
   all six care guides. */
.toc a { color: var(--orange-400); font-weight: 500; }
.toc a:hover { color: #fff; text-decoration: underline; }

/* Prev / next page links */
.pager { display: flex; flex-wrap: wrap; gap: var(--s-4); justify-content: space-between; margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--line); }
.pager a {
  flex: 1 1 240px;
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: var(--s-4) var(--s-5);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  background: var(--bg-2);
  transition: border-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.pager a:hover { border-color: var(--orange-500); text-decoration: none; transform: translateY(-2px); }
.pager span { font-size: 0.76rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--text-dim); font-family: var(--font-head); font-weight: 700; }
.pager strong { font-family: var(--font-head); color: var(--text-strong); font-size: 1.02rem; }
.pager .pager__next { text-align: right; align-items: flex-end; }

/* --------------------------------------------------------------------------
   23. TESTIMONIALS
   Elementor: Testimonial widget + Star Rating widget
   NOTE: EctothermInc has no customer reviews yet, so this section is
   commented out in the HTML. Styles are ready — uncomment the block in
   index.html once real testimonials exist. Do not publish placeholder
   reviews; fabricated testimonials are an FTC problem.
   -------------------------------------------------------------------------- */
.testimonial {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--s-6);
  height: 100%;
}
.stars { display: flex; gap: 3px; color: var(--orange-500); }
.stars svg { width: 18px; height: 18px; }
.testimonial__quote { font-size: 1.03rem; color: var(--text-muted); font-style: italic; margin: 0; }
.testimonial__person { display: flex; align-items: center; gap: var(--s-3); margin-top: auto; }
.testimonial__avatar { width: 46px; height: 46px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.testimonial__name { font-family: var(--font-head); font-weight: 700; color: var(--text-strong); font-size: 0.98rem; }
.testimonial__meta { font-size: 0.86rem; color: var(--text-dim); }

/* --------------------------------------------------------------------------
   24. FOOTER
   Elementor: Footer template — Container (flex row) + Site Logo + Nav Menu +
              Icon List + Social Icons widget
   -------------------------------------------------------------------------- */
.site-footer {
  background-color: var(--bg-0);
  background-image:
    radial-gradient(65% 70% at 100% 0%, rgba(139, 92, 246, 0.11), transparent 64%),
    var(--tex-grain);
  background-repeat: no-repeat, repeat;
  background-position: right top, 0 0;
  color: var(--text-body);
  padding-top: clamp(3rem, 6vw, 4.5rem);
}

.footer-top { display: flex; flex-wrap: wrap; gap: var(--s-7); padding-bottom: var(--s-7); }
.footer-brand { flex: 1.6 1 280px; min-width: 0; }
.footer-brand img { height: 62px; width: auto; margin-bottom: var(--s-4); }
.footer-brand p { font-size: 0.95rem; color: var(--purple-200); max-width: 340px; }

.footer-col { flex: 1 1 170px; min-width: 0; }
.footer-col h3 {
  font-size: 0.8rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: #fff;
  margin-bottom: var(--s-4);
}
.footer-col ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: var(--s-3); }
.footer-col li { margin: 0; }
.footer-col a { color: var(--purple-200); font-size: 0.94rem; }
.footer-col a:hover { color: var(--orange-400); text-decoration: none; }

.social { display: flex; gap: var(--s-3); margin-top: var(--s-5); }
.social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px; height: 42px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.08);
  color: #fff;
  transition: background-color 0.18s var(--ease), transform 0.18s var(--ease);
}
.social a:hover { background: var(--orange-500); transform: translateY(-2px); text-decoration: none; }
.social svg { width: 19px; height: 19px; }

/* Header variant: smaller tiles, and shown only from 1200px up.
   The desktop nav is 646px wide and the CTA 148px, so at the 1025px end of the
   desktop range (the nav collapses to a hamburger at 1024px) there is only
   about 83px of slack in the header row - not enough for three marks without
   crowding the nav. Below 1200px these hide and the drawer copy takes over. */
.social--header { display: none; }
.social--nav { margin-top: var(--s-6); justify-content: center; }

@media (min-width: 1200px) {
  .social--header {
    display: flex;
    margin-top: 0;
    /* The auto margin moves here from .header-cta. The marks sit before the
       button so the primary action still ends the row; if both kept an auto
       margin the free space would divide between them and leave the icons
       stranded beside the nav instead of grouped with the button. */
    margin-left: auto;
    gap: var(--s-2);
    flex-shrink: 0;
  }
  .social--header a { width: 34px; height: 34px; border-radius: 8px; }
  .social--header svg { width: 16px; height: 16px; }
  .header-cta { margin-left: 0; }
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-4);
  align-items: center;
  justify-content: space-between;
  padding-block: var(--s-5);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  font-size: 0.87rem;
  color: var(--text-dim);
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: var(--s-5); }
.footer-bottom a { color: var(--text-dim); }
.footer-bottom a:hover { color: var(--orange-400); }

/* --------------------------------------------------------------------------
   24b. UTILITIES
   These replace what used to be inline style="" attributes. Elementor cannot
   carry inline styles through a template import, so every one-off adjustment
   has to be a real class.
   Elementor: apply under Advanced > CSS Classes.
   -------------------------------------------------------------------------- */
.is-centered { justify-content: center; }
.u-align-start { align-items: flex-start; }

.u-mt-2 { margin-top: var(--s-2); }
.u-mt-3 { margin-top: var(--s-3); }
.u-mt-4 { margin-top: var(--s-4); }
.u-mt-6 { margin-top: var(--s-6); }
.u-mt-7 { margin-top: var(--s-7); }
.u-mb-5 { margin-bottom: var(--s-5); }
.u-mb-6 { margin-bottom: var(--s-6); }
.u-mb-8 { margin-bottom: var(--s-8); }

.u-gap-6 { gap: var(--s-6); }
.u-fs-sm { font-size: 1.1rem; }
.u-list-tight { padding-left: 1.1rem; margin: 0; }

/* Contact page columns */
.form-col--main { flex: 1.5 1 480px; min-width: 0; }
.form-col--side { flex: 1 1 300px; min-width: 0; }

/* Page-hero height variants */
.page-hero--short { min-height: 280px; }
.page-hero--tall  { min-height: 440px; }

/* Card headings link to the card's destination; the link inherits the heading
   colour rather than turning orange. (Was an inline color:inherit.) */
.card__body h3 a { color: inherit; }
.card__body h3 a:hover { color: inherit; text-decoration: none; }

/* --------------------------------------------------------------------------
   25. RESPONSIVE
   Elementor: matches the default Tablet (1024) / Mobile (767) breakpoints
   -------------------------------------------------------------------------- */

/* Tablet */
@media (max-width: 1024px) {
  :root { --header-h: 72px; }

  /* The closed off-canvas panel sits at translateX(100%), which extends the
     document's scroll width. That is contained by `body { overflow-x: hidden }`
     in the base styles, which is enough on its own.

     Do NOT add `html { overflow-x: clip }` here. It was here for a while on the
     theory that `clip` contains overflow without creating a scroll container and
     so is safe for sticky. On the root element it is NOT safe: the root's
     overflow propagates to the viewport, and it silently broke the sticky header
     at every width below 1024px while desktop kept working. Measured, not
     assumed. */

  .brand img { height: 44px; }

  /* Swap the full logo for the compact mark */
  .brand .brand__mark { height: 44px; }

  .nav-toggle { display: flex; }
  .header-cta { display: none; }

  /* Mobile panel — flex column, toggled by aria-expanded (JS toggles the
     attribute only; Elementor's Nav Menu widget does this natively). */
  .nav {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--purple-900);
    border-top: 1px solid rgba(255, 255, 255, 0.1);
    padding: var(--s-5) var(--s-5) var(--s-8);
    overflow-y: auto;
    overscroll-behavior: contain;
    transform: translateX(100%);
    visibility: hidden;
    transition: transform 0.28s var(--ease), visibility 0.28s;
  }
  .nav[data-open="true"] { transform: translateX(0); visibility: visible; }

  .nav__list { flex-direction: column; align-items: stretch; gap: 0; width: 100%; }
  .nav__item { width: 100%; border-bottom: 1px solid rgba(255, 255, 255, 0.08); }

  .nav__link {
    justify-content: space-between;
    font-size: 1.05rem;
    padding: 1rem 0.25rem;
    border-radius: 0;
  }
  .nav__link:hover { background: transparent; }

  /* Submenus expand inline on mobile via <details>/open state */
  .nav__submenu {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0 0 var(--s-3) var(--s-4);
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.28s var(--ease);
  }
  .nav__item[data-open="true"] > .nav__submenu { max-height: 520px; }
  .nav__item[data-open="true"] .nav__caret { transform: rotate(180deg); }
  .nav__submenu a { padding: 0.6rem 0.25rem; font-size: 0.98rem; }
  .nav__submenu a:hover { background: transparent; color: var(--orange-400); }

  /* Mobile CTA pinned inside the panel (.header-cta is hidden at this width) */
  .nav__cta { display: block; margin-top: var(--s-6); }
  .nav__cta .btn { width: 100%; }

  .row--4 > * { flex: 1 1 calc(50% - var(--s-6)); }

  .hero { min-height: auto; }
  .hero__overlay {
    background: linear-gradient(180deg, rgba(18,6,39,0.86) 0%, rgba(18,6,39,0.90) 100%);
  }

  .split--reverse, .step-block--reverse { flex-direction: row; }

}

/* Mobile */
@media (max-width: 767px) {
  body { font-size: 1rem; }

  .container { padding-inline: var(--s-4); }

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

  .split { gap: var(--s-6); }
  .split__media, .split__body { flex: 1 1 100%; }

  .step-block { gap: var(--s-5); padding-block: var(--s-6); }
  .step-block__media, .step-block__body { flex: 1 1 100%; }

  .stats { gap: var(--s-5); }
  .stat { flex: 1 1 40%; }

  .btn-group { flex-direction: column; align-items: stretch; }
  .btn-group .btn { width: 100%; }

  .gallery__item { flex: 1 1 calc(50% - var(--s-3)); }
  .gallery-feature__main { flex: 1 1 100%; }
  .gallery-feature__side { flex: 1 1 100%; }

  .media-pair__offset { margin-top: 0; }

  /* Three frames beside a portrait become unreadable thumbnails on a phone
     (roughly 105px wide), so the group unstacks into one column at full width
     and each photo keeps its own aspect ratio. */
  .photo-group { grid-template-columns: 1fr; }

  .clutch__media img { min-height: 220px; }
  .clutch__body { padding: var(--s-5); }

  .accordion__q { padding: var(--s-4); font-size: 1rem; }
  .accordion__a { padding: 0 var(--s-4) var(--s-4); }

  .footer-top { gap: var(--s-6); }
  .footer-brand { flex: 1 1 100%; }
  .footer-col { flex: 1 1 calc(50% - var(--s-6)); }
  .footer-bottom { justify-content: flex-start; }

  .pager a { flex: 1 1 100%; }
  .pager .pager__next { text-align: left; align-items: flex-start; }

  .callout { flex-direction: column; gap: var(--s-3); }
}

/* --------------------------------------------------------------------------
   26. MOTION + PRINT
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ==========================================================================
   27. ELEMENTOR COMPATIBILITY LAYER
   --------------------------------------------------------------------------
   Only relevant on the WordPress build. Elementor wraps every widget in
   .elementor-widget > .elementor-widget-container, and makes every container
   a flex box — neither of which the static markup has. These rules reconcile
   the two so a single stylesheet drives both.

   Harmless on the static site: none of these selectors match there.
   ========================================================================== */

/* --- Containers ----------------------------------------------------------
   Elementor containers default to flex. Our sections are block-level; the
   handful that need flex declare it themselves above and win on source order. */
.elementor .e-con { --display: block; }

/* Elementor sets max-width:100% on direct children of a container, which
   overrides .container's own max-width. Take it back. */
.elementor .container,
.e-con > .container { max-width: var(--container); margin-inline: auto; width: 100%; }
.elementor .container--narrow,
.e-con > .container--narrow { max-width: var(--container-narrow); }

/* Same problem for every other width-constrained block: Elementor's
   `max-width: 100%` on container children overrides them all. */
.elementor .section-head { max-width: 900px; }
.elementor .section-head > p,
.elementor .section-head .elementor-widget-text-editor { max-width: 720px; }
.elementor .section-head.center > p,
.elementor .section-head.center .elementor-widget-text-editor { margin-inline: auto; }
.elementor .hero__content { max-width: 680px; }
.elementor .hero__text { max-width: 560px; }
/* The heading is centred by `margin-inline: auto`, but the heading normaliser
   further down sets `margin: 0` at the SAME specificity and later in the file,
   which silently knocked this heading left of the paragraph and buttons under
   it. Naming the Elementor class raises specificity above the normaliser, the
   same way the .prose heading rules do. */
.elementor .cta-band h2,
.elementor .cta-band h2.elementor-heading-title { max-width: 900px; margin-inline: auto; }
.elementor .cta-band p { max-width: 600px; margin-inline: auto; }
.elementor .footer-brand p { max-width: 340px; }

.elementor .elementor-widget-container { min-width: 0; }

/* --- Flex sizing -----------------------------------------------------------
   Elementor's own stylesheet loads AFTER the theme's, and its `.e-con` rule
   sets flex-basis/grow/shrink and width individually. At equal specificity the
   later rule wins, which silently flattened every side-by-side layout into a
   stack. Re-declaring these with the `.elementor` prefix raises specificity so
   they win regardless of load order. */
.elementor .e-con { width: auto; }

/* ...but `width: auto` above is two-class specificity, so it beats every
   single-class fixed width and stretches anything meant to stay small.
   Restore those explicitly. */
/* Layout containers must still fill their parent. Without this they shrink to
   fit their content and then centre themselves, pulling the hero copy into the
   middle of the screen instead of sitting left in the 1200px column. */
.elementor .container,
.elementor .hero__inner,
.elementor .page-hero__inner,
.elementor .cta-band__inner,
.elementor .section-head,
.elementor .split__media,
.elementor .split__body   { width: 100%; }

.elementor .rule            { width: 64px; flex-shrink: 0; }
.elementor .center .rule,
.elementor .rule.center-x   { margin-inline: auto; }
/* flex-shrink must be restated too: Elementor's .e-con sets it from a custom
   property, which otherwise squeezes these below their fixed width. */
.elementor .statement__mark { width: 64px; flex-shrink: 0; }
.elementor .statement__rule { width: 2px; flex-shrink: 0; align-self: stretch; }
.elementor .media-pair > *  { width: auto; }

.elementor .row > *          { flex: 1 1 260px; }
.elementor .row--2 > *       { flex: 1 1 calc(50% - var(--s-6)); }
.elementor .row--3 > *       { flex: 1 1 calc(33.333% - var(--s-6)); }
.elementor .row--4 > *       { flex: 1 1 calc(25% - var(--s-6)); }

.elementor .split__media,
.elementor .split__body      { flex: 1 1 400px; }
.elementor .step-block__media { flex: 1 1 340px; }
.elementor .step-block__body  { flex: 1 1 380px; }

.elementor .clutch__media    { flex: 1 1 320px; }
.elementor .clutch__body     { flex: 1.4 1 380px; }

.elementor .gallery__item          { flex: 1 1 220px; }
.elementor .gallery--wide .gallery__item { flex: 1 1 300px; }
.elementor .gallery-feature__main  { flex: 4 1 0; }
.elementor .gallery-feature__side  { flex: 3 1 0; align-content: flex-start; }
.elementor .gallery-feature__side > * { flex: 1 1 calc(50% - var(--s-3)); }
.elementor .media-pair > *         { flex: 1 1 0; }

.elementor .stat             { flex: 1 1 180px; }
.elementor .footer-brand     { flex: 1.6 1 280px; }
.elementor .footer-col       { flex: 1 1 170px; }
.elementor .form-col--main   { flex: 1.5 1 480px; }
.elementor .form-col--side   { flex: 1 1 300px; }
.elementor .form__row > *    { flex: 1 1 240px; }
.elementor .pager a          { flex: 1 1 240px; }

.elementor .icon-box__icon,
.elementor .callout__icon,
.elementor .checklist__box,
.elementor .step-badge,
.elementor .brand,
.elementor .header-cta       { flex-shrink: 0; }

/* --- Images --------------------------------------------------------------
   A custom class on an image widget lands on the WRAPPER, not the <img>, so
   full-bleed backgrounds need their inner image sized explicitly. */
.elementor .elementor-widget-image { text-align: initial; }
.elementor .elementor-widget-image img { display: block; max-width: 100%; }
.elementor .hero__bg img,
.elementor .page-hero__bg img,
.elementor .cta-band__bg img { width: 100%; height: 100%; object-fit: cover; }

/* CRITICAL: a custom class on an image widget lands on the WRAPPER DIV, not
   the <img>. So `object-position` set on .hero__bg does nothing in Elementor —
   it has to be pushed down to the image itself, or the browser crops from the
   centre and takes the top of the chameleon's head off.
   Values mirror the static rules exactly. */
.elementor .hero--art .hero__bg img { object-position: 72% 20%; }
.elementor .page-hero__bg img       { object-position: center center; }

@media (max-width: 900px) {
  .elementor .hero--art .hero__bg img { object-position: 82% 22%; }
}
@media (max-width: 480px) {
  .elementor .hero--art .hero__bg img { object-position: 88% 22%; }
}

/* Aspect-ratio'd images sit one level deeper than in the static markup. */
.elementor .card__media img,
.elementor .gallery__item img,
.elementor .gallery-feature__side img { width: 100%; }
.elementor .gallery-feature__main img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.elementor .clutch__media .elementor-widget-image,
.elementor .clutch__media .elementor-widget-container { height: 100%; }
.elementor .clutch__media img { height: 100%; }

/* --- Buttons -------------------------------------------------------------
   .btn classes land on the widget wrapper. Strip the wrapper back to nothing
   and move the appearance onto Elementor's inner <a>. */
.elementor .elementor-widget-button.btn {
  display: inline-block;
  width: auto;
  padding: 0;
  border: 0;
  background: none;
  box-shadow: none;
  transform: none;
}
.elementor .elementor-widget-button.btn:hover { transform: none; box-shadow: none; }
.elementor .elementor-widget-button .elementor-button-wrapper { line-height: 0; }

.elementor .elementor-widget-button .elementor-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  font-family: var(--font-head);
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.2;
  padding: 0.95rem 1.9rem;
  border: 2px solid transparent;
  border-radius: var(--radius);
  background: var(--purple-600);
  color: #fff;
  transition: transform 0.16s var(--ease), background-color 0.16s var(--ease),
              color 0.16s var(--ease), border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.elementor .elementor-widget-button .elementor-button:hover { transform: translateY(-2px); }

.elementor .btn--primary .elementor-button {
  background: var(--orange-500); color: #fff;
  box-shadow: 0 4px 16px rgba(255, 85, 0, 0.32);
}
.elementor .btn--primary .elementor-button:hover {
  background: var(--orange-600); box-shadow: 0 8px 24px rgba(255, 85, 0, 0.42);
}
.elementor .btn--secondary .elementor-button { background: var(--purple-600); }
.elementor .btn--secondary .elementor-button:hover { background: var(--purple-500); }
.elementor .btn--outline .elementor-button {
  background: transparent; color: var(--text-strong); border-color: var(--line-strong);
}
.elementor .btn--outline .elementor-button:hover {
  border-color: var(--orange-500); color: var(--orange-400); background: var(--bg-2);
}
.elementor .btn--ghost .elementor-button {
  background: transparent; color: #fff; border-color: rgba(255, 255, 255, 0.4);
}
.elementor .btn--ghost .elementor-button:hover { background: rgba(255, 255, 255, 0.1); border-color: #fff; }
.elementor .btn--lg .elementor-button { font-size: 1.05rem; padding: 1.15rem 2.4rem; }
.elementor .elementor-widget-button.btn--block { display: block; width: 100%; }
.elementor .btn--block .elementor-button { display: flex; width: 100%; }

/* --- Elements that used to be flex items ---------------------------------
   Wrapping means these are no longer flex children, so inline elements never
   pick up their width. Blockify them. */
.elementor .callout__icon,
.elementor .icon-box__icon,
.elementor .checklist__box,
.elementor .step-badge { display: flex; }
.elementor .icon-box__icon,
.elementor .callout__icon { align-items: center; justify-content: center; }

/* Widget wrappers standing in for former flex children must not stretch. */
.elementor .callout > .elementor-widget-html,
.elementor .checklist-card__head > .elementor-widget-html,
.elementor .icon-box > .elementor-widget-html { flex-shrink: 0; }

/* --- Elementor Nav Menu ---------------------------------------------------
   The Nav Menu widget emits its own markup (.elementor-nav-menu, .elementor-item,
   .elementor-nav-menu--dropdown) rather than the .nav__link classes the static
   header uses. This maps the widget's structure onto the same design so the
   WordPress header matches the static one, while the menu itself stays editable
   under Appearance > Menus.

   Note the static header's own .nav rules are deliberately NOT reused here —
   they include a fixed off-canvas mobile panel that would fight Elementor's
   built-in mobile dropdown. */

.elementor .site-nav { flex: 1 1 auto; display: flex; justify-content: flex-end; }

/* Reset applies to both menus. The horizontal layout must NOT: Elementor emits
   the same .elementor-nav-menu class for the desktop bar and the mobile
   dropdown, so a bare `display:flex` here lays the mobile panel out as one
   row and collapses it to zero height. Scope the row to the desktop menu. */
.elementor .elementor-nav-menu {
  list-style: none;
  margin: 0;
  padding: 0;
}
.elementor .elementor-nav-menu--main > .elementor-nav-menu {
  display: flex;
  align-items: center;
  gap: var(--s-1);
}
.elementor .elementor-nav-menu li { margin: 0; position: relative; }

/* Mobile dropdown. Elementor drops the panel in normal flow inside its own
   widget wrapper, and that wrapper is position:relative like every Elementor
   widget, so an absolutely positioned panel would size itself to the wrapper
   (a narrow column beside the logo) rather than the header. Making the wrapper
   static hands the containing block back to .header-inner. */
@media (max-width: 1024px) {
  .elementor .header-inner { position: relative; }
  .elementor .elementor-element.elementor-nav-menu--toggle { position: static; }

  .elementor .elementor-nav-menu--dropdown.elementor-nav-menu__container {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    width: auto;
    border-radius: 0;
  }
  .elementor .elementor-nav-menu--dropdown .elementor-nav-menu { display: block; width: 100%; }
  .elementor .elementor-nav-menu--dropdown .elementor-nav-menu li { display: block; width: 100%; }
}

.elementor .elementor-nav-menu a.elementor-item {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-head);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: #e8e4f5;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius);
  white-space: nowrap;
  fill: currentColor;
  transition: color 0.16s var(--ease), background-color 0.16s var(--ease);
}
.elementor .elementor-nav-menu a.elementor-item:hover,
.elementor .elementor-nav-menu a.elementor-item:focus,
.elementor .elementor-nav-menu a.elementor-item.elementor-item-active {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
}
.elementor .elementor-nav-menu a.elementor-item.elementor-item-active { color: var(--orange-400); }

/* Dropdown panel */
.elementor .elementor-nav-menu--dropdown,
.elementor .elementor-nav-menu .sub-menu {
  min-width: 258px;
  background: var(--purple-700);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--s-2);
}
.elementor .elementor-nav-menu a.elementor-sub-item {
  display: block;
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 500;
  color: #ded8f0;
  padding: 0.62rem 0.9rem;
  border-radius: var(--radius);
}
.elementor .elementor-nav-menu a.elementor-sub-item:hover,
.elementor .elementor-nav-menu a.elementor-sub-item:focus {
  background: var(--orange-500);
  color: #fff;
}

/* Burger toggle */
.elementor .elementor-menu-toggle {
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: var(--radius);
  padding: 0.6rem;
}
.elementor .elementor-menu-toggle:hover { background: rgba(255, 255, 255, 0.14); }

/* Mobile dropdown panel */
.elementor .elementor-nav-menu--dropdown.elementor-nav-menu__container {
  background: var(--purple-900);
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 0;
  box-shadow: var(--shadow-lg);
}
.elementor .elementor-nav-menu--dropdown a.elementor-item,
.elementor .elementor-nav-menu--dropdown a.elementor-sub-item {
  font-size: 1.02rem;
  padding: 0.9rem 1.2rem;
  border-radius: 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

/* The header row: logo left, nav centre-right, CTA hard right. */
.elementor .site-header .header-inner { align-items: center; }
.elementor .site-header .brand { flex-shrink: 0; }
.elementor .site-header .header-cta { flex-shrink: 0; }

@media (max-width: 1024px) {
  /* Elementor handles the mobile menu itself; just hide the desktop CTA to
     match the static header's behaviour. */
  .elementor .site-header .header-cta { display: none; }
}

/* Sticky header.
   `.site-header` already carries `position: sticky`, and that works on the
   static site where it is a direct child of <body>. In Elementor it is wrapped
   in <header class="elementor-location-header">, which is exactly as tall as
   the header itself (85px), so sticky has no room to travel and the bar just
   scrolls away. The wrapper IS a direct child of <body>, so make the wrapper
   the sticky element and let the inner one go back to static. */
.elementor-location-header {
  position: sticky;
  top: 0;
  z-index: 1000;
}
.elementor .site-header { position: static; }

/* --- Vertical rhythm ------------------------------------------------------
   Two mirror-image problems caused by widget wrapping:

   1. A <p> that sat among siblings statically is now ALONE inside its widget
      container, so `p:last-child { margin-bottom: 0 }` fires and eats the gap.
   2. Elementor zeroes heading margins, so spacing has to move to the wrapper.

   Both are fixed by moving all vertical spacing onto the widget wrapper, then
   zeroing it inside containers that already space their children with `gap`. */

/* Elementor resets margin and line-height on heading titles (but NOT
   font-size — never override that here, it collapses every heading to body
   size). Restore our line-height with enough specificity to win. */
.elementor h1.elementor-heading-title,
.elementor h2.elementor-heading-title,
.elementor h3.elementor-heading-title,
.elementor h4.elementor-heading-title,
.elementor h5.elementor-heading-title,
.elementor h6.elementor-heading-title { line-height: 1.1; margin: 0; }

/* Content inside a widget never carries its own bottom margin... */
.elementor .elementor-widget-container > *:last-child { margin-bottom: 0; }
/* ...the wrapper does, so spacing is uniform however the widget is nested.

   IMPORTANT: Elementor ships
       .e-con .elementor-widget.elementor-widget { margin-block-end: 0 }
   a doubled class at (0,3,0), setting the LOGICAL property. Every rule below
   therefore repeats `.elementor-widget` to reach (0,4,0) and sets
   `margin-block-end` rather than `margin-bottom`. Drop either half and
   Elementor silently wins, and every stacked paragraph loses its gap. */
.elementor .elementor-widget.elementor-widget-heading,
.elementor .elementor-widget.elementor-widget-text-editor { margin-block-end: var(--s-4); }
.elementor .elementor-widget.elementor-widget:last-child { margin-block-end: 0; }

/* Containers that space children with `gap` must not also carry margins,
   or every stacked item gains a double gap. Mirrors the `margin: 0` rules
   the static stylesheet applies in these same contexts. These tie with the
   rule above at (0,4,0) and win on document order, so they must stay below it. */
.elementor .icon-box > .elementor-widget.elementor-widget,
.elementor .card__body > .elementor-widget.elementor-widget,
.elementor .step > .elementor-widget.elementor-widget,
.elementor .step-mini > .elementor-widget.elementor-widget,
.elementor .clutch__body > .elementor-widget.elementor-widget,
.elementor .clutch__top > .elementor-widget.elementor-widget,
.elementor .stack > .elementor-widget.elementor-widget,
.elementor .checklist-card__head > .elementor-widget.elementor-widget,
.elementor .testimonial > .elementor-widget.elementor-widget,
.elementor .checklist__text > .elementor-widget.elementor-widget,
.elementor .btn-group > .elementor-widget.elementor-widget { margin-block-end: 0; }

/* Callout headings sit tighter to their body text than normal headings. */
.elementor .callout__body > .elementor-widget.elementor-widget-heading { margin-block-end: var(--s-2); }

/* Two contexts where the static design deliberately stacks a paragraph margin
   on top of the container's gap. Re-add it so the spacing matches. */
.elementor .clutch__body > .elementor-widget.elementor-widget-text-editor:not(:last-child) { margin-block-end: var(--s-4); }
.elementor .cta-band .elementor-widget.elementor-widget-text-editor { margin-block-end: var(--s-6); }

/* Long-form guides: `.prose > h2` is a DIRECT-child selector, and Elementor
   buries every heading two divs deeper, so the section spacing was lost.
   Re-apply it to the heading tag itself (the margin collapses out through the
   widget wrapper, which has no padding or border of its own). */
.elementor .prose h2.elementor-heading-title { margin-top: var(--s-8); }
.elementor .prose h3.elementor-heading-title { margin-top: var(--s-6); }
.elementor .prose > .elementor-widget:first-child h2.elementor-heading-title { margin-top: 0; }
/* ...but not headings nested inside a component, which set their own spacing. */
.elementor .prose .callout h2.elementor-heading-title,
.elementor .prose .callout h3.elementor-heading-title,
.elementor .prose .card h3.elementor-heading-title,
.elementor .prose .icon-box h3.elementor-heading-title,
.elementor .prose .toc h2.elementor-heading-title { margin-top: 0; }

/* --- Whole-card links ------------------------------------------------------
   .card--link works by stretching an ::after off the card's heading link to
   cover the card. That needs .card to be the nearest POSITIONED ancestor.
   Elementor breaks it: every widget and container it emits carries
   position:relative, so the overlay sizes itself to the heading widget (about
   204x22px) and only the heading text is clickable. The rest of the card
   highlights on hover but does nothing when clicked.

   Making the card's own wrappers static hands the positioning context back to
   .card. Scoped to .card--link so no other Elementor widget is affected. */
.elementor .card--link .card__body,
.elementor .card--link .card__media,
.elementor .card--link > .elementor-element,
.elementor .card--link .elementor-widget { position: static; }
.elementor .card--link { position: relative; }
/* Above the sibling widgets, which paint later in DOM order. */
.elementor .card--link .card__stretch::after { z-index: 3; }

/* --- Decorative empty elements -------------------------------------------- */
.elementor .rule { min-height: 4px; }
.elementor .hero__overlay,
.elementor .page-hero__overlay,
.elementor .cta-band__overlay { pointer-events: none; }

/* --- Elementor Pro form ---------------------------------------------------
   The form widget is the one place Elementor paints its own field chrome: it
   gives fields a WHITE background but lets the text colour inherit from the
   dark page. Measured live on /contact/ before this block existed:

     selects      #cbc0e4 on #ffffff  = 1.72:1   (theme body colour on white)
     placeholders #9da5ae on #ffffff  = 2.49:1   (Elementor's own default)
     text inputs  #1f2124 on #ffffff  = 16.14:1  (fine - Elementor sets this)

   Only the selects and placeholders were wrong; the inputs were always fine.
   These rules put field text back on the field instead of on the page.
   Note --line-strong is a white 20% border for dark panels, so it is NOT
   usable here; the border below is a literal that reads on white. */
.elementor .elementor-form .elementor-field-group .elementor-field-textual {
  color: #1f2124;
  background-color: #fff;
  border: 1.5px solid #8f87a8;          /* 3.30:1 on white */
  border-radius: var(--radius);
  font-family: var(--font-body);
}
/* 5.34:1 on white, against Elementor's 2.49:1. opacity:1 because Elementor's
   own rule sets opacity 0.6, which would undo the darker colour. */
.elementor .elementor-form .elementor-field-group .elementor-field-textual::placeholder {
  color: #6a6a75;
  opacity: 1;
}
/* The actual cause, found in frontend.min.css:
     .elementor-field-group .elementor-field-textual        { color: #1f2124 }
     .elementor-field-group .elementor-select-wrapper select { color: inherit }
   Elementor sets dark text on every field, then hands <select> back to
   `inherit` - which on this dark theme resolves to the pale body colour.
   That is why the inputs were fine and only the selects were unreadable.
   This override names the wrapper too, so it beats that rule on specificity
   rather than relying on source order. */
.elementor .elementor-form .elementor-field-group .elementor-select-wrapper select.elementor-field-textual {
  color: #1f2124;
}
/* Some platforms paint option rows from the OS menu, not the select. */
.elementor .elementor-form .elementor-field-group select.elementor-field-textual option {
  color: #1f2124;
  background-color: #fff;
}
.elementor .elementor-form .elementor-field-group .elementor-field-textual:focus {
  outline: none;
  border-color: var(--orange-500);
  box-shadow: 0 0 0 3px rgba(255, 85, 0, 0.15);
}
/* Labels sit on the dark page, not on a field, so they keep the light colour. */
.elementor .elementor-form .elementor-field-group > label {
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text-strong);
}
/* --- Form success panel ---------------------------------------------------
   Elementor confirms a send with one line of small green text under the button,
   left below the whole filled-in form. People miss it and submit again.
   assets/js/form-sent.js hides the card's contents on success and appends
   .form-sent in their place. The hide uses a class rather than [hidden]
   because Elementor sets display:flex on container children, which wins. */
.form-sent-hide { display: none !important; }

.form-sent {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--s-4);
  padding: clamp(1.5rem, 5vw, 3rem) 0;
}
.form-sent:focus { outline: none; }
.form-sent__icon {
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  border: 2px solid var(--orange-500);
  background: rgba(255, 85, 0, 0.13);
  color: var(--orange-500);
}
.form-sent__icon svg { width: 30px; height: 30px; }
.form-sent h2 { margin: 0; }
.form-sent p {
  margin: 0;
  max-width: 46ch;
  color: var(--text-body);
}
.form-sent__aside {
  font-size: 0.93rem;
  color: var(--text-dim);
}

/* --- Site banner ----------------------------------------------------------
   One line above the header, printed on wp_body_open by inc/banner.php.
   It sits ABOVE the header in the DOM and is not sticky itself, so it scrolls
   away while the header stays pinned. Announce once, then get out of the way.
   Starts hidden and is revealed by its own script, so someone who dismissed it
   never sees it flash past. */
.site-banner {
  background: var(--bg-2);
  border-bottom: 1px solid var(--line);
  font-size: 0.86rem;
}
.site-banner--sale {
  background: var(--orange-600);
  border-bottom-color: rgba(0, 0, 0, 0.25);
}
.site-banner__inner {
  max-width: var(--container);
  margin-inline: auto;
  padding: 0.38rem var(--s-5);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.2rem 0.8rem;
  line-height: 1.4;
}
.site-banner__text {
  margin: 0;
  color: var(--text-body);
  text-align: center;
}
.site-banner--sale .site-banner__text { color: #fff; font-weight: 600; }

.site-banner__link {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  color: var(--orange-400);
  text-decoration: underline;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.site-banner__link:hover { color: var(--orange-500); }
/* On the orange band an orange link would vanish, so it goes white. */
.site-banner--sale .site-banner__link { color: #fff; }
.site-banner--sale .site-banner__link:hover { color: #fff; opacity: 0.82; }

.site-banner__close {
  position: absolute;
  right: var(--s-4);
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--text-dim);
  cursor: pointer;
}
.site-banner--sale .site-banner__close { color: rgba(255, 255, 255, 0.85); }
.site-banner__close svg { width: 13px; height: 13px; }
.site-banner__close:hover { background: rgba(255, 255, 255, 0.12); color: var(--text-strong); }
.site-banner__inner { position: relative; }

@media (max-width: 640px) {
  /* The close button stops overlapping the text by leaving the flow. */
  .site-banner__inner { padding-right: 3rem; padding-left: var(--s-4); justify-content: flex-start; }
  .site-banner__text { text-align: left; }
}

/* --- Header announcement megaphone ----------------------------------------
   Inserted beside Contact Us by inc/banner.php whenever a banner is active.
   The header is sticky, so this keeps the announcement reachable after the
   strip has scrolled away or been dismissed. */
.banner-alert-wrap { position: relative; display: flex; align-items: center; }

.banner-alert {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  padding: 0;
  border: 1.5px solid rgba(255, 122, 51, 0.55);
  border-radius: 50%;
  background: rgba(255, 85, 0, 0.14);
  color: var(--orange-400);
  cursor: pointer;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease), color 0.18s var(--ease);
}
.banner-alert svg { width: 19px; height: 19px; }
.banner-alert:hover,
.banner-alert[aria-expanded="true"] {
  background: var(--orange-500);
  border-color: var(--orange-500);
  color: #fff;
}
/* A live sale is worth more than a quiet outline. */
.banner-alert--sale {
  background: var(--orange-500);
  border-color: var(--orange-500);
  color: #fff;
}

.banner-alert__pop {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  z-index: 60;
  width: max-content;
  max-width: min(320px, calc(100vw - 2rem));
  padding: var(--s-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--bg-2);
  box-shadow: var(--shadow-md);
  text-align: left;
}
.banner-alert__pop p {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-body);
}
.banner-alert__pop a {
  display: inline-block;
  margin-top: var(--s-3);
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 0.85rem;
  color: var(--orange-400);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.banner-alert__pop a:hover { color: var(--orange-500); }

@media (max-width: 1024px) {
  /* Clear of the burger, and never wider than the screen. */
  .banner-alert { width: 34px; height: 34px; }
  .banner-alert svg { width: 17px; height: 17px; }
  .banner-alert__pop { right: auto; left: 50%; transform: translateX(-50%); }
}

/* --- Away notice ----------------------------------------------------------
   Inserted above the contact form by assets/js/form-sent.js when away mode is
   on in Settings > EctothermInc. Warm rather than alarming: this is a holiday,
   not an outage, and the form still works. */
.away-notice {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  margin-bottom: var(--s-5);
  padding: var(--s-4);
  border: 1px solid rgba(255, 122, 51, 0.45);
  border-left: 3px solid var(--orange-500);
  border-radius: var(--radius);
  background: rgba(255, 85, 0, 0.09);
}
.away-notice__icon {
  flex-shrink: 0;
  color: var(--orange-400);
  margin-top: 1px;
}
.away-notice__icon svg { width: 22px; height: 22px; display: block; }
.away-notice strong {
  display: block;
  font-family: var(--font-head);
  color: var(--text-strong);
  margin-bottom: 2px;
}
.away-notice p {
  margin: 0;
  color: var(--text-body);
  font-size: 0.95rem;
  line-height: 1.55;
}

/* Consent checkbox: Elementor ships the 13px browser default with no rule
   targeting it at all. This matches the static site's .field-check box -
   20px, orange accent, aligned to the first line of the label instead of
   floating against the middle of a wrapped paragraph.

   Deliberately NOT copying the rest of .field-check: that rule also sets the
   label to --text-muted at 0.93rem. Measured on the live card, that would take
   this label from 9.86:1 / 16px down to 5.57:1 / 15px. Both pass, but this is
   the consent statement, so it keeps the contrast and size it has. */
.elementor .elementor-form .elementor-field-type-acceptance .elementor-field-option {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
}
.elementor .elementor-form input[type="checkbox"].elementor-acceptance-field {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  margin: 3px 0 0;
  accent-color: var(--orange-500);
}
/* Elementor leaves this label at a tighter line-height than the rest of the
   form, which is what made the wrapped consent text look cramped. Spacing
   only - colour and size are deliberately untouched, see above. */
.elementor .elementor-form .elementor-field-type-acceptance .elementor-field-option label {
  line-height: 1.5;
}

/* Submit button: the site's orange, not Elementor's grey. */
.elementor .elementor-form button[type="submit"],
.elementor .elementor-form .elementor-button[type="submit"] {
  background-color: var(--orange-500);
  color: #fff;
  font-family: var(--font-head);
  font-weight: 700;
  letter-spacing: 0.02em;
  border: none;
  border-radius: var(--radius);
}
.elementor .elementor-form button[type="submit"]:hover,
.elementor .elementor-form .elementor-button[type="submit"]:hover {
  background-color: var(--orange-600);
  color: #fff;
}

@media print {
  .site-header, .site-footer, .cta-band, .nav-toggle, .pager { display: none !important; }
  body { font-size: 11pt; color: #000; }
  .page-hero { min-height: auto; background: none; }
  .page-hero__bg, .page-hero__overlay { display: none; }
  .page-hero h1, .page-hero p { color: #000; }
  .checklist__box { border-color: #000; }
  .card, .checklist-card, .accordion__item { break-inside: avoid; box-shadow: none; }
  a { color: #000; text-decoration: underline; }
  .section { padding-block: 1rem; }
}
