/* =========================================================================
   Good Graph — CSR & Impact Communications
   Single stylesheet. Mobile-first. No build step, no dependencies.

   PALETTE (brand system — do not add hues)
     Navy       #16324F   primary text / headings
     Green      #3E8E2F   accents, rules, graphics, LARGE text only
     Green deep #2E7D32   button fills + small green text (AA-safe; this hex
                          is the end stop of the logo's own green gradient)
     Teal       #0E7490   ONLY inside navy -> green gradients
     Off-white  #FAFAF7   page background
   ========================================================================= */

/* -------------------------------------------------------------------------
   1. Fonts — self-hosted, no third-party requests
   ------------------------------------------------------------------------- */

/* Inter is a variable font: one file covers weights 100-900. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(fonts/inter-var-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Poppins ships as static instances — one file per weight.
   latin-ext carries the rupee sign (U+20B9), so the stat band renders it. */
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/poppins-500-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(fonts/poppins-500-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;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/poppins-600-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url(fonts/poppins-600-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;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/poppins-700-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+2074, U+20AC, U+2122, U+2191,
    U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Poppins';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url(fonts/poppins-700-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;
}

/* -------------------------------------------------------------------------
   2. Tokens
   ------------------------------------------------------------------------- */

:root {
  /* Brand */
  --navy: #16324f;
  --green: #3e8e2f;
  --green-deep: #2e7d32;
  --teal: #0e7490;
  --bg: #fafaf7;
  --surface: #ffffff;

  /* Navy at opacity — stays inside the palette, no new hues */
  --ink: var(--navy);
  --ink-muted: rgba(22, 50, 79, 0.74); /* 5.68:1 on bg, 5.82:1 on cards */
  /* 0.68 is the floor that clears AA for normal text: 4.75:1 on --bg and
     4.84:1 on white cards. At 0.56 this token measured 3.39:1 and failed
     on five elements (trust line, footer descriptor, channel labels,
     form fallback, about note). */
  --ink-soft: rgba(22, 50, 79, 0.68);
  --rule: rgba(22, 50, 79, 0.14);
  --rule-strong: rgba(22, 50, 79, 0.28);
  --grid-line: rgba(22, 50, 79, 0.05);
  --shadow-sm: 0 1px 2px rgba(22, 50, 79, 0.04), 0 2px 8px rgba(22, 50, 79, 0.04);
  --shadow-md: 0 2px 4px rgba(22, 50, 79, 0.04), 0 12px 32px rgba(22, 50, 79, 0.08);

  --gradient-brand: linear-gradient(90deg, var(--navy) 0%, var(--teal) 52%, var(--green) 100%);

  /* Type */
  --font-head: 'Poppins', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --font-body: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* Fluid scale — min at 360px, max at 1280px */
  --step--1: clamp(0.813rem, 0.79rem + 0.10vw, 0.875rem);
  --step-0: clamp(1rem, 0.96rem + 0.17vw, 1.094rem);
  --step-1: clamp(1.125rem, 1.06rem + 0.30vw, 1.313rem);
  --step-2: clamp(1.375rem, 1.24rem + 0.60vw, 1.75rem);
  --step-3: clamp(1.75rem, 1.51rem + 1.04vw, 2.375rem);
  --step-4: clamp(2.125rem, 1.69rem + 1.91vw, 3.25rem);
  /* Capped at 52px so the hero headline sits on two lines in the two-column
     layout — "Your CSR does good." / "Make it count." — rather than four. */
  --step-5: clamp(2.25rem, 1.55rem + 3.1vw, 3.25rem);

  /* Space */
  --gutter: clamp(1.25rem, 0.9rem + 1.6vw, 2.5rem);
  --section-y: clamp(4rem, 2.8rem + 5.2vw, 7.5rem);
  --wrap: 1180px;

  --radius: 4px;
  --radius-lg: 8px;

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

  --header-h: 68px;
}

/* Taller header so the logo can be read rather than just recognised. */
@media (min-width: 900px) {
  :root {
    --header-h: 80px;
  }
}

/* -------------------------------------------------------------------------
   3. Reset / base
   ------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* Anchor targets clear the sticky header */
  scroll-padding-top: calc(var(--header-h) + 16px);
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.65;
  font-feature-settings: 'kern' 1, 'liga' 1, 'calt' 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--font-head);
  font-weight: 700;
  line-height: 1.14;
  letter-spacing: -0.018em;
  margin: 0;
  text-wrap: balance;
}

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

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

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

/* A class rule such as .channel{display:flex} outranks the UA stylesheet's
   [hidden]{display:none}, so hidden elements would still render. */
