/* ==========================================================================
   Habitus Concept, base
   Palette and type floors from Habitus_Concept_Brand_Ground_Truth.md
   ========================================================================== */

@font-face {
  font-family: "Eurostile";
  src: url("../assets/fonts/Eurostile-Regular.ttf") format("truetype");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Eurostile";
  src: url("../assets/fonts/Eurostile-Bold.ttf") format("truetype");
  font-weight: 700;
  font-display: swap;
}

:root {
  /* Brand */
  --navy:        #00334F;
  --teal:        #004D73;
  --blue:        #4B9BBB;
  --blue-soft:   #C9DCE6;

  /* Surfaces, sampled from the 2025-2026 catalog. --paper-rgb carries the
     same colour as a bare triplet, because a wash laid over media has to be
     built with rgba() and rgba() cannot take a hex custom property. Anything
     that swaps --paper has to swap this with it. */
  --paper-rgb:   250, 248, 245;
  --paper:       #FAF8F5;
  /* the deep plate: the ground the project tiles sit on, and the ground the
     makers band takes now that the marks have no plate of their own */
  --plate:       #04151F;
  /* The collections index is set in one ink, the way its reference board is.
     It cannot be --navy directly: navy swaps to near black on the dark ground
     and the label, the rules and the links all disappear into the page. */
  --edit-ink:    #00334F;
  --paper-2:     #F2EEE8;
  --sand:        #E9DFCF;
  --sand-deep:   #E5CBA9;

  /* Ink */
  --ink:         #14181B;
  --ink-muted:   #474E54;
  --ink-invert:  #FFFFFF;

  --rule:        rgba(20, 24, 27, 0.14);
  --rule-strong: rgba(20, 24, 27, 0.28);
  --rule-invert: rgba(255, 255, 255, 0.20);

  /* Type. Eurostile is the only typeface in the brand ground truth, so it is
     the only typeface here. It is a wide face with a 70% x-height to cap-height
     ratio, so the scale below runs smaller and looser than a serif scale would. */
  --display: "Eurostile", "Eurostile LT Std", "Bank Gothic", "Helvetica Neue", Arial, sans-serif;
  --ui:      var(--display);
  --sans:    var(--display);   /* kept so older rules keep resolving */

  --step-label: 0.8125rem;   /* 13px, identification only */
  --step-body:  1.125rem;    /* 18px, Eurostile needs the extra size at length */
  --step-lead:  1.3125rem;   /* 21px */

  /* Rhythm */
  --gut: clamp(20px, 4vw, 64px);
  --sec: clamp(88px, 12vh, 168px);
  --maxw: 1560px;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.66, 0, 0.2, 1);

  /* Header metrics live here rather than on .site-head, because the hero has
     to reserve room under a fixed bar and is not one of its descendants.
     The lockup is held as large as the bar will take: the brand ground truth
     puts a legibility floor under the wordmark for a 40+ audience, so the bar
     is sized to the mark rather than the mark trimmed to a target bar height.
     It is the scrolled state that gets short, which is where it matters. */
  --head-logo: clamp(54px, 5.6vw, 78px);
  --head-pad: clamp(12px, 1.1vw, 16px);
  --head-h: calc(var(--head-logo) + 2 * var(--head-pad));
}

/* Dark theme, driven by the footer switch. The brand already owns a dark
   ground, so this is a token swap rather than a second design. */
:root[data-theme="dark"] {
  --paper-rgb:   6, 23, 31;
  --paper:       #06171F;
  --plate:       #0C2532;
  --edit-ink:    #E8F0F4;
  --paper-2:     #0B222E;
  --sand:        #0E2A38;
  --sand-deep:   #123244;
  --navy:        #030D13;
  --teal:        #7FC3E0;
  --ink:         #E8F0F4;
  --ink-muted:   #A9C2CE;
  --rule:        rgba(255, 255, 255, 0.16);
  --rule-strong: rgba(255, 255, 255, 0.36);
}
:root[data-theme="dark"] .site-head[data-solid="true"] { background: rgba(6, 23, 31, 0.9); }
:root[data-theme="dark"] .site-head[data-solid="true"] .logo-col { opacity: 0; }
:root[data-theme="dark"] .site-head[data-solid="true"] .logo-rev { opacity: 1; }
:root[data-theme="dark"] .site-head[data-solid="true"] .nav a { color: var(--ink); }
:root[data-theme="dark"] .site-head[data-solid="true"] .nav-toggle span { background: var(--ink); }
:root[data-theme="dark"] .btn--solid { --btn-fg: #04151F; --btn-bd: var(--blue); background: var(--blue); }
:root[data-theme="dark"] .btn--solid::after { background: #fff; }
:root[data-theme="dark"] .btn--solid:hover { color: #04151F; border-color: #fff; }
:root[data-theme="dark"] .icon-btn::after { background: var(--paper-2); color: var(--ink); }

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-size: var(--step-body);
  line-height: 1.68;
  font-weight: 400;
  letter-spacing: 0.002em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }
button { font: inherit; color: inherit; }

::selection { background: var(--sand-deep); color: var(--ink); }

:focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--navy); color: #fff; padding: 12px 18px; z-index: 999;
}
.skip:focus { left: 12px; top: 12px; }

