/* ==========================================================================
   Velora Productions - main stylesheet
   Tokens and rules follow design-system/velora-productions/MASTER.md
   ========================================================================== */

/* --------------------------------------------------------------- 1. Tokens */

:root {
  /* Colour - the two brand colours, plus darker tints of the SAME green hue.
     Brand green #36736A is hsl(171, 36%, 33%); --green-deep and --ink are that
     identical hue at 18% and 9% lightness, so every dark surface on the site is
     the logo green, just deeper. No second hue exists in this system.

     Measured against cream #F4EEDF:
       --green       4.75:1   AA for normal text. Gold FAILS on it (2.29:1).
       --green-deep 10.07:1   gold 4.84:1
       --ink        14.70:1   gold 7.07:1                                    */
  --green: #36736a; /* THE brand green - every section surface */
  --green-deep: #1d3e3a; /* same hue, darker - body text on cream */
  --ink: #0f1f1d; /* same hue, deepest - footer and photo scrims */
  --cream: #f4eedf; /* THE brand cream */
  --cream-soft: #fbf7ee;
  --cream-dim: #e3dac3;
  --gold: #c8a24c; /* accent - only on --ink, never on --green */
  --gold-deep: #9a7a2e;

  /* Kept as an alias so existing rules read cleanly; it IS the brand green. */
  --forest: var(--green);

  /* Semantic */
  --bg: var(--cream);
  --fg: var(--green-deep);
  --fg-muted: var(--green);
  --rule: var(--cream-dim);

  /* Type */
  --font-display: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --font-body: "Montserrat", ui-sans-serif, system-ui, -apple-system, sans-serif;

  --fs-display-xl: clamp(2.75rem, 7vw, 6rem);
  --fs-display-l: clamp(2.25rem, 5vw, 4.25rem);
  --fs-display-m: clamp(1.875rem, 3.6vw, 3rem);
  --fs-h3: clamp(1.25rem, 2vw, 1.625rem);
  --fs-body-l: 1.0625rem;
  --fs-body: 1rem;
  --fs-small: 0.875rem;
  --fs-eyebrow: 0.6875rem;

  /* Space */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 64px;
  --space-8: 96px;
  --space-9: 128px;
  --space-10: 160px;

  --gutter: clamp(20px, 5vw, 64px);
  --measure-wide: 1280px;
  --section-y: clamp(80px, 11vw, 160px);

  /* Motion */
  --dur-fast: 180ms;
  --dur-base: 320ms;
  --dur-slow: 620ms;
  --ease-out: cubic-bezier(0.22, 0.9, 0.26, 1);
  --ease-inout: cubic-bezier(0.4, 0, 0.2, 1);

  /* Layers */
  --z-rail: 40;
  /* The drawer sits BELOW the nav so the burger stays visible as the close
     control once the drawer is open. */
  --z-drawer: 50;
  --z-nav: 60;
  --z-splash: 9999;

  --nav-h: 76px;
}

/* ----------------------------------------------------------- 2. Foundation */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

body.is-locked {
  overflow: hidden;
}