[hidden] {
  display: none !important;
}

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

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

/* Visible focus everywhere — never remove without replacing */
:focus-visible {
  outline: 2px solid var(--green-deep);
  outline-offset: 3px;
  border-radius: 2px;
}
:focus:not(:focus-visible) {
  outline: none;
}

::selection {
  background: rgba(62, 142, 47, 0.22);
  color: var(--navy);
}

/* -------------------------------------------------------------------------
   4. Layout primitives
   ------------------------------------------------------------------------- */

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

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

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

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--navy);
  color: #fff;
  padding: 0.75rem 1.25rem;
  border-radius: 0 0 var(--radius) 0;
  font-size: var(--step--1);
  font-weight: 600;
}
.skip-link:focus {
  left: 0;
}

/* Text for screen readers only — e.g. "(opens in a new tab)" cues. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Small all-caps label — wide tracking, per brand system */
.eyebrow {
  font-family: var(--font-head);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--green-deep); /* AA-safe green for small text */
  margin: 0 0 1rem;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.eyebrow::before {
  content: '';
  width: 22px;
  height: 2px;
  background: var(--green);
  flex: none;
}
.section-head {
  max-width: 46ch;
  margin-bottom: clamp(2.5rem, 1.9rem + 2.6vw, 4rem);
}

.section-head h2 {
  font-size: var(--step-4);
}

.section-head .lede {
  margin-top: 1.1rem;
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ink-muted);
}

/* The one green word in a heading. Large text only — 3.9:1 is AA at this size. */
.accent {
  color: var(--green);
}

/* Faint graph-paper texture */
.grid-bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--grid-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
  background-size: 34px 34px;
  background-position: center;
  -webkit-mask-image: radial-gradient(ellipse 90% 70% at 50% 40%, #000 30%, transparent 100%);
  mask-image: radial-gradient(ellipse 90% 70% at 50% 40%, #000 30%, transparent 100%);
  z-index: 0;
}

.section > .wrap {
  position: relative;
  z-index: 1;
}

/* -------------------------------------------------------------------------
   5. Buttons
   ------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  font-family: var(--font-head);
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: 0.005em;
  padding: 0.9rem 1.6rem;
  border-radius: var(--radius);
  border: 1px solid transparent;
  transition: background-color 0.22s var(--ease), border-color 0.22s var(--ease),
    color 0.22s var(--ease), transform 0.22s var(--ease), box-shadow 0.22s var(--ease);
  will-change: transform;
  text-align: center;
}

.btn:hover {
  transform: translateY(-2px);
}
.btn:active {
  transform: translateY(0);
}

/* Primary — white on green-deep = 5.13:1 (AA). #3E8E2F would be 4.11:1 (fail). */
.btn--primary {
  background: var(--green-deep);
  color: #fff;
  box-shadow: var(--shadow-sm);
}
.btn--primary:hover {
  background: #276a2a;
  box-shadow: var(--shadow-md);
}

.btn--ghost {
  background: transparent;
  color: var(--navy);
  border-color: var(--rule-strong);
}
.btn--ghost:hover {
  border-color: var(--navy);
  background: rgba(22, 50, 79, 0.03);
}

.btn__arrow {
  transition: transform 0.24s var(--ease);
}
.btn:hover .btn__arrow {
  transform: translateX(3px);
}
.btn--ghost:hover .btn__arrow {
  transform: translateY(3px);
}

/* -------------------------------------------------------------------------
   6. Header
   ------------------------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(250, 250, 247, 0.86);
  backdrop-filter: saturate(180%) blur(12px);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}

.header.is-stuck {
  border-bottom-color: var(--rule);
  background: rgba(250, 250, 247, 0.94);
}

.header__inner {
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.header__logo {
  display: block;
  flex: none;
}

/* Compact lockup, aspect 1055:283. Inline SVG needs an explicit height —
   width follows from the viewBox. */
.logo-lockup {
  height: 44px;
  width: auto;
  display: block;
}

@media (min-width: 900px) {
  .header__logo .logo-lockup {
    height: 52px;
  }
}

.nav {
  display: none;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: clamp(1.25rem, 0.6rem + 1.3vw, 2.25rem);
}

.nav__link {
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--ink-muted);
  position: relative;
  padding: 0.4rem 0;
  transition: color 0.2s var(--ease);
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: 0;
  height: 2px;
  width: 100%;
  background: var(--green);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s var(--ease);
}
.nav__link:hover,
.nav__link[aria-current='true'] {
  color: var(--navy);
}
.nav__link:hover::after,
.nav__link[aria-current='true']::after {
  transform: scaleX(1);
}

