/* =========================================================
   Community Building Agency — Redesign v2 (style.css)
   Warm · gradient · editorial · community-led
   ========================================================= */

:root {
  /* Base */
  --bg:        #ffffff;   /* white */
  --surface:   #ffffff;
  --ink:       #1d2a62;   /* delft blue */
  --muted:     #5b6486;   /* muted navy */
  --line:      #e6e9ef;   /* neutral line */

  /* Brand stops — Delft Blue / Carolina / Beige / Pistachio / Fern */
  --coral:     #437118;   /* fern green — text accents */
  --peach:     #87aece;   /* carolina blue */
  --rose:      #87aece;   /* carolina blue */
  --carolina-deep: #4378a3; /* carolina blue darkened to 4.7:1 on white, for small text */
  --lav:       #1d2a62;   /* delft blue */
  --mint:      #afd06e;   /* pistachio */
  --gold:      #87aece;   /* carolina blue */

  /* Signature gradients */
  --grad-warm:   linear-gradient(120deg, #437118 0%, #87aece 55%, #1d2a62 100%);
  --grad-sun:    linear-gradient(120deg, #437118 0%, #87aece 100%);
  --grad-soft:   linear-gradient(150deg, #eef6db 0%, #e3edf7 50%, #ecf4dd 100%);
  --grad-mint:   linear-gradient(150deg, #e6f1cf, #dce9f4);
  --grad-ink:    linear-gradient(150deg, #141d44 0%, #1d2a62 60%, #243168 100%);
  /* home-grad-green's radial falloff (dark centre, lighter edges) with its stops' lightness moved onto the navy hue */
  --grad-ink-radial: radial-gradient(ellipse at center, #101736 0%, #141d44 19%, #1f2c67 56%, #25367d 90%);

  --radius:   24px;
  --radius-sm:16px;
  --radius-pill: 999px;
  --maxw:     1160px;
  --pad:      clamp(1.25rem, 4vw, 2.5rem);
  /* 100px + the 1px bottom border = the footer's 101px (2.4rem padding top and
     bottom, one line of text, 1px top border), while the footer fits on one
     line. Below 940px the footer wraps and grows, so the header drops back to
     78px there (see Nav collapse) rather than following it. */
  --header-h: 100px;
  --logo-mark: 32px;
  --banner-h: 38px;

  --shadow:    0 2px 6px rgba(29,42,98,.06), 0 24px 60px -20px rgba(29,42,98,.18);
  --shadow-sm: 0 1px 3px rgba(29,42,98,.06), 0 12px 30px -16px rgba(29,42,98,.15);

  --ease: cubic-bezier(.21,.6,.35,1);

  --font-display: "Fraunces", Georgia, serif;
  --font-body: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

html { background: var(--bg); }

body {
  margin: 0;
  font-family: var(--font-body);
  background: transparent;
  color: var(--ink);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* One single fixed background image for the whole site. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: url("assets/home/home-grad-green.png") center center / cover no-repeat;
}

/* Pages that opt out of the poster and sit on flat white.
   The .section top border is white, so it also stops showing as a divider. */
body.page-white { background: var(--bg); }
body.page-white::before { content: none; }

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

.container {
  width: 100%;
  max-width: var(--maxw);
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}

/* ---------- Typography ---------- */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.08;
  letter-spacing: -0.015em;
  margin: 0;
  font-optical-sizing: auto;
}
h1 { font-size: clamp(2.7rem, 6.2vw, 4.6rem); font-weight: 540; }
h2 { font-size: clamp(2rem, 4vw, 3.1rem); }
h3 { font-size: 1.35rem; font-weight: 560; }

p { margin: 0 0 1rem; }
.lead { font-size: 1.18rem; color: var(--muted); }
.body { color: var(--muted); }
.max-60 { max-width: 58ch; }

.grad-text {
  background: var(--grad-warm);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  font-family: var(--font-body);
  font-size: 0.74rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--coral);
  margin: 0 0 1.1rem;
}
.eyebrow::before {
  content: "";
  width: 26px; height: 2px; border-radius: 2px;
  background: var(--grad-warm);
}
.eyebrow.center { justify-content: center; }
/* blue eyebrow for white sections; plain --peach is too pale to read on white */
.eyebrow.eyebrow-blue { color: var(--carolina-deep); }
.eyebrow.eyebrow-blue::before { background: linear-gradient(120deg, var(--carolina-deep), var(--peach)); }

a { color: inherit; }

/* ---------- Buttons ---------- */
.btn-primary, .btn-outline {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  font-family: var(--font-body);
  font-size: 0.92rem;
  letter-spacing: 0.01em;
  font-weight: 700;
  padding: 0.95rem 1.7rem;
  border-radius: var(--radius-pill);
  cursor: pointer;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: transform .28s var(--ease), box-shadow .28s var(--ease), background .28s var(--ease), color .28s var(--ease);
}
.btn-primary {
  background: var(--grad-warm);
  background-size: 160% 160%;
  /* The 1.5px transparent border above sits outside the default padding-box
     origin, so the gradient would tile into it and show its end colour as a
     dark hairline along the top and left. Origin at the border box covers it. */
  background-origin: border-box;
  color: #fff;
  box-shadow: 0 10px 26px -8px rgba(29,42,98,.34);
}
.btn-primary:hover { transform: translateY(-3px); background-position: 100% 0; box-shadow: 0 16px 34px -10px rgba(29,42,98,.4); }
/* Join Community button: blue by default, the standard green-blue on hover.
   background-image can't transition between gradients, so the hover one sits on
   a ::before layer that fades in; isolation keeps that layer behind the label.
   inset -1.5px reaches under the transparent border, like background-origin above. */
.btn-primary.join-btn {
  position: relative;
  isolation: isolate;
  background-image: linear-gradient(120deg, var(--ink) 0%, var(--carolina-deep) 50%, var(--peach) 100%);
}
.btn-primary.join-btn::before {
  content: "";
  position: absolute; inset: -1.5px; z-index: -1;
  border-radius: inherit;
  background: var(--grad-warm);
  background-size: 160% 160%;
  opacity: 0;
  transition: opacity .28s var(--ease);
}
.btn-primary.join-btn:hover::before { opacity: 1; }
.btn-outline {
  background: var(--surface);
  color: var(--ink);
  border-color: var(--line);
}
.btn-outline:hover { transform: translateY(-3px); border-color: var(--coral); color: var(--coral); box-shadow: var(--shadow-sm); }
.btn-large { padding: 1.1rem 2.1rem; font-size: 0.98rem; }
.btn-full { width: 100%; }

/* Temporary site-wide notice, pinned above the header. Its height is a
   variable because the header sticks below it and anchor offsets have to
   clear both; an explicit height keeps that number exact rather than
   depending on padding and line-height. */
.dev-banner {
  position: sticky;
  top: 0;
  z-index: 60;
  min-height: 38px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0 .75rem;
  margin: 0;
  padding: .4rem .6rem;
  background: #fff;
  color: #d2042d;
  font-family: var(--font-body);
  /* same size at every width — it wraps to a second line on a very narrow
     phone rather than shrinking, and main.js keeps --banner-h in step */
  font-size: .7rem;
  letter-spacing: .18em;
  line-height: 1.5;
  text-transform: uppercase;
  font-weight: 700;
  text-align: center;
  border-bottom: 1px solid var(--line);
}
.dev-banner-date { opacity: .72; }
.dev-banner-date::before { content: "·"; margin-right: .75rem; opacity: .5; }
/* Banner switched off site-wide; the markup stays on every page. Delete these
   two rules to bring it back. --banner-h is zeroed here too so the header and
   anchor offsets don't reserve 38px before main.js measures the (hidden) banner. */
.dev-banner { display: none; }
:root { --banner-h: 0px; }

/* ---------- Header ---------- */
.site-header {
  position: sticky;
  top: var(--banner-h);
  z-index: 50;
  background: rgba(255,255,255,.90);
  backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--line);
}
.site-header .container { max-width: none; }
/* the side gaps match the gap above and below the logo sphere —
   (header height - sphere height) / 2 — so the logo sits as far from the side
   as from the top at both header heights (100px desktop, 78px with the burger) */
.site-header .container {
  --nav-edge: calc((var(--header-h) - var(--logo-mark)) / 2);
  padding-left: var(--nav-edge);
  padding-right: var(--nav-edge);
}
.nav-inner { display: flex; align-items: center; justify-content: space-between; gap: clamp(.75rem, 3vw, 2rem); height: var(--header-h); }
/* min-width:0 lets the logo shrink instead of pushing the burger off-screen */
.logo { display: flex; align-items: center; gap: .7rem; min-width: 0; text-decoration: none; }
.logo-mark {
  width: var(--logo-mark); height: var(--logo-mark);
  object-fit: contain;
  display: block;
  flex-shrink: 0;
}
.logo-text {
  /* same family as the nav links */
  font-family: var(--font-body);
  font-weight: 600;
  /* scales down on narrow screens so the wordmark stays on one line */
  font-size: clamp(.85rem, 4.6vw, 1.4rem);
  /* letter-spacing: 0.04em; */
  color: var(--ink);
  white-space: nowrap;
  /* last-resort guard: truncate rather than overflow the header */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.nav-links { display: flex; align-items: center; gap: 1.2rem; }
.nav-links a { text-decoration: none; font-size: 0.9rem; font-weight: 500; color: var(--muted); transition: color .2s var(--ease); white-space: nowrap; }
.nav-links a:hover { color: var(--ink); }
.nav-links a[aria-current="page"] { color: var(--ink); font-weight: 700; }
/* Same gradient treatment as .btn-primary: drawn at 160% so the button shows
   the green-to-light-blue part, sliding towards the navy end on hover. */
.nav-cta {
  color: #fff !important;
  background: var(--grad-warm);
  background-size: 160% 160%;
  background-origin: border-box;
  padding: 0.65rem 1.3rem;
  border-radius: var(--radius-pill);
  font-weight: 700;
  box-shadow: 0 8px 20px -8px rgba(29,42,98,.3);
  transition: transform .28s var(--ease), box-shadow .28s var(--ease), background .28s var(--ease);
}
.nav-cta:hover { transform: translateY(-2px); background-position: 100% 0; }

.nav-toggle {
  display: none;
  flex-direction: column; align-items: center; justify-content: center;
  gap: 5px; background: none; border: 0; cursor: pointer; padding: 8px;
  /* 44px = iOS minimum tap target; never shrink or the burger clips */
  width: 44px; height: 44px; margin-right: -8px;
  flex-shrink: 0;
}
.nav-toggle span { width: 24px; height: 2px; background: var(--ink); border-radius: 2px; transition: transform .3s var(--ease), opacity .3s; }
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { transform: translateY(-0px) rotate(-45deg); }

/* ---------- Subpages ---------- */
/* symmetric top/bottom padding from .section, so the space below the button
   matches the space between the navbar and the eyebrow.
   .eyebrow is inline-flex site-wide, which puts it on a text line and adds
   ~10px of half-leading above it — enough to make the top gap visibly bigger
   than the bottom one. Block-level flex drops the line box; .eyebrow.center
   already supplies justify-content, so it still centres. */
.page-hero .eyebrow { display: flex; }
/* Subpage heroes are content-driven, so the gap above the eyebrow is just the
   section's top padding and reads the same on every page. (A min-height with
   centred content used to live here; on the shorter Services hero it created
   ~170px of extra free space above and below, making that page's spacing look
   nothing like Join Community's.)
   When the header is the hero's last element there's nothing below it to
   separate, so its 3rem margin would otherwise add to the bottom padding. */
.page-hero .section-header:last-child { margin-bottom: 0; }
/* likewise the last paragraph inside it, whose 1rem margin would otherwise
   sit on top of the hero's bottom padding */
.page-hero .section-header > :last-child { margin-bottom: 0; }
/* index's .hero carries no top border; subpage heroes use .section, so drop it here.
   #community-photos is a full-bleed strip with no divider above it either. */
.page-hero, #community-photos { border-top: 0; }
.page-hero h1 { font-size: clamp(2.2rem, 5vw, 3.4rem); }
.page-hero .lead { margin-top: 1.2rem; }
/* 404 page: its hero is the whole page, so <main> stretches to fill the
   screen between header and footer and centres the message in it (the
   footer sits at the bottom instead of halfway up). A flex column rather
   than a min-height sum, since the footer's height varies (its links stack
   on phones). The section's padding is equal top and bottom, so the text
   lands in the true middle. */
body:has(.notfound) { display: flex; flex-direction: column; min-height: 100dvh; }
body:has(.notfound) main { flex: 1; display: flex; flex-direction: column; justify-content: center; }

/* hidden must win over any display set below */
[hidden] { display: none !important; }

/* auto-scrolling community photo strip — full-bleed, drifting sideways */
.marquee {
  position: relative; z-index: 1;
  width: 100vw; margin-left: calc(50% - 50vw);
  overflow: hidden;
}
.marquee-track {
  display: flex;
  width: max-content;
  /* scale with the strip's length when photos change, or the scroll speed
     changes (120s suited the earlier 15 photos, ~6,800px wide at 400px tall;
     115s keeps that pace for the current 14, ~6,500px including gaps).
     main.js reads this duration for the photo strip's JS-driven drift. */
  animation: marquee-scroll 115s linear infinite;
}
/* the track holds two identical copies, so -50% lands exactly on the seam */
@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* uniform height, width follows each photo's own proportions — nothing is
   cropped, so wide shots stay wide and portrait shots stay narrow.
   max-width:none overrides the global img rule, which would otherwise
   fight the auto width inside a max-content flex track. */
.marquee-track img {
  flex: 0 0 auto;
  height: clamp(240px, 30vw, 400px);
  width: auto;
  max-width: none;
  display: block;
}
/* thin white line between photos — a fixed 2px, since scaling it down would
   go sub-pixel and blur. A margin rather than a flex gap, so both copies stay
   equal and -50% still lands on the seam. */
#community-photos .marquee-track img { margin-right: 2px; }
/* the same line under the strip, setting it off from the blue band below */
#community-photos { border-bottom: 2px solid #fff; }
/* main.js adds .is-manual when it takes over from the CSS animation, so the
   strip can also be dragged, swiped or trackpad-scrolled. pan-y keeps vertical
   swipes scrolling the page on phones; overflow:hidden beats the reduced-motion
   rule's native scrolling, which would fight the JS transform; overscroll
   containment stops a sideways trackpad swipe from triggering browser back. */
.marquee.is-manual {
  overflow: hidden;
  cursor: grab;
  touch-action: pan-y;
  overscroll-behavior-x: contain;
  user-select: none; -webkit-user-select: none;
}
.marquee.is-manual .marquee-track { animation: none; will-change: transform; }
.marquee.is-dragging { cursor: grabbing; }
/* discourages saving the photos (main.js also blocks the right-click menu):
   no dragging them out, no iOS long-press "Save to Photos". A deterrent only —
   anyone determined can still take a screenshot. */
#community-photos img { -webkit-user-drag: none; -webkit-touch-callout: none; }

/* confirmation shown in place of the sign-up form */
.confirmation { text-align: center; }
/* focused programmatically so screen readers land on it — no visible ring */
.confirmation:focus:not(:focus-visible) { outline: none; }
.confirmation h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); margin-bottom: .9rem; }
.confirmation .lead { max-width: 46ch; margin: 0 auto; }
/* multi-paragraph confirmations: buttons sit between paragraphs, each one
   closer to the text that introduces it than to the paragraph after it */
.confirmation .lead + .lead { margin-top: 1rem; }
.confirmation .social-actions + .lead { margin-top: 1.8rem; }
.confirmation .social-actions { margin-top: 1.2rem; }
.confirmation .lead a { color: var(--coral); }
.confirmation-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 62px; height: 62px; border-radius: 50%;
  background: var(--grad-sun); color: #fff;
  font-size: 1.7rem; font-weight: 700;
  margin-bottom: 1.3rem;
}

/* Instagram / WhatsApp button pair */
.social-actions { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; margin-top: 1.8rem; }
.btn-icon { width: 18px; height: 18px; flex: 0 0 auto; object-fit: contain; }
/* Both social buttons share one look. The supplied icons are solid black
   glyphs, so the fill has to stay light for them to read — the brand gradient
   is dropped here (the shorthand clears it, since a gradient is an image).
   A hairline border separates them on light backgrounds. */
.social-actions .btn-primary {
  background: #fff;
  color: var(--ink);
  border-color: var(--line);
  box-shadow: var(--shadow-sm);
}
.social-actions .btn-primary:hover { background: #f4f6fa; border-color: var(--line); }
/* on the dark band the white fill separates on its own */
.section-cta .social-actions .btn-primary { border-color: transparent; }
.section-cta .btn-outline { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.section-cta .btn-outline:hover { background: #fff; color: var(--ink); border-color: #fff; }

.field-optional { font-weight: 500; color: var(--muted); }

/* the default .section-header caps at 60ch, which left this hero's headline
   wrapping to six lines inside a 747px column with 167px empty either side.
   The headline takes the full container; the body copy stays a touch narrower
   so lines don't get uncomfortably long to read. */
.page-hero .section-header { max-width: 100%; }
.page-hero .hero-intro { max-width: 880px; margin-left: auto; margin-right: auto; }

/* multi-paragraph hero copy (Join Community). Paragraphs carry .lead — the same
   token the services hero uses — so size/colour stay defined in exactly one
   place. Only spacing is set here. */
.hero-intro { margin-top: 1.2rem; }
.hero-intro p { margin-bottom: 1rem; }
.hero-intro p:last-child { margin-bottom: 0; }

/* standalone form container (Join Community) */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 4vw, 2.6rem);
  box-shadow: var(--shadow-sm);
  max-width: 720px;
  margin: 0 auto;
  position: relative;
  z-index: 1;
}

/* ---------- Sections ---------- */
/* keeps anchored headings clear of the sticky header */
.section, .hero { scroll-margin-top: calc(var(--header-h) + var(--banner-h)); }
.section { padding: clamp(4.5rem, 9vw, 8rem) 0; position: relative; border-top: 1.5px solid rgba(255,255,255,.85); }
.section-header { margin-bottom: 3rem; max-width: 60ch; }
.section-header.center { margin-left: auto; margin-right: auto; text-align: center; }
.section-header h2 { margin-top: .4rem; }
.section-header .lead { margin-top: 1rem; }

.bg-soft, .bg-mint { background: transparent; }

/* Sections with a solid white background — the rest let the poster show through,
   so the page alternates poster / white / poster as you scroll. */
#intro-video, #about-us, #what-we-do, #why-community, #why-us, #founder { background: var(--surface); }
/* Founder and Trusted By are both white and sit next to each other, so their
   two paddings stack into a gap twice the size of any other — with no change of
   background to explain it. Drop the second one; the adjacent-sibling selector
   means this stops applying by itself if the sections are ever reordered. */
#founder + #why-us { padding-top: 0; }
/* same for the video section sitting directly below About Us */
#about-us + #intro-video { padding-top: 0; }

/* decorative blobs — hidden site-wide (single fixed bg handles this), kept only in CTA */
.blob { position: absolute; border-radius: 50%; filter: blur(70px); opacity: .7; pointer-events: none; z-index: 0; display: none; }
.section-cta .blob { display: block; }
.blob-1 { width: 460px; height: 460px; background: radial-gradient(circle, #afd06e, transparent 70%); top: -120px; right: -80px; }
.blob-2 { width: 420px; height: 420px; background: radial-gradient(circle, #87aece, transparent 70%); bottom: -140px; left: -90px; }
.blob-3 { width: 380px; height: 380px; background: radial-gradient(circle, #87aece, transparent 70%); top: 30%; left: -120px; }

/* ---------- Light text over the dark gradient backdrop ----------
   Only .hero, #who-we-help and #process let home-grad-green show through, so only the
   text sitting directly on it flips to white. Deliberately NOT set as
   `color` on the sections themselves: each of them also contains white cards
   (hero cards, process cards, the spheres) whose text must stay dark. */
.hero h1,
#who-we-help h2,
#process h2 { color: #fff; }

.hero .hero-subtitle { color: rgba(255,255,255,.84); }

/* the brand gradient's green and navy stops vanish on dark green */
.hero .grad-text { background-image: linear-gradient(120deg, #cfe9a6 0%, #bcd8f0 100%); }

#who-we-help .eyebrow,
#process .eyebrow { color: var(--mint); }
#who-we-help .eyebrow::before,
#process .eyebrow::before { background: linear-gradient(120deg, #afd06e, #cfe3f5); }

/* the open "etc." sphere is the one tag with no white fill behind it */
.who-tags span.who-tag-more { border-color: rgba(255,255,255,.5); color: rgba(255,255,255,.8); }

/* ---------- Hero ---------- */
.hero { position: relative; padding: clamp(3.5rem, 7vw, 6rem) 0 clamp(4.5rem, 9vw, 7rem); overflow: hidden; }
/* text left, globe right */
.hero-grid {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.hero-copy h1 { margin-bottom: 1.5rem; }
.hero-subtitle { font-size: 1.18rem; color: var(--muted); max-width: 46ch; margin-bottom: 2.2rem; }
.hero-actions { display: flex; gap: 1rem; flex-wrap: wrap; }
.hero-visual { position: relative; }
/* 3D globe (globe.js): the static image shows until the canvas is ready,
   and stays if WebGL isn't available */
.globe-3d {
  position: relative;
  width: 100%; max-width: 460px; aspect-ratio: 1 / 1;
  margin-left: auto;
  /* drop-shadow, not box-shadow: it follows the round edge */
  filter: drop-shadow(0 6px 14px rgba(0,0,0,.18)) drop-shadow(0 30px 50px rgba(0,0,0,.32));
}
.globe-3d img,
.globe-3d canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
/* The placeholder (the CBA sphere logo, which fills its whole image) is shown
   at the size the 3D globe renders: globe.js's camera (fov 30 at distance 4.2)
   draws the radius-1 sphere across tan(asin(1/4.2)) / tan(15°) = 91.5% of the
   canvas, so the swap doesn't jump. Recalculate if the camera changes. */
.globe-3d img { inset: 4.25%; width: 91.5%; height: 91.5%; }
.globe-3d canvas {
  opacity: 0; transition: opacity .6s var(--ease);
  cursor: grab;
  /* vertical swipes still scroll the page on phones */
  touch-action: pan-y;
}
.globe-3d.is-ready canvas { opacity: 1; }
.globe-3d.is-ready img { opacity: 0; transition: opacity .6s var(--ease); }
.globe-3d.is-dragging canvas { cursor: grabbing; }
.hero-actions-below { display: none; }


/* ---------- Who We Help (marquee-ish strip) ---------- */
.who-strip { text-align: center; max-width: 72ch; margin: 0 auto; position: relative; z-index: 1; }
/* Eleven peers: identical diameter, identical gap. Two staggered rows on a
   hexagonal packing — row offset is (d + gap) x sin(60deg), which makes the
   diagonal centre distance equal the horizontal one, so the gap is the same
   13.2px in every direction rather than just along each row.
   The band is wide rather than square: spreading horizontally is what lets
   each sphere reach ~220px, and in a circle the diameter is what buys
   readable text. It breaks out past .who-strip to use the viewport width. */
.who-tags {
  position: relative;
  width: min(calc((100vw - 3rem) * .85), 1180px);
  margin-left: 50%;
  transform: translateX(-50%);
  aspect-ratio: 1386 / 422;
  margin-top: 2.8rem;
  --sphere: 15.87%;             /* of container width */
}
.who-tags span {
  --x: 50%;
  --y: 50%;
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;       /* stacks the <br>-split label lines */
  align-items: center;
  justify-content: center;
  text-align: center;
  width: var(--sphere);
  aspect-ratio: 1 / 1;
  padding: .8rem;
  border-radius: 50%;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  font-size: clamp(.82rem, 1.3vw, 1.05rem);
  font-weight: 600;
  line-height: 1.35;
  transition: scale .3s var(--ease), box-shadow .3s var(--ease);
}
/* top row of six */
.who-tags span:nth-child(1)  { --x:  7.94%; --y: 26.07%; }  /* Fashion brands */
.who-tags span:nth-child(2)  { --x: 24.76%; --y: 26.07%; }  /* Independent designers */
.who-tags span:nth-child(3)  { --x: 41.59%; --y: 26.07%; }  /* Retailers & concept stores */
.who-tags span:nth-child(4)  { --x: 58.41%; --y: 26.07%; }  /* Media & publishing */
.who-tags span:nth-child(5)  { --x: 75.24%; --y: 26.07%; }  /* Creative agencies & studios */
.who-tags span:nth-child(6)  { --x: 92.06%; --y: 26.07%; }  /* Artists */
/* bottom row of five, offset by half a step */
.who-tags span:nth-child(7)  { --x: 16.35%; --y: 73.93%; }  /* Creators */
.who-tags span:nth-child(8)  { --x: 33.17%; --y: 73.93%; }  /* Personal brands */
.who-tags span:nth-child(9)  { --x: 50.00%; --y: 73.93%; }  /* Event organisers */
.who-tags span:nth-child(10) { --x: 66.83%; --y: 73.93%; }  /* Community-led organisations */
.who-tags span:nth-child(11) { --x: 83.65%; --y: 73.93%; }  /* And more… */
.who-tags span:hover { scale: 1.05; box-shadow: var(--shadow); z-index: 2; }

/* trailing "etc." rather than another category — an open, dashed sphere */
.who-tags .who-tag-more {
  background: transparent;
  border: 1px dashed rgba(29,42,98,.3);
  box-shadow: none;
  color: var(--muted);
  font-weight: 500;
}
.who-tags .who-tag-more:hover { scale: 1; box-shadow: none; }
/* Narrow screens: the same hexagonal packing turned on its side — two columns
   of 6 and 5 instead of two rows. The coordinates are literally the desktop
   ones with x and y swapped, since a transposed hex grid keeps every gap
   equal. Width is capped so the spheres don't balloon on a small tablet. */
@media (max-width: 760px) {
  .who-tags {
    width: min(calc(100vw - 2.5rem), 340px);
    aspect-ratio: 1918 / 6300;
    --sphere: 52.14%;           /* of container width, 2 columns */
  }
  .who-tags span { font-size: clamp(.86rem, 3.4vw, 1rem); padding: .7rem; }
  /* left column of six */
  .who-tags span:nth-child(1)  { --x: 26.07%; --y:  7.94%; }
  .who-tags span:nth-child(2)  { --x: 26.07%; --y: 24.76%; }
  .who-tags span:nth-child(3)  { --x: 26.07%; --y: 41.59%; }
  .who-tags span:nth-child(4)  { --x: 26.07%; --y: 58.41%; }
  .who-tags span:nth-child(5)  { --x: 26.07%; --y: 75.24%; }
  .who-tags span:nth-child(6)  { --x: 26.07%; --y: 92.06%; }
  /* right column of five, offset by half a step */
  .who-tags span:nth-child(7)  { --x: 73.93%; --y: 16.35%; }
  .who-tags span:nth-child(8)  { --x: 73.93%; --y: 33.17%; }
  .who-tags span:nth-child(9)  { --x: 73.93%; --y: 50.00%; }
  .who-tags span:nth-child(10) { --x: 73.93%; --y: 66.83%; }
  .who-tags span:nth-child(11) { --x: 73.93%; --y: 83.65%; }
}

/* ---------- Frameworks ---------- */
.framework-block { text-align: center; max-width: 780px; margin: 0 auto; position: relative; z-index: 1; }

/* Strategic frameworks — large items in gradient rectangles */
.framework-list {
  list-style: none;
  margin: 0 auto;
  padding: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: .8rem;
  text-align: center;
  /* wide enough for the longest title (591px incl. padding and chevron) and
     the longest description (664px) to each hold one line */
  max-width: 700px;
}
/* Each item is a tap target that expands its description. Tap rather than
   hover, so it behaves the same on a phone as on a desktop.
   The gradient lives on the <li>, not the button, so the whole box grows
   downward and the description sits inside it. */
.framework-item {
  border-radius: var(--radius-sm);
  background-image: linear-gradient(120deg, #141d44 0%, #1d2a62 55%, #2a3a7e 100%);
  box-shadow: var(--shadow-sm);
  overflow: hidden;           /* keeps the panel within the rounded corners */
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.framework-item:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.framework-item:has(.framework-toggle:focus-visible) { outline: 3px solid var(--mint); outline-offset: 3px; }

.framework-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  width: 100%;
  text-align: left;
  cursor: pointer;
  border: 0;
  background: none;
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2.6vw, 1.9rem);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: #fff;
  padding: 1rem 1.6rem;
}
.framework-toggle:focus-visible { outline: none; }

/* chevron, rotates to point up while the panel is open */
.framework-chevron {
  flex: 0 0 auto;
  width: 11px; height: 11px;
  border-right: 2.5px solid currentColor;
  border-bottom: 2.5px solid currentColor;
  transform: rotate(45deg) translate(-3px, -3px);
  transition: transform .3s var(--ease);
}
.framework-item.is-open .framework-chevron { transform: rotate(-135deg) translate(-3px, -3px); }

/* 0fr -> 1fr animates to the content's natural height, which a max-height
   guess cannot do. visibility keeps collapsed text out of the a11y tree. */
.framework-panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows .32s var(--ease), visibility .32s;
}
.framework-item.is-open .framework-panel { grid-template-rows: 1fr; visibility: visible; }
.framework-panel-inner { overflow: hidden; }
.framework-panel p {
  margin: 0;
  /* no top padding: the button's own bottom padding is the gap */
  padding: 0 1.6rem 1.15rem;
  font-family: var(--font-body);
  font-size: .97rem;
  line-height: 1.6;
  color: rgba(255,255,255,.8);
  text-align: left;
}

@media (prefers-reduced-motion: reduce) {
  .framework-panel, .framework-chevron, .framework-toggle { transition: none; }
}
.pill-list { display: flex; flex-wrap: wrap; gap: .65rem; }
.pill-list.center { justify-content: center; }
.pill-list span {
  background: var(--surface);
  border: 1px solid var(--line);
  padding: .6rem 1.2rem;
  border-radius: var(--radius-pill);
  font-size: .95rem;
  font-weight: 500;
  transition: border-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.pill-list span:hover { border-color: transparent; transform: translateY(-2px); box-shadow: var(--shadow-sm); }

/* ---------- Process ---------- */
.process-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.4rem; position: relative; z-index: 1; }
.process-step {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2.2rem 1.8rem 1.8rem;
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
  overflow: hidden;
}
.process-step::after {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 4px;
  background: var(--grad-warm); opacity: 0; transition: opacity .28s var(--ease);
}
.process-step:hover { transform: translateY(-6px); box-shadow: var(--shadow); }
.process-step:hover::after { opacity: 1; }
.step-number {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: 14px;
  font-family: var(--font-display); font-size: 1.15rem; font-weight: 600;
  color: #fff; background: var(--grad-sun);
  margin-bottom: 1.1rem;
}
.process-step h3 { margin-bottom: .5rem; }
.process-step p { color: var(--muted); font-size: .96rem; margin: 0; }

/* ---------- Visual strip ---------- */
.visual-strip { position: relative; z-index: 1; width: 100vw; margin-left: calc(50% - 50vw); padding: 0; }
.visual-strip-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; width: 100%; margin: 0; padding: 0; }
.visual-strip-grid img { width: 100%; height: 100%; aspect-ratio: 3 / 4; object-fit: cover; display: block; }

/* ---------- Services ---------- */
.service-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.5rem; align-items: stretch; position: relative; z-index: 1; }
.service-card {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2.2rem 2rem;
  transition: transform .28s var(--ease), box-shadow .28s var(--ease);
}
.service-card.featured {
  background: var(--grad-ink);
  border: none;
  color: #fff;
}
.service-card.featured .body,
.service-card.featured .service-outcome { color: rgba(255,255,255,.8); }
.service-card.featured .service-outcome { background: rgba(255,255,255,.08); }
.service-card.featured .service-outcome strong { color: #fff; }
.service-card:hover { transform: translateY(-6px); box-shadow: var(--shadow); }
.service-card h3 { margin-bottom: .8rem; }
.service-tag {
  font-size: .66rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 800;
  padding: .3rem .7rem; border-radius: var(--radius-pill);
  background: var(--grad-sun); color: #fff;
}
.service-list { color: var(--muted); font-size: .95rem; padding-left: 1.1rem; margin: 0 0 1rem; }
.service-list li { margin-bottom: .45rem; }
.service-outcome { font-size: .93rem; background: var(--grad-soft); border-radius: var(--radius-sm); padding: 1rem 1.1rem; margin: auto 0 1.5rem; }
.service-card .btn-primary, .service-card .btn-outline { width: 100%; }
.service-price { text-align: center; }
.service-price .price {
  display: block;
  font-family: var(--font-body);
  font-size: 1.2rem;
  font-weight: 700;
  color: var(--ink);
}
.service-price .price-note { display: block; font-size: .85rem; color: var(--muted); margin-top: .25rem; }
.service-card.featured .service-price .price { color: #fff; }
.service-card.featured .service-price .price-note { color: rgba(255,255,255,.7); }
.service-card.featured .btn-outline { background: transparent; color: #fff; border-color: rgba(255,255,255,.4); }
.service-card.featured .btn-outline:hover { background: #fff; color: var(--ink); }

/* ---------- Why community ---------- */
.two-col { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; position: relative; z-index: 1; }
.benefit-list { display: flex; flex-direction: column; gap: .9rem; }
.benefit-list .benefit {
  display: flex; align-items: center; gap: .9rem;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: .9rem 1.2rem;
  font-weight: 500;
  box-shadow: var(--shadow-sm);
}
.benefit .tick {
  flex: 0 0 auto;
  width: 28px; height: 28px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--grad-warm); color: #fff; font-size: .8rem; font-weight: 700;
}

/* ---------- Community values & guidelines (Join Community page) ---------- */
/* #values is a .section-cta band, so its edges separate it from the white
   sections around it and each side keeps its normal padding.
   Block-level eyebrows for the same half-leading reason as .page-hero .eyebrow. */
#values, #guidelines { border-top: 0; }
#values .eyebrow, #guidelines .eyebrow { display: flex; }
/* .section-cta sets white text on the band; the white cards inside must stay dark */
#values .process-step { color: var(--ink); }
#values { background: var(--grad-ink-radial); }
/* four values: 2x2 reads better than the 3-column process grid, which would leave one orphan */
.values-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.4rem; position: relative; z-index: 1; max-width: 1000px; margin: 0 auto; }
.guideline-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; position: relative; z-index: 1; max-width: 1000px; margin: 0 auto; }
.guideline-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 2.2rem 2rem;
  box-shadow: var(--shadow-sm);
}
.guideline-card h3 { margin-bottom: 1.2rem; }
.guideline-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .8rem; }
.guideline-list li { display: flex; align-items: flex-start; gap: .8rem; color: var(--muted); font-size: .96rem; }
/* same badge as .benefit .tick; the top nudge centres it on the first line of a wrapped item */
.guideline-list .tick {
  flex: 0 0 auto;
  width: 24px; height: 24px; border-radius: 50%; margin-top: -.05rem;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--grad-warm); color: #fff; font-size: .72rem; font-weight: 700;
}
.guideline-list .tick-no { background: var(--ink); }
.guideline-note {
  max-width: 1000px; margin: 1.4rem auto 0; position: relative; z-index: 1;
  background: var(--grad-soft); border-radius: var(--radius-sm);
  padding: 1.3rem 1.5rem; color: var(--muted); font-size: .96rem;
}
.guideline-note strong { color: var(--ink); }

/* ---------- Embedded video ---------- */
/* The source video is 16:9 (Vimeo's snippet shipped 75%, i.e. 4:3, which
   letterboxed it). 56.25% reserves the right height before the iframe loads,
   so nothing below jumps. */
.video-embed {
  position: relative;
  z-index: 1;
  max-width: 860px;
  margin: 0 auto;
  overflow: hidden;
  /* deeper than the shared --shadow so the player lifts off the white section */
  box-shadow: 0 5px 14px rgba(29,42,98,.16), 0 36px 80px -17px rgba(29,42,98,.5);
  background: #000;
}
.video-embed-ratio { position: relative; padding-top: 56.25%; }
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* uses the eyebrow treatment — uppercased in CSS, so the markup keeps normal
   sentence case and screen readers don't spell it out */
.video-caption {
  max-width: 860px;
  margin: 1rem auto 0;
  text-align: center;
  font-size: .74rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
}

/* ---------- Why us ---------- */
/* The logo strip reuses the photo marquee (full-bleed track, two copies, -50%
   scroll); it only needs a smaller image height and a quicker cycle.
   48s suits home-logos-strip.png (5170px wide); scale it if the strip's length
   changes, or the scroll speed changes with it. */
.marquee-logos .marquee-track { animation-duration: 48s; }
.marquee-logos .marquee-track img { height: clamp(30px, 3.6vw, 48px); }

/* ---------- Founder ---------- */
.founder-inner {
  display: flex; flex-direction: column; align-items: center; gap: clamp(2rem, 4vw, 2.8rem);
  position: relative; z-index: 1;
}
.founder-photo-wrap { position: relative; width: 280px; max-width: 100%; }
.founder-photo { position: relative; z-index: 1; width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: 22px; }
.founder-text { max-width: 70ch; text-align: center; }
.founder-text p { font-size: 1.08rem; color: var(--muted); line-height: 1.75; margin-bottom: 1.2rem; }
.founder-name { font-family: var(--font-display); font-weight: 600; color: var(--ink); }

/* ---------- CTA ---------- */
.section-cta { background: var(--grad-ink); color: #fff; position: relative; overflow: hidden; }
.section-cta .blob { opacity: .35; }
.section-cta .eyebrow { color: var(--peach); }
/* all-blue dash to match the eyebrow text; light stops so it stays visible on the dark band */
.section-cta .eyebrow::before { background: linear-gradient(120deg, var(--peach), #cfe3f5); }
.cta-layout { display: grid; grid-template-columns: 1.5fr 1fr; gap: 2.2rem; align-items: stretch; position: relative; z-index: 1; }
/* Matches the height of the community photo strip (.marquee-logos aside, the
   photo strip's images use this same clamp), with the content centred in it.
   Below ~640px the copy is taller than 240px, so the section grows to fit
   rather than clipping. */
.cta-compact {
  min-height: clamp(240px, 30vw, 400px);
  display: flex;
  align-items: center;
  /* keeps the button clear of the bottom edge at the widths where the copy
     wraps and the section becomes content-driven rather than min-height-driven */
  padding-top: 2rem;
  padding-bottom: 2rem;
}

/* single-column variant, for a CTA with no contact card beside it */
.cta-layout-center { grid-template-columns: 1fr; text-align: center; }
.cta-layout-center .cta-box { max-width: 820px; margin: 0 auto; }
/* wide enough for the "Follow us on Instagram…" line to stay on one line
   (it needs 898px); below ~1000px the container is narrower and it wraps */
.cta-compact .cta-box { max-width: 920px; }
.cta-box h2 { margin-bottom: 1rem; }
.cta-box .body { color: rgba(255,255,255,.78); }
.cta-actions { margin-top: 1.8rem; }
.cta-note { font-size: .92rem; color: rgba(255,255,255,.6); margin-top: 1rem; max-width: 42ch; }
.contact-card { background: rgba(255,255,255,.07); border: 1px solid rgba(255,255,255,.14); border-radius: var(--radius); padding: 2.2rem; }
.contact-card h3 { margin-bottom: 1.4rem; }
.contact-label { font-size: .76rem; text-transform: uppercase; letter-spacing: .08em; color: rgba(255,255,255,.55); margin: 0 0 .3rem; font-weight: 700; }
.contact-card a { color: #fff; text-decoration: none; word-break: break-all; }
.contact-card a:hover { text-decoration: underline; }

/* ---------- Footer ---------- */
.footer { border-top: 1px solid var(--line); padding: 2.4rem 0; background: var(--bg); }
.footer-meta { font-size: .88rem; color: var(--muted); margin: 0; text-align: center; }
.footer-meta a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.footer-meta a:hover { color: var(--coral); }

/* ---------- Fade-in ---------- */
.fade-in, .fade-in-delayed { opacity: 0; transform: translateY(28px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.fade-in-delayed { transition-delay: .15s; }
.fade-in.visible, .fade-in-delayed.visible { opacity: 1; transform: none; }

/* =========================================================
   Modal (survey)
   ========================================================= */
.modal { position: fixed; inset: 0; z-index: 100; display: none; }
.modal.is-open { display: block; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(34,29,42,.55); backdrop-filter: blur(4px); }
/* Concentric corners: for the dialog's curve to run parallel to the submit
   button's rather than cut across it, the outer radius must be the inner
   radius plus the gap between them.
     inner = 28px  — the button is a pill, so half its 56px height
     gap   = .modal-content's padding, which is responsive, so this is too */
.modal-dialog {
  position: relative;
  /* one source of truth: .modal-content pads by this, and the concentric
     border-radius below is derived from it */
  --modal-pad: clamp(1.25rem, 4vw, 2.8rem);
  /* the width keeps a gutter on narrow screens, where max-width alone would
     let the dialog run edge to edge */
  width: calc(100% - 2rem);
  max-width: 660px;
  overflow-y: auto;
  /* vh on iOS Safari measures the viewport with the toolbars hidden, so
     5vh + 90vh + 5vh is taller than what is actually on screen and the submit
     button ends up below the fold. dvh tracks the real visible height. */
  margin: 5vh auto;  max-height: 90vh;
  margin: 5dvh auto; max-height: 90dvh;
  background: var(--surface);
  border-radius: calc(28px + var(--modal-pad));
  box-shadow: 0 40px 90px rgba(0,0,0,.35);
}
/* sits inside the content padding, vertically centred on the eyebrow line:
   the eyebrow's top is at --modal-pad and its line box is .72rem x 1.5 tall,
   so its middle is .54rem below that; the 40px button is shifted up by half */
.modal-close {
  position: absolute; top: calc(var(--modal-pad) + .54rem - 20px); right: var(--modal-pad); width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--bg); font-size: 1.4rem; line-height: 1; cursor: pointer; color: var(--ink); z-index: 2;
}
.modal-content { padding: var(--modal-pad); }
.modal-eyebrow { font-size: .72rem; line-height: 1.5; letter-spacing: .18em; text-transform: uppercase; color: var(--coral); font-weight: 700; margin: 0 0 .6rem; }
.modal-content h2 { font-size: clamp(1.6rem, 3vw, 2.1rem); }
.modal-subtitle { margin: 1.8rem 0 .6rem; font-size: 1.2rem; }
.modal-body { color: var(--muted); font-size: .98rem; }

.survey-form { margin-top: 1.6rem; }
.field { display: block; margin-bottom: 1.4rem; }
.field-label { display: block; font-size: .93rem; font-weight: 600; margin-bottom: .55rem; color: var(--ink); }
.survey-form textarea,
.survey-form input[type="email"],
.survey-form input[type="tel"],
.survey-form input[type="text"] {
  width: 100%; font: inherit; font-size: .96rem; padding: .85rem .95rem; border-radius: var(--radius-sm);
  border: 1.5px solid var(--line); background: var(--bg); color: var(--ink); resize: vertical;
}
.survey-form textarea:focus, .survey-form input:focus { outline: none; border-color: var(--coral); box-shadow: 0 0 0 4px rgba(175,208,110,.32); }
.field-hint { display: block; font-size: .84rem; color: var(--muted); margin-top: .45rem; line-height: 1.5; }
.consent a { color: var(--coral); }
.radio-grid { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; border: 0; padding: 0; margin: 0; }
.radio-grid label { font-size: .92rem; display: flex; align-items: center; gap: .5rem; color: var(--muted); }
fieldset.field { border: 0; padding: 0; }
.consent { display: flex; gap: .7rem; font-size: .88rem; color: var(--muted); align-items: flex-start; margin-bottom: 1.2rem; }
.consent input { margin-top: .3rem; }
.divider { height: 1px; background: var(--line); margin: 1.8rem 0; }

/* community agreement — fixed height with its own scrollbar, so the full text
   is readable in the form without making the dialog enormous. tabindex=0 in the
   markup lets keyboard users scroll it. */
.agreement-box {
  max-height: 260px;
  overflow-y: auto;
  overscroll-behavior: contain;
  border: 1.5px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg);
  padding: 1rem 1.15rem;
  margin: 0 0 1.2rem;
  font-size: .88rem;
  line-height: 1.6;
  color: var(--muted);
}
.agreement-box:focus-visible { outline: none; border-color: var(--coral); box-shadow: 0 0 0 4px rgba(175,208,110,.32); }
.agreement-box h4 { margin: 0 0 .7rem; font-family: var(--font-body); font-size: .92rem; font-weight: 700; color: var(--ink); }
.agreement-box h5 { margin: 1.2rem 0 .4rem; font-family: var(--font-body); font-size: .86rem; font-weight: 700; color: var(--ink); }
.agreement-box ul { margin: 0 0 .7rem; padding-left: 1.1rem; }
.agreement-box li { margin-bottom: .35rem; }
.agreement-box p { margin: 0 0 .7rem; }
.agreement-box > :last-child { margin-bottom: 0; }
.agreement-box a { color: var(--coral); }
.form-status { font-size: .92rem; color: var(--coral); margin-top: .9rem; text-align: center; font-weight: 600; }
/* Until it has a message this sits empty under the submit button, but still
   carries .9rem above and the global p's 1rem below — which made the gap under
   the button larger than the padding at the sides. Collapse it while empty;
   it stays in the DOM so the aria-live announcement still works. */
.form-status:empty { margin: 0; }

/* ---------- Legal pages (Privacy Policy) ---------- */
.legal { max-width: 760px; margin: 0 auto; color: var(--muted); line-height: 1.7; }
.legal h2 { font-size: clamp(1.35rem, 2.4vw, 1.7rem); margin: 2.8rem 0 1rem; color: var(--ink, inherit); }
.legal h2:first-child { margin-top: 0; }
.legal h3 { font-size: 1.08rem; margin: 1.6rem 0 .6rem; color: var(--ink, inherit); }
.legal p { margin-bottom: 1rem; }
.legal ul { margin: 0 0 1.2rem; padding-left: 1.3rem; list-style: disc; }
.legal li { margin-bottom: .4rem; }
.legal strong { color: var(--ink, inherit); font-weight: 600; }
.legal a { color: var(--coral); word-break: break-word; }

/* =========================================================
   Responsive
   ========================================================= */
@media (max-width: 940px) {
  .hero-grid { grid-template-columns: 1fr; }
  .globe-3d { margin: 0 auto; max-width: 340px; }
  .hero-copy { text-align: center; }
  .hero-subtitle { margin-left: auto; margin-right: auto; }
  .hero-actions { justify-content: center; }
  /* single column: the button moves below the globe */
  .hero-copy .hero-actions { display: none; }
  .hero-actions-below { display: flex; margin-top: 2rem; }
  .process-grid { grid-template-columns: repeat(2, 1fr); }
  .service-grid { grid-template-columns: 1fr; }
  .two-col { grid-template-columns: 1fr; }
  .guideline-grid { grid-template-columns: 1fr; }
  .founder-inner { grid-template-columns: 1fr; text-align: center; justify-items: center; }
  .cta-layout { grid-template-columns: 1fr; }

}

/* ---------- Nav collapse ----------
   Logo + 3 links + CTA need ~900px on one line, so the burger takes over below 940px. */
@media (max-width: 940px) {
  :root { --header-h: 78px; }
  .nav-links {
    position: absolute; top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    background: var(--surface); border-bottom: 1px solid var(--line); padding: .5rem var(--pad) 1.25rem;
    max-height: calc(100dvh - var(--header-h) - var(--banner-h)); overflow-y: auto;
    transform: translateY(-12px); opacity: 0; pointer-events: none; transition: opacity .25s var(--ease), transform .25s var(--ease);
  }
  .nav-links.open { opacity: 1; transform: none; pointer-events: auto; }
  /* full-width rows give each link a comfortable tap target */
  .nav-links a { padding: .85rem 0; font-size: 1rem; border-bottom: 1px solid var(--line); }
  .nav-links a:last-child { border-bottom: 0; }
  .nav-links .nav-cta { text-align: center; margin-top: 1rem; padding: .95rem 1.3rem; }
  .nav-toggle { display: flex; }
}
@media (max-width: 640px) {
  /* copyright and the two policy links each on their own line; the dot separators go */
  .footer-meta > span[aria-hidden] { display: none; }
  .footer-meta a { display: block; margin-top: .5rem; }
  body { font-size: 16px; }
  .process-grid { grid-template-columns: 1fr; }
  .values-grid { grid-template-columns: 1fr; }
  .visual-strip-grid { grid-template-columns: 1fr; }
  .visual-strip-grid img { aspect-ratio: 4 / 5; }
  .radio-grid { grid-template-columns: 1fr; }

  /* Phone dialogs: use more of the screen and spend less height per row, so a
     long form needs less scrolling to reach Submit. */
  .modal-dialog { margin: 2dvh auto; max-height: 96dvh; }
  .survey-form { margin-top: 1.1rem; }
  .field { margin-bottom: 1rem; }
  .field-label { margin-bottom: .35rem; }
  .survey-form textarea,
  .survey-form input[type="email"],
  .survey-form input[type="tel"],
  .survey-form input[type="text"] { padding: .7rem .85rem; }
  .radio-grid { gap: .45rem; }
  .agreement-box { max-height: 170px; padding: .85rem 1rem; margin-bottom: 1rem; }
  .divider { margin: 1.2rem 0; }
  .consent { margin-bottom: .9rem; }
  .modal-content h2 { font-size: 1.5rem; }
  .modal-body { font-size: .92rem; }
  .btn-large { padding: .95rem 1.7rem; }

  /* the copy wraps to several lines here, so the section is content-driven and
     1.25rem left the button almost touching the bottom edge */
  .cta-compact { padding-top: 2.5rem; padding-bottom: 2.5rem; }
}

/* respect a reduced-motion preference: stop the drift, allow manual swiping */
@media (prefers-reduced-motion: reduce) {
  .marquee-track { animation: none; }
  .marquee { overflow-x: auto; }
}