img,
svg,
picture {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

/* A <picture> is only a wrapper, so a cover image's `height: 100%` would
   otherwise resolve against an auto-height box and collapse to its aspect
   ratio. Give the wrapper the frame's box wherever we crop. */
.hero__frame picture,
.frame picture,
.pagehead__bg picture,
.cta-band__bg picture {
  width: 100%;
  height: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  letter-spacing: 0.005em;
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The ring has to clear 3:1 against whatever it sits on. Gold manages that on
   --ink only (7.1:1) and fails badly on cream (2.1:1), so the ring follows the
   surface: deep green on light, cream on dark. */
:focus-visible {
  outline: 2px solid var(--focus-ring, var(--green-deep));
  outline-offset: 2px;
}

.nav,
.drawer,
.rail,
.footer,
.section--forest,
.section--green,
.section--ink,
.cta-band,
.pagehead {
  --focus-ring: var(--cream);
}

::selection {
  background: var(--green);
  color: var(--cream);
}

.skip-link {
  position: absolute;
  top: -100px;
  left: var(--gutter);
  z-index: calc(var(--z-splash) + 1);
  padding: 12px 20px;
  background: var(--cream);
  color: var(--forest);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: top var(--dur-fast) var(--ease-out);
}

.skip-link:focus-visible {
  top: 12px;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------------------------------------------------------- 3. Layout help */

.shell {
  width: 100%;
  max-width: var(--measure-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.shell--narrow {
  max-width: 920px;
}

.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--cream {
  background: var(--cream);
  color: var(--forest);
}

.section--soft {
  background: var(--cream-soft);
  color: var(--forest);
}

/* Brand-green surfaces. Cream clears AA at 4.75:1, but nothing dimmer does -
   a tinted "muted" tone lands at 3.4:1 and fails. So secondary text here is
   cream too, and the hierarchy comes from scale, weight and rules instead of
   from colour. Gold is excluded entirely (2.29:1). */
.section--forest,
.section--green {
  background: var(--green);
  color: var(--cream);
  --fg-muted: var(--cream);
  --rule: rgba(244, 238, 223, 0.28);
}

/* The deepest tint keeps enough range for a genuinely muted tone and for gold. */
.section--ink {
  background: var(--ink);
  color: var(--cream);
  --fg-muted: #b3c6bd;
  --rule: rgba(244, 238, 223, 0.14);
}

.section--tight {
  padding-block: clamp(56px, 7vw, 96px);
}

/* ------------------------------------------------------------- 4. Type kit */

.eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0 0 var(--space-4);
  color: var(--fg-muted);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.eyebrow::before {
  content: "";
  width: 32px;
  height: 1px;
  background: currentColor;
  opacity: 0.65;
  flex: none;
}

.eyebrow--center {
  justify-content: center;
}

.display-xl {
  font-size: var(--fs-display-xl);
  line-height: 1.02;
  letter-spacing: -0.012em;
}

.display-l {
  font-size: var(--fs-display-l);
  line-height: 1.08;
  letter-spacing: -0.008em;
}

.display-m {
  font-size: var(--fs-display-m);
  line-height: 1.14;
}

.lead {
  max-width: 62ch;
  color: var(--fg-muted);
  font-size: var(--fs-body-l);
  line-height: 1.78;
  font-weight: 300;
}

.body-measure {
  max-width: 68ch;
}

.center {
  text-align: center;
}

.center .lead,
.center .body-measure {
  margin-inline: auto;
}

.section-head {
  margin-bottom: clamp(40px, 5vw, 72px);
}

.section-head .display-l,
.section-head .display-m {
  max-width: 20ch;
}

.section-head.center .display-l,
.section-head.center .display-m {
  margin-inline: auto;
}

/* Gold is legible on --ink only - see MASTER.md §1 */
.section--ink .accent {
  color: var(--gold);
}

.section--forest .accent,
.section--green .accent {
  color: var(--cream);
}

.section--cream .accent,
.section--soft .accent {
  color: var(--green);
}

.italic-accent {
  font-style: italic;
  font-weight: 300;
}

/* --------------------------------------------------------------- 5. Button */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 48px;
  padding: 14px 30px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    transform var(--dur-fast) var(--ease-out);
}

.btn:active {
  transform: scale(0.98);
}

.btn svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.btn--gold {
  background: var(--gold);
  color: var(--ink);
  border-color: var(--gold);
}

.btn--gold:hover {
  background: #dbb469;
  border-color: #dbb469;
}

/* The nav and drawer sit on the brand green, where a gold fill only reaches a
   2.29:1 boundary. Cream gives 4.75:1 against the green and 10:1 for its label,
   and reads as the same family as the gold in-page CTAs. */
.btn--cream {
  background: var(--cream);
  color: var(--green-deep);
  border-color: var(--cream);
}

.btn--cream:hover {
  background: #ffffff;
  border-color: #ffffff;
}

.btn--outline {
  border-color: currentColor;
  color: inherit;
}

.btn--outline:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--green-deep);
}

.section--cream .btn--outline:hover,
.section--soft .btn--outline:hover {
  background: var(--green);
  border-color: var(--green);
  color: var(--cream);
}

.btn--solid {
  background: var(--green);
  border-color: var(--green);
  color: var(--cream);
}

.btn--solid:hover {
  background: var(--green-deep);
  border-color: var(--green-deep);
}

/* Text link with a drawing underline */
.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: inherit;
}

.link-arrow::after {
  content: "";
  width: 28px;
  height: 1px;
  background: currentColor;
  transition: width var(--dur-base) var(--ease-out);
}

.link-arrow:hover::after {
  width: 44px;
}

/* ------------------------------------------------------------------ 6. Nav */

.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: var(--z-nav);
  display: flex;
  align-items: center;
  min-height: var(--nav-h);
  padding-block: 10px;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out);
}

/* While the nav is transparent it can sit over a bright part of a photograph
   (a lit ceiling, a white LED wall). This scrim keeps the links legible over
   any image, and fades out once the solid bar takes over. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0 0 auto;
  height: 180px;
  background: linear-gradient(
    to bottom,
    rgba(15, 31, 29, 0.88) 0%,
    rgba(15, 31, 29, 0.52) 45%,
    rgba(15, 31, 29, 0) 100%
  );
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}

.nav.is-solid {
  background: var(--green);
  border-bottom-color: rgba(244, 238, 223, 0.32);
}

.nav.is-solid::before {
  opacity: 0;
}

.nav__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  width: 100%;
  max-width: var(--measure-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.nav__brand {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--cream);
  flex: none;
}

.nav__brand svg {
  width: auto;
  height: 42px;
  color: var(--cream);
  transition: height var(--dur-base) var(--ease-out);
}

.nav.is-solid .nav__brand svg {
  height: 36px;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.4vw, 38px);
}

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--cream);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.05em;
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 8px;
  width: 0;
  height: 1px;
  background: var(--cream);
  transition: width var(--dur-base) var(--ease-out);
}

.nav__link:hover::after,
.nav__link[aria-current="page"]::after {
  width: 100%;
}

.nav__link[aria-current="page"] {
  color: var(--cream);
  font-weight: 600;
}

.nav__cta {
  flex: none;
}

.nav__cta .btn {
  min-height: 44px;
  padding: 11px 24px;
  font-size: 0.6875rem;
}

.nav__burger {
  display: none;
  width: 48px;
  height: 48px;
  margin-right: -10px;
  place-items: center;
  color: var(--cream);
}

.nav__burger span {
  position: relative;
  display: block;
  width: 24px;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-base) var(--ease-out),
    opacity var(--dur-fast) var(--ease-out);
}

.nav__burger span::before,
.nav__burger span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 24px;
  height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-base) var(--ease-out);
}

.nav__burger span::before {
  top: -7px;
}

.nav__burger span::after {
  top: 7px;
}

.nav__burger[aria-expanded="true"] span {
  background: transparent;
}

.nav__burger[aria-expanded="true"] span::before {
  transform: translateY(7px) rotate(45deg);
}

.nav__burger[aria-expanded="true"] span::after {
  transform: translateY(-7px) rotate(-45deg);
}

/* Mobile drawer */
.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: grid;
  grid-template-rows: var(--nav-h) 1fr;
  background: var(--forest);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-12px);
  transition: opacity var(--dur-base) var(--ease-out),
    transform var(--dur-base) var(--ease-out),
    visibility 0s linear var(--dur-base);
}