.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;
}

/* --- primitives ---------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gut);
}

.label {
  font-family: var(--ui);
  font-size: var(--step-label);
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--ink-muted);
  line-height: 1.2;
  margin: 0;
}
.label--invert { color: var(--blue-soft); }

/* --- statement type -------------------------------------------------------
   A statement set as one or more setup lines and then the line it lands on,
   the payoff in Eurostile Bold. Same family throughout, so the emphasis is
   weight and colour rather than a second typeface, and the leading is tight
   enough that the lines read as one sentence rather than as a stack. Started
   in the hero; the manifesto panel and the partnership split use it too, so it
   lives here rather than in any one section's stylesheet.
   -------------------------------------------------------------------------- */

.say {
  --say-set: var(--ink-muted);
  --say-pay: var(--ink);
  display: flex;
  flex-direction: column;
  text-wrap: balance;
}
.say-set { display: block; font-weight: 400; color: var(--say-set); }
.say-pay { display: block; font-weight: 700; color: var(--say-pay); }

/* on a photograph or a film, where the ground is dark and reversed */
.say--invert { --say-set: rgba(255, 255, 255, 0.82); --say-pay: #fff; }

h1, h2, h3, h4 {
  font-weight: 400;
  letter-spacing: -0.005em;
  line-height: 1.16;
  margin: 0;
  text-wrap: balance;
}

.h-display { font-size: clamp(1.95rem, 4.4vw, 4rem);   line-height: 1.14; letter-spacing: -0.012em; }
.h-1       { font-size: clamp(1.55rem, 3vw, 2.8rem);   line-height: 1.18; letter-spacing: -0.009em; }
.h-2       { font-size: clamp(1.3rem, 2vw, 1.95rem);   line-height: 1.24; }
.h-3       { font-size: clamp(1.05rem, 1.3vw, 1.3rem); line-height: 1.32; letter-spacing: 0.002em; }

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

.lead { font-size: var(--step-lead); line-height: 1.6; color: var(--ink-muted); }
.measure { max-width: 26ch; }        /* ch is wider in Eurostile, so the counts drop */
.measure-wide { max-width: 42ch; }

a { color: var(--teal); text-decoration-thickness: 1px; text-underline-offset: 0.22em; }

/* --- buttons ------------------------------------------------------------- */

.btn {
  --btn-fg: var(--ink);
  --btn-bd: var(--rule-strong);
  display: inline-flex;
  align-items: center;
  gap: 0.9em;
  font-family: var(--sans);
  font-size: var(--step-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--btn-fg);
  text-decoration: none;
  padding: 1.05em 1.6em;
  border: 1px solid var(--btn-bd);
  background: none;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  isolation: isolate;
  transition: color 0.45s var(--ease), border-color 0.45s var(--ease);
}
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--ink);
  transform: scaleY(0);
  transform-origin: bottom;
  transition: transform 0.5s var(--ease);
  z-index: -1;
}
.btn:hover { color: var(--paper); border-color: var(--ink); }
.btn:hover::after { transform: scaleY(1); transform-origin: top; }

.btn .arw { transition: transform 0.45s var(--ease); }
.btn:hover .arw { transform: translateX(4px); }

/* a row of buttons; a single button in one behaves exactly as before */
.cta-row { display: flex; flex-wrap: wrap; gap: clamp(10px, 1.2vw, 16px); }

