/**
 * Theme Name: Astra child theme for Space Melbourne
 * Theme URI: https://space-melbourne.com
 * Description: Space Melbourne child theme — Stage 2 Global Foundation
 * Author: Grey Lily Media
 * Author URI: https://greylilymedia.co
 * Template: astra
 * Version: 2.0.0
 * License: GPL-2.0-or-later
 */

/* ==========================================================================
   1. FONT FACES
   Self-hosted WOFF2. 9 files: 6 Newsreader + 3 Public Sans.
   Newsreader italic and regular each share one file per subset across
   weights 400 and 500 (variable font data covers the range).
   Public Sans shares one file per subset across all weights 400–700.
   Preloaded: newsreader-regular-latin + public-sans-latin (via functions.php).
   ========================================================================== */

/* Newsreader — italic — vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-italic-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* Newsreader — italic — latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-italic-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Newsreader — italic — latin */
@font-face {
  font-family: 'Newsreader';
  font-style: italic;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-italic-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Newsreader — regular — vietnamese */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-regular-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* Newsreader — regular — latin-ext */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-regular-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Newsreader — regular — latin */
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/newsreader-regular-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Public Sans — vietnamese (covers weights 400–700) */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/public-sans-vietnamese.woff2') format('woff2');
  unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB;
}
/* Public Sans — latin-ext */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/public-sans-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* Public Sans — latin */
@font-face {
  font-family: 'Public Sans';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('https://space-melbourne.com/wp-content/themes/astra-child/fonts/public-sans-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   2. ROOT TOKENS — Complete approved --sm- system
   ========================================================================== */

:root {

  /* ── Colour ── */
  --sm-ink:            #14181F;   /* Primary dark — nav, footer, dark sections */
  --sm-ink-700:        #1D2530;   /* Dark card / section variant */
  --sm-paper:          #F6F2EA;   /* Primary light background */
  --sm-paper-100:      #EFE7D8;   /* Inset panels, pull-quote bands on Paper */
  --sm-clay:           #B9673D;   /* Primary accent — CTAs, large fills */
  --sm-clay-600:       #9C5330;   /* Clay hover / pressed state */
  --sm-clay-800:       #7C3F20;   /* Text-safe clay — eyebrows/labels on Paper */
  --sm-slate:          #55707A;   /* Secondary accent, used sparingly */
  --sm-line:           #DDD2BC;   /* Hairlines / dividers on Paper */
  --sm-line-ink:       rgba(246,242,234,.16); /* Hairlines on Ink */
  --sm-text-muted:     #5B5648;   /* Secondary text on Paper */
  --sm-text-muted-ink: #AEB4BA;   /* Secondary text on Ink */

  /* ── Typography ── */
  --sm-font-display: 'Newsreader', Georgia, serif;
  --sm-font-body:    'Public Sans', Arial, sans-serif;

  /* ── Fluid type scales (§02) ── */
  --sm-fluid-h1:        clamp(2.25rem, 1.5rem + 3.2vw, 5.5rem);
  --sm-fluid-h2:        clamp(1.75rem, 1.45rem + 1.6vw, 3.25rem);
  --sm-fluid-h3:        clamp(1.375rem, 1.25rem + 0.6vw, 1.875rem);
  --sm-fluid-intro:     clamp(1.125rem, 1.05rem + 0.4vw, 1.375rem);
  --sm-fluid-body-l:    clamp(1.0625rem, 1rem + 0.2vw, 1.25rem);
  --sm-fluid-pullquote: clamp(1.375rem, 1.2rem + 0.7vw, 1.875rem);

  /* ── Spacing scale ── */
  --sm-space-1:  4px;
  --sm-space-2:  8px;
  --sm-space-3:  12px;
  --sm-space-4:  16px;
  --sm-space-5:  24px;
  --sm-space-6:  32px;
  --sm-space-7:  48px;
  --sm-space-8:  64px;
  --sm-space-9:  96px;
  --sm-space-10: 140px;

  /* ── Section vertical padding defaults ── */
  --sm-section-y: var(--sm-space-10);

  /* ── Container widths ── */
  --sm-w-narrow:  640px;
  --sm-w-default: 1180px;
  --sm-w-wide:    1400px;
  --sm-w-full:    100vw;

  /* ── Radius and border ── */
  --sm-radius: 2px;
  --sm-border: 1px solid var(--sm-line);

  /* ── Motion ── */
  --sm-dur-fast:    200ms;
  --sm-dur-base:    500ms;
  --sm-dur-slow:    800ms;
  --sm-dur-hero:    900ms;
  --sm-ease-out:    cubic-bezier(.16,1,.3,1);
  --sm-ease-in-out: cubic-bezier(.65,0,.35,1);

  /* ── Z-index layers ── */
  --sm-z-nav:          50;
  --sm-z-overlay:      40;
  --sm-z-convergence:   5;
}

/* ==========================================================================
   3. BASE / RESET
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { font-size: 100%; scroll-behavior: smooth; }

body {
  background-color: var(--sm-paper);
  color: var(--sm-ink);
  font-family: var(--sm-font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

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

/* ==========================================================================
   4. TYPOGRAPHY
   ========================================================================== */

h1, .sm-display {
  font-family: var(--sm-font-display);
  font-weight: 500;
  font-size: var(--sm-fluid-h1) !important;
  line-height: 1.08 !important;
  letter-spacing: -0.01em;
  max-width: 20ch;
}

h2, .sm-h2 {
  font-family: var(--sm-font-display);
  font-weight: 500;
  font-size: var(--sm-fluid-h2) !important;
  line-height: 1.2 !important;
  max-width: 22ch;
}

h3, .sm-h3 {
  font-family: var(--sm-font-display);
  font-weight: 500;
  font-size: var(--sm-fluid-h3) !important;
  line-height: 1.25 !important;
  max-width: 30ch;
}

/* Stage 4.1 note: the active Elementor Kit's (ID 2015) own default h1/h2/h3
   font-family and colour now match this system directly (fixed at the kit
   level in Stage 4.1), so font-family/colour no longer need !important here.
   font-size and line-height stay !important: the kit can only store a fixed
   px default per breakpoint, not this system's fluid clamp() scale, so a
   real (if narrow) conflict remains there. */

h4 {
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 1.25rem;
  line-height: 1.3;
  max-width: 30ch;
}

h5 {
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 1.0625rem;
  line-height: 1.35;
  max-width: 32ch;
}

h6 {
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  max-width: 36ch;
}

p, li, td, th {
  font-family: var(--sm-font-body);
  max-width: 70ch;
}

a {
  color: var(--sm-clay-800);
  text-decoration: none;
  transition: color var(--sm-dur-fast) var(--sm-ease-out);
}
a:hover {
  color: var(--sm-clay-600);
  text-decoration: underline;
}

.sm-eyebrow {
  display: block;
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 0.8125rem;
  line-height: 1.3;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  color: inherit;
}

.sm-intro {
  font-family: var(--sm-font-body);
  font-weight: 400;
  font-size: var(--sm-fluid-intro);
  line-height: 1.6;
  max-width: 62ch;
}

.sm-body-l {
  font-family: var(--sm-font-body);
  font-weight: 400;
  font-size: var(--sm-fluid-body-l);
  line-height: 1.65;
  max-width: 74ch;
}

.sm-caption {
  font-family: var(--sm-font-body);
  font-weight: 500;
  font-size: 0.8125rem;
  line-height: 1.5;
  max-width: 40ch;
  color: var(--sm-text-muted);
}

.sm-pullquote,
blockquote.sm-pullquote {
  font-family: var(--sm-font-display);
  font-weight: 400;
  font-style: italic;
  font-size: var(--sm-fluid-pullquote);
  line-height: 1.5;
  max-width: 56ch;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
}

hr, .sm-rule {
  border: none;
  border-top: var(--sm-border);
  margin: var(--sm-space-7) 0;
}

/* ==========================================================================
   5. LAYOUT UTILITIES
   ========================================================================== */

.sm-section {
  position: relative;
  width: 100%;
  padding-top: var(--sm-section-y);
  padding-bottom: var(--sm-section-y);
}

.sm-section__inner,
.sm-inner {
  max-width: var(--sm-w-default);
  /* Stage 5C: Elementor's own .e-con core rule sets margin-inline-start/end
     via CSS custom properties at the same specificity (single class), and
     wins the cascade when those properties resolve to 0 — silently
     left-anchoring every section wrapper instead of centring it. !important
     forces our centring to win regardless of load order, matching the same
     fix already applied to .sm-hero and .sm-credibility-strip. */
  margin-inline: auto !important;
  padding-inline: var(--sm-space-6);
}

.sm-wide {
  max-width: var(--sm-w-wide);
  margin-inline: auto !important;
  padding-inline: var(--sm-space-6);
}

.sm-narrow {
  max-width: var(--sm-w-narrow);
  margin-inline: auto !important;
  padding-inline: var(--sm-space-6);
}

.sm-stack {
  display: flex !important;
  flex-direction: column;
  gap: var(--sm-space-5);
}

.sm-split {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  gap: var(--sm-space-8);
  align-items: start !important;
}

.sm-split > .e-con {
  width: auto !important;
  flex: none !important;
}

.sm-grid-4 {
  display: grid !important;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--sm-space-6);
}

.sm-flow > * + * { margin-top: var(--sm-space-5); }

.elementor-section.elementor-section-boxed > .elementor-container,
.e-con-inner { max-width: var(--sm-w-default); }

/* ==========================================================================
   6. SECTION THEMES
   ========================================================================== */

.sm-theme-paper {
  background-color: var(--sm-paper);
  color: var(--sm-ink);
}
.sm-theme-paper a           { color: var(--sm-clay-800); }
.sm-theme-paper a:hover     { color: var(--sm-clay-600); }
.sm-theme-paper .sm-eyebrow { color: var(--sm-clay-800); }

.sm-theme-ink {
  background-color: var(--sm-ink);
  color: var(--sm-paper);
}
.sm-theme-ink a               { color: var(--sm-clay); }
.sm-theme-ink a:hover          { color: var(--sm-clay-600); }
.sm-theme-ink .sm-eyebrow      { color: var(--sm-clay); }
.sm-theme-ink .sm-caption      { color: var(--sm-text-muted-ink); }
.sm-theme-ink hr,
.sm-theme-ink .sm-rule         { border-color: var(--sm-line-ink); }
.sm-theme-ink h1, .sm-theme-ink h2, .sm-theme-ink h3,
.sm-theme-ink h4, .sm-theme-ink h5, .sm-theme-ink h6 { color: var(--sm-paper) !important; }
.sm-theme-ink p, .sm-theme-ink li { color: var(--sm-paper); }
/* CSS audit: .sm-theme-ink .sm-caption's colour is already set (and already
   wins on specificity, no !important needed) by the inline rule above in
   this same section — the duplicate !important declaration that used to
   sit here was fully redundant and has been removed. */

.sm-theme-clay-tint {
  background-color: var(--sm-paper-100);
  color: var(--sm-ink);
}
.sm-theme-clay-tint a           { color: var(--sm-clay-800); }
.sm-theme-clay-tint a:hover     { color: var(--sm-clay-600); }
.sm-theme-clay-tint .sm-eyebrow { color: var(--sm-clay-800); }

.sm-theme-editorial {
  background-color: var(--sm-paper);
  color: var(--sm-ink);
}
.sm-theme-editorial > .sm-inner { max-width: var(--sm-w-narrow); }

.sm-theme-image-led {
  background-color: var(--sm-ink);
  color: var(--sm-paper);
  overflow: hidden;
}
.sm-theme-image-led h1, .sm-theme-image-led h2, .sm-theme-image-led h3,
.sm-theme-image-led h4, .sm-theme-image-led h5, .sm-theme-image-led h6,
.sm-theme-image-led p, .sm-theme-image-led li { color: var(--sm-paper) !important; }
.sm-theme-image-led .sm-eyebrow { color: var(--sm-clay) !important; }

/* ==========================================================================
   7. BUTTONS
   ========================================================================== */

.sm-button,
.sm-button.elementor-button,
.elementor-button-wrapper .elementor-button,
.elementor-widget-button .elementor-button,
.wp-block-button__link,
a.button,
button,
input[type="submit"] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--sm-paper);
  background-color: var(--sm-clay);
  border: none;
  border-radius: var(--sm-radius);
  padding: 14px 28px;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out),
              color var(--sm-dur-fast) var(--sm-ease-out);
}