.drawer.is-open {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

.drawer__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--gutter) calc(var(--space-7) + env(safe-area-inset-bottom));
  overflow-y: auto;
}

.drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 60px;
  padding-block: 10px;
  border-bottom: 1px solid rgba(244, 238, 223, 0.14);
  color: var(--cream);
  font-family: var(--font-display);
  font-size: 1.75rem;
  line-height: 1.2;
}

/* Drawer links are 28px display type, so the 3:1 large-text threshold applies.
   The current page sits at full cream (4.75:1); the rest at 3.3:1. */
.drawer__link {
  color: rgba(244, 238, 223, 0.72);
}

.drawer__link[aria-current="page"] {
  color: var(--cream);
  font-weight: 600;
}

.drawer__link span {
  font-family: var(--font-body);
  font-size: 0.6875rem;
  letter-spacing: 0.2em;
  color: var(--cream);
}

.drawer__foot {
  margin-top: var(--space-6);
  display: grid;
  gap: var(--space-3);
  color: var(--cream);
  font-size: var(--fs-small);
}

.drawer__foot a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 10px;
}

/* ----------------------------------------------------------------- 7. Hero */

.hero {
  position: relative;
  /* Scroll track for the sticky crossfade. One viewport per frame. */
  height: calc(var(--hero-frames, 4) * 85vh);
}

.hero__sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  min-height: 560px;
  overflow: hidden;
}

.hero__media {
  position: absolute;
  inset: 0;
}

.hero__frame {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 900ms var(--ease-inout);
  will-change: opacity;
}

.hero__frame.is-active {
  opacity: 1;
}

.hero__frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* The copy block occupies roughly the bottom 15–60% of the hero, so the scrim
   needs a floor across that band rather than fading out through it. Worked
   against a worst-case pure-white frame: cream display type (large, 3:1) needs
   ~0.49 opacity, and the 11px kicker (normal, 4.5:1) needs ~0.62. The stops
   below hold ≥0.66 everywhere the copy sits. */
.hero__veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(15, 31, 29, 0.92) 0%,
    rgba(15, 31, 29, 0.8) 45%,
    rgba(15, 31, 29, 0.66) 62%,
    rgba(15, 31, 29, 0.34) 85%,
    rgba(15, 31, 29, 0.72) 100%
  );
}

.hero__copy {
  position: absolute;
  inset: auto 0 clamp(96px, 14vh, 150px);
  width: 100%;
  max-width: var(--measure-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
  color: var(--cream);
}

/* Cream, not gold: over a photograph the backdrop is never reliably dark enough
   for a mid-tone like gold to clear 4.5:1 at this size. Cream reaches 6.1:1
   against the scrim floor above. */
.hero__kicker {
  margin-bottom: var(--space-4);
  color: var(--cream);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}

.hero__lines {
  position: relative;
  min-height: calc(var(--fs-display-xl) * 2.1);
}

.hero__line {
  position: absolute;
  inset: 0 auto auto 0;
  max-width: 17ch;
  font-size: var(--fs-display-xl);
  line-height: 1.02;
  letter-spacing: -0.012em;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 620ms var(--ease-out), transform 620ms var(--ease-out);
  pointer-events: none;
}

.hero__line.is-active {
  opacity: 1;
  transform: none;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.hero__cue {
  position: absolute;
  left: 50%;
  bottom: clamp(28px, 5vh, 46px);
  transform: translateX(-50%);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  color: rgba(244, 238, 223, 0.8);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
}

.hero__cue i {
  display: block;
  width: 1px;
  height: 42px;
  background: linear-gradient(to bottom, var(--gold), transparent);
}

/* Compact hero for inner pages */
.pagehead {
  position: relative;
  display: grid;
  align-items: end;
  min-height: clamp(400px, 56vh, 620px);
  padding-top: calc(var(--nav-h) + var(--space-6));
  padding-bottom: clamp(48px, 7vw, 88px);
  overflow: hidden;
  /* The deepest tint, not the brand green: the scrim above composites onto this,
     and it is also what shows if the photograph fails to load - where gold
     eyebrows would drop to 2.29:1 on green but hold 7.07:1 here. */
  background: var(--ink);
  color: var(--cream);
  isolation: isolate;
}

.pagehead__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.pagehead__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pagehead::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to top,
    rgba(15, 31, 29, 0.95) 0%,
    rgba(15, 31, 29, 0.86) 38%,
    rgba(15, 31, 29, 0.6) 72%,
    rgba(15, 31, 29, 0.55) 100%
  );
}