.header__cta {
  display: none;
  padding: 0.62rem 1.15rem;
  font-size: var(--step--1);
}

.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 44px;
  height: 44px;
  align-items: center;
  margin-right: -10px;
  flex: none;
}
.nav-toggle__bar {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--navy);
  transition: transform 0.3s var(--ease), opacity 0.2s var(--ease);
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(2) {
  opacity: 0;
}
.nav-toggle[aria-expanded='true'] .nav-toggle__bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

/* Mobile panel.
   visibility (not just max-height) is what keeps the collapsed links out of
   the tab order — a clipped element is still focusable. It is delayed to the
   end of the collapse so the panel stays visible while it animates shut. */
.mobile-nav {
  display: block;
  overflow: hidden;
  max-height: 0;
  visibility: hidden;
  border-top: 1px solid transparent;
  transition: max-height 0.36s var(--ease), border-color 0.36s var(--ease),
    visibility 0s linear 0.36s;
  background: var(--bg);
}
.mobile-nav[data-open='true'] {
  /* Viewport-based cap, not a fixed px value: at 200% text-only zoom the
     links + CTA exceed 460px and the CTA would be clipped but focusable.
     overflow-y lets the panel scroll if it still cannot fit. */
  max-height: calc(100vh - var(--header-h));
  max-height: calc(100dvh - var(--header-h));
  overflow-y: auto;
  visibility: visible;
  border-top-color: var(--rule);
  transition: max-height 0.36s var(--ease), border-color 0.36s var(--ease),
    visibility 0s linear 0s;
}

/* Without JS the toggle can never fire, so show the menu permanently rather
   than stranding mobile visitors with no navigation. */
.no-js .nav-toggle {
  display: none;
}
.no-js .mobile-nav {
  max-height: none;
  visibility: visible;
  border-top-color: var(--rule);
}
.mobile-nav__list {
  padding: 0.75rem 0 1.5rem;
}
.mobile-nav__list a {
  display: block;
  padding: 0.85rem 0;
  font-family: var(--font-head);
  font-weight: 500;
  font-size: var(--step-1);
  border-bottom: 1px solid var(--rule);
}
.mobile-nav__cta {
  margin-top: 1.25rem;
  width: 100%;
}

@media (min-width: 900px) {
  .nav {
    display: block;
  }
  .header__cta {
    display: inline-flex;
  }
  .nav-toggle,
  .mobile-nav {
    display: none;
  }
}

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

.hero {
  position: relative;
  padding-block: clamp(3rem, 1.6rem + 6vw, 6rem) clamp(3.5rem, 2rem + 6vw, 6.5rem);
  overflow: hidden;
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  gap: clamp(2.5rem, 1.5rem + 4vw, 4rem);
  align-items: center;
}

/* No max-width here — the grid column already sets the measure. A ch-based
   cap resolves against the *body* font size, not the headline's, so it
   squeezes the h1 far harder than intended. */
.hero__copy {
  min-width: 0;
}

.hero h1 {
  font-size: var(--step-5);
  line-height: 1.06;
  letter-spacing: -0.028em;
}

.hero h1 .line {
  display: block;
}

.hero__sub {
  margin-top: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--ink-muted);
  max-width: 52ch;
}

.hero__actions {
  margin-top: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  display: flex;
  flex-wrap: wrap;
  gap: 0.85rem;
}

/* Stacked buttons of unequal width read as untidy, and full-width gives a
   bigger tap target on the one screen where that matters most. */
@media (max-width: 479px) {
  .hero__actions .btn {
    width: 100%;
  }
}

@media (min-width: 880px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1.12fr) minmax(0, 0.88fr);
    gap: clamp(2rem, 1rem + 3vw, 3.5rem);
  }
}

/* -------------------------------------------------------------------------
   7b. Hero signature visual — the rising graph that ends in a leaf

   ARCHITECTURE: the base rules below describe the FINAL, FULLY-RENDERED
   state. Every start-state and every animation lives inside
   @media (prefers-reduced-motion: no-preference). So a reduced-motion user
   — or any UA without the query — gets the finished graph on first paint,
   with no motion and no !important overrides to keep in sync.

   Geometry, gradient stops, arrowhead ratios and the leaf path are lifted
   from goodgraph-logo-primary.svg so the hero reads as the same hand.
   Ids are hg- prefixed to avoid collisions with the logo SVGs.
   ------------------------------------------------------------------------- */

.hero__visual {
  position: relative;
  width: 100%;
  max-width: 760px;
  margin-inline: auto;
  line-height: 0;
}