.sm-button:hover,
.sm-button.elementor-button:hover,
.elementor-button-wrapper .elementor-button:hover,
.elementor-widget-button .elementor-button:hover,
.wp-block-button__link:hover,
a.button:hover,
button:hover,
input[type="submit"]:hover {
  background-color: var(--sm-clay-600);
  color: var(--sm-paper);
  text-decoration: none;
}

.sm-button--outline {
  background-color: transparent;
  color: var(--sm-clay);
  border: 1px solid var(--sm-clay);
}
.sm-button--outline:hover {
  background-color: var(--sm-clay);
  color: var(--sm-paper);
}

.sm-theme-ink .sm-button--outline {
  color: var(--sm-paper);
  border-color: var(--sm-paper);
}
.sm-theme-ink .sm-button--outline:hover {
  background-color: var(--sm-paper);
  color: var(--sm-ink);
}

.ast-btn, .ast-outline-btn, .astra-button,
.elementor-button { border-radius: var(--sm-radius) !important; }

/* ==========================================================================
   8. IMAGE TREATMENTS
   ========================================================================== */

.sm-image {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0;
}
/* Stage 6.1 fix: as with the portrait/landscape/square modifiers below,
   .sm-image itself only ever lands on the Elementor wrapper element in
   this project, never on the <img> directly — so the actual image was
   never told to fill its container width. On any image whose registered
   WordPress size is narrower than its Elementor column (e.g. the built-in
   "large" size, 1024px, inside a wider split-section column), this left
   the image sitting at its native pixel width with visible empty space
   beside it, rather than filling and cropping to the column as designed. */
.sm-image img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 0;
}
/* Stage 6.1 fix: Elementor's _css_classes control places sm-image--* on the
   widget's outer wrapper element, never on the inner <img>. aspect-ratio
   affects layout (unlike object-fit/object-position, which are no-ops on a
   non-replaced element), so applying it to that wrapper forced its own box
   to an inflated height derived purely from its width (e.g. a 1360px-wide
   wrapper was forced to 1700px tall) regardless of the image's real
   rendered size — creating large false empty space beneath the image and
   pushing every section below it down the page. Targeting the descendant
   img (or an img carrying the class directly, for any future non-Elementor
   usage) fixes this without changing the visual crop treatment. */
.sm-image--portrait img,
img.sm-image--portrait {
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center top;
}
.sm-image--landscape img,
img.sm-image--landscape {
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.sm-image--square img,
img.sm-image--square {
  aspect-ratio: 1;
  object-fit: cover;
}

/* ==========================================================================
   9. COMPONENT SKELETONS
   ========================================================================== */

.sm-capability-list {
  list-style: none;
  padding: 0;
  margin: var(--sm-space-6) 0 0;
  border-top: var(--sm-border);
}
.sm-capability-list__item {
  border-bottom: var(--sm-border);
}
.sm-capability-list__item a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sm-space-4);
  padding: var(--sm-space-4) 0;
  font-family: var(--sm-font-body);
  font-size: var(--sm-fluid-body-l);
  font-weight: 500;
  text-decoration: none;
  transition: padding-left var(--sm-dur-fast) var(--sm-ease-out);
}
.sm-capability-list__item a::after {
  content: "\2192";
  font-size: 0.9em;
  opacity: 0.55;
  flex-shrink: 0;
  transition: transform var(--sm-dur-fast) var(--sm-ease-out), opacity var(--sm-dur-fast) var(--sm-ease-out);
}
.sm-capability-list__item a:hover {
  padding-left: var(--sm-space-2);
}
.sm-capability-list__item a:hover::after {
  transform: translateX(4px);
  opacity: 1;
}

/* ---- Training: distinct image treatment from Facilitation (landscape
   crop + clay accent rule) so the two sections read as complementary,
   not repeated, compositions. ------------------------------------- */
.sm-image--training::before {
  content: "";
  display: block;
  height: 3px;
  width: 64px;
  background-color: var(--sm-clay);
  margin-bottom: var(--sm-space-5);
}

/* ---- Process: strengthen the static signature-diagram treatment so the
   01-05 sequence reads as a deliberate progression without relying on
   the (currently disabled) GSAP step-highlight. Larger index numerals,
   a clay accent on the final "Action" step to mark the resolution point
   (echoing the Convergence Mark's resolved/aligned state), and directional
   connectors between steps at the desktop row layout only. ------------- */
.sm-process__step-index {
  font-size: 1.375rem;
}
.sm-process__step:last-child .sm-process__step-index,
.sm-process__step:last-child .sm-process__step-label {
  color: var(--sm-clay);
}
.sm-process__step:last-child {
  border-top-color: var(--sm-clay);
}
@media (min-width: 1101px) {
  .sm-process__step { position: relative; }
  .sm-process__step:not(:last-child)::after {
    content: "\2192";
    position: absolute;
    top: 0;
    right: -21px;
    transform: translateY(-50%);
    color: var(--sm-text-muted-ink);
    font-size: 0.9rem;
  }
}

/* ---- Leadership: editorial profile composition. Space Bangkok is now a
   designed relationship inside the bio column (ruled aside), not a
   separately stacked full-width block below the profile row. Asymmetric
   split gives the bio + related copy more room than the portrait. The
   single .sm-profile-row pattern (see below) can accept a second row for
   a future Jenn profile without needing structural rework. ------------ */
.sm-profile--asym {
  grid-template-columns: 0.8fr 1.2fr;
}
.sm-profile__related {
  margin-top: var(--sm-space-6);
  padding-top: var(--sm-space-5);
  border-top: var(--sm-border);
}
.sm-profile__related .sm-eyebrow {
  margin-bottom: var(--sm-space-2);
}
.sm-profile__related p:not(.sm-eyebrow) {
  font-size: 0.9375rem;
  color: var(--sm-text-muted);
  max-width: 60ch;
}

/* Alpaca 2092: photo of Jenn Weidman (Charlie + Jenn together) added
   above the Space Bangkok mention in the Leadership profile, as a
   placeholder until Charlie supplies alternative imagery. Full-width
   landscape image (sized up per Troy's follow-up request — originally a
   small 96px thumbnail, now spans the whole .sm-profile__related block's
   width) sitting above the existing eyebrow/paragraph text, without
   disturbing the primary Charlie portrait in the split layout above it. */
.sm-profile__related-media {
  width: 100% !important;
  margin-bottom: var(--sm-space-4);
}
.sm-profile__related-media .sm-image {
  border-radius: 4px;
  overflow: hidden;
}

/* CSS audit: gap/align-items merged into the canonical .sm-process__steps
   rule in §15 (STAGE 4) — this was a duplicate partial rule for the same
   selector left over from Stage 5B's Process strengthening pass. */

.sm-profile {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  gap: var(--sm-space-8);
  align-items: start;
}

.sm-credibility-strip {
  display: grid !important;
  grid-template-columns: repeat(4, 1fr) !important;
  gap: var(--sm-space-6) var(--sm-space-7);
  align-items: start;
}
.sm-credibility-strip > .e-con {
  width: auto !important;
  flex: none !important;
  padding-left: var(--sm-space-6);
  border-left: var(--sm-border);
}
.sm-credibility-strip > .e-con:first-child {
  padding-left: 0;
  border-left: none;
}
.sm-hero__actions > .e-con,
.sm-hero__actions > .elementor-widget-button { width: auto !important; flex: 0 0 auto !important; }
/* Stage 5: fixed a real horizontal-overflow bug — at narrow widths above
   the 480px column-stack breakpoint, a long credibility-strip value
   (e.g. "Peacebuilding · Resilience · Leadership") would not wrap and
   pushed the whole page wider than the viewport. min-width:0 lets the
   flex item shrink and wrap its text instead of forcing overflow. */