.pagehead__inner {
  width: 100%;
  max-width: var(--measure-wide);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.pagehead .eyebrow {
  color: var(--gold);
}

.pagehead .lead {
  color: #d7e0d9;
}

/* Breadcrumb */
.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: var(--space-5);
  font-size: var(--fs-small);
  color: #bdcfc6;
}

.crumbs a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

.crumbs a:hover {
  color: var(--gold);
}

.crumbs [aria-current="page"] {
  color: var(--cream);
}

.crumbs svg {
  width: 14px;
  height: 14px;
  opacity: 0.6;
}

/* -------------------------------------------------------------- 8. Pillars */

.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--rule);
  border-block: 1px solid var(--rule);
}

.pillars__item {
  padding: clamp(32px, 4vw, 52px) clamp(20px, 3vw, 40px);
  background: var(--cream);
  text-align: center;
}

.section--forest .pillars__item,
.section--ink .pillars__item {
  background: var(--forest);
}

.section--ink .pillars__item {
  background: var(--ink);
}

.pillars__item h3 {
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.2;
}

.pillars__item p {
  margin-top: 10px;
  color: var(--fg-muted);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

/* ----------------------------------------------------------- 9. Stat strip */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: clamp(28px, 4vw, 56px);
}

.stat__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.75rem, 5vw, 4rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.section--ink .stat__num {
  color: var(--gold);
}

.section--forest .stat__num,
.section--green .stat__num {
  color: var(--cream);
}

.stat__label {
  display: block;
  margin-top: 14px;
  padding-top: 14px;
  border-top: 1px solid var(--rule);
  color: var(--fg-muted);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ---------------------------------------------------------- 10. Media pair */

.split {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  align-items: center;
  gap: clamp(32px, 6vw, 88px);
}

.split--reverse .split__media {
  order: 2;
}

/* The vision section pairs a portrait clip with four paragraphs. An even split
   would make the video tower over the copy, so the media column takes the
   smaller share. */
.split--vision {
  grid-template-columns: minmax(0, 0.78fr) minmax(0, 1fr);
}


.split__media {
  position: relative;
}

.frame {
  position: relative;
  overflow: hidden;
  background: var(--forest);
}

.frame img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}

.frame--4x5 {
  aspect-ratio: 4 / 5;
}

.frame--2x3 {
  aspect-ratio: 2 / 3;
}

.frame--3x2 {
  aspect-ratio: 3 / 2;
}

.frame--16x9 {
  aspect-ratio: 16 / 9;
}

.frame--1x1 {
  aspect-ratio: 1 / 1;
}

.frame--9x16 {
  aspect-ratio: 9 / 16;
}

/* ------------------------------------------------- 10b. Seamless video loop

   A clip whose last frame is nothing like its first cannot loop without a
   visible jump cut, so the wrap is crossfaded instead: two layers of the same
   file, the incoming one already playing before the outgoing one runs out.
   Linear easing keeps the combined opacity steady through the handover rather
   than dipping in the middle. */

.loop {
  background: var(--ink);
}

.loop__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--loop-fade, 900ms) linear;
}

.loop__layer.is-active {
  opacity: 1;
}

.frame__tag {
  position: absolute;
  left: 0;
  bottom: 0;
  padding: 12px 20px;
  background: var(--gold);
  color: var(--ink);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

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

.vision__sign {
  margin-top: var(--space-5);
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.625rem);
  line-height: 1.4;
}

/* ----------------------------------------------------- 10b. Floating media

   Paper resting on still water: it drifts and tilts, slowly but visibly. Two
   separate cycles on nested elements, with durations that share no common factor
   (9.5s and 11.5s - that is 19 and 23 half-seconds), so the pair only realigns
   every 218 seconds, around three and a half minutes. Nothing reads as a loop.
   If you retime these, keep that property: 10s and 12s would resync every minute
   and the movement would start to feel mechanical.

   The reveal animation owns the transform on the wrapper above these, which is
   why the drift and the tilt each need their own element: two animations cannot
   share one transform property.

   Peak travel is 30px vertical and 12px horizontal, with the tilt peaking at
   1.26 degrees - which swings a corner of the frame about 11px. Measured on
   screen, the frame's edge travels around 32px. Both are transform-only, so
   nothing reflows while it moves. */

.drift,
.drift__tilt {
  will-change: transform;
}

.drift {
  animation: veloraDrift 9.5s ease-in-out -3.5s infinite;
}

.drift__tilt {
  animation: veloraTilt 11.5s ease-in-out -5.5s infinite;
}