.hg-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* --- Final state --- */

.hg-line {
  stroke-dasharray: 100; /* pathLength="100" => dash units are % of length */
  stroke-dashoffset: 0;
}

/* The idle bead is invisible at rest; only its own animation reveals it. */
.hg-sheen {
  stroke-dasharray: 2.5 97.5;
  stroke-dashoffset: 105;
  opacity: 0;
}

/* Pivots declared here so they travel with the element, not the animation.
   transform-box: fill-box is required — without it transform-origin resolves
   against the viewBox and the arrowhead flies in from the canvas centre. */
.hg-dot {
  transform-box: fill-box;
  transform-origin: 50% 50%;
}
.hg-arrow {
  transform-box: fill-box;
  transform-origin: 100% 50%; /* the tip */
}
.hg-leaf {
  transform-box: fill-box;
  transform-origin: 2% 100%; /* the stem base */
}

/* --- Motion: opt-in only --- */

@media (prefers-reduced-motion: no-preference) {
  /* Start states */
  .hg-grid,
  .hg-axis,
  .hg-band,
  .hg-axis-labels {
    opacity: 0;
  }
  .hg-line {
    stroke-dashoffset: 100;
  }
  .hg-dot {
    opacity: 0;
    transform: scale(0.3);
  }
  .hg-arrow {
    opacity: 0;
    transform: scale(0.2);
  }
  .hg-leaf {
    opacity: 0;
    transform: rotate(-18deg) scale(0.72);
  }

  /* Timeline — 2.38s total */
  .hg-grid   { animation: hg-fade 0.55s cubic-bezier(0.4, 0, 0.2, 1) 0.05s both; }
  .hg-axis   { animation: hg-fade 0.5s cubic-bezier(0.4, 0, 0.2, 1) 0.14s both; }
  .hg-band-1 { animation: hg-rise 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) 0.2s both; }
  .hg-band-2 { animation: hg-rise 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) 0.3s both; }

  /* The line plots itself */
  .hg-line { animation: hg-draw 1.2s cubic-bezier(0.32, 0.06, 0.36, 1) 0.34s both; }

  /* Dots land as the drawing head passes them. Delays are each vertex's
     arc-length fraction run back through the draw easing curve. */
  .hg-dots circle { animation: hg-pop 0.34s cubic-bezier(0.3, 0.75, 0.35, 1) both; }
  .hg-dots circle:nth-child(1) { animation-delay: 0.36s; }
  .hg-dots circle:nth-child(2) { animation-delay: 0.53s; }
  .hg-dots circle:nth-child(3) { animation-delay: 0.62s; }
  .hg-dots circle:nth-child(4) { animation-delay: 0.7s; }
  .hg-dots circle:nth-child(5) { animation-delay: 0.77s; }
  .hg-dots circle:nth-child(6) { animation-delay: 0.85s; }
  .hg-dots circle:nth-child(7) { animation-delay: 0.96s; }
  .hg-dots circle:nth-child(8) { animation-delay: 1.1s; }

  /* The area under the line washes in behind it */
  .hg-band-3 { animation: hg-fade 0.75s cubic-bezier(0.4, 0, 0.2, 1) 0.9s both; }

  .hg-arrow { animation: hg-arrow-in 0.26s cubic-bezier(0.2, 0.7, 0.3, 1) 1.56s both; }
  .hg-leaf  { animation: hg-leaf-in 0.62s cubic-bezier(0.2, 0.7, 0.3, 1) 1.74s both; }
  .hg-axis-labels { animation: hg-fade 0.5s cubic-bezier(0.4, 0, 0.2, 1) 1.95s both; }

  /* Idle: a reading travels the series every 9s. Reads as a measurement
     instrument rather than decoration — the right register for this audience. */
  .hg-sheen { animation: hg-sheen 9s linear 3s infinite; }
}

@keyframes hg-fade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes hg-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes hg-draw {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}

@keyframes hg-pop {
  0%   { opacity: 0; transform: scale(0.3); }
  65%  { opacity: 1; transform: scale(1.1); }
  100% { opacity: 1; transform: scale(1); }
}

@keyframes hg-arrow-in {
  0%   { opacity: 0; transform: scale(0.2); }
  60%  { opacity: 1; transform: scale(1.06); }
  100% { opacity: 1; transform: scale(1); }
}

/* The overshoot lives in the keyframes, not in a springy easing curve —
   a 3.5deg settle, not a bounce. */