.sm-credibility-strip > .e-con { min-width: 0; max-width: 100%; }
.sm-credibility-strip__label {
  display: block;
  font-family: var(--sm-font-body);
  font-size: 0.8125rem;
  color: var(--sm-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.sm-credibility-strip__value {
  display: block;
  font-family: var(--sm-font-display);
  font-size: var(--sm-fluid-h3);
  font-weight: 500;
  line-height: 1.15;
}
@media (max-width: 768px) {
  .sm-credibility-strip {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}

/* ---- Footer: the footer-menu widget area was computing display:none
   (cause not traced to any rule in this stylesheet or Astra's own
   generated CSS — likely an Astra builder state issue), silently
   dropping the key-links row the brief requires (Facilitation, Training,
   How We Work, About, Insights, Contact all exist in the menu itself,
   just never painted). Force it visible and give it a restrained,
   small-type treatment consistent with the rest of the footer. -------- */
.footer-widget-area[data-section="section-footer-menu"] {
  display: block !important;
}
#astra-footer-menu.astra-footer-horizontal-menu {
  gap: var(--sm-space-5);
  flex-wrap: wrap;
}
#astra-footer-menu .menu-link {
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}

.sm-article-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.sm-article-list__item {
  padding-block: var(--sm-space-6);
  border-top: var(--sm-border);
}
.sm-article-list__item:last-child { border-bottom: var(--sm-border); }

.sm-case-study-row {
  display: grid !important;
  grid-template-columns: 1fr 2fr;
  gap: var(--sm-space-6);
  padding-block: var(--sm-space-6);
  border-top: var(--sm-border);
}

.sm-related-band {
  display: flex !important;
  align-items: baseline;
  gap: var(--sm-space-5);
  padding-block: var(--sm-space-7);
  border-top: var(--sm-border);
}

.sm-cta,
.sm-cta.sm-inner {
  text-align: center;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  max-width: 640px;
}
.sm-cta .sm-inner { max-width: 640px; }
.sm-cta .elementor-widget-button,
.sm-cta > .e-con { width: auto !important; flex: 0 0 auto !important; }

/* ==========================================================================
   10. CONVERGENCE MARK
   Static state. Motion added in Stage 3.
   ========================================================================== */

.sm-convergence {
  position: relative;
  display: flex !important;
  align-items: center;
  gap: 4px;
  width: 260px;
  height: 90px;
  overflow: visible;
  z-index: var(--sm-z-convergence);
}

.sm-convergence__bar {
  display: block;
  width: 46px;
  height: 3px;
  border-radius: var(--sm-radius);
  transform-origin: center;
  flex-shrink: 0;
  transition: transform var(--sm-dur-slow) var(--sm-ease-out),
              opacity var(--sm-dur-slow) var(--sm-ease-out);
}

.sm-convergence__bar:nth-child(1) { background: var(--sm-text-muted-ink); }
.sm-convergence__bar:nth-child(2) { background: var(--sm-clay); }
.sm-convergence__bar:nth-child(3) { background: var(--sm-text-muted-ink); }
.sm-convergence__bar:nth-child(4) { background: var(--sm-paper); }
.sm-convergence__bar:nth-child(5) { background: var(--sm-clay); }
.sm-convergence__bar:nth-child(6) { background: var(--sm-text-muted-ink); }
.sm-convergence__bar:nth-child(7) { background: var(--sm-text-muted-ink); }

.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(1) { transform: rotate(-32deg); opacity: 0.6; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(2) { transform: rotate(-16deg); opacity: 0.7; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(3) { transform: rotate(22deg);  opacity: 0.65; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(4) { transform: rotate(8deg);   opacity: 0.8; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(5) { transform: rotate(-26deg); opacity: 0.7; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(6) { transform: rotate(14deg);  opacity: 0.75; }
.sm-convergence[data-state="scatter"] .sm-convergence__bar:nth-child(7) { transform: rotate(-20deg); opacity: 0.8; }

.sm-convergence[data-state="aligned"] .sm-convergence__bar { transform: rotate(0deg); opacity: 1; }

/* ==========================================================================
   11. MOTION UTILITY STATES
   Stage 6.1 — rebuilt to a visible-by-default architecture after the Stage
   6 regression review. Every reveal class below now renders fully visible,
   full opacity, no offset, no clip — on its own, unconditionally. The
   hidden "about to animate" state ONLY exists underneath the html.sm-js
   selector, and homepage-motion.js is the only thing that ever adds
   html.sm-js — as literally its first action, wrapped so that if anything
   later in the script throws, html.sm-js is removed again immediately.
   Net effect: no JS, a blocked script, a thrown exception mid-run, or an
   unsupported browser all converge on the same result — full visibility,
   matching the approved Stage 5 static composition — rather than a hidden
   default that depends on a reveal script successfully reaching the end.
   ========================================================================== */

.sm-reveal,
.sm-reveal--left,
.sm-reveal--right,
.sm-clip-reveal {
  opacity: 1;
  transform: none;
  clip-path: none;
}

html.sm-js .sm-reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--sm-dur-base) var(--sm-ease-out),
              transform var(--sm-dur-base) var(--sm-ease-out);
}
html.sm-js .sm-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.sm-reveal--stagger .sm-reveal {
  transition-delay: calc(var(--sm-reveal-i, 0) * 80ms);
}

.sm-image-reveal { overflow: hidden; }
html.sm-js .sm-image-reveal img {
  transform: scale(1.04);
  transition: transform var(--sm-dur-slow) var(--sm-ease-out);
}
html.sm-js .sm-image-reveal.is-visible img { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .sm-reveal,
  .sm-reveal--left,
  .sm-reveal--right,
  .sm-convergence__bar,
  .sm-image-reveal img,
  .sm-clip-reveal,
  .sm-rule-expand::before,
  .sm-process__step {
    transition: none !important;
    transform: none !important;
    opacity: 1 !important;
    clip-path: none !important;
  }
}

/* ==========================================================================
   16. STAGE 6 — HOMEPAGE MOTION SYSTEM
   These classes are applied at runtime by js/homepage-motion.js ONLY — they
   are never written into Elementor markup, and (per the section 11 note
   above) have zero visual effect unless html.sm-js is also present. A
   visitor with JavaScript disabled, or whose motion script fails for any
   reason, sees the full Stage 5 static composition — never a partially or
   permanently hidden section.
   ========================================================================== */

/* Directional variant for the Problem section — small, non-chaotic offsets
   implying competing perspectives, per Stage 6 §7. */
html.sm-js .sm-reveal--left  { opacity: 0; transform: translate(-16px, 16px); transition: opacity var(--sm-dur-base) var(--sm-ease-out), transform var(--sm-dur-base) var(--sm-ease-out); }
html.sm-js .sm-reveal--right { opacity: 0; transform: translate(16px, 16px); transition: opacity var(--sm-dur-base) var(--sm-ease-out), transform var(--sm-dur-base) var(--sm-ease-out); }
html.sm-js .sm-reveal--left.is-visible,
html.sm-js .sm-reveal--right.is-visible { opacity: 1; transform: translate(0, 0); }

/* Rule-line expand — What We Do / Training capability rows (Stage 6 §8–9) */
.sm-rule-expand { position: relative; }
.sm-rule-expand::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 1px;
  width: 100%;
  background: var(--sm-line);
  transform: scaleX(1);
  transform-origin: left;
  transition: transform var(--sm-dur-base) var(--sm-ease-out);
}
.sm-theme-ink .sm-rule-expand::before,
.sm-theme-image-led .sm-rule-expand::before { background: var(--sm-line-ink); }
html.sm-js .sm-rule-expand::before { transform: scaleX(0); }
html.sm-js .sm-rule-expand.is-visible::before { transform: scaleX(1); }

/* Hero / feature image reveal — restrained clip wipe, not a zoom (Stage 6 §6, §14) */
html.sm-js .sm-clip-reveal {
  clip-path: inset(0 0 100% 0);
  transition: clip-path var(--sm-dur-hero) var(--sm-ease-out);
}
html.sm-js .sm-clip-reveal.is-visible { clip-path: inset(0 0 0% 0); }

/* Process active-step emphasis — driven by GSAP ScrollTrigger on desktop/
   laptop only (Stage 6 §10); homepage-motion.js only ever sets
   data-motion="active" above the 1100px process breakpoint, and removes it
   entirely for prefers-reduced-motion. Steps are fully opaque unless this
   attribute is present, so the static (no-JS, reduced-motion, mobile)
   presentation is completely unaffected. */
.sm-process__step { transition: opacity var(--sm-dur-fast) var(--sm-ease-out); }
.sm-process[data-motion="active"] .sm-process__step { opacity: 0.45; }
.sm-process[data-motion="active"] .sm-process__step.is-current { opacity: 1; }

/* ==========================================================================
   12. RESPONSIVE RULES
   Breakpoints: xl 1440 | lg 1200 | md 992 | sm 768 | xs 480
   ========================================================================== */

@media (max-width: 992px) {
  :root { --sm-section-y: var(--sm-space-9); }
  .sm-split { grid-template-columns: 1fr !important; gap: var(--sm-space-6); }
  .sm-grid-4 { grid-template-columns: repeat(2, 1fr); }
  .sm-profile { grid-template-columns: 1fr; }
  /* CSS audit: the .sm-process__steps column-stack override that used to
     live here is superseded by the dedicated @media (max-width: 1100px)
     rule in §15 (Process needs a wider threshold than the shared 992px
     breakpoint — see that rule's comment). Removed as dead/redundant. */
}

@media (max-width: 768px) {
  .sm-inner, .sm-wide, .sm-narrow { padding-inline: var(--sm-space-5); }
  .sm-eyebrow { font-size: 0.6875rem; }
  .sm-convergence { width: 200px; height: 70px; }
  .sm-convergence__bar { width: 35px; }

  /* Stage 6.2: on mobile, Elementor collapses the Cross-Cultural Work
     mosaic (.sm-culture-grid) from a 3-column grid into a single flex
     column, so its images stack directly on top of one another. The
     grid's desktop gap (--sm-space-4, 16px) reads fine as mosaic
     seams but is nowhere near enough breathing room between two
     full-width stacked photos — the section was reading as one long,
     uninterrupted block of imagery rather than a composed sequence.
     Widening the gap only at this breakpoint gives each photo room to
     read as its own beat. This is a spacing-only correction — no
     images, copy, or structure were added, removed, or reordered. */
  .sm-culture-grid { gap: var(--sm-space-7) !important; }
}

@media (max-width: 480px) {
  :root { --sm-section-y: var(--sm-space-8); }
  .sm-grid-4 { grid-template-columns: 1fr; }
  .sm-credibility-strip {
    grid-template-columns: 1fr !important;
    gap: var(--sm-space-5);
  }
  .sm-credibility-strip > .e-con {
    border-left: none;
    padding-left: 0;
    border-top: var(--sm-border);
    padding-top: var(--sm-space-4);
  }
  .sm-credibility-strip > .e-con:first-child {
    border-top: none;
    padding-top: 0;
  }
  .sm-case-study-row { grid-template-columns: 1fr; }
  .sm-convergence { width: 150px; height: 54px; }
  .sm-convergence__bar { width: 26px; }
}

/* ==========================================================================
   13. ASTRA INTEGRATION OVERRIDES
   ========================================================================== */

.ast-container,
.ast-container-fluid .ast-page-builder-template .ast-content-layout-wrap,
.site-content .ast-container { max-width: var(--sm-w-default); }

#secondary, .widget-area { display: none !important; }
#primary { flex: 1 1 100%; max-width: 100%; }

.ast-above-header, .ast-below-header,
.ast-page-title-bar, .ast-archive-title { display: none; }

.ast-btn, .ast-outline-btn {
  /* CSS audit: border-radius already covered by the shared rule in §7
     BUTTONS (.ast-btn, .ast-outline-btn, .astra-button, .elementor-button)
     — removed here as a duplicate declaration on the same two selectors. */
  font-family: var(--sm-font-body) !important;
  font-weight: 600 !important;
  font-size: 0.9375rem !important;
}

body,
.ast-site-identity, .ast-header-custom-item,
.menu-item a, .main-header-menu .menu-item a { font-family: var(--sm-font-body); }
.entry-title, .site-title { font-family: var(--sm-font-display); }

/* ==========================================================================
   14. STAGE 3 — HEADER, FOOTER & NAVIGATION
   ========================================================================== */

/* ---- Header shell + sticky behaviour ------------------------------------
   Outer geometry stays stable (Option B — visual condensation). The header
   is always solid Ink by default (matches the approved sticky Ink state).
   Two class-driven hooks let future page templates (Stage 4 hero pages)
   vary the *initial* state without a second header system:
     body.sm-header-transparent   -> header starts transparent, becomes
                                      Ink once #masthead.is-scrolled
     body.sm-header-on-paper      -> header starts on Paper (dark text/logo),
                                      becomes Ink once #masthead.is-scrolled
   Neither class is applied anywhere yet (no hero exists until Stage 4); the
   default (no class) renders a solid Ink header everywhere, which is what
   every current page uses. */

#masthead.site-header {
  position: sticky;
  top: 0;
  z-index: var(--sm-z-nav);
  background-color: var(--sm-ink);
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out);
}
/* The CTA's corrected padding (see §1 CTA fix) needs a touch more room
   than the shared 1180px content max-width to avoid the nav wrapping to a
   second line at desktop/laptop widths. Widen the header's own container
   only — body content sections keep the standard 1180px measure. */
#masthead .ast-container {
  max-width: 1300px;
}
/* Astra paints the primary row's own background on top of #masthead
   (Stage 2 left it at Paper) — override the actual painted layer. */