@keyframes veloraDrift {
  0% {
    transform: translate3d(0, 0, 0);
  }
  25% {
    transform: translate3d(-9px, -18px, 0);
  }
  50% {
    transform: translate3d(6px, -30px, 0);
  }
  75% {
    transform: translate3d(12px, -12px, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

@keyframes veloraTilt {
  0% {
    transform: rotate(0deg);
  }
  33% {
    transform: rotate(1.26deg);
  }
  66% {
    transform: rotate(-1.02deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

/* -------------------------------------------------------------- 11. Cards */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  gap: clamp(20px, 2.6vw, 32px);
}

.cards--2 {
  grid-template-columns: repeat(2, 1fr);
}

.cards--3 {
  grid-template-columns: repeat(3, 1fr);
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--cream-soft);
  border: 1px solid var(--rule);
  transition: border-color var(--dur-base) var(--ease-out);
}

.section--forest .card,
.section--ink .card {
  background: rgba(244, 238, 223, 0.045);
}

.card:hover {
  border-color: var(--cream);
}

.section--cream .card:hover,
.section--soft .card:hover {
  border-color: var(--green);
}

.card:hover .frame img,
.card:focus-within .frame img {
  transform: scale(1.045);
}

.card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--space-3);
  padding: clamp(22px, 2.4vw, 32px);
}

.card__meta {
  color: var(--fg-muted);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.card__title {
  font-size: var(--fs-h3);
  line-height: 1.2;
}

.card__text {
  color: var(--fg-muted);
  font-size: var(--fs-small);
  line-height: 1.75;
  font-weight: 300;
}

/* The director cards: a cut-out portrait on the brand green above the name.
   The frame already carries that green, so a photo that has not loaded yet
   leaves the right colour rather than a hole. */
.team__close {
  max-width: 62ch;
  margin: var(--space-6) auto 0;
  color: var(--fg-muted);
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 1.8vw, 1.4rem);
  line-height: 1.6;
  text-align: center;
}

.card__body .link-arrow {
  margin-top: auto;
}

/* Whole-card link target, keyboard reachable via the inner anchor */
.card__link::after {
  content: "";
  position: absolute;
  inset: 0;
}

/* --------------------------------------------------------- 11b. Carousel

   Three cards in view, advancing one at a time. The track is a flex row that
   translates by exactly one slide plus one gap; the slide width is derived from
   --visible so the same markup gives 3, 2 or 1 across without any JS branching
   on breakpoints. */

.carousel {
  --visible: 3;
  --carousel-gap: clamp(20px, 2.6vw, 32px);
  position: relative;
}

.carousel__viewport {
  overflow: hidden;
  /* Room for the focus ring on a card link, which would otherwise be clipped
     by the overflow above. */
  margin: -4px;
  padding: 4px;
}

.carousel__track {
  display: flex;
  gap: var(--carousel-gap);
  margin: 0;
  padding: 0;
  list-style: none;
  transition: transform var(--dur-slow) var(--ease-inout);
  will-change: transform;
}

.carousel__track.is-instant {
  transition: none;
}

.carousel__slide {
  flex: 0 0
    calc((100% - (var(--visible) - 1) * var(--carousel-gap)) / var(--visible));
  display: flex;
}

.carousel__slide > .card {
  flex: 1;
}

.carousel__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-top: clamp(24px, 3vw, 36px);
}

.carousel__count {
  color: var(--fg-muted);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.carousel__buttons {
  display: flex;
  gap: 10px;
}

.carousel__btn {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--rule);
  color: inherit;
  background: transparent;
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.carousel__btn:hover {
  background: var(--green);
  border-color: var(--green);
  color: var(--cream);
}

.section--forest .carousel__btn:hover,
.section--green .carousel__btn:hover,
.section--ink .carousel__btn:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--green-deep);
}

.carousel__btn svg {
  width: 20px;
  height: 20px;
}

/* One button, two icons: whichever matches the current state is shown. */
.carousel__ico-play,
.carousel[data-playing="false"] .carousel__ico-pause {
  display: none;
}

.carousel[data-playing="false"] .carousel__ico-play {
  display: block;
}

@media (max-width: 1023px) {
  .carousel {
    --visible: 2;
  }
}

@media (max-width: 680px) {
  .carousel {
    --visible: 1;
  }

  .carousel__bar {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .carousel__buttons {
    justify-content: center;
  }

  .carousel__count {
    text-align: center;
  }
}

/* ------------------------------------------------------- 12. Service rows */

.rows {
  border-top: 1px solid var(--rule);
}

.row {
  display: grid;
  grid-template-columns: 90px 1fr minmax(0, 1.1fr);
  align-items: start;
  gap: clamp(20px, 4vw, 56px);
  padding-block: clamp(34px, 4.5vw, 60px);
  border-bottom: 1px solid var(--rule);
}

.row__index {
  color: var(--fg-muted);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-variant-numeric: tabular-nums;
}

.section--ink .row__index {
  color: var(--gold);
}

.section--forest .row__index,
.section--green .row__index {
  color: var(--cream);
}

.row__title {
  font-size: clamp(1.625rem, 2.8vw, 2.25rem);
  line-height: 1.16;
}

.row__text {
  color: var(--fg-muted);
  font-size: var(--fs-body);
  line-height: 1.8;
  font-weight: 300;
}

.row__list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  margin-top: var(--space-4);
}