@keyframes hg-leaf-in {
  0%   { opacity: 0; transform: rotate(-18deg) scale(0.72); }
  55%  { opacity: 1; transform: rotate(3.5deg) scale(1.03); }
  100% { opacity: 1; transform: rotate(0deg) scale(1); }
}

@keyframes hg-sheen {
  0%   { stroke-dashoffset: 105; opacity: 0; }
  4%   { opacity: 0.5; }
  36%  { opacity: 0.5; }
  42%  { stroke-dashoffset: -6; opacity: 0; }
  100% { stroke-dashoffset: -6; opacity: 0; }
}

/* --- Hero visual, small screens ---
   Do not crop. The composition is 8:5; at 360px that is a 225px band, which
   is a legitimate hero band. Cropping horizontally is the trap: anchoring
   xMax to keep the leaf amputates the navy origin point and the "rises from
   a low base" reading dies. So: full-bleed instead, hide the axis labels
   (17 user-units is ~6px at 360w), and thicken the strokes so the artwork
   keeps its weight at 0.375x scale. */
@media (max-width: 639px) {
  .hero__visual {
    max-width: none;
    width: auto;
    margin-inline: calc(-1 * var(--gutter));
  }
  .hg-axis-labels { display: none; }
  .hg-line      { stroke-width: 17; }
  .hg-band-line { stroke-width: 3.8; }
  .hg-dot       { stroke-width: 2.5; } /* thinner ring, bigger colour core */
  .hg-sheen     { stroke-width: 12; }
}

@media (min-width: 640px) and (max-width: 879px) {
  .hero__visual {
    max-width: 720px;
    margin-top: clamp(0.5rem, 0.2rem + 1.2vw, 1.5rem);
  }
}

/* Desktop: bleed into the right gutter so the leaf breathes into whitespace
   rather than stopping at a container edge. Nothing important sits in the
   outer 90 units left or 125 right, so the bleed is safe. */
@media (min-width: 880px) {
  .hero__visual {
    max-width: none;
    margin-right: clamp(-64px, -3.5vw, 0px);
  }
}

/* -------------------------------------------------------------------------
   8. The gap — stat band
   ------------------------------------------------------------------------- */

.gap-band {
  background: var(--navy);
  color: #fff;
  position: relative;
  overflow: hidden;
}

.gap-band .grid-bg {
  --grid-line: rgba(255, 255, 255, 0.055);
  -webkit-mask-image: radial-gradient(ellipse 80% 80% at 20% 50%, #000 20%, transparent 100%);
  mask-image: radial-gradient(ellipse 80% 80% at 20% 50%, #000 20%, transparent 100%);
}

.gap-band .eyebrow {
  color: #8fd07a; /* green tinted for contrast on navy — 8.4:1 */
}
.gap-band .eyebrow::before {
  background: #8fd07a;
}

.gap-band__inner {
  display: grid;
  gap: clamp(2.25rem, 1.4rem + 3.4vw, 4rem);
  align-items: center;
}

.stat {
  border-left: 3px solid var(--green);
  padding-left: clamp(1.1rem, 0.8rem + 1.2vw, 1.75rem);
}

.stat__value {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(3rem, 2rem + 4.4vw, 5.25rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
  display: block;
  font-variant-numeric: tabular-nums;
}

.stat__unit {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--font-head);
  font-size: var(--step-1);
  font-weight: 600;
  color: #8fd07a;
  letter-spacing: 0.01em;
}

.stat__caption {
  margin-top: 1.1rem;
  font-size: var(--step--1);
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.76);
  max-width: 34ch;
}

.gap-band h2 {
  font-size: var(--step-3);
  color: #fff;
}

.gap-band__body {
  margin-top: 1.2rem;
  color: rgba(255, 255, 255, 0.82);
  max-width: 52ch;
}

.gap-band__quote {
  margin-top: clamp(1.75rem, 1.4rem + 1.4vw, 2.5rem);
  padding-top: clamp(1.5rem, 1.2rem + 1.2vw, 2rem);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
  font-family: var(--font-head);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.34;
  letter-spacing: -0.015em;
  color: #fff;
  max-width: 30ch;
}

@media (min-width: 860px) {
  .gap-band__inner {
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: clamp(3rem, 1.5rem + 5vw, 6rem);
  }
}

/* -------------------------------------------------------------------------
   9. Services
   ------------------------------------------------------------------------- */

.cards {
  display: grid;
  gap: 1.25rem;
}

@media (min-width: 720px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1020px) {
  .cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1.5rem;
  }
}

.card {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: clamp(1.6rem, 1.3rem + 1.2vw, 2.25rem);
  display: flex;
  flex-direction: column;
  position: relative;
  overflow: hidden;
  transition: transform 0.32s var(--ease), box-shadow 0.32s var(--ease),
    border-color 0.32s var(--ease);
}