#masthead.site-header .ast-main-header-wrap,
#masthead.site-header .ast-primary-header-bar.main-header-bar {
  background-color: var(--sm-ink) !important;
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out);
}
body.admin-bar #masthead.site-header { top: 32px; }
@media (max-width: 782px) {
  body.admin-bar #masthead.site-header { top: 46px; }
}

body.sm-header-transparent #masthead.site-header,
body.sm-header-transparent #masthead.site-header .ast-main-header-wrap,
body.sm-header-transparent #masthead.site-header .ast-primary-header-bar.main-header-bar {
  background-color: transparent !important;
}
body.sm-header-transparent #masthead.site-header.is-scrolled,
body.sm-header-transparent #masthead.site-header.is-scrolled .ast-main-header-wrap,
body.sm-header-transparent #masthead.site-header.is-scrolled .ast-primary-header-bar.main-header-bar {
  background-color: var(--sm-ink) !important;
}

body.sm-header-on-paper #masthead.site-header,
body.sm-header-on-paper #masthead.site-header .ast-main-header-wrap,
body.sm-header-on-paper #masthead.site-header .ast-primary-header-bar.main-header-bar {
  background-color: var(--sm-paper) !important;
}
body.sm-header-on-paper #masthead.site-header.is-scrolled,
body.sm-header-on-paper #masthead.site-header.is-scrolled .ast-main-header-wrap,
body.sm-header-on-paper #masthead.site-header.is-scrolled .ast-primary-header-bar.main-header-bar {
  background-color: var(--sm-ink) !important;
}
body.sm-header-on-paper #masthead.site-header:not(.is-scrolled) .site-logo-img img { filter: brightness(0); }
body.sm-header-on-paper #masthead.site-header:not(.is-scrolled) .main-header-menu > .menu-item > a.menu-link { color: var(--sm-ink); }

.ast-primary-header-bar.main-header-bar {
  padding-block: var(--sm-space-5);
  transition: padding-block var(--sm-dur-fast) var(--sm-ease-out);
}
#masthead.site-header.is-scrolled .ast-primary-header-bar.main-header-bar {
  padding-block: var(--sm-space-3);
}

/* Logo — grey source asset rendered Paper-toned on the Ink header via
   filter (no separate white asset exists yet — see Stage 3 report). */
/* Stage 7.1: logo size increased from 52/38/42px to 60/44/48px (~15%).
   Stage 7.2: increased again to 64/50/52px, plus a vertical-alignment fix
   (see the #masthead .ast-site-identity rule directly below this block).
   Diagnosis: no Astra Customizer logo-width setting exists (theme_mods
   audit confirmed only custom_logo, nav_menu_locations, custom_css_post_id
   are set) — sizing has always come entirely from this block, set at the
   original Stage 3 header build. The logo asset itself is a wide/flat
   rectangular lockup (1084×486, ~2.23:1), so a height-based max-height
   cap renders a proportionally narrow width even at a reasonable height,
   reading as smaller/timid next to the nav and CTA button. Width stays
   "auto" throughout so the aspect ratio is preserved — only the height
   cap changes. Header bar is 88px tall with headroom to spare, so this
   still sits comfortably without crowding the nav or button. */
.site-logo-img img.custom-logo {
  max-height: 64px;
  width: auto;
  height: auto;
  filter: brightness(0) invert(1);
  transition: max-height var(--sm-dur-fast) var(--sm-ease-out);
}
#masthead.site-header.is-scrolled .site-logo-img img.custom-logo {
  max-height: 50px;
}
@media (max-width: 768px) {
  .site-logo-img img.custom-logo { max-height: 52px; }
}

/* Stage 7.2: vertical alignment fix. Astra's own dynamically-generated
   inline stylesheet (#astra-theme-css-inline-css) sets
   ".ast-builder-layout-element .ast-site-identity { margin-top: -30px; }"
   -- an auto-calculated compensation margin based on Astra's own internal
   default logo assumptions, not our actual custom logo height. That stale
   offset was pulling the logo up almost to the very top of the 88px header
   band (measured live: ~0px gap above the logo, ~29px below -- nowhere
   near centred). The identity element is itself a flex container with
   align-items: center inherited from three ancestor levels (all already
   display:flex/align-items:center in Astra's own markup) -- the -30px was
   fighting that natural centring rather than assisting it. Removing the
   offset entirely (margin-top: 0) lets the existing flex centring do the
   work, and was confirmed empirically to produce a symmetric gap (17px
   above / 17px below, measured in the normal state). This selector
   (#masthead .ast-site-identity) is an ID + one class, which already
   outranks Astra's inline rule (two classes, no ID) under normal CSS
   specificity rules -- no !important is needed. Applies to both the
   normal and .is-scrolled states, since Astra's own margin-top rule is
   likewise not state-specific, and flex centring adapts automatically to
   the smaller sticky-state logo without a separate override. */
#masthead .ast-site-identity {
  margin-top: 0;
}

/* ---- Primary navigation ---------------------------------------------- */

.main-header-menu > .menu-item > a.menu-link {
  color: var(--sm-paper);
  font-family: var(--sm-font-body);
  font-weight: 500;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  transition: color var(--sm-dur-fast) var(--sm-ease-out);
}
.main-header-menu > .menu-item > a.menu-link:hover,
.main-header-menu > .menu-item > a.menu-link:focus-visible {
  color: var(--sm-clay);
}
.main-header-menu .menu-link:focus-visible,
.main-header-menu .dropdown-menu-toggle:focus-visible {
  outline: 2px solid var(--sm-clay);
  outline-offset: 2px;
}

/* ---- Dropdown submenus — restrained / editorial, no mega-menu -------- */