.row__list li {
  padding: 7px 14px;
  border: 1px solid var(--rule);
  color: var(--fg-muted);
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

/* ------------------------------------------------------- 13. Client strip */

.clients {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(28px, 5vw, 72px);
}

.clients li {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  letter-spacing: 0.06em;
  color: var(--fg-muted);
  opacity: 0.85;
}

/* ----------------------------------------------------- 13b. Logo marquee

   A continuous loop, not a carousel: nothing steps, nothing settles, the row
   simply never stops. Benchmarked against synthesia.io, which runs the same
   construction - two identical tracks side by side inside an overflow-hidden
   flex wrapper, both translating left at a constant linear rate. When the first
   track has travelled its own width the second is exactly where it began, so
   the restart is invisible. Linear timing is essential; any easing would make
   the loop point visible as a stutter.

   Every logo sits in an identical box with object-fit: contain, so a wide
   wordmark and a square badge occupy the same space and nothing is stretched.
   That is what keeps the row even - the assets vary, the boxes do not.

   The edges are masked to transparent rather than cut, so logos dissolve in and
   out instead of appearing at a hard border. */

.marquee {
  display: flex;
  overflow: hidden;
  /* Fade at both ends. -webkit- first for older Safari. */
  -webkit-mask-image: linear-gradient(
    90deg,
    transparent 0%,
    #000 7%,
    #000 93%,
    transparent 100%
  );
  mask-image: linear-gradient(
    90deg,
    transparent 0%,
    #000 7%,
    #000 93%,
    transparent 100%
  );
}

.marquee__track {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: var(--marquee-gap, clamp(44px, 6vw, 80px));
  padding-right: var(--marquee-gap, clamp(44px, 6vw, 80px));
  margin: 0;
  padding-left: 0;
  list-style: none;
  animation: veloraMarquee var(--marquee-dur, 40s) linear infinite;
  will-change: transform;
}

/* Moving content should yield to the reader. */
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track {
  animation-play-state: paused;
}

.marquee__item {
  flex: 0 0 auto;
  /* Deliberately NOT grid with place-items:center. Centring the item sets
     align-self:center, which stops the image stretching to the grid area - and
     a non-stretched grid area counts as an indefinite height, so the image's
     height:100% silently falls back to auto and the row goes ragged. The box
     is a plain block; object-fit does the centring. */
  display: block;
  width: var(--marquee-w, 150px);
  height: var(--marquee-h, 42px);
}

.marquee__item img {
  /* Fill the box and let object-fit letterbox inside it. Sizing with
     max-width/max-height percentages is not dependable in a fixed-height grid
     item - it let logos render at 60, 90, even 116px inside a 42px box - and
     uniform height is the entire point of this row. width/height 100% plus
     contain is unambiguous: the box decides, the artwork fits, nothing is
     stretched. */
  width: 100%;
  height: 100%;
  object-fit: contain;
  /* Insurance, not a substitute for proper assets: grayscale strips any colour
     that slips through, and multiply drops a white box into the cream behind
     it. Both are no-ops on a black-on-transparent PNG. */
  filter: grayscale(1);
  mix-blend-mode: multiply;
}

/* Until real logos exist, the names carry the row in the display face. */
.marquee__item span {
  font-family: var(--font-display);
  font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
  line-height: 1.1;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: var(--green-deep);
  text-align: center;
}

/* Travels left to right: the row starts shifted a full track-width to the left,
   so the second (duplicate) track is what fills the viewport at 0%, and the
   first slides in from the left to land exactly where the second began. The
   two are identical, so the restart is invisible. Going this way reads more
   easily than right-to-left. */
@keyframes veloraMarquee {
  from {
    transform: translateX(-100%);
  }

  to {
    transform: translateX(0);
  }
}

@media (max-width: 680px) {
  .marquee {
    --marquee-w: 116px;
    --marquee-h: 34px;
    --marquee-gap: 36px;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Stop entirely and let the set sit still, centred and wrapped. The second
     track is a duplicate, so it is removed rather than shown twice. */
  .marquee {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .marquee__track {
    animation: none;
    flex-wrap: wrap;
    justify-content: center;
    padding-right: 0;
  }

  .marquee__track[aria-hidden="true"] {
    display: none;
  }
}

/* --------------------------------------------------------------- 14. Quote */

.quote {
  max-width: 24ch;
  margin-inline: auto;
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.6vw, 3rem);
  line-height: 1.24;
  text-align: center;
}

.quote__cite {
  display: block;
  margin-top: var(--space-5);
  color: var(--fg-muted);
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-style: normal;
}

/* ----------------------------------------------------------------- 15. CTA */

.cta-band {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: var(--ink);
  color: var(--cream);
}

.cta-band__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
}

.cta-band__bg img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.42;
}

.cta-band::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    to right,
    rgba(15, 31, 29, 0.94) 0%,
    rgba(15, 31, 29, 0.72) 60%,
    rgba(15, 31, 29, 0.55) 100%
  );
}

/* ---------------------------------------------------------------- 16. Form */

.form {
  display: grid;
  gap: var(--space-4);
}

.field {
  display: grid;
  gap: 8px;
}

.field > label {
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--fg-muted);
}

.field .req {
  color: var(--gold);
}

.section--cream .field .req,
.section--soft .field .req {
  color: var(--green);
}

.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: 52px;
  padding: 14px 16px;
  background: transparent;
  border: 1px solid var(--rule);
  border-radius: 0;
  color: inherit;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  transition: border-color var(--dur-base) var(--ease-out);
}

.field textarea {
  min-height: 132px;
  resize: vertical;
}

.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 22px) 50%, calc(100% - 16px) 50%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 44px;
}

.field input:hover,
.field select:hover,
.field textarea:hover {
  border-color: var(--fg-muted);
}

.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible {
  border-color: var(--focus-ring, var(--green-deep));
}

.field input::placeholder,
.field textarea::placeholder {
  color: var(--fg-muted);
  opacity: 0.7;
}

.field__hint {
  font-size: 0.75rem;
  color: var(--fg-muted);
  line-height: 1.6;
}