/* Rising-graph accent that draws across the top edge on hover */
.card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 3px;
  background: var(--gradient-brand);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.42s var(--ease-out);
}

.card:hover,
.card:focus-within {
  transform: translateY(-4px);
  box-shadow: var(--shadow-md);
  border-color: rgba(22, 50, 79, 0.2);
}
.card:hover::before,
.card:focus-within::before {
  transform: scaleX(1);
}

.card__index {
  font-family: var(--font-head);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  color: var(--green-deep);
  margin-bottom: 1.4rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.card__index::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--rule);
}

.card__icon {
  width: 40px;
  height: 40px;
  margin-bottom: 1.15rem;
  color: var(--navy);
}

/* Deliberately below --step-2: at 28px the longest title ("CSR Program
   Strategy & Storytelling") broke to three ragged lines in a 354px card. */
.card h3 {
  font-size: clamp(1.25rem, 1.13rem + 0.55vw, 1.5rem);
  line-height: 1.26;
}

.card__lead {
  margin-top: 0.85rem;
  color: var(--ink-muted);
  font-size: var(--step-0);
  line-height: 1.6;
}

.card__bullets {
  margin-top: 1.5rem;
  padding-top: 1.35rem;
  border-top: 1px solid var(--rule);
  display: grid;
  gap: 0.7rem;
}

.card__bullets li {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  font-size: var(--step--1);
  line-height: 1.5;
  color: var(--ink-muted);
}

.card__bullets li::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green);
  flex: none;
  margin-top: 0.5em;
}

/* -------------------------------------------------------------------------
   10. Method — Create / Measure / Grow
   ------------------------------------------------------------------------- */

.method {
  display: grid;
  gap: clamp(2.25rem, 1.6rem + 2.6vw, 3rem);
  position: relative;
}

.step {
  position: relative;
  padding-top: 2rem;
  border-top: 1px solid var(--rule);
}

.step__num {
  position: absolute;
  top: -0.75rem;
  left: 0;
  background: var(--bg);
  padding-right: 0.9rem;
  font-family: var(--font-head);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--green-deep);
}

.step__icon {
  width: 52px;
  height: 52px;
  color: var(--navy);
  margin-bottom: 1.4rem;
}

.step h3 {
  font-size: var(--step-3);
  letter-spacing: -0.02em;
}

.step__lead {
  margin-top: 0.5rem;
  font-family: var(--font-head);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--green-deep);
}

.step__detail {
  margin-top: 1rem;
  color: var(--ink-muted);
  font-size: var(--step-0);
  line-height: 1.62;
  max-width: 38ch;
}

@media (min-width: 800px) {
  .method {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.75rem, 0.8rem + 2.6vw, 3.25rem);
  }
}

/* -------------------------------------------------------------------------
   11. Audiences
   ------------------------------------------------------------------------- */

.audiences {
  display: grid;
  gap: clamp(2.5rem, 1.6rem + 3.4vw, 4.5rem);
}

.audience {
  padding-top: 1.75rem;
  border-top: 2px solid var(--navy);
}

.audience:nth-child(2) {
  border-top-color: var(--green);
}

.audience h3 {
  font-size: var(--step-2);
  line-height: 1.24;
}

.audience__intro {
  margin-top: 0.85rem;
  color: var(--ink-muted);
  font-size: var(--step-0);
  max-width: 40ch;
}

.audience__lines {
  margin-top: 1.9rem;
  display: grid;
  gap: 1.5rem;
}

.audience__line h4 {
  font-family: var(--font-head);
  font-size: var(--step-0);
  font-weight: 600;
  letter-spacing: -0.005em;
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.audience__line h4::before {
  content: '';
  width: 14px;
  height: 2px;
  background: var(--green);
  flex: none;
}

.audience__line p {
  margin-top: 0.5rem;
  padding-left: calc(14px + 0.6rem);
  color: var(--ink-muted);
  font-size: var(--step--1);
  line-height: 1.6;
  max-width: 44ch;
}

@media (min-width: 800px) {
  .audiences {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(2.5rem, 1rem + 5vw, 5rem);
  }
}

/* -------------------------------------------------------------------------
   12. About
   ------------------------------------------------------------------------- */

.about__inner {
  display: grid;
  gap: clamp(2.5rem, 1.6rem + 3.4vw, 4.5rem);
  align-items: start;
}

.about h2 {
  font-size: var(--step-4);
}

.about__body {
  margin-top: 1.4rem;
  color: var(--ink-muted);
  font-size: var(--step-1);
  line-height: 1.62;
  max-width: 54ch;
}

.belief {
  margin: 0;
  padding: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  background: var(--surface);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--green);
  border-radius: var(--radius-lg);
  position: relative;
}