.main-header-menu .sub-menu {
  background-color: var(--sm-ink-700);
  border: none;
  border-radius: var(--sm-radius);
  box-shadow: 0 8px 24px rgba(20, 24, 31, 0.18);
  padding-block: var(--sm-space-3);
  min-width: 260px;
  transition: opacity var(--sm-dur-fast) var(--sm-ease-out);
}
.main-header-menu .sub-menu .menu-item > a.menu-link {
  color: var(--sm-paper);
  font-family: var(--sm-font-body);
  font-size: 0.9375rem;
  padding: var(--sm-space-3) var(--sm-space-5);
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out), color var(--sm-dur-fast) var(--sm-ease-out);
}
.main-header-menu .sub-menu .menu-item > a.menu-link:hover,
.main-header-menu .sub-menu .menu-item > a.menu-link:focus-visible {
  background-color: rgba(246, 242, 234, 0.06);
  color: var(--sm-clay);
}
.main-header-menu .sub-menu .menu-item > a.menu-link:focus-visible {
  outline: 2px solid var(--sm-clay);
  outline-offset: -2px;
}

/* ---- Header CTA — Book a Consultation, visually distinct -------------- */

.ast-header-button-1 .ast-custom-button-link {
  font-family: var(--sm-font-body);
  font-weight: 600;
  letter-spacing: 0.01em;
  display: inline-block;
}
/* Astra's own dynamic CSS for this element isn't landing (0 padding,
   0 radius on the actual visual node) — style the real button node
   (.ast-custom-button, inside the .ast-custom-button-link anchor)
   directly so the CTA reads as a deliberate button, not highlighted text. */
.ast-header-button-1 .ast-custom-button {
  display: inline-flex !important;
  align-items: center;
  padding: 11px 22px !important;
  line-height: 1.3 !important;
  white-space: nowrap;
  border-radius: var(--sm-radius) !important;
  background-color: var(--sm-clay) !important;
  color: var(--sm-paper) !important;
  font-family: var(--sm-font-body);
  font-weight: 600;
  letter-spacing: 0.01em;
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out);
}
.ast-header-button-1 .ast-custom-button-link:hover .ast-custom-button,
.ast-header-button-1 .ast-custom-button-link:focus-visible .ast-custom-button {
  background-color: var(--sm-clay-600) !important;
}
.ast-header-button-1 .ast-custom-button-link:focus-visible {
  outline: 2px solid var(--sm-paper);
  outline-offset: 2px;
}

/* ---- Tablet: preserve composition rather than stretch desktop nav ----- */

@media (max-width: 1200px) and (min-width: 769px) {
  .main-header-menu > .menu-item > a.menu-link { font-size: 0.875rem; padding-inline: var(--sm-space-3); }
  .ast-primary-header-bar.main-header-bar { padding-block: var(--sm-space-4); }
}

/* ---- Mobile off-canvas navigation -------------------------------------- */

.ast-mobile-popup-drawer,
.ast-mobile-popup-container .ast-mobile-popup-inner-content {
  background-color: var(--sm-ink) !important;
}
.ast-mobile-popup-drawer .ast-mobile-popup-inner-content { padding: var(--sm-space-6) var(--sm-space-5); }
.ast-mobile-popup-drawer .main-header-menu .menu-item > a.menu-link {
  color: var(--sm-paper);
  font-family: var(--sm-font-body);
  font-size: 17px;
  padding: var(--sm-space-4) var(--sm-space-2);
  min-height: 44px;
  display: flex;
  align-items: center;
}
.ast-mobile-popup-drawer .main-header-menu .menu-item { border-bottom: 1px solid var(--sm-line-ink); }
.ast-mobile-popup-drawer .main-header-menu .sub-menu {
  background-color: transparent;
  box-shadow: none;
  padding-left: var(--sm-space-4);
}
.ast-mobile-popup-drawer .main-header-menu .sub-menu .menu-item > a.menu-link { font-size: 16px; color: var(--sm-text-muted-ink); }
.ast-mobile-popup-drawer .dropdown-menu-toggle {
  min-width: 44px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.ast-mobile-popup-drawer .ast-header-button-1 {
  margin-top: var(--sm-space-5);
  padding-inline: var(--sm-space-2);
}
/* Astra's own .ast-builder-button-wrap sizes to its content inside the
   flex row and doesn't stretch on its own — without this, the width:100%
   further down has nothing full-width to fill against. */
.ast-mobile-popup-drawer .ast-header-button-1 .ast-builder-button-wrap {
  width: 100%;
}
.ast-mobile-popup-drawer .ast-header-button-1 .ast-custom-button-link {
  display: block !important;
  width: 100%;
}
.ast-mobile-popup-drawer .ast-header-button-1 .ast-custom-button {
  display: flex !important;
  width: 100%;
  box-sizing: border-box;
  justify-content: center;
  align-items: center;
  font-size: 1rem !important;
  padding: var(--sm-space-4) !important;
  min-height: 44px;
  line-height: 1.3 !important;
}
.ast-mobile-popup-drawer #ast-mobile-header-toggle,
.ast-mobile-popup-drawer .mobile-menu-close,
.ast-mobile-popup-drawer button[class*="close"] {
  min-width: 44px;
  min-height: 44px;
  color: var(--sm-paper);
}

/* ---- Footer ------------------------------------------------------------ */

#colophon.site-footer {
  background-color: var(--sm-ink);
  color: var(--sm-text-muted-ink);
  font-family: var(--sm-font-body);
}
#colophon.site-footer a { color: var(--sm-paper); text-decoration: none; }
#colophon.site-footer a:hover,
#colophon.site-footer a:focus-visible { color: var(--sm-clay); }
#colophon .site-above-footer-wrap,
#colophon .site-below-footer-wrap {
  border-color: var(--sm-line-ink);
}
#colophon .main-header-menu,
#colophon .footer-menu {
  font-size: 0.9375rem;
}
#colophon .sm-footer-meta {
  display: flex;
  align-items: center;
  gap: var(--sm-space-3);
  color: var(--sm-text-muted-ink);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}
#colophon .sm-footer-meta img { width: 28px; height: 28px; opacity: 0.85; filter: brightness(0) invert(1); }

/* Stage 7.2: footer content-width alignment fix. Diagnosis: the footer's
   two Astra builder rows (.site-above-footer-wrap containing the nav +
   social icons, and .site-below-footer-wrap containing the Melbourne ·
   Bangkok / copyright line) had zero horizontal padding and no max-width
   (measured live: 20px 0px padding, max-width: none) — they ran edge to
   edge of the browser viewport, completely independent of the sm-inner
   content-width system (1180px, centred, padded) that every other section
   on every page uses. This is why the footer read as "accidental" rather
   than editorial: the nav/social row started flush against the browser
   edge instead of lining up under the CTA/hero column above it, and the
   below-row copyright text — already text-align: center — was centring
   on the full raw viewport width rather than on the same 1180px column as
   the rest of the page, so at wide viewports it visibly drifted from the
   content above it. Fix: give both rows' inner grid-columns wrapper the
   same treatment as .sm-inner elsewhere in this file. No !important
   needed — the only existing rule on this class only sets column-gap, and
   this selector (two classes) is scoped under .site-footer so it doesn't
   touch anything outside the footer. */
.site-footer .ast-builder-footer-grid-columns {
  max-width: var(--sm-w-default);
  margin-inline: auto;
  padding-inline: var(--sm-space-6);
}
/* ==========================================================================
   END OF STAGE 3 — HEADER, FOOTER & NAVIGATION
   ========================================================================== */

/* ==========================================================================
   15. STAGE 4 — HOMEPAGE STATIC BUILD
   Small, targeted additions only — the page is built almost entirely from
   the existing component skeletons (§9) and layout utilities (§5).
   ========================================================================== */

/* ---- Hero: asymmetric split, not a centred/boxed template ------------- */

.sm-hero {
  /* Stage 6.1 fix: Elementor's own per-element generated CSS
     (.elementor-element.elementor-element-<id>) uses a two-class
     selector, which outranks this single-class .sm-hero rule and was
     silently winning with display:flex + a stacked flex-direction —
     collapsing the intended two-column hero into a full-width stack
     (each column rendering at the full hero width, one above the
     other) and inflating total hero height well beyond the Stage 5
     approved layout. !important here matches the same, already-
     established pattern used elsewhere on this project for exactly
     this class of Elementor-vs-child-theme specificity conflict. */
  display: grid !important;
  grid-template-columns: 11fr 13fr !important;
  gap: var(--sm-space-8);
  align-items: start;
}
/* Stage 5: widened the text column (5fr/7fr -> 11fr/13fr) so the approved
   H1 wraps to 3 balanced lines at desktop instead of 4 with an orphaned
   final word. align-items changed center -> start so the image's top edge
   reads level with the eyebrow/H1 baseline instead of overflowing evenly
   above and below a shorter text column. */
/* Stage 5: the hero's own top padding is reduced below (see the
   :has() rule further down) so the gap under the sticky header reads as
   deliberate breathing room rather than dead space, without touching the
   global --sm-section-y rhythm used by every other section. */
.sm-section.sm-theme-paper:has(> .sm-hero) { padding-top: 72px; }
@media (max-width: 767px) {
  .sm-section.sm-theme-paper:has(> .sm-hero) { padding-top: 48px; }
}
.sm-hero__media .sm-image { border-radius: var(--sm-radius); }
/* Secondary hero action: editorial text-link with a directional cue, not a
   second button — keeps Book a Consultation as the single visual anchor. */
.sm-cta-link .elementor-button,
.sm-cta-link.elementor-button {
  display: inline-flex !important;
  align-items: center;
  gap: 6px;
  background: none !important;
  border: none !important;
  padding: 0 !important;
  height: auto !important;
  min-height: 0 !important;
  color: var(--sm-clay-800) !important;
  font-family: var(--sm-font-body);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
}
.sm-cta-link .elementor-button::after { content: '\2192'; transition: transform var(--sm-dur-fast) var(--sm-ease-out); }
.sm-cta-link .elementor-button:hover,
.sm-cta-link .elementor-button:focus-visible {
  color: var(--sm-clay-600) !important;
  text-decoration: underline;
}
.sm-cta-link .elementor-button:hover::after { transform: translateX(3px); }
.sm-hero__content { display: flex !important; flex-direction: column !important; gap: var(--sm-space-5); }
.sm-hero__actions { display: flex !important; flex-direction: row !important; flex-wrap: wrap; gap: var(--sm-space-3); align-items: center; margin-top: var(--sm-space-2); padding: 0 !important; }
/* The hero text column is a fixed 5fr of a 5fr/7fr split, so its available
   width narrows faster than the viewport as the window shrinks toward
   laptop widths. The two actions were wrapping onto separate lines several
   hundred pixels before the hero's own md (992px) stacking breakpoint —
   not a genuine mobile-width constraint. Trimming the primary button's
   horizontal padding slightly within this row only (not the shared
   .sm-button rule used site-wide) keeps both actions on one line through
   laptop widths without changing button sizing anywhere else on the site. */