.field__error {
  display: none;
  align-items: center;
  gap: 8px;
  font-size: 0.8125rem;
  font-weight: 500;
  color: #ffb4a8;
}

.section--cream .field__error,
.section--soft .field__error {
  color: #a33b26;
}

.field.is-invalid .field__error {
  display: flex;
}

.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: #ffb4a8;
}

.section--cream .field.is-invalid input,
.section--cream .field.is-invalid select,
.section--cream .field.is-invalid textarea,
.section--soft .field.is-invalid input,
.section--soft .field.is-invalid select,
.section--soft .field.is-invalid textarea {
  border-color: #a33b26;
}

.field__error svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.form__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4);
}

.form__summary {
  display: none;
  padding: 18px 20px;
  border: 1px solid #ffb4a8;
  background: rgba(255, 180, 168, 0.08);
}

.section--cream .form__summary,
.section--soft .form__summary {
  border-color: #a33b26;
  background: rgba(163, 59, 38, 0.06);
}

.form__summary.is-shown {
  display: block;
}

.form__summary h3 {
  font-family: var(--font-body);
  font-size: var(--fs-small);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.form__summary ul {
  margin-top: 10px;
  display: grid;
  gap: 6px;
  list-style: disc;
  padding-left: 18px;
  font-size: var(--fs-small);
}

.form__summary a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.form__status {
  font-size: var(--fs-small);
  line-height: 1.7;
}

.form__status:empty {
  display: none;
}

/* A sent enquiry and a refused one have to look different at a glance, not
   only read differently. Both colours are the ones the fields already use. */
.form__status {
  font-weight: 500;
  color: var(--green-deep);
}

.form__status.is-error {
  color: #a33b26;
}

.section--forest .form__status,
.section--ink .form__status {
  color: var(--cream);
}

.section--forest .form__status.is-error,
.section--ink .form__status.is-error {
  color: #ffb4a8;
}

.form__legal {
  font-size: 0.75rem;
  line-height: 1.7;
  color: var(--fg-muted);
}

/* ------------------------------------------------------- 17. Contact rail */

.rail {
  position: fixed;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--z-rail);
  display: flex;
  flex-direction: column;
  border: 1px solid rgba(244, 238, 223, 0.38);
  border-right: 0;
  background: var(--green);
}

.rail a {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  color: var(--cream);
  transition: background-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.rail a + a {
  border-top: 1px solid rgba(244, 238, 223, 0.26);
}

.rail a:hover {
  background: var(--cream);
  color: var(--green-deep);
}

.rail svg {
  width: 20px;
  height: 20px;
}

@media (max-width: 1023px) {
  .rail {
    display: none;
  }
}

/* --------------------------------------------------------- 17b. Sound

   Audio that plays on its own for more than three seconds has to be stoppable
   (WCAG 1.4.2, Level A), so this control is fixed, present on every page and at
   every width - unlike the contact rail, which hides below 1024px. Bottom left,
   clear of the rail on the right and of the thumb zone for the nav. */

.sound {
  position: fixed;
  left: clamp(16px, 3vw, 28px);
  bottom: calc(clamp(16px, 3vw, 28px) + env(safe-area-inset-bottom));
  z-index: var(--z-rail);
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 1px solid rgba(244, 238, 223, 0.38);
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  transition: background-color var(--dur-base) var(--ease-out),
    border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.sound:hover {
  background: var(--cream);
  border-color: var(--cream);
  color: var(--green-deep);
}

.sound svg {
  width: 20px;
  height: 20px;
}

/* Four bars that rise and fall while the music plays, and sit flat when it is
   paused - so the state is readable without relying on colour alone. */
.sound__bars {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  height: 18px;
}

.sound__bars i {
  display: block;
  width: 2px;
  height: 4px;
  background: currentColor;
  border-radius: 1px;
  transform-origin: center;
}

.sound[aria-pressed="true"] .sound__bars i {
  animation: veloraBars 1.1s ease-in-out infinite;
}

.sound[aria-pressed="true"] .sound__bars i:nth-child(2) {
  animation-duration: 1.45s;
}

.sound[aria-pressed="true"] .sound__bars i:nth-child(3) {
  animation-duration: 0.9s;
}

.sound[aria-pressed="true"] .sound__bars i:nth-child(4) {
  animation-duration: 1.3s;
}

/* One control, two faces: bars while playing, crossed speaker while muted. */
.sound__off {
  display: none;
}

.sound[aria-pressed="false"] .sound__bars {
  display: none;
}

.sound[aria-pressed="false"] .sound__off {
  display: block;
}

@keyframes veloraBars {
  0%,
  100% {
    height: 4px;
  }
  50% {
    height: 16px;
  }
}

/* ------------------------------------------------------------- 18. Footer */

.footer {
  position: relative;
  background: var(--ink);
  color: var(--cream);
  --fg-muted: #a9bdb3;
  --rule: rgba(244, 238, 223, 0.14);
}

.footer__top {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) repeat(3, minmax(0, 1fr));
  gap: clamp(32px, 4vw, 64px);
  padding-block: clamp(56px, 7vw, 88px);
}

.footer__brand svg {
  width: auto;
  height: 76px;
  color: var(--cream);
}

/* Sits directly under the wordmark as part of the lockup. Gold clears 7.07:1
   on the footer's --ink ground. */
.footer__tagline {
  margin-top: 18px;
  color: var(--gold);
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-style: italic;
  letter-spacing: 0.04em;
}

.footer__blurb {
  max-width: 34ch;
  margin-top: var(--space-4);
  color: var(--fg-muted);
  font-size: var(--fs-small);
  line-height: 1.8;
  font-weight: 300;
}

.footer__addr {
  margin-top: var(--space-4);
  color: var(--fg-muted);
  font-size: 0.8125rem;
  line-height: 1.8;
  font-style: normal;
}

/* The contact column carries the address, the numbers, the email and the
   social row, so it sits straight under its heading rather than taking the
   brand column's top margin. Each line is its own grid row, which gives the
   links a tappable box without the <br> spacing that a text block would. */
.footer__col--contact .footer__addr {
  display: grid;
  justify-items: start;
  margin-top: 0;
}

.footer__addr-place {
  margin-bottom: 10px;
}

.footer__col--contact .footer__addr a {
  display: inline-flex;
  align-items: center;
  min-height: 34px;
  transition: color var(--dur-fast) var(--ease-out);
}

.footer__col--contact .footer__addr a:hover {
  color: var(--cream);
}

.footer__col h3 {
  margin-bottom: var(--space-4);
  color: var(--gold);
  font-family: var(--font-body);
  font-size: var(--fs-eyebrow);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.footer__col li a,
.footer__col li span {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  color: var(--fg-muted);
  font-size: 0.875rem;
  transition: color var(--dur-fast) var(--ease-out);
}

.footer__col li a:hover {
  color: var(--cream);
}

.footer__social {
  display: flex;
  gap: 10px;
  margin-top: var(--space-4);
}

.footer__social a {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--rule);
  color: var(--fg-muted);
  transition: border-color var(--dur-base) var(--ease-out),
    color var(--dur-base) var(--ease-out);
}

.footer__social a:hover {
  border-color: var(--gold);
  color: var(--gold);
}

.footer__social svg {
  width: 18px;
  height: 18px;
}

.footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: var(--space-4);
  border-top: 1px solid var(--rule);
  color: var(--fg-muted);
  font-size: 0.75rem;
}