.belief p {
  font-family: var(--font-head);
  font-size: var(--step-2);
  font-weight: 600;
  line-height: 1.36;
  letter-spacing: -0.018em;
  color: var(--navy);
}

.belief figcaption {
  margin-top: 1.15rem;
  padding-top: 1.15rem;
  border-top: 1px solid var(--rule);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

.about__note {
  margin-top: 1.5rem;
  font-size: var(--step--1);
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.about__note .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--green);
  flex: none;
}

@media (min-width: 860px) {
  .about__inner {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  }
}

/* -------------------------------------------------------------------------
   13. Contact
   ------------------------------------------------------------------------- */

.contact {
  background: var(--surface);
  border-top: 1px solid var(--rule);
}

.contact__inner {
  display: grid;
  gap: clamp(2.75rem, 1.8rem + 3.8vw, 4.5rem);
  align-items: start;
}

.contact h2 {
  font-size: var(--step-4);
}

.contact__lead {
  margin-top: 1.2rem;
  color: var(--ink-muted);
  font-size: var(--step-1);
  line-height: 1.58;
  max-width: 42ch;
}

.contact__channels {
  margin-top: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
  display: grid;
  gap: 0.85rem;
}

.channel {
  display: flex;
  align-items: center;
  gap: 0.95rem;
  padding: 1rem 1.15rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  transition: border-color 0.24s var(--ease), background-color 0.24s var(--ease),
    transform 0.24s var(--ease);
  background: var(--bg);
}
.channel:hover {
  border-color: var(--rule-strong);
  transform: translateX(3px);
}

.channel__icon {
  width: 22px;
  height: 22px;
  color: var(--green-deep);
  flex: none;
}

.channel__label {
  display: block;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-family: var(--font-head);
}

.channel__value {
  display: block;
  font-weight: 500;
  font-size: var(--step-0);
  margin-top: 0.15rem;
  word-break: break-word;
}

.channel__arrow {
  margin-left: auto;
  color: var(--ink-soft);
  flex: none;
  transition: transform 0.24s var(--ease), color 0.24s var(--ease);
}
.channel:hover .channel__arrow {
  transform: translateX(3px);
  color: var(--navy);
}

/* --- Form --- */

.form {
  background: var(--bg);
  border: 1px solid var(--rule);
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 1.2rem + 1.4vw, 2.25rem);
}

.form__intro {
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin-bottom: 1.75rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--rule);
}

.field {
  margin-bottom: 1.25rem;
}

.field label {
  display: block;
  font-family: var(--font-head);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-muted);
  margin-bottom: 0.5rem;
}

.field .req {
  color: var(--green-deep);
  margin-left: 0.15rem;
}

.field input,
.field textarea {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--step-0);
  color: var(--navy);
  background: var(--surface);
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  padding: 0.8rem 0.95rem;
  transition: border-color 0.2s var(--ease), box-shadow 0.2s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}

.field textarea {
  resize: vertical;
  min-height: 128px;
  line-height: 1.6;
}

/* Placeholder text is still text: at 0.38 it measured 2.16:1. Every field has
   a persistent visible label above it, so the darker hint cannot be mistaken
   for a filled value. */
.field input::placeholder,
.field textarea::placeholder {
  color: var(--ink-soft);
}

.field input:hover,
.field textarea:hover {
  border-color: rgba(22, 50, 79, 0.4);
}

.field input:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--green-deep);
  box-shadow: 0 0 0 3px rgba(46, 125, 50, 0.16);
}

/* Only show invalid styling once the field has been touched/submitted */
.form.is-validated .field input:invalid,
.form.is-validated .field textarea:invalid {
  border-color: #9d2626;
}

.field__error {
  display: none;
  margin-top: 0.4rem;
  font-size: var(--step--1);
  color: #9d2626;
}
.form.is-validated .field input:invalid ~ .field__error,
.form.is-validated .field textarea:invalid ~ .field__error {
  display: block;
}

/* Honeypot — hidden from humans, visible to bots. Not display:none, which some
   bots detect; kept out of the a11y tree with aria-hidden + tabindex="-1". */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__submit {
  width: 100%;
  margin-top: 0.5rem;
}

.form__submit[aria-busy='true'] {
  opacity: 0.75;
  pointer-events: none;
}