.sm-hero__actions .sm-button { padding: 14px 20px; }

@media (max-width: 992px) {
  .sm-hero { grid-template-columns: 1fr !important; }
  .sm-hero__media { order: -1; }
}

/* ---- How It Works: editorial process row, no numbered circles --------- */

.sm-process__steps {
  display: flex !important;
  flex-direction: row !important;
  gap: var(--sm-space-6);
  align-items: flex-start;
}
.sm-process__step {
  flex: 1 1 0;
  padding-top: var(--sm-space-5);
  border-top: 1px solid var(--sm-line-ink);
  display: flex !important;
  flex-direction: column !important;
  gap: var(--sm-space-2);
}
.sm-process__step-index {
  font-family: var(--sm-font-display);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--sm-clay);
}
.sm-process__step-label {
  font-family: var(--sm-font-display);
  font-size: 1.125rem;
  font-weight: 500;
}
.sm-process__step-desc { font-size: 0.9375rem; color: var(--sm-text-muted-ink); }
.sm-process .sm-convergence { margin-inline: auto; margin-bottom: var(--sm-space-7); }

@media (max-width: 1100px) {
  /* Stage 5 fix: .sm-process__steps had flex-direction:row !important with no
     responsive override, so all 5 steps were forced into one row at every
     width down to mobile — causing mid-word breaks ("Compl/exity",
     "Alignm/ent") once each column dropped below ~160px. 992px (the shared
     laptop/tablet breakpoint) was tried first but "Complexity" still broke
     at 1008–1084px, so this rule gets its own slightly wider threshold
     rather than moving the shared 992px breakpoint used elsewhere on the
     page. The border-left/padding-left treatment below was already written
     for a stacked layout but the flex-direction change to make it happen
     was missing. Vertical stack preserves the 01–05 sequence and
     directional logic without forcing an unusable horizontal squeeze. */
  .sm-process__steps { flex-direction: column !important; gap: var(--sm-space-6) !important; }
  .sm-process__step { border-top: none; border-left: 1px solid var(--sm-line-ink); padding-top: 0; padding-left: var(--sm-space-5); padding-bottom: var(--sm-space-2); }
}

/* ---- Cross-cultural work: restrained image grid, no travel-brochure feel */

.sm-culture-grid {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--sm-space-4);
}
.sm-culture-grid > *:first-child { grid-column: span 2; grid-row: span 2; height: 100%; }
.sm-culture-grid > *:first-child img { height: 100%; object-fit: cover; aspect-ratio: auto; }
@media (max-width: 768px) {
  .sm-culture-grid { grid-template-columns: 1fr 1fr; }
  .sm-culture-grid > *:first-child { grid-column: span 2; grid-row: auto; }
}

/* ---- Leadership: keep the profile grid from stretching a single short
   bio into an oversized column on very wide screens ---------------------- */

.sm-profile__bio > * + * { margin-top: var(--sm-space-4); }

/* ==========================================================================
   16. STAGE 5B — HOMEPAGE VISUAL COMPOSITION REDESIGN
   Motion remains disabled (SM_MOTION_ENABLED = false). Static composition
   pass only — no new animation, no content architecture changes.
   ========================================================================== */

/* ---- Complexity section: asymmetric editorial split -------------------
   Structural change: 1915bce converted from single-column stack into a
   two-column split (0012d62 lead col | 7e7ae23 points col) via Elementor
   Document API. Replaces the narrow-text-on-wide-section problem with a
   deliberate large-H2 / ruled-statements composition. -------------------- */

.sm-theme-editorial > .sm-complexity-split {
  max-width: var(--sm-w-default) !important;
}

.sm-complexity-split {
  grid-template-columns: 0.85fr 1.15fr;
  gap: var(--sm-space-9);
  align-items: start;
}

.sm-complexity-lead h2 {
  font-size: clamp(2rem, 1.4rem + 2.6vw, 3.75rem) !important;
  max-width: 13ch;
}

.sm-complexity-points {
  padding-top: var(--sm-space-5);
  border-top: var(--sm-border);
}

.sm-ruled-list {
  list-style: none;
  margin: var(--sm-space-6) 0 0;
  padding: 0;
}

.sm-ruled-list li {
  padding: var(--sm-space-4) 0;
  border-top: var(--sm-border);
  font-family: var(--sm-font-body);
  font-size: var(--sm-fluid-body-l);
  line-height: 1.5;
  color: var(--sm-text-muted);
}

.sm-ruled-list li:last-child {
  border-bottom: var(--sm-border);
}

@media (max-width: 768px) {
  .sm-complexity-lead h2 {
    font-size: var(--sm-fluid-h2) !important;
    max-width: none;
  }
  .sm-complexity-points {
    padding-top: var(--sm-space-4);
  }
}

/* ==========================================================================
   17. STAGE 6A — HERO MOTION ONLY
   Scoped entirely to .sm-hero[data-hero-motion="..."]. The unconditional
   default (no attribute present) is the plain, fully visible Stage 5B/5C
   static hero — nothing below ever hides content unless
   js/homepage-hero-motion.js has already run and explicitly opted the
   hero into a "ready" state (see that file's header comment for the full
   visible-by-default → capability check → prep → animate architecture).

   Deliberately independent of, and unrelated to, the disabled §16 Stage 6
   sitewide motion system (html.sm-js / GSAP / ScrollTrigger): a different
   gating attribute, scoped to .sm-hero only, with its own kill switch
   (SM_HERO_MOTION_ENABLED in functions.php). No other homepage section is
   touched by any rule in this block.

   No !important is used anywhere below — checked first: none of
   .sm-eyebrow / h1 / .sm-intro / .sm-hero__actions / .sm-hero__media
   carry any existing opacity, transform, or clip-path declaration
   (Elementor-generated or otherwise) at the same or higher specificity,
   so plain cascade order and normal specificity are enough here.
   ========================================================================== */

/* Stage 6A.2 fix: the Stage 6A.1 architecture declared `transition` on the
   attribute-PRESENCE selector, so it was active during BOTH "ready" and
   "animate". That meant the fade-to-hidden itself was animated (420ms),
   and since the JS only allows ~24ms between setting "ready" and
   "animate" (the double-rAF handoff), the element never actually reached
   opacity 0 — it was still mid-fade (~0.88–0.96) when the target flipped
   back to 1, so it visually just dipped and snapped back: a flicker, not
   an entrance. Confirmed via frame-by-frame computed-style samples.

   Fix: the "ready" state now applies its hidden values with
   transition: none — an instant, uncontested snap to the true starting
   point, guaranteed to commit before anything else runs. `transition` is
   now declared ONLY on the "animate" rule (per element, with its own
   delay baked directly into the shorthand rather than relying on a
   separate same-specificity delay rule and cascade order), so the
   fade/rise in only ever runs in the one direction: hidden → visible. */
.sm-hero[data-hero-motion="ready"] .sm-eyebrow,
.sm-hero[data-hero-motion="ready"] h1,
.sm-hero[data-hero-motion="ready"] .sm-intro,
.sm-hero[data-hero-motion="ready"] .sm-hero__actions {
  opacity: 0;
  transform: translateY(16px);
  transition: none;
}

/* Stage 6A.2: the clip-path "roller-blind" reveal is removed. inset(0 0
   100% 0) clips 100% from the BOTTOM, so as that value fell toward 0% the
   visible window grew from the TOP edge downward — a top-to-bottom wipe,
   not the bottom-to-top wipe the Stage 6A.1 report incorrectly described.
   Replaced with a restrained opacity + horizontal drift + very slight
   scale settle — no clip-path, no crop-region change at any point, so
   the final frame is pixel-identical to the approved static image. */
.sm-hero[data-hero-motion="ready"] .sm-hero__media {
  opacity: 0;
  transform: translateX(10px) scale(1.01);
  transition: none;
}

.sm-hero[data-hero-motion="animate"] .sm-eyebrow,
.sm-hero[data-hero-motion="animate"] h1,
.sm-hero[data-hero-motion="animate"] .sm-intro,
.sm-hero[data-hero-motion="animate"] .sm-hero__actions,
.sm-hero[data-hero-motion="animate"] .sm-hero__media {
  opacity: 1;
  transform: none;
}

/* Stage 6A.2 sequence: overlapping rather than fully sequential — the
   image starts within the eyebrow/H1 window instead of waiting for text
   to finish, so the CTA and image are both settled well inside ~1.3s
   instead of the visitor waiting on a fully serial chain. Delay is baked
   into each element's own transition shorthand (not a separate rule) so
   there is no same-specificity cascade-order dependency for timing. */
.sm-hero[data-hero-motion="animate"] .sm-eyebrow {
  transition: opacity 500ms var(--sm-ease-out) 0ms, transform 500ms var(--sm-ease-out) 0ms;
}
.sm-hero[data-hero-motion="animate"] h1 {
  transition: opacity 500ms var(--sm-ease-out) 100ms, transform 500ms var(--sm-ease-out) 100ms;
}
.sm-hero[data-hero-motion="animate"] .sm-intro {
  transition: opacity 500ms var(--sm-ease-out) 220ms, transform 500ms var(--sm-ease-out) 220ms;
}
.sm-hero[data-hero-motion="animate"] .sm-hero__actions {
  transition: opacity 500ms var(--sm-ease-out) 350ms, transform 500ms var(--sm-ease-out) 350ms;
}
.sm-hero[data-hero-motion="animate"] .sm-hero__media {
  transition: opacity 800ms var(--sm-ease-out) 150ms, transform 800ms var(--sm-ease-out) 150ms;
}