.btn--solid { --btn-fg: var(--paper); --btn-bd: var(--navy); background: var(--navy); }
.btn--solid::after { background: var(--teal); }
.btn--solid:hover { color: #fff; border-color: var(--teal); }

.btn--invert { --btn-fg: #fff; --btn-bd: var(--rule-invert); }
.btn--invert::after { background: #fff; }
.btn--invert:hover { color: var(--navy); border-color: #fff; }

/* Glass call, for buttons that sit on the film or on a navy plate. This is a
   web frosted-glass approximation, not a platform material: a near-transparent
   fill, a blur behind it, and a rim that is a gradient masked down to the
   border so the top and bottom edges catch light and the sides do not. */
.btn--glass {
  --btn-fg: #fff;
  --btn-bd: transparent;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  backdrop-filter: blur(10px) saturate(1.3);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.16);
  transition: color 0.45s var(--ease), background-color 0.35s linear,
              transform 0.45s var(--ease);
}
.btn--glass::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.4px;
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.50) 0%, rgba(255, 255, 255, 0.16) 20%,
    rgba(255, 255, 255, 0) 40%, rgba(255, 255, 255, 0) 60%,
    rgba(255, 255, 255, 0.16) 80%, rgba(255, 255, 255, 0.50) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
}
.btn--glass::after { background: #fff; }
.btn--glass:hover { color: var(--navy); background: rgba(255, 255, 255, 0.10); transform: scale(1.02); }

@media (prefers-reduced-transparency: reduce) {
  .btn--glass {
    background: rgba(255, 255, 255, 0.16);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

/* --- header -------------------------------------------------------------- */

.site-head {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 3vw, 44px);
  padding: var(--head-pad) var(--gut);
  transition: transform 0.55s var(--ease), background-color 0.4s linear,
              border-color 0.4s linear, padding 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-head[data-solid="true"] {
  --head-logo: clamp(42px, 4.2vw, 56px);
  background: rgba(250, 248, 245, 0.9);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  backdrop-filter: saturate(1.4) blur(14px);
  border-bottom-color: var(--rule);
}
.site-head[data-hidden="true"] { transform: translateY(-102%); }

/* The supplied lockup, in two colourways so it reads on the film and on paper. */
.brand {
  display: block;
  position: relative;
  flex: none;
  line-height: 0;
  z-index: 2;
}
.brand img {
  display: block;
  height: var(--head-logo);
  width: auto;
  transition: opacity 0.4s linear, height 0.4s var(--ease);
}
.brand .logo-rev { position: absolute; inset: 0; }
.site-head[data-solid="true"] .logo-rev { opacity: 0; }
.site-head[data-solid="false"] .logo-col { opacity: 0; }

.nav {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2vw, 34px);
  min-width: 0;
  /* Tracked caps carry a trailing 0.16em after the final letter, so a nav that
     is mathematically inside the gutter still reads as if it were jammed
     against the edge. The row is pulled back by exactly one tracking step and
     given its own inset, which is what buys CONTACT its margin. */
  margin-right: -0.16em;
  padding-right: clamp(4px, 0.6vw, 10px);
}
.nav a {
  font-family: var(--sans);
  font-size: var(--step-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: #fff;
  white-space: nowrap;
  position: relative;
  padding-block: 4px;
  transition: color 0.4s linear, opacity 0.3s linear;
}
.site-head[data-solid="true"] .nav a { color: var(--ink); }
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0.16em; bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.45s var(--ease);
}
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); transform-origin: left; }

.nav-toggle { display: none; }

@media (max-width: 900px) {
  .nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    height: 100svh;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    gap: 6px;
    padding: 0 var(--gut);
    background: var(--navy);
    transform: translateY(-100%);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: transform 0.7s var(--ease), opacity 0.3s linear, visibility 0.7s;
    z-index: 1;
  }
  .nav a { color: #fff !important; font-size: 1.05rem; padding-block: 14px; }
  body[data-menu="open"] .nav {
    transform: translateY(0);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
  }
  body[data-menu="open"] { overflow: hidden; }

  .nav-toggle {
    display: block;
    position: relative;
    z-index: 2;
    width: 40px; height: 26px;
    border: 0; background: none; cursor: pointer; padding: 0;
  }
  .nav-toggle span {
    position: absolute; left: 6px; right: 6px; height: 1px;
    background: #fff;
    transition: transform 0.45s var(--ease), opacity 0.2s linear, background-color 0.4s linear;
  }
  .nav-toggle span:nth-child(1) { top: 9px; }
  .nav-toggle span:nth-child(2) { top: 16px; }
  .site-head[data-solid="true"] .nav-toggle span { background: var(--ink); }
  body[data-menu="open"] .nav-toggle span { background: #fff !important; }
  body[data-menu="open"] .nav-toggle span:nth-child(1) { transform: translateY(3.5px) rotate(15deg); }
  body[data-menu="open"] .nav-toggle span:nth-child(2) { transform: translateY(-3.5px) rotate(-15deg); }
}

/* --- footer ---------------------------------------------------------------
   A layered card rather than a flat navy band: the page ground carries a navy
   body, the body carries a deeper box holding the directory, and the legal bar
   sits in the body under the box. Below the card the wordmark is set into the
   ground rather than printed on it, by an SVG filter that casts a shadow under
   the glyphs, lights their top edge from inside and shades their bottom edge.
   -------------------------------------------------------------------------- */

.site-foot {
  position: relative;
  background: var(--paper-2);
  color: var(--blue-soft);
  padding: clamp(40px, 6vw, 84px) 0 0;
}
.site-foot a { color: #fff; text-decoration: none; transition: color 0.25s linear; }
.site-foot a:hover { color: var(--blue); }

.foot-card {
  background: var(--navy);
  border: 1px solid var(--rule-invert);
  border-radius: clamp(22px, 3vw, 48px);
  padding: clamp(6px, 0.6vw, 9px);
  overflow: hidden;
}
.foot-box {
  position: relative;
  background: #04151F;
  border-radius: clamp(16px, 2.4vw, 40px);
  padding: clamp(28px, 3.6vw, 60px);
  overflow: hidden;
}

.foot-grid {
  display: grid;
  grid-template-columns: 1fr 0.85fr 1.05fr;
  gap: clamp(28px, 3.4vw, 56px);
  align-items: start;
}
.foot-h {
  font-family: var(--ui);
  font-size: var(--step-label);
  letter-spacing: 0.19em;
  text-transform: uppercase;
  font-weight: 400;
  color: #fff;
  margin: 0 0 18px;
}
.foot-p { color: var(--blue-soft); margin: 0 0 20px; max-width: 30ch; }
.foot-col { position: relative; }
.foot-col--follow { position: relative; }

.foot-orb {
  position: absolute;
  right: -10px; top: -20px;
  width: 130px; height: 130px;
  border-radius: 50%;
  background: var(--blue);
  opacity: 0.16;
  filter: blur(38px);
  pointer-events: none;
}

/* Following is the thing this footer asks for, so it reads as three named
   destinations with the handle on each rather than three unlabelled circles.
   An icon on its own makes the reader guess which account it is. */
.foot-follow {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
  max-width: 380px;
}
.foot-follow a {
  display: flex;
  align-items: center;
  gap: clamp(10px, 2.6vw, 14px);
  padding: 11px clamp(11px, 2.8vw, 14px);
  border: 1px solid var(--rule-invert);
  background: rgba(255, 255, 255, 0.04);
  transition: background-color 0.3s linear, border-color 0.3s linear, transform 0.4s var(--ease);
}
.foot-follow a:hover,
.foot-follow a:focus-visible {
  background: rgba(255, 255, 255, 0.09);
  border-color: rgba(255, 255, 255, 0.42);
  transform: translateX(3px);
}
.foot-follow-ico {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border: 1px solid var(--rule-invert);
  border-radius: 50%;
  color: #fff;
}
.foot-follow-ico svg { width: 17px; height: 17px; }
.foot-follow-ico svg[fill="none"] { fill: none; }
.foot-follow li:nth-child(2) .foot-follow-ico svg { fill: currentColor; }
.foot-follow-txt { display: grid; gap: 1px; min-width: 0; }
.foot-follow-net {
  font-family: var(--ui);
  font-size: var(--step-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--blue-soft);
}
.foot-follow-at {
  /* the longest of the three is the address, and it has to survive a 390px
     card without breaking mid-word, so the size gives before the string does */
  font-size: clamp(0.84rem, 3.1vw, 1rem);
  line-height: 1.35;
  color: #fff;
  overflow-wrap: break-word;
}
.foot-follow .arw {
  margin-left: auto;
  flex: none;
  color: var(--blue-soft);
  transition: transform 0.4s var(--ease);
}
.foot-follow a:hover .arw { transform: translateX(4px); }

.foot-list { display: grid; gap: 11px; }
.foot-address { font-style: normal; line-height: 1.9; }

.foot-social { display: flex; gap: 10px; margin-bottom: 26px; }
.icon-btn {
  position: relative;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border: 1px solid var(--rule-invert);
  border-radius: 50%;
  color: #fff;
  transition: background-color 0.3s linear, border-color 0.3s linear, transform 0.35s var(--ease);
}
.icon-btn svg { width: 19px; height: 19px; }
.icon-btn:hover { background: rgba(255, 255, 255, 0.1); border-color: #fff; transform: translateY(-2px); }
.icon-btn::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  padding: 5px 10px;
  border-radius: 3px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 12px;
  letter-spacing: 0.08em;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.22s linear, transform 0.28s var(--ease);
}
.icon-btn:hover::after, .icon-btn:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }

.theme-row { display: flex; align-items: center; gap: 11px; color: var(--blue-soft); }
.theme-ico { width: 17px; height: 17px; flex: none; }
.switch {
  width: 46px; height: 25px;
  flex: none;
  padding: 2px;
  border: 1px solid var(--rule-invert);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.1);
  cursor: pointer;
  transition: background-color 0.3s linear, border-color 0.3s linear;
}
.switch-thumb {
  display: block;
  width: 19px; height: 19px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.32s var(--ease);
}
.switch[aria-checked="true"] { background: var(--blue); border-color: var(--blue); }
.switch[aria-checked="true"] .switch-thumb { transform: translateX(21px); }

/* the legal bar lives in the navy body, under the box, not inside it */
.foot-base {
  display: flex; flex-wrap: wrap; gap: 12px 28px;
  justify-content: space-between; align-items: center;
  padding: clamp(14px, 1.4vw, 20px) clamp(20px, 2.6vw, 44px);
  padding-right: clamp(72px, 8vw, 110px);   /* room for the WhatsApp button */
  font-family: var(--ui);
  font-size: var(--step-label);
  letter-spacing: 0.1em;
  color: var(--blue-soft);
}
.foot-base-nav { display: flex; flex-wrap: wrap; gap: 12px 26px; }

@media (max-width: 1080px) {
  .foot-grid { grid-template-columns: 1fr 1fr; row-gap: 44px; }
  .foot-col--follow { grid-column: span 2; }
}
@media (max-width: 620px) {
  .foot-grid { grid-template-columns: 1fr; }
  .foot-col--follow { grid-column: span 1; }
  .foot-base { justify-content: flex-start; gap: 18px; }
}

/* --- the wordmark in the ground ------------------------------------------ */

.foot-word {
  display: flex;
  justify-content: center;
  overflow: hidden;                 /* the filter paints well outside the glyphs */
  padding: clamp(8px, 1.4vw, 24px) 0 clamp(10px, 1.2vw, 20px);
  pointer-events: none;
}
.foot-word-defs { position: absolute; width: 0; height: 0; }

.foot-word-mark {
  margin: 0;
  font-weight: 700;
  /* set to the page width: seven wide Eurostile caps at this size fill the
     measure, so the mark is trimmed by its own container rather than scaled */
  font-size: clamp(2.8rem, 19.2vw, 17.4rem);
  line-height: 0.92;
  letter-spacing: -0.012em;
  white-space: nowrap;
  color: #fff;
  filter: url(#hc-emboss);
  -webkit-user-select: none;
  user-select: none;
}

/* Dark ground: the emboss is a light effect and it has nothing to catch, so
   the mark drops the filter and becomes a quiet ghost instead. */
:root[data-theme="dark"] .foot-word-mark {
  color: rgba(232, 240, 244, 0.09);
  filter: none;
}

/* --- WhatsApp ------------------------------------------------------------ */

.wa-float {
  position: fixed;
  right: clamp(16px, 2.4vw, 32px);
  bottom: clamp(16px, 2.4vw, 32px);
  z-index: 80;
  display: inline-flex;
  align-items: center;
  gap: 0;
  height: 56px;
  padding: 0 16px;
  border-radius: 999px;
  background: var(--navy);
  color: #fff;
  text-decoration: none;
  box-shadow: 0 10px 30px rgba(0, 32, 51, 0.32);
  transition: gap 0.45s var(--ease), padding 0.45s var(--ease),
              background-color 0.3s linear, transform 0.45s var(--ease);
}
.wa-float svg { width: 26px; height: 26px; fill: currentColor; flex: none; }
.wa-float span {
  font-family: var(--sans);
  font-size: var(--step-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  transition: max-width 0.5s var(--ease);
}
.wa-float:hover, .wa-float:focus-visible {
  background: var(--teal);
  gap: 12px;
  transform: translateY(-2px);
}
.wa-float:hover span, .wa-float:focus-visible span { max-width: 160px; }
@media (max-width: 600px) {
  .wa-float { height: 52px; padding: 0 13px; }
  .wa-float:hover span, .wa-float:focus-visible span { max-width: 0; }
}

.wa-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
}
.wa-inline svg { width: 1.05em; height: 1.05em; fill: currentColor; flex: none; }

.contact-stack { display: flex; flex-direction: column; gap: 0.45em; align-items: flex-start; }

/* --- reveal -------------------------------------------------------------- */

[data-reveal] {
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
  transition-delay: var(--d, 0ms);
}
.js [data-reveal] { opacity: 0; transform: translateY(18px); }
[data-reveal].in { opacity: 1; transform: none; }

.rule-full { height: 1px; background: var(--rule); border: 0; margin: 0; }

@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;
  }
  [data-reveal] { opacity: 1; transform: none; }
}