/* Always rendered, never display:none — an aria-live region that enters the
   accessibility tree at the same moment as its content is frequently not
   announced (NVDA/Chrome). :empty collapses it visually while it waits. */
.form__status {
  margin-top: 1.1rem;
  font-size: var(--step--1);
  line-height: 1.55;
  padding: 0.9rem 1rem;
  border-radius: var(--radius);
}
.form__status:empty {
  margin: 0;
  padding: 0;
  border: 0;
}
.form__status[data-state='success'] {
  background: rgba(46, 125, 50, 0.09);
  border: 1px solid rgba(46, 125, 50, 0.32);
  color: #245e27;
}
.form__status[data-state='error'] {
  background: rgba(157, 38, 38, 0.07);
  border: 1px solid rgba(157, 38, 38, 0.3);
  color: #8a2020;
}

.form__fallback {
  margin-top: 1.1rem;
  font-size: var(--step--1);
  color: var(--ink-soft);
}
.form__fallback a {
  font-weight: 600;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-color: var(--rule-strong);
}
.form__fallback a:hover {
  text-decoration-color: var(--green);
}

@media (min-width: 880px) {
  .contact__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    gap: clamp(3rem, 1.5rem + 5vw, 5.5rem);
  }
}

/* -------------------------------------------------------------------------
   14. Footer
   ------------------------------------------------------------------------- */

.footer {
  background: var(--bg);
  border-top: 1px solid var(--rule);
  padding-block: clamp(2.75rem, 2.2rem + 2.2vw, 4rem) 2rem;
}

.footer__top {
  display: grid;
  gap: 2rem;
  padding-bottom: clamp(2rem, 1.6rem + 1.6vw, 2.75rem);
  border-bottom: 1px solid var(--rule);
}

.footer__logo .logo-lockup {
  height: clamp(52px, 44px + 2.4vw, 66px);
}

.footer__descriptor {
  margin-top: 1.1rem;
  font-size: var(--step--1);
  color: var(--ink-soft);
  max-width: 40ch;
}

.social {
  margin-top: 1.5rem;
  display: flex;
  gap: 0.6rem;
}

.social__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  color: var(--ink-muted);
  transition: color 0.22s var(--ease), border-color 0.22s var(--ease),
    background-color 0.22s var(--ease), transform 0.22s var(--ease);
}

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

.social__link:hover {
  color: var(--green-deep);
  border-color: var(--green-deep);
  background: rgba(62, 142, 47, 0.06);
  transform: translateY(-2px);
}

.footer__nav {
  display: grid;
  gap: 0.75rem;
  align-content: start;
}

.footer__nav a {
  font-size: var(--step--1);
  color: var(--ink-muted);
  transition: color 0.2s var(--ease);
  justify-self: start;
}
.footer__nav a:hover {
  color: var(--navy);
}

.footer__bottom {
  margin-top: 1.75rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  align-items: center;
  justify-content: space-between;
  font-size: var(--step--1);
  color: var(--ink-soft);
}

.footer__tagline {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.72rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.footer__tagline .dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--green);
  flex: none;
}

@media (min-width: 760px) {
  .footer__top {
    grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
    gap: 3rem;
  }
  .footer__nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem 1.5rem;
  }
}

/* -------------------------------------------------------------------------
   15. Scroll reveal — restrained, and off entirely under reduced motion
   ------------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.7s var(--ease-out), transform 0.7s var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
}

/* If JS never runs, content must still be visible. */
.no-js [data-reveal] {
  opacity: 1;
  transform: none;
}

/* -------------------------------------------------------------------------
   16. Reduced motion
   ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    /* Without this, .mobile-nav's `visibility 0s linear 0.36s` close
       transition keeps clipped links focusable for 0.36s after closing. */
    transition-delay: 0s !important;
    scroll-behavior: auto !important;
  }

  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }

  .btn:hover,
  .card:hover,
  .channel:hover,
  .social__link:hover,
  .btn:hover .btn__arrow,
  .btn--ghost:hover .btn__arrow,
  .channel:hover .channel__arrow {
    transform: none;
  }
}

/* -------------------------------------------------------------------------
   17. Print
   ------------------------------------------------------------------------- */

@media print {
  .header,
  .mobile-nav,
  .hero__visual,
  .form,
  .nav-toggle,
  .skip-link {
    display: none !important;
  }
  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }
  .section {
    padding-block: 1.5rem;
    break-inside: avoid;
  }
  .gap-band {
    background: #fff;
    color: #000;
  }
  .gap-band h2,
  .gap-band__quote {
    color: #000;
  }
  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 9pt;
    color: #555;
  }
}