/* Belt-and-suspenders: homepage-hero-motion.js already checks
   prefers-reduced-motion and never sets data-hero-motion at all when it's
   on, so in normal operation this block is unreachable dead weight — kept
   anyway per Stage 6A §8 as a CSS-level backstop independent of JS. */
@media (prefers-reduced-motion: reduce) {
  .sm-hero[data-hero-motion="ready"] .sm-eyebrow,
  .sm-hero[data-hero-motion="ready"] h1,
  .sm-hero[data-hero-motion="ready"] .sm-intro,
  .sm-hero[data-hero-motion="ready"] .sm-hero__actions,
  .sm-hero[data-hero-motion="ready"] .sm-hero__media,
  .sm-hero[data-hero-motion="animate"] .sm-eyebrow,
  .sm-hero[data-hero-motion="animate"] h1,
  .sm-hero[data-hero-motion="animate"] .sm-intro,
  .sm-hero[data-hero-motion="animate"] .sm-hero__actions,
  .sm-hero[data-hero-motion="animate"] .sm-hero__media {
    opacity: 1;
    transform: none;
    transition: none;
  }
}
/* ==========================================================================
   18. STAGE 6C — CONVERGENCE MARK MOTION ONLY
   Scoped entirely to .sm-convergence[data-convergence-motion="..."] inside
   the homepage Process section. Independent of, and unrelated to, the
   disabled §16 Stage 6 sitewide system's .sm-convergence[data-state="scatter"]
   rules (different attribute entirely, different gating — own kill switch
   SM_CONVERGENCE_MOTION_ENABLED in functions.php, vs SM_MOTION_ENABLED /
   html.sm-js). Those pre-existing scatter/aligned rules are untouched by
   this section and are not used here — their rotation range (up to ±32deg)
   is more dramatic than this stage's restrained ±8–12deg brief, so a fresh,
   independent starting state was defined rather than reusing them.

   The unconditional default (no attribute present) is the existing approved
   "aligned" composition — nothing below ever moves the mark unless
   js/homepage-convergence-motion.js has already run and explicitly opted it
   into a "ready" state after confirming capability (IntersectionObserver
   present, reduced-motion off). Process step labels, connecting lines, and
   timeline are not touched by any rule in this block.

   .sm-convergence__bar already carries an unconditional transition
   (§3 above) at specificity (0,1,0). The "ready" rule below is deliberately
   MORE specific (attribute + class + nth-child) so it can force
   transition:none and instantly snap to the divergent starting values —
   the same fix proven necessary in Stage 6A.1/6A.2: without this, the move
   TO the starting position would itself animate, and with only a couple of
   animation frames between "ready" and "animate", the bars would never
   actually reach their divergent starting point before reversing back to
   aligned. The "animate" rule then declares its own transition (also at
   higher specificity than the base), so it is not lost when the state
   changes — the other lesson from that same fix.

   No new !important is used anywhere below. The existing reduced-motion
   block (§11, further below) already targets the bare .sm-convergence__bar
   class with !important and unconditionally forces transition:none,
   transform:none, opacity:1 — that pre-existing rule already fully
   neutralises every rule in this section for reduced-motion users (higher
   specificity is irrelevant once !important is in play), verified live
   rather than assumed. */

.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar {
  transition: none;
}
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(1) { transform: rotate(-11deg); opacity: 0.85; }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(2) { transform: rotate(9deg);   opacity: 0.9;  }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(3) { transform: rotate(-8deg);  opacity: 0.92; }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(4) { transform: rotate(10deg);  opacity: 0.88; }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(5) { transform: rotate(-9deg);  opacity: 0.92; }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(6) { transform: rotate(8deg);   opacity: 0.9;  }
.sm-convergence[data-convergence-motion="ready"] .sm-convergence__bar:nth-child(7) { transform: rotate(-10deg); opacity: 0.85; }

.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar {
  transform: rotate(0deg);
  opacity: 1;
  transition: transform 700ms var(--sm-ease-out), opacity 700ms var(--sm-ease-out);
}
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(1),
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(7) { transition-delay: 0ms; }
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(2),
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(6) { transition-delay: 60ms; }
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(3),
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(5) { transition-delay: 120ms; }
.sm-convergence[data-convergence-motion="animate"] .sm-convergence__bar:nth-child(4) { transition-delay: 180ms; }
/* ==========================================================================
   19. STAGE 6D — INTEGRATED PROCESS + CONVERGENCE NARRATIVE MOTION
   Replaces the standalone Stage 6C one-shot trigger (retired via
   SM_CONVERGENCE_MOTION_ENABLED = false in functions.php, script file kept
   on disk, not deleted). The Convergence Mark is no longer an isolated
   interaction — it is now driven continuously, in lock-step with scroll
   position, by js/homepage-process-motion.js (GSAP + ScrollTrigger, scrub,
   no pin) alongside the five .sm-process__step elements, so the mark and
   the step progression read as one system across Complexity -> Space ->
   Clarity -> Alignment -> Action.

   Everything below is opt-in via classes/attributes applied only by that
   script after it confirms GSAP + ScrollTrigger loaded and
   prefers-reduced-motion is off. With no attribute/class present (script
   never ran, threw, or reduced motion is on) every rule below is inert:
   the mark renders at its existing default aligned composition (no
   opacity/transform declared on the bare .sm-convergence__bar class) and
   every step renders at its existing default full-opacity, always-readable
   state. This is the same visible-by-default principle used in every prior
   motion stage on this project.

   No new !important anywhere in this block. */

/* While the narrative sequence is driving the mark, GSAP writes transform/
   opacity directly via inline styles on every scroll tick. The bars'
   pre-existing base transition (var(--sm-dur-slow) = 800ms, specificity
   0,1,0) must not fight that — without this override the browser would try
   to ease each tiny per-frame value change over 800ms, turning a crisp
   scroll-linked resolve into a laggy blur. This selector (0,2,0) wins on
   specificity alone; no !important needed. Stage 6C's own
   [data-convergence-motion] rules are untouched and simply never trigger
   now that its script is disabled. */
.sm-convergence[data-process-motion="active"] .sm-convergence__bar {
  transition: none;
}

/* Process step emphasis states. Transition lives on the bare class so the
   class toggles the JS applies on every activeIndex change animate
   smoothly rather than snapping. */
.sm-process__step {
  transition: border-color 300ms var(--sm-ease-out),
              opacity 300ms var(--sm-ease-out);
}

/* Every step except the current one dims slightly — still fully readable
   (0.6 opacity keeps well above any accessibility floor for decorative
   emphasis; no text is ever hidden), never disappears, matches the brief's
   explicit "do not make inactive steps disappear completely". */
.sm-process__step.is-process-quiet {
  opacity: 0.6;
}

/* Steps at or before the active index get the same clay border-color
   already used unconditionally on the last ("Action") step — this is a
   longhand border-color override of the existing border-top/border-left
   shorthand (identical mechanism to the pre-existing :last-child rule
   directly above it in §15), so it works at both the desktop border-top
   row layout and the <=1100px border-left stacked layout with one rule. */
.sm-process__step.is-process-reached {
  border-color: var(--sm-clay);
}

/* Only the current step gets the clay index/label text treatment — same
   colour already used permanently on the last step, so there is no visual
   discontinuity when the sequence's active index reaches step 5. */
/* Alpaca issue 2085: active-step emphasis was colour-only (subtle); adding
   font-weight so the current step visibly 'pops' against the other four as
   the narrative cycles Complexity -> Space -> Clarity -> Alignment -> Action
   on scroll (confirmed via homepage-process-motion.js: activeIndex already
   advances 0..4 across all five steps, this was not a cycling bug). */
.sm-process__step.is-process-active .sm-process__step-index,
.sm-process__step.is-process-active .sm-process__step-label {
  color: var(--sm-clay);
  font-weight: 700;
}

/* ==========================================================================
   20. ELEMENTOR ENTRANCE ANIMATION FAILSAFE

   Motion Reliability Report, section 5. Elementor's native entrance-
   animation feature hides animated elements with its own unconditional
   core-CSS rule (.elementor-invisible { visibility: hidden; }, no
   !important) and relies entirely on its own JavaScript scroll observer
   to clear that class. If that observer ever fails to initialise for any
   reason — the LiteSpeed Guest Optimization / jQuery race already fixed,
   a future plugin conflict, or any other JS failure earlier in the page
   — an animated element has no independent way to become visible again.
   This is a pure-CSS, no-JavaScript backstop for that one specific class.
   It does not add a new reveal system: it targets Elementor's own existing
   selector and does nothing at all unless that class is still present
   several seconds after the element exists, which only happens on
   failure. On every normal page load Elementor's own script clears the
   class (or the animation completes) well inside the 4s delay below, so
   this rule has no visible effect under normal operation and does not
   alter, delay, or race the approved entrance animations in any way.

   No !important: Elementor's own rule has none and is a single-class
   selector, and this child theme's stylesheet already loads after
   Elementor's core CSS in this site's normal enqueue order, so plain
   cascade order wins without needing one. Applies unconditionally,
   including under prefers-reduced-motion, because this is a content-
   visibility safety net rather than a decorative motion effect — those
   visitors need the backstop too.
   ========================================================================== */
.elementor-invisible {
  animation: sm-elementor-failsafe 0.01s linear 4s forwards;
}

@keyframes sm-elementor-failsafe {
  to { visibility: visible; }
}