.footer__bar nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
}

.footer__bar a {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
}

.footer__bar a:hover {
  color: var(--cream);
}

/* ------------------------------------------------------ 19. Scroll reveal */

/* Visible by default - JS opts in, so no-JS and crawlers always see content. */
.js .reveal {
  opacity: 0;
  transform: translateY(18px);
}

.js .reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-slow) var(--ease-out),
    transform var(--dur-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

/* --------------------------------------------------------- 20. Responsive */

@media (max-width: 1100px) {
  .footer__top {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer__brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 1023px) {
  :root {
    --nav-h: 68px;
  }

  .nav__links,
  .nav__cta {
    display: none;
  }

  .nav__burger {
    display: grid;
  }

  .cards--3 {
    grid-template-columns: repeat(2, 1fr);
  }

  .row {
    grid-template-columns: 56px 1fr;
  }

  .row__text-cell {
    grid-column: 2;
  }
}

@media (max-width: 860px) {
  .split,
  .cards--2 {
    grid-template-columns: 1fr;
  }

  .split--reverse .split__media {
    order: 0;
  }

  .pillars {
    grid-template-columns: 1fr;
  }

  .pillars__item + .pillars__item {
    border-top: 1px solid var(--rule);
  }
}

@media (max-width: 680px) {
  .cards--3,
  .cards {
    grid-template-columns: 1fr;
  }

  .form__grid {
    grid-template-columns: 1fr;
  }

  .hero__lines {
    min-height: calc(var(--fs-display-xl) * 3.4);
  }

  .hero__line {
    max-width: 13ch;
  }

  /* Give the copy block room and let the buttons share a consistent width,
     rather than two pills of different lengths stacked on top of each other. */
  .hero__copy {
    bottom: clamp(64px, 11vh, 104px);
  }

  .hero__actions {
    margin-top: var(--space-5);
    gap: var(--space-2);
  }

  .hero__actions .btn {
    width: 100%;
  }

  /* On touch the scroll affordance is redundant, and it crowds the CTAs. */
  .hero__cue {
    display: none;
  }

  .footer__top {
    grid-template-columns: 1fr;
  }

  .footer__bar {
    justify-content: flex-start;
  }

  .split--vision {
    grid-template-columns: 1fr;
  }
}

/* ----------------------------------------------------- 21. Reduced motion */

@media (prefers-reduced-motion: reduce) {
  /* No crossfade, and main.js never starts playback - the poster frame shows. */
  .loop__layer {
    transition: none;
  }

  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .js .reveal {
    opacity: 1;
    transform: none;
  }

  .frame img {
    transition: none;
  }

  /* The drift keyframes rest at the natural position, so stopping them lands
     the image correctly - but pin it explicitly rather than relying on that. */
  .drift,
  .drift__tilt {
    animation: none !important;
    transform: none;
    will-change: auto;
  }

  .hero__cue i {
    background: var(--gold);
  }
}

/* --------------------------------------------------------------- 22. Print */

@media print {
  .nav,
  .drawer,
  .rail,
  .hero__cue,
  #velora-splash {
    display: none !important;
  }

  body {
    background: #fff;
    color: #000;
  }
}