/* ==========================================================================
   21. INTERNAL PAGE TEMPLATE SYSTEM (Stage 7)

   New, documented reusable components for internal/service pages, built
   for the Facilitation Overview prototype and intended for reuse across
   every internal page in the approved pattern. Every internal-page section
   other than the hero reuses existing homepage classes as-is (sm-section,
   sm-theme-*, sm-inner/sm-narrow/sm-wide, sm-split/sm-stack, sm-eyebrow,
   sm-intro, sm-body-l, sm-ruled-list, sm-button, sm-cta-link,
   sm-related-band, sm-cta, sm-process__step* for a static numbered-step
   layout with no motion, sm-image*) — nothing above this point in the file
   is modified. The three classes and two tokens below are the only
   genuinely new pieces, needed because the brief calls for a distinct,
   smaller internal-page hero rather than reusing the full homepage hero.

   No JavaScript, no GSAP/ScrollTrigger, no new animation system: this
   section is CSS-only.
   ========================================================================== */

:root {
  --sm-w-medium: 820px;
  --sm-fluid-page-title: clamp(2rem, 1.6rem + 2vw, 3.75rem);
}

.sm-page-hero {
  /* Deliberately shallower than the homepage hero's default 140px
     section padding (var(--sm-section-y)) — "smaller and more
     practical" per the Stage 7 brief, not a scaled-down copy of the
     full homepage hero. */
  padding-top: var(--sm-space-8);
  padding-bottom: var(--sm-space-8);
}

.sm-page-hero__inner {
  /* Narrow/medium single text column, per brief — between .sm-narrow
     (640px, tighter than reads well for an eyebrow + H1 + intro
     paragraph) and .sm-inner (1180px, full section width). Same
     centring mechanism as every existing width utility in this file
     (Elementor's own .e-con rule sets margin-inline via CSS custom
     properties at equal specificity and wins when they resolve to 0,
     so !important is required here for the same already-documented
     reason as .sm-inner/.sm-wide/.sm-narrow above). */
  max-width: var(--sm-w-medium);
  margin-inline: auto !important;
  padding-inline: var(--sm-space-6);
}

.sm-page-hero__title {
  /* h1 already carries font-size/line-height !important (Stage 4.1:
     the active Elementor Kit's own fixed per-breakpoint default
     otherwise wins at equal tag-selector specificity). This class is
     higher specificity than the bare h1 tag selector, but still needs
     !important to beat that existing !important rule under normal
     cascade rules — same conflict, same fix, applied to a smaller
     fluid scale sized for a page title rather than the homepage's
     full-scale H1. */
  font-size: var(--sm-fluid-page-title) !important;
  line-height: 1.1 !important;
  max-width: 18ch;
}

/* ==========================================================================
   21.1 INTERNAL PAGE — MEDIUM WIDTH UTILITY (Stage 7.1)

   Added during the Stage 7.1 alignment refinement pass. Diagnosis: on the
   Facilitation Overview prototype, the Suitable For and Related Pathways
   sections used the plain .sm-inner width (var(--sm-w-default), 1180px).
   That width is correct for sections with enough content to fill it (the
   split "What This Creates" section, the dark process-steps section), but
   Suitable For and Related Pathways only contain a heading plus a short
   list/band group, so the content sat flush left inside a much wider box,
   reading as accidentally left-heavy rather than deliberately composed.

   The homepage already has a precedent for narrowing a themed section's
   .sm-inner column (.sm-theme-editorial > .sm-inner, used by the homepage
   Complexity section). That rule could not be reused directly here: it is
   scoped by theme class (sm-theme-paper, sm-theme-clay-tint), and both of
   those theme classes are also used by existing homepage sections — a
   theme-scoped rule would have silently narrowed homepage sections too,
   which the brief explicitly prohibits. This utility is a plain, unscoped
   class instead, applied directly to the two affected containers on the
   Facilitation page only, so it cannot affect the homepage.

   Uses the existing --sm-w-medium token introduced for the internal-page
   hero (Stage 7). margin-inline: auto needs !important for the same
   already-documented reason as .sm-inner/.sm-narrow/.sm-wide above
   (Elementor's own .e-con rule sets margin-inline via CSS custom
   properties at equal specificity and wins when they resolve to 0) — this
   is the same existing justification applied to a sibling class, not a
   new pattern.

   Reusable: intended for any future internal-page section whose content
   is too sparse to read well at the full 1180px .sm-inner width.
   ========================================================================== */

.sm-inner-medium {
  max-width: var(--sm-w-medium);
  margin-inline: auto !important;
  padding-inline: var(--sm-space-6);
}
/* ==========================================================================
   Next: Stage 5 — Responsive and Visual Refinement
   ========================================================================== */


/* ==========================================================================
   Stage 10 — WooCommerce / Retreats brand alignment
   Scoped to .woocommerce and EAEL product-list output only.
   Brings buttons, hover states, and price styling into the Clay\/Ink\/Paper
   system. Does not touch core .sm-button or any other site button.
   ========================================================================== */

.woocommerce a.button,
.woocommerce button.button,
.woocommerce .add_to_cart_button,
.woocommerce .single_add_to_cart_button,
.eael-woo-product-list a.button,
.eael-woo-product-list .add_to_cart_button {
  background-color: var(--sm-clay) !important;
  color: var(--sm-paper) !important;
  border: none !important;
  border-radius: var(--sm-radius);
  font-family: var(--sm-font-body);
  font-weight: 600;
  letter-spacing: 0.01em;
  box-shadow: none !important;
  transition: background-color var(--sm-dur-fast) var(--sm-ease-out);
}

.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce .add_to_cart_button:hover,
.woocommerce .single_add_to_cart_button:hover,
.eael-woo-product-list a.button:hover,
.eael-woo-product-list .add_to_cart_button:hover {
  background-color: var(--sm-clay-600) !important;
  color: var(--sm-paper) !important;
}

.eael-woo-product-list .eael-load-more-btn,
.eael-woo-product-list .eael-load-more-btn button,
.eael-woo-product-list-load-more-btn {
  background-color: var(--sm-clay) !important;
  color: var(--sm-paper) !important;
  border: none !important;
  border-radius: var(--sm-radius);
  font-family: var(--sm-font-body);
  font-weight: 600;
}

.eael-woo-product-list .eael-load-more-btn:hover,
.eael-woo-product-list .eael-load-more-btn button:hover,
.eael-woo-product-list-load-more-btn:hover {
  background-color: var(--sm-clay-600) !important;
}

.woocommerce .price,
.woocommerce .woocommerce-Price-amount,
.eael-woo-product-list .price {
  color: var(--sm-ink);
  font-family: var(--sm-font-display);
}

.woocommerce ul.products li.product,
.eael-woo-product-list .products li.product {
  padding: var(--sm-space-4);
}

.woocommerce span.onsale,
.eael-product-list-content-header-badge-sale {
  background-color: var(--sm-clay) !important;
  color: var(--sm-paper) !important;
}

@media (max-width: 767px) {
  .eael-woo-product-list .products {
    grid-template-columns: 1fr !important;
  }
}

/* ==========================================================================
   Stage 10.1 — Related products title typography fix
   Scoped to WooCommerce's single-product Related products block only.
   !important is required here: the site's global "h2, .sm-h2" rule (see
   the Colour/Type section of this file) sets font-size and line-height
   with !important, and WooCommerce renders each related-product title
   as an <h2 class="woocommerce-loop-product__title">, so it inherits
   that page-heading-scale rule directly. A plain, unqualified override
   cannot win against an !important rule regardless of selector
   specificity, so !important is used here too — scoped tightly to the
   related-products title only, nothing else.
   ========================================================================== */

.woocommerce .related.products ul.products li.product .woocommerce-loop-product__title,
.woocommerce div.related.products ul.products li.product h2,
.woocommerce div.related.products ul.products li.product h3 {
  font-family: var(--sm-font-body) !important;
  font-size: 1.15rem !important;
  line-height: 1.3 !important;
  font-weight: 600 !important;
  margin: var(--sm-space-2) 0 var(--sm-space-1) !important;
  color: var(--sm-ink) !important;
}

.woocommerce .related.products > h2 {
  font-family: var(--sm-font-display) !important;
  font-size: var(--sm-fluid-h3, 1.75rem) !important;
  margin-bottom: var(--sm-space-5);
}

@media (max-width: 767px) {
  .woocommerce .related.products ul.products li.product .woocommerce-loop-product__title,
  .woocommerce div.related.products ul.products li.product h2,
  .woocommerce div.related.products ul.products li.product h3 {
    font-size: 1.05rem !important;
    line-height: 1.35 !important;
  }
}



/* Stage 10.2 — Single product title sizing (scoped to WooCommerce single-product only).
   !important is required on font-size/line-height: the site's existing global rule
   'h1, .sm-display { font-size: var(--sm-fluid-h1) !important; line-height: 1.08 !important; }'
   already uses !important, and WooCommerce's single-product title is a literal <h1>, so it
   inherits that page-hero-scale rule directly. A plain rule cannot override an !important
   property regardless of specificity, so matching !important is used here, scoped tightly
   to .single-product .product_title.entry-title only — the global h1 rule itself is untouched
   and every other h1 on the site (page heroes, etc.) is unaffected. */
.single-product .product_title.entry-title {
  font-size: clamp(2rem, 4vw, 3.4rem) !important;
  line-height: 1.1 !important;
  font-family: var(--sm-font-display);
  font-weight: 400;
  max-width: none;
  margin-bottom: var(--sm-space-4);
}

/* Stage 10.2 — Product description link colour (scoped to WooCommerce single-product only)
   !important is required here: the source text (product IDs 1877, 1997) contains an inline
   style="color:#33cccc" span around the link text. Per the Stage 10.2 brief, product content
   may not be edited, and inline styles beat any external stylesheet rule regardless of
   selector specificity unless matched with !important. Scope is limited to single-product
   description/summary links only — no other links on the site are affected. */
.single-product .woocommerce-Tabs-panel a,
.single-product .woocommerce-Tabs-panel a *,
.single-product .summary.entry-summary a,
.single-product .summary.entry-summary a * {
  color: var(--sm-clay-800) !important;
  text-decoration: underline !important;
}
.single-product .woocommerce-Tabs-panel a:hover,
.single-product .woocommerce-Tabs-panel a:hover *,
.single-product .summary.entry-summary a:hover,
.single-product .summary.entry-summary a:hover * {
  color: var(--sm-clay-600) !important;
}
