/* ==========================================================================
   Economic Zones Chamber — Design System
   Dark navy / glass-card aesthetic inspired by modern infrastructure sites.
   ========================================================================== */

:root{
  --navy-950:#050b16;
  --navy-900:#08132a;
  --navy-800:#0d1e3d;
  --navy-700:#12294f;
  --navy-600:#1a3660;
  --blue-500:#2f6fed;
  --blue-400:#4c8dff;
  --blue-300:#8ab4ff;
  --gold-400:#e8b04b;
  --cream-100:#f7f1e4;
  /* Zone lifecycle status — shared by map pins, directory-card chips, the
     modal chip, and the detail-page badge, so the color always means the
     same thing wherever a zone's status appears. */
  --status-operational:#2f9e5c;
  --status-development:#b08d57;
  --status-planned:#8a92a3;
  --ink-050:#f4f8ff;
  --ink-100:#e6edfb;
  --slate-300:#aebcdb;
  --slate-400:#8fa0c4;
  --slate-500:#6c7ea3;
  --surface:#f5f7fb;
  --surface-alt:#eef1f8;
  --gray-900:#101728;
  --gray-600:#525d76;
  --border-dark:rgba(255,255,255,.12);
  --border-light:rgba(16,23,40,.09);
  --shadow-lg:0 30px 60px -20px rgba(5,11,22,.45);
  --shadow-md:0 18px 40px -18px rgba(5,11,22,.35);
  --radius-lg:22px;
  --radius-md:14px;
  --gutter:clamp(1.25rem, 4vw, 3rem);
  --container-w:1674px; /* was 1240px, +35% */
  --font-serif:'Marcellus', Georgia, serif;
  /* Marcellus ships one weight (400) — headings/accents that use the serif
     face request this instead of a hardcoded 700 so the browser doesn't
     synthesize a faux-bold. */
  --font-serif-weight:400;
  --font-sans:'Montserrat', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  /* How far the homepage stat band is pulled up over the hero's bottom edge.
     Bottom-anchored hero elements (scroll cue, slider arrows) size their own
     clearance off this same variable so the two can never collide, no
     matter what value this gets tuned to at a given breakpoint. */
  --stat-overlap:92px;
  /* Warm neutral alternate to --surface, for editorial/photo-led sections
     that want to read less like a UI panel and more like print. */
  --paper:#f7f4ee;
}

*,*::before,*::after{ box-sizing:border-box; }
html{ scroll-behavior:smooth; }
/* Form controls don't inherit font-family from the body by default (UA
   stylesheets give them their own font) — without this, every button,
   input, select and textarea silently falls back to the OS UI font
   instead of Montserrat, including text nested inside a <button> like
   the gallery tile captions/category labels. */
button,input,select,textarea{ font-family:inherit; }
body{
  margin:0;
  font-family:var(--font-sans);
  color:var(--gray-900);
  background:var(--surface);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
ul{ margin:0; padding:0; list-style:none; }
h1,h2,h3,h4{ font-family:var(--font-serif); line-height:1.15; margin:0 0 .5em; font-weight:var(--font-serif-weight); }
p{ margin:0 0 1em; }
.container{
  width:100%; max-width:var(--container-w); margin-inline:auto; padding-inline:var(--gutter);
}
/* .hero is display:flex, which would otherwise shrink this to fit its
   content and let the auto margins re-center that shrunk box — pulling
   the (left-aligned) heading/paragraph text away from the same left
   edge every other section's .container lines up on. width:100% above
   keeps it a full-width block like it is everywhere else. */

.skip-link{
  position:absolute; left:-999px; top:0; background:var(--blue-500); color:#fff;
  padding:.75rem 1.25rem; z-index:999; border-radius:0;
}
.skip-link:focus{ left:0; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  *{ animation-duration:.001ms !important; transition-duration:.001ms !important; }
}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.5rem;
  padding:.9rem 1.7rem; border-radius:0; font-weight:600; font-size:.95rem;
  border:1px solid transparent; cursor:pointer; transition:transform .25s ease, box-shadow .25s ease, background-color .25s ease, color .25s ease;
  white-space:nowrap;
}
.btn-sm{ padding:.65rem 1.3rem; font-size:.85rem; }
.btn-primary{ background:var(--blue-500); color:#fff; box-shadow:0 12px 24px -10px rgba(47,111,237,.7); }
.btn-primary:hover{ background:var(--blue-400); transform:translateY(-2px); }
.btn-outline{ background:transparent; color:var(--ink-050); border-color:rgba(255,255,255,.35); }
.btn-outline:hover{ background:rgba(255,255,255,.1); transform:translateY(-2px); }
.btn-dark{ background:var(--navy-900); color:#fff; }
.btn-dark:hover{ background:var(--navy-700); transform:translateY(-2px); }
.btn-block{ width:100%; }

.eyebrow{
  display:inline-flex; align-items:center; gap:.6rem; font-size:.78rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:var(--blue-400); margin-bottom:1rem;
}
.eyebrow::before{ content:''; width:28px; height:2px; background:var(--blue-400); display:inline-block; }
.section-head{ max-width:720px; margin-bottom:3rem; }
.section-head.center{ margin-inline:auto; text-align:center; }
.section-head h2{ font-size:clamp(1.8rem,3.2vw,2.6rem); color:var(--navy-900); }
.section-head p{ color:var(--gray-600); font-size:1.05rem; }
.on-dark .section-head h2{ color:#fff; }
.on-dark .section-head p{ color:var(--slate-300); }

/* ---------- Location bar (above the header) ----------
   Fixed height (not padding-derived) so .site-header's `top` and every
   page's hero/section padding-top — which clear the fixed header by a
   hardcoded rem value — can offset against one known number. Hidden
   below 768px (same breakpoint the hero padding-top overrides use) so
   the header collapses back to top:0 and none of those mobile values
   need their own adjustment. */
.location-bar{
  position:fixed; inset-inline:0; top:0; z-index:201; height:38px;
  background:var(--navy-950); border-bottom:1px solid var(--border-dark);
  display:flex; align-items:center; overflow:hidden;
}
.location-bar .container{ display:flex; align-items:center; gap:.9rem; }
.location-bar-label{
  flex:none; font-size:.66rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
  color:var(--slate-500);
}
/* Marquee: .location-bar-track clips to the row; .location-bar-marquee is
   two copies of the same list placed side by side (width:max-content) and
   scrolled left by exactly half its own width, so the moment the first
   copy has fully scrolled off, the second is in the exact position the
   first started in — a seamless loop with no jump or gap. The duplicate
   copy is aria-hidden since it's a purely visual repeat of the first.
   The seam gap lives on the <ul> itself (margin-right), not as a `gap`
   on .location-bar-marquee between the two copies — a gap here would
   make each copy's true width (content + its share of the gap) not
   divide evenly into 50% of the total, so the translateX(-50%) loop
   would land half a gap short each cycle: a visible stutter/jump at
   every repeat instead of a clean loop. */
.location-bar-track{
  flex:1; min-width:0; overflow:hidden;
  mask-image:linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
}
.location-bar-marquee{
  display:flex; width:max-content;
  animation:location-marquee 38s linear infinite;
}
.location-bar-track:hover .location-bar-marquee{ animation-play-state:paused; }
@media (prefers-reduced-motion:reduce){
  .location-bar-marquee{ animation:none; }
}
.location-bar ul{
  display:flex; flex-wrap:nowrap; list-style:none; margin:0; padding:0; gap:0 1.1rem; margin-right:1.1rem;
  font-size:.74rem; font-weight:600; color:var(--slate-300); letter-spacing:.02em; white-space:nowrap;
}
.location-bar li + li::before{ content:'\00b7'; margin-right:1.1rem; color:var(--slate-500); }
@keyframes location-marquee{
  from{ transform:translateX(0); }
  to{ transform:translateX(-50%); }
}
@media (max-width:768px){
  .location-bar{ display:none; }
  .site-header{ top:0 !important; }
}

/* ---------- Header ---------- */
.site-header{
  position:fixed; inset-inline:0; top:38px; z-index:200;
  padding:1.1rem 0;
  /* Kept solid (not transparent-over-hero) now that the hero is bright —
     the nav's white text/logo need a dark backdrop regardless of scroll
     position, since it can no longer borrow contrast from a dark photo. */
  background:rgba(6,14,30,.94);
  /* No backdrop-filter here: at 94% opacity it added negligible visible
     blur, but *any* filter/backdrop-filter on this ancestor turns it into
     the containing block for position:fixed descendants — which broke the
     mobile nav overlay (#mainNav), clipping its fullscreen background to
     this header's own ~70px box instead of the viewport. */
  transition:background-color .35s ease, box-shadow .35s ease, padding .35s ease;
}
.site-header.scrolled{
  background:rgba(6,14,30,.86);
  box-shadow:0 10px 30px -18px rgba(0,0,0,.6);
  padding:.7rem 0;
}
/* Homepage only: the hero is a dark video with a wash overlay, so the
   header can safely start transparent and blend into it — unlike every other page,
   where the "always solid" rule above still applies because the header
   can't assume what's behind it. Scrolling past the hero still lands on
   the shared .scrolled rule above, same solid navy as everywhere else. */
.is-home .site-header:not(.scrolled){
  background:linear-gradient(180deg, rgba(5,11,22,.55), rgba(5,11,22,0));
  box-shadow:none;
}
.header-inner{ display:flex; align-items:center; justify-content:space-between; gap:1.5rem; }

/* flex-shrink:0 — a flex row that runs out of room shrinks whichever
   children it can; without this the logo (a replaced element, unlike the
   nowrap nav text beside it) is what gives, silently collapsing toward
   0 width instead of the row visibly overflowing. */
.brand{ display:flex; align-items:center; gap:.7rem; flex-shrink:0; }
.brand-logo{ height:48px; width:auto; display:block; }
.brand-logo-footer{ height:56px; width:auto; }
/* Simple inline lockup — no background card/tag treatment. Kept modest
   (not the full .container gutter-eating width a taller logo would need)
   so there's still visible breathing space from the edge on narrow
   screens, which the previous vertical-logo treatment lost. */
.brand-logo-header{ height:52.5px; width:auto; } /* 42px + 25% */

/* Inline AITS wordmark image standing in for the literal word "AITS"
   inside a heading — sized off font-size (em) so it scales with the
   heading's own responsive clamp() instead of a fixed px value, and
   nudged down slightly since image baselines sit lower than text. */
.aits-inline-logo{
  display:inline-block; height:.85em; width:auto; vertical-align:baseline;
  margin:0 .06em;
}

.main-nav ul{ display:flex; gap:2rem; white-space:nowrap; }
.main-nav a{
  color:var(--ink-100); font-size:.82rem; font-weight:600; letter-spacing:.04em; text-transform:uppercase;
  position:relative; padding:.3rem 0;
}
/* Between the mobile hamburger breakpoint and full desktop width, the nav
   has grown to 8 items and needs tighter spacing to avoid wrapping. */
@media (max-width:1400px){
  .main-nav ul{ gap:1.1rem; }
  .main-nav a{ font-size:.74rem; }
}
.main-nav a::after{
  content:''; position:absolute; left:0; bottom:-2px; width:0; height:2px; background:var(--blue-400);
  transition:width .25s ease;
}
.main-nav a:hover::after,
.main-nav a.active::after{ width:100%; }
.main-nav a.active{ color:#fff; }

.header-actions{ display:flex; align-items:center; gap:1rem; }
.header-actions .btn-primary{ letter-spacing:.04em; text-transform:uppercase; font-size:.78rem; }
.nav-toggle{
  display:none; flex-direction:column; justify-content:center; gap:5px; width:38px; height:38px;
  background:rgba(255,255,255,.08); border:1px solid var(--border-dark); border-radius:0; cursor:pointer;
  position:relative; z-index:160; /* above .main-nav's fixed overlay (150) so it stays clickable to close */
}
.nav-toggle span{ height:2px; background:#fff; margin-inline:8px; border-radius:0; transition:transform .3s ease, opacity .3s ease; }
.nav-toggle.open span:nth-child(1){ transform:translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2){ opacity:0; }
.nav-toggle.open span:nth-child(3){ transform:translateY(-7px) rotate(-45deg); }

/* ---------- Hero / parallax sections ---------- */
.parallax-section{ position:relative; overflow:hidden; }
.hero{
  position:relative; overflow:hidden; color:#fff;
  min-height:92vh; display:flex; align-items:center;
  padding-top:11.5rem; padding-bottom:8rem;
}
/* Fixed (not vh-relative) so every subpage hero renders at the exact same
   height regardless of how much its heading/subtitle text wraps — sized to
   comfortably fit the longest current heading (investors, 3 lines) plus
   subtitle and buttons, with headroom to spare. */
.hero.hero-compact{ min-height:800px; padding-top:12.5rem; padding-bottom:6rem; }

.parallax-bg{
  position:absolute; inset:-15% 0; background-size:cover; background-position:center;
  will-change:transform; z-index:0;
}
/* Directory hero only: the standard -15% overscan inflates this element's
   height by 30% for parallax safety, which (since this particular photo's
   own aspect ratio is close to the hero box's) forces `cover` into a much
   tighter horizontal crop than the box actually needs — a smaller overscan
   still comfortably clears this section's max ~22px parallax offset
   (speed 0.22) while letting `cover` show noticeably more of the photo. */
.parallax-bg-relaxed{ inset:-5% 0; }
.section-overlay{ position:absolute; inset:0; z-index:1; }
/* ---------- Hero background treatment: "the contrast" ----------
   Was "the fade" — a gradient that lightened toward the bottom until it
   nearly matched the body background, so the photo blended seamlessly
   into the page below it. To revert to that, swap this rule back to:
     background:
       radial-gradient(60% 55% at 12% 15%, rgba(76,141,255,.28), transparent 70%),
       linear-gradient(180deg, rgba(255,255,255,.5) 0%, rgba(234,242,255,.82) 45%, rgba(246,249,255,.97) 100%);
   ...and also revert the "the contrast" text-color companions below:
   .hero{ color:var(--navy-900); }, .hero-eyebrow{ background:var(--navy-900);
   border-color:rgba(255,255,255,.12); box-shadow:0 8px 18px -8px rgba(8,19,42,.45); },
   .hero .subtitle{ color:var(--gray-600); }, .hero .subtitle b/strong{ color:var(--navy-900); },
   and restore the .hero .btn-outline dark-text override (removed below,
   since the base .btn-outline is already styled for a dark background). */
.overlay-hero{ background:rgba(5,11,22,.55); }
.overlay-dark{ background:linear-gradient(120deg, rgba(5,11,22,.92), rgba(10,22,48,.86)); }
.overlay-navy-fade{ background:linear-gradient(180deg, rgba(8,19,42,.4), var(--navy-900) 90%); }

/* Homepage hero: video background, no dark wash — text sits on its own
   glass card instead so it stays legible against whatever's playing
   behind it. (Used to be the second of two slides in a hero slider;
   the first slide — direct-on-video text with a dark wash — was removed,
   and this became the only hero treatment.) */
.hero-text-card{
  background:rgba(255,255,255,.5); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px);
  border:1px solid rgba(255,255,255,.6); border-radius:0;
  /* Fixed, not clamp(vw) — container-query units below measure this
     card's own content-box (after padding), so a padding value that
     itself moved with viewport width would make the heading's "available
     width" wobble independently of the card's actual size, undermining
     the whole point of querying it. */
  padding:2.4rem; max-width:640px; box-shadow:var(--shadow-lg);
  /* .hero h1's font-size clamp below scales off the viewport (vw) — a fair
     stand-in for full-bleed text, but wrong for this card: its
     640px cap means the text's *actual* available width shrinks out of
     step with the viewport as the card itself narrows, so vw-based sizing
     doesn't shrink enough and the heading wraps further than it "expects",
     growing taller than the hero has room for. Querying the card's own
     width instead ties the heading's size to the space it truly has. */
  container-type:inline-size;
}
/* .hero prefix (3 classes) rather than just .hero-text-card (2) — matches
   the established pattern below for out-specificity-ing .hero h1/.hero
   .subtitle regardless of source order, since these two rules are equal
   specificity to those and would otherwise lose to whichever comes later
   in the file (confirmed empirically: without the prefix this rule had
   zero effect — .hero h1's vw-based size was winning outright). */
.hero .hero-text-card h1{ font-size:clamp(1.7rem, 10.5cqi, 4.2rem); }
.hero .hero-text-card .subtitle{ font-size:clamp(.92rem, 3.6cqi, 1.25rem); }
/* The card is always its own light glass panel regardless of which hero
   background recipe (.overlay-hero) is currently active, so its text
   keeps dark-on-light styling independent of "the fade" vs "the
   contrast" — this stays correct under either. Prefixed with .hero so
   these out-specificity the general .hero .subtitle/.btn-outline rules
   further down regardless of source order (equal-specificity selectors
   would otherwise lose to whichever comes later in the file). */
.hero .hero-text-card{ color:var(--navy-900); }
.hero .hero-text-card .hero-eyebrow{
  background:var(--navy-900); border-color:rgba(255,255,255,.12);
  box-shadow:0 8px 18px -8px rgba(8,19,42,.45);
}
.hero .hero-text-card .subtitle{ color:var(--gray-600); }
.hero .hero-text-card .subtitle b, .hero .hero-text-card .subtitle strong{ color:var(--navy-900); }
.hero .hero-text-card .btn-outline{ color:var(--navy-900); border-color:rgba(16,23,40,.3); }
.hero .hero-text-card .btn-outline:hover{ background:rgba(16,23,40,.06); }

.hero .container{ position:relative; z-index:2; }
.hero-eyebrow{
  display:inline-flex; align-items:center; gap:.6rem; font-size:.8rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase; color:#fff;
  background:var(--blue-500); border:1px solid rgba(255,255,255,.2);
  padding:.5rem 1.1rem; border-radius:0; margin-bottom:1.6rem;
  box-shadow:0 8px 20px -8px rgba(47,111,237,.65);
}
.hero h1{
  font-size:clamp(2.4rem, 5.2vw, 4.2rem); max-width:15ch; margin-bottom:.4em;
}
.hero-compact h1{ max-width:21ch; }

.hero .subtitle{
  font-size:clamp(1rem,1.6vw,1.25rem); color:var(--slate-300); max-width:52ch; margin-bottom:2.2rem;
  font-weight:400;
}
.hero .subtitle b, .hero .subtitle strong{ color:#fff; }
/* Every page header except the homepage's uses .hero-compact — white
   reads more legibly against their photo/overlay combinations than the
   slightly-dimmed slate-300 the homepage hero uses. */
.hero-compact .subtitle{ color:#fff; }
.hero-ctas{ display:flex; gap:1rem; flex-wrap:wrap; }
/* Base rule — previously only .cta-banner .btn-row had gap/flex, so every
   other .btn-row (Convening the Ecosystem, etc.) rendered with no spacing
   at all between buttons. Same gap as .hero-ctas so button spacing reads
   consistently sitewide. */
.btn-row{ display:flex; gap:1rem; flex-wrap:wrap; }
/* No dark-text override here for "the contrast" — the base .btn-outline
   (transparent + light border/text) already suits a dark hero. See the
   .hero-text-card override above for slide 2's light-card exception. */
.hero-scroll-cue{
  position:absolute; bottom:calc(var(--stat-overlap) + 1.6rem); left:50%; transform:translateX(-50%); z-index:5;
  display:flex; flex-direction:column; align-items:center; gap:.5rem; color:var(--slate-300);
  font-size:.72rem; letter-spacing:.14em; text-transform:uppercase;
}
.hero-scroll-cue span{
  width:1px; height:34px; background:linear-gradient(var(--blue-400), transparent);
  animation:scrollcue 1.8s ease-in-out infinite;
}
@keyframes scrollcue{ 0%{ transform:scaleY(.3); opacity:.4; } 50%{ transform:scaleY(1); opacity:1; } 100%{ transform:scaleY(.3); opacity:.4; } }

/* ---------- Overlapping stat / feature band ---------- */
.stat-band{
  position:relative; z-index:6; margin-top:calc(-1 * var(--stat-overlap));
}
.stat-card{
  background:rgba(255,255,255,.78); backdrop-filter:blur(18px); -webkit-backdrop-filter:blur(18px);
  border:1px solid var(--border-light); border-radius:0;
  box-shadow:var(--shadow-lg);
  display:grid; grid-template-columns:repeat(4,1fr);
}
.stat-card .stat{
  padding:2.2rem 1.5rem; text-align:center; border-right:1px solid var(--border-light);
}
.stat-card .stat:last-child{ border-right:none; }
.stat-num{
  font-family:var(--font-serif); font-size:clamp(1.8rem,3vw,2.6rem); color:var(--navy-900); font-weight:var(--font-serif-weight);
  display:block;
}
.stat-num .suffix{ color:var(--blue-500); }
.stat-label{ color:var(--gray-600); font-size:.85rem; margin-top:.35rem; }

/* ---------- Overlap grid (The Chamber / What We Do) ---------- */
.overlap-grid{
  position:relative; z-index:5; display:grid; grid-template-columns:1.15fr 1fr; gap:2rem;
  align-items:stretch;
}
.panel{
  border-radius:0; padding:2.6rem; height:100%;
  display:flex; flex-direction:column;
}
.panel-dark{ background:var(--navy-900); color:var(--ink-100); box-shadow:var(--shadow-md); }
.panel-dark h3{ color:#fff; }
.panel-dark p{ color:var(--slate-300); }
.panel-glass{
  background:rgba(13,24,49,.9); color:#fff; box-shadow:var(--shadow-lg);
  border:1px solid var(--border-dark);
}
.panel-link{
  display:inline-flex; align-items:center; gap:.5rem; color:var(--blue-300); font-weight:600; margin-top:1rem;
}
.panel-link svg{ width:16px; height:16px; transition:transform .25s ease; }
.panel-link:hover svg{ transform:translateX(4px); }

/* Chamber panel: real photo background with a dark gradient wash so copy stays legible */
.panel-photo{
  position:relative; overflow:hidden; min-height:420px; justify-content:flex-end;
  background-size:cover; background-position:center;
}
.panel-photo::before{
  content:''; position:absolute; inset:0;
  background:linear-gradient(180deg, rgba(5,11,22,.35) 0%, rgba(6,13,26,.75) 55%, rgba(5,11,22,.96) 100%);
}
.panel-photo > *{ position:relative; z-index:1; }
.panel-photo .eyebrow{ color:var(--blue-300); }

/* What We Do: spacious vertical list instead of a cramped icon grid */
.pillar-mini-list{ display:flex; flex-direction:column; gap:1.5rem; margin-top:1.4rem; flex-grow:1; }
.pillar-mini{ display:flex; gap:1rem; align-items:flex-start; }
.pillar-mini .icon-chip{ flex:none; }
.pillar-mini h5{ font-size:1rem; margin:0 0 .3rem; color:#fff; }
.pillar-mini p{ font-size:.88rem; color:var(--slate-400); margin:0; line-height:1.5; }
.icon-chip{
  width:44px; height:44px; border-radius:0; display:flex; align-items:center; justify-content:center;
  background:rgba(76,141,255,.15); color:var(--blue-300);
}
.icon-chip svg{ width:22px; height:22px; }

/* ---------- Generic image wrap w/ fallback gradient ---------- */
.img-wrap{
  position:relative; overflow:hidden; background:linear-gradient(135deg, var(--navy-700), var(--navy-900));
}
.img-wrap img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; }

/* ---------- Light content sections ---------- */
.section{ padding:6rem 0; }
.section-tight{ padding:4rem 0; }
.bg-surface{ background:var(--surface); }
.bg-surface-alt{ background:var(--surface-alt); }
.bg-paper{ background:var(--paper); }
.bg-navy{ background:var(--navy-900); color:var(--ink-100); }
.bg-navy-grad{ background:linear-gradient(160deg, var(--navy-950), var(--navy-800)); color:var(--ink-100); }

.two-col{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(2rem,5vw,5rem); align-items:center; }
.two-col.reverse{ direction:rtl; }
.two-col.reverse > *{ direction:ltr; }

/* Statement banner: bold headline + supporting paragraph, e.g. the
   homepage "Advancing Economic Competitiveness" block. */
.statement-v2 h2{
  font-family:var(--font-sans); font-weight:800; text-transform:none;
  font-size:clamp(1.9rem, 3.4vw, 2.9rem); line-height:1.15; letter-spacing:-.01em;
  color:var(--navy-900); margin-bottom:1.2rem;
}
.statement-v2 h2 .accent{ color:var(--blue-500); }
.statement-v2 p{ color:var(--gray-600); font-size:1.05rem; max-width:46ch; }
.stat-mini-row{ display:flex; gap:2.2rem; margin:2rem 0; flex-wrap:wrap; }

/* ---------- Our Impact: click-to-play video cards ---------- */
.video-grid{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(1.5rem,3vw,2.5rem); }
.video-card{
  position:relative; background:#fff; border-radius:0; overflow:hidden;
  box-shadow:var(--shadow-md);
}
.video-card video{ display:block; width:100%; aspect-ratio:16/9; object-fit:cover; background:var(--navy-900); }
/* Native <video> ships with no `controls` attribute — this button is the
   only way to start playback, per the click-to-play requirement. It sits
   over the whole frame (full click target, not just the icon) and steps
   out of the way via pointer-events once playing so a second click can
   reach the video underneath to toggle pause (see main.js). */
.video-play-btn{
  position:absolute; top:0; left:0; right:0; aspect-ratio:16/9;
  display:flex; align-items:center; justify-content:center;
  background:rgba(8,19,42,.32); border:0; padding:0; cursor:pointer;
  transition:opacity .25s ease, background .25s ease;
}
.video-play-btn:hover{ background:rgba(8,19,42,.44); }
.video-play-btn-icon{
  width:74px; height:74px; border-radius:50%; display:flex; align-items:center; justify-content:center;
  background:rgba(255,255,255,.14); backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  border:1.5px solid rgba(255,255,255,.75); transition:transform .25s ease, background .25s ease;
}
.video-play-btn:hover .video-play-btn-icon{ transform:scale(1.08); background:rgba(255,255,255,.24); }
.video-play-btn-icon svg{ width:24px; height:24px; color:#fff; margin-left:3px; }
.video-card.has-started .video-play-btn{ opacity:0; pointer-events:none; }
.video-card-info{ padding:1.4rem 1.6rem 1.6rem; }
.video-card-info h4{ color:var(--navy-900); margin-bottom:.5rem; }
.video-card-info p{ color:var(--gray-600); font-size:.92rem; margin:0; }
@media (max-width:820px){ .video-grid{ grid-template-columns:1fr; } }
.stat-mini{ }
.stat-mini .num{ font-family:var(--font-serif); font-size:2.1rem; color:var(--blue-500); font-weight:var(--font-serif-weight); }
.stat-mini .label{ font-size:.85rem; color:var(--gray-600); }
.on-dark .stat-mini .num{ color:var(--blue-300); }
.on-dark .stat-mini .label{ color:var(--slate-300); }

.feature-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:1.6rem; }
.feature-grid.cols-2{ grid-template-columns:repeat(2,1fr); }
.feature-grid.cols-3{ grid-template-columns:repeat(3,1fr); }
.feature-card{
  background:#fff; border:1px solid var(--border-light); border-radius:0;
  padding:2rem 1.7rem; box-shadow:0 1px 0 rgba(16,23,40,.03);
  transition:transform .35s ease, box-shadow .35s ease, border-color .35s ease;
}
.feature-card:hover{ transform:translateY(-6px); box-shadow:var(--shadow-md); border-color:transparent; }
.feature-card .icon-chip{ background:rgba(47,111,237,.1); color:var(--blue-500); margin-bottom:1.2rem; }
.feature-card h4{ font-size:1.08rem; color:var(--navy-900); }
.feature-card p{ color:var(--gray-600); font-size:.92rem; margin:0; }
.feature-card .step-num{
  font-family:var(--font-serif); font-size:.85rem; color:var(--blue-500); font-weight:var(--font-serif-weight); letter-spacing:.05em;
}

.on-dark .feature-card{ background:rgba(255,255,255,.05); border-color:var(--border-dark); }
.on-dark .feature-card h4{ color:#fff; }
.on-dark .feature-card p{ color:var(--slate-300); }
.on-dark .feature-card .icon-chip{ background:rgba(76,141,255,.16); color:var(--blue-300); }

/* Photo-topped variant — same card, a representative photo above the copy
   instead of (or in addition to) an icon, for grids where a photo exists. */
.feature-card--photo{ padding:0; overflow:hidden; }
.feature-card--photo .feature-card-photo{
  aspect-ratio:16/10; background-size:cover; background-position:center;
}
.feature-card--photo .feature-card-body{ padding:1.6rem 1.7rem 1.9rem; }
.feature-card--photo .icon-chip{ margin-top:-2.6rem; margin-bottom:1rem; position:relative; z-index:1; box-shadow:0 8px 18px -8px rgba(8,19,42,.35); }
.on-dark .feature-card--photo .icon-chip{ background:var(--navy-800); }

/* Numbered pillar list (What We Do) */
.pillar-list{ display:flex; flex-direction:column; gap:0; }
.pillar-row{
  display:grid; grid-template-columns:110px 1fr; gap:2rem; padding:2.6rem 0; border-top:1px solid var(--border-light);
}
.pillar-row:last-child{ border-bottom:1px solid var(--border-light); }
.pillar-row .index{ font-family:var(--font-serif); font-size:2.6rem; color:var(--blue-500); opacity:.5; font-weight:var(--font-serif-weight); }
.pillar-row h3{ font-size:1.4rem; color:var(--navy-900); margin-bottom:.5rem; }
.pillar-row p{ color:var(--gray-600); max-width:65ch; }
.chip-list{ display:flex; flex-wrap:wrap; gap:.6rem; margin-top:1rem; }
.chip{
  font-size:.82rem; font-weight:600; color:var(--blue-500); background:rgba(47,111,237,.08);
  padding:.4rem .9rem; border-radius:0;
}
.chip-muted{ color:var(--gray-600); background:rgba(16,23,40,.06); }
/* Same three colors as the map pins/legend (--status-*), so a zone's
   status reads the same wherever it appears. */
.chip-status{ color:#fff; }
.chip-status-operational{ background:var(--status-operational); }
.chip-status-under-development{ background:var(--status-development); }
.chip-status-planned{ background:var(--status-planned); }

/* ---------- Directory (search/filter toolbar, zone grid, pagination) ---------- */
.btn-outline-dark{ background:transparent; color:var(--navy-900); border-color:rgba(16,23,40,.25); }
.btn-outline-dark:hover{ background:rgba(16,23,40,.05); transform:translateY(-2px); }

.directory-stats{
  display:flex; flex-wrap:wrap; gap:.5rem 1.6rem; color:var(--gray-600); font-size:.92rem;
  margin-bottom:1.6rem;
}
.directory-stats strong{ color:var(--navy-900); font-weight:700; }
.directory-caveat{ color:var(--gray-600); font-size:.82rem; max-width:75ch; margin-top:2rem; }
.directory-load-more{ display:flex; justify-content:center; margin-top:2.6rem; }

.directory-toolbar{
  display:grid; grid-template-columns:repeat(auto-fill, minmax(170px, 1fr)); gap:1.2rem; align-items:end;
  background:#fff; border:1px solid var(--border-light); border-radius:0;
  padding:1.8rem; box-shadow:0 1px 0 rgba(16,23,40,.03); margin-bottom:1.6rem;
}
.directory-search-group{ grid-column:span 3; }
/* Without this, a <select> full of long country/sector names keeps its
   track at that min-content width even after the toolbar collapses to a
   single column on narrow screens, forcing the whole page into horizontal
   scroll. */
.directory-toolbar > *{ min-width:0; }
.directory-toolbar select{ max-width:100%; }
.directory-toolbar-actions{ display:flex; gap:.7rem; }
.directory-toolbar-actions .btn{ white-space:nowrap; }
.directory-result-count{ color:var(--gray-600); font-size:.92rem; margin-bottom:1.6rem; }

/* ---------- Search autocomplete ---------- */
.directory-autocomplete{ position:relative; width:100%; }
.directory-autocomplete input{ width:100%; text-transform:capitalize; }
.directory-autocomplete-list{
  position:absolute; top:calc(100% + .4rem); left:0; right:0; z-index:20;
  background:#fff; border:1px solid var(--border-light); border-radius:0;
  box-shadow:var(--shadow-md); list-style:none; margin:0; padding:.4rem; max-height:280px; overflow-y:auto;
}
.directory-autocomplete-list li{
  display:flex; align-items:center; justify-content:space-between; gap:.8rem;
  padding:.6rem .7rem; border-radius:0; cursor:pointer; font-size:.92rem;
}
.directory-autocomplete-list li:hover, .directory-autocomplete-list li.is-active{ background:var(--surface); }
.directory-autocomplete-name{ color:var(--navy-900); font-weight:600; }
.directory-autocomplete-country{ color:var(--gray-600); font-size:.82rem; flex:none; }

/* ---------- Directory map ---------- */
.directory-map-card{
  border-radius:0; overflow:hidden; margin-bottom:2rem;
  border:1px solid var(--border-light); box-shadow:0 1px 0 rgba(16,23,40,.03);
}
.directory-map-legend{
  display:flex; flex-wrap:wrap; gap:1.4rem; align-items:center;
  padding:.9rem 1.4rem; background:#fff; border-top:1px solid var(--border-light);
  font-size:.82rem; color:var(--gray-600);
}
.directory-map-legend span{ display:inline-flex; align-items:center; gap:.5rem; }
.directory-map-swatch{ width:12px; height:12px; border-radius:50%; display:inline-block; flex:none; }
/* Fluid height: scales with viewport width between a usable floor and a
   sensible ceiling, instead of a fixed px height that's cramped on phones
   or absurdly tall on ultra-wide monitors. Also user-resizable (drag the
   handle in the bottom-right corner) — directory-map.js calls Leaflet's
   invalidateSize() whenever that resize happens. */
.directory-map{
  width:100%; height:clamp(352px, 46.2vw, 572px);
  resize:vertical; overflow:auto; min-height:220px; max-height:90vh;
}
.directory-map-empty{
  display:flex; align-items:center; justify-content:center; height:100%;
  min-height:320px; background:var(--surface-alt); color:var(--gray-600);
  font-size:.95rem; text-align:center; padding:2rem;
}
/* The [hidden] attribute is how JS toggles this on/off across AJAX
   searches — without this override, .directory-map-empty's own
   display:flex above (higher specificity than the UA stylesheet's
   [hidden]{display:none}) would keep it visible regardless. */
.directory-map-empty[hidden]{ display:none; }
/* Content inside a Leaflet hover tooltip — the bubble chrome (rounded
   box, pointer) is Leaflet's default (.leaflet-tooltip), restyled below
   to match the site instead of Leaflet's plain-white default; this inner
   markup is ours. */
.leaflet-tooltip{
  background:#fff; border:1px solid var(--border-light); border-radius:0;
  box-shadow:var(--shadow-md); padding:.7rem .9rem; opacity:1 !important;
}
.leaflet-tooltip-top:before{ border-top-color:#fff; }
.map-tooltip{ font-family:var(--font-sans); max-width:200px; }
.map-tooltip .map-tooltip-chip{
  display:inline-block; font-size:.68rem; font-weight:700; letter-spacing:.06em; text-transform:uppercase;
  color:var(--blue-500); margin-bottom:.3rem;
}
.map-tooltip h4{ font-family:var(--font-sans); font-size:.95rem; color:var(--navy-900); margin:0 0 .2rem; font-weight:700; }
.map-tooltip p{ font-size:.82rem; color:var(--gray-600); margin:0 0 .4rem; }
.map-tooltip .map-tooltip-cta{ font-size:.8rem; font-weight:600; color:var(--blue-500); }
.leaflet-container{ font-family:var(--font-sans); }

/* Gear-badge marker (echoes the gear in the Chamber's logo) replacing
   Leaflet's default teardrop pin. Deliberately kept circular — the one
   exception to the sitewide sharp-corner rule, since a round pin/badge is
   the standard, expected convention for a map marker. */
.zone-marker-badge{
  width:30px; height:30px; border-radius:50%; background:var(--blue-500);
  border:2px solid #fff; box-shadow:0 2px 8px rgba(8,19,42,.4);
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  transition:transform .15s ease;
}
.zone-marker-badge:hover{ transform:scale(1.12); }
/* Colored by the zone's real-world lifecycle status, not the brand blue —
   reads at a glance across a map with dozens of pins. Same three colors
   reused by .chip-status-* below so the color language matches everywhere
   a zone's status appears (map, cards, modal, detail page). */
.zone-marker-badge.is-operational{ background:var(--status-operational); }
.zone-marker-badge.is-under-development{ background:var(--status-development); }
.zone-marker-badge.is-planned{ background:var(--status-planned); }
.map-tooltip-status{ font-size:.78rem; font-weight:600; color:var(--gray-600); margin:-.2rem 0 .4rem; }

/* ---------- Zone details modal ---------- */
.zone-modal-backdrop{
  position:fixed; inset:0; z-index:300; background:rgba(5,11,22,.6);
  display:flex; align-items:center; justify-content:center; padding:1.5rem;
  opacity:0; visibility:hidden; transition:opacity .2s ease, visibility .2s;
}
.zone-modal-backdrop.is-open{ opacity:1; visibility:visible; }
.zone-modal{
  position:relative; background:#fff; border-radius:0; box-shadow:var(--shadow-lg);
  width:100%; max-width:620px; max-height:85vh; overflow-y:auto;
  padding:2.4rem; transform:translateY(12px); transition:transform .2s ease;
}
.zone-modal-backdrop.is-open .zone-modal{ transform:translateY(0); }
.zone-modal-close{
  position:absolute; top:1.2rem; right:1.2rem; width:36px; height:36px; border-radius:0;
  border:1px solid var(--border-light); background:var(--surface); color:var(--navy-900);
  font-size:1.4rem; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.zone-modal-close:hover{ background:var(--surface-alt); }
.zone-modal-loading, .zone-modal-error{ color:var(--gray-600); text-align:center; padding:2rem 0; }
.zone-modal-header .chip{ margin-bottom:.8rem; }
.zone-modal-header h3{ font-size:clamp(1.4rem,3vw,1.8rem); color:var(--navy-900); margin-bottom:.2rem; }
.zone-modal-sector{ color:var(--blue-500); font-weight:600; margin-bottom:1.4rem; }
.zone-modal-section h4{ font-family:var(--font-sans); font-size:.78rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--gray-600); margin-bottom:.5rem; }
.zone-modal-section p{ color:var(--gray-600); font-size:.98rem; margin-bottom:1.4rem; }
.zone-modal-details{ display:grid; gap:.9rem; margin-bottom:1.6rem; padding-top:.4rem; border-top:1px solid var(--border-light); }
.zone-modal-detail-row{ display:flex; gap:.6rem; font-size:.92rem; }
.zone-modal-detail-row dt{ color:var(--gray-600); flex:none; width:90px; font-weight:600; }
.zone-modal-detail-row dd{ margin:0; color:var(--navy-900); }
.zone-modal-detail-row a{ color:var(--blue-500); font-weight:600; }
.zone-modal-actions{ display:flex; gap:.8rem; flex-wrap:wrap; }

.zone-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.6rem; }
.zone-card{
  display:flex; flex-direction:column; background:#fff; border:1px solid var(--border-light);
  border-radius:0; padding:1.8rem; box-shadow:0 1px 0 rgba(16,23,40,.03);
  transition:transform .3s ease, box-shadow .3s ease, border-color .3s ease;
}
.zone-card:hover{ transform:translateY(-6px); box-shadow:var(--shadow-md); border-color:transparent; }
.zone-card-top{ display:flex; gap:.5rem; flex-wrap:wrap; margin-bottom:1rem; }
.zone-card h3{ font-size:1.2rem; color:var(--navy-900); margin-bottom:.3rem; }
.zone-card-sector{ font-size:.85rem; font-weight:600; color:var(--blue-500); margin-bottom:.7rem; }
.zone-card-excerpt{ color:var(--gray-600); font-size:.92rem; flex-grow:1; }

.empty-state{
  text-align:center; padding:4rem 2rem; background:var(--surface-alt); border-radius:0;
}
.empty-state h3{ color:var(--navy-900); margin-bottom:.5rem; }
.empty-state p{ color:var(--gray-600); margin-bottom:1.4rem; }

.pagination{ display:flex; justify-content:center; align-items:center; gap:.5rem; margin-top:2.6rem; flex-wrap:wrap; }
.pagination-page, .pagination-arrow{
  display:flex; align-items:center; justify-content:center; width:40px; height:40px;
  border-radius:0; font-weight:600; font-size:.9rem; color:var(--gray-600);
  border:1px solid var(--border-light); transition:background-color .2s ease, color .2s ease, border-color .2s ease;
}
.pagination-page:hover, .pagination-arrow:hover{ background:rgba(47,111,237,.08); color:var(--blue-500); border-color:transparent; }
.pagination-page.is-active{ background:var(--blue-500); color:#fff; border-color:transparent; }

/* Logo / partner grid */
.partner-grid{ display:grid; grid-template-columns:repeat(6,1fr); gap:1.1rem; }
.partner-chip{
  display:flex; align-items:center; justify-content:center; text-align:center; padding:1.4rem 1rem;
  background:rgba(255,255,255,.04); border:1px solid var(--border-dark); border-radius:0;
  color:var(--slate-300); font-weight:600; font-size:.82rem; min-height:74px;
  transition:transform .3s ease, color .3s ease, border-color .3s ease;
}
.partner-chip:hover{ transform:translateY(-4px); color:#fff; border-color:var(--blue-400); }

.partner-logo-card{
  display:flex; align-items:center; justify-content:center; min-height:96px; padding:1.3rem 1.2rem;
  background:#fff; border-radius:0; border:1px solid var(--border-dark);
  transition:transform .3s ease, box-shadow .3s ease; position:relative;
  color:inherit; text-decoration:none; /* neutralize default <a> styling where a card is now a link */
}
.partner-logo-card:hover{ transform:translateY(-5px); box-shadow:var(--shadow-md); }
.partner-logo-card img{
  max-height:44px; max-width:100%; width:auto; object-fit:contain; margin:0 auto;
}
/* A couple of partner marks (e.g. IEID) read as illegibly small at the
   standard 44px cap — this modifier gives them more room without
   resizing the whole grid. */
.partner-logo-card-lg img{ max-height:64px; }
.partner-logo-card .partner-fallback{
  display:none; font-size:.78rem; font-weight:600; color:var(--navy-900); text-align:center; line-height:1.3;
}
.partner-logo-card img.broken + .partner-fallback{ display:block; }
.partner-logo-card img.broken{ display:none; }

/* Tier / pricing cards */
.tier-grid{ display:grid; grid-template-columns:repeat(5,1fr); gap:1.4rem; align-items:stretch; }
.tier-card{
  background:#fff; border:1px solid var(--border-light); border-radius:0;
  padding:2rem 1.5rem; display:flex; flex-direction:column; box-shadow:0 1px 0 rgba(16,23,40,.03);
  transition:transform .35s ease, box-shadow .35s ease;
}
.tier-card:hover{ transform:translateY(-8px); box-shadow:var(--shadow-md); }
.tier-card.featured{ background:var(--navy-900); color:#fff; border-color:var(--navy-900); }
.tier-card.featured h3, .tier-card.featured .tier-tag{ color:#fff; }
.tier-card.featured p, .tier-card.featured li{ color:var(--slate-300); }
.tier-tag{ font-size:.72rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--blue-500); margin-bottom:.6rem; }
.tier-card h3{ font-size:1.25rem; color:var(--navy-900); margin-bottom:.5rem; }
.tier-card p{ color:var(--gray-600); font-size:.88rem; flex-grow:0; }
.tier-card ul{ margin:1.2rem 0; display:flex; flex-direction:column; gap:.6rem; flex-grow:1; }
.tier-card li{ display:flex; gap:.55rem; font-size:.85rem; color:var(--gray-600); align-items:flex-start; }
.tier-card li svg{ width:16px; height:16px; flex:none; margin-top:.15rem; color:var(--blue-500); }
.tier-card.featured li svg{ color:var(--blue-300); }

/* Steps (Investors path) */
.step-track{ position:relative; display:grid; grid-template-columns:repeat(4,1fr); gap:1.6rem; }
.step-track::before{
  content:''; position:absolute; top:34px; left:8%; right:8%; height:1px;
  background:repeating-linear-gradient(90deg, var(--border-dark) 0 8px, transparent 8px 16px);
}
.step-item{ position:relative; text-align:left; }
.step-circle{
  width:68px; height:68px; border-radius:0; background:var(--navy-800); border:1px solid var(--blue-500);
  display:flex; align-items:center; justify-content:center; font-family:var(--font-serif); font-size:1.4rem;
  color:var(--blue-300); margin-bottom:1.2rem; position:relative; z-index:1;
}

/* Quote / mission block */
.quote-block{
  border-left:3px solid var(--blue-500); padding-left:1.6rem; margin:1.6rem 0;
  font-family:var(--font-serif); font-size:1.3rem; color:var(--navy-900); font-style:italic;
}
.on-dark .quote-block{ color:#fff; }

/* Governance / value cards */
.value-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:1.6rem; }

/* Form (Contact) */
/* min-width:0 on the grid items: without it, a 1fr/auto track still grows
   to fit its content's min-content width (e.g. a long unbreakable email
   address), which can exceed the grid's own container on narrow screens
   and push the whole layout into horizontal scroll. */
.contact-grid{ display:grid; grid-template-columns:.85fr 1.15fr; gap:clamp(2rem,4vw,4rem); }
.contact-grid > *{ min-width:0; }
.form-card{
  background:#fff; border-radius:0; padding:clamp(1.6rem,3vw,2.6rem); box-shadow:var(--shadow-md);
  border:1px solid var(--border-light);
}
.form-row{ display:grid; grid-template-columns:1fr 1fr; gap:1.2rem; margin-bottom:1.2rem; }
.form-group{ display:flex; flex-direction:column; gap:.5rem; margin-bottom:1.2rem; }
.form-group label{ font-size:.85rem; font-weight:600; color:var(--navy-900); }
.form-group input, .form-group select, .form-group textarea{
  border:1px solid var(--border-light); border-radius:0; padding:.85rem 1rem; font-family:var(--font-sans);
  font-size:.95rem; background:var(--surface); transition:border-color .25s ease, box-shadow .25s ease;
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus{
  outline:none; border-color:var(--blue-500); box-shadow:0 0 0 4px rgba(47,111,237,.15); background:#fff;
}
.contact-info-card{
  background:var(--navy-900); color:#fff; border-radius:0; padding:clamp(1.8rem,3vw,2.6rem);
  display:flex; flex-direction:column; gap:1.6rem; height:100%;
}
.contact-info-card .info-row{ display:flex; gap:1rem; align-items:flex-start; }
.contact-info-card h4{ color:#fff; margin-bottom:.2rem; font-size:1.05rem; }
.contact-info-card p, .contact-info-card a{ color:var(--slate-300); font-size:.92rem; overflow-wrap:anywhere; }
.contact-info-card a:hover{ color:#fff; }
.form-note{
  background:rgba(47,111,237,.08); border:1px dashed rgba(47,111,237,.4); border-radius:0;
  padding:1rem 1.2rem; font-size:.85rem; color:var(--navy-900); margin-top:1rem;
}
.info-row-caveat{ display:block; font-size:.78rem; color:var(--slate-400); margin-top:.2rem; }

/* ---------- Zone detail page: key facts + single-pin map ---------- */
.zone-key-facts{ margin:0; padding-left:1.3rem; color:var(--gray-600); font-size:.98rem; }
.zone-key-facts li{ margin-bottom:.6rem; }
.zone-map-card{
  border-radius:0; overflow:hidden; margin-top:1rem;
  border:1px solid var(--border-light); box-shadow:0 1px 0 rgba(16,23,40,.03);
}
.zone-map{ width:100%; height:340px; }

/* ---------- Gallery ---------- */
.gallery-filter{ display:flex; flex-wrap:wrap; gap:.7rem; margin-bottom:2rem; }
.gallery-filter-pill{
  display:inline-flex; align-items:center; padding:.55rem 1.2rem; border-radius:0;
  font-size:.86rem; font-weight:600; color:var(--gray-600); background:#fff;
  border:1px solid var(--border-light); transition:background-color .2s ease, color .2s ease, border-color .2s ease;
}
.gallery-filter-pill:hover{ border-color:var(--blue-400); color:var(--blue-500); }
.gallery-filter-pill.is-active{ background:var(--navy-900); color:#fff; border-color:var(--navy-900); }

.gallery-load-more{ display:flex; justify-content:center; margin-top:2.6rem; }
.gallery-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:1.1rem; }
.gallery-tile{
  position:relative; aspect-ratio:4/3; border-radius:0; overflow:hidden;
  border:none; padding:0; cursor:pointer; background:var(--navy-800);
}
.gallery-tile img{ width:100%; height:100%; object-fit:cover; transition:transform .5s ease; }
.gallery-tile:hover img{ transform:scale(1.06); }
.gallery-tile-overlay{
  position:absolute; inset:0; display:flex; flex-direction:column; justify-content:flex-end; gap:.2rem;
  padding:1rem; text-align:left;
  background:linear-gradient(180deg, transparent 40%, rgba(5,11,22,.82) 100%);
  opacity:0; transition:opacity .25s ease;
}
.gallery-tile:hover .gallery-tile-overlay, .gallery-tile:focus-visible .gallery-tile-overlay{ opacity:1; }
.gallery-tile-category{ font-size:.68rem; font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--blue-300); }
.gallery-tile-caption{ font-size:.85rem; color:#fff; font-weight:600; }

.gallery-lightbox{
  position:fixed; inset:0; z-index:400; background:rgba(5,11,22,.92);
  display:flex; align-items:center; justify-content:center; padding:2rem;
}
/* JS toggles the [hidden] attribute to open/close — without this override
   the class's own display:flex above (higher specificity than the UA
   stylesheet's [hidden]{display:none}) would keep it visible regardless. */
.gallery-lightbox[hidden]{ display:none; }
.gallery-lightbox-figure{ max-width:min(90vw, 1100px); max-height:88vh; display:flex; flex-direction:column; gap:1rem; }
.gallery-lightbox-figure img{ max-height:72vh; width:auto; max-width:100%; margin-inline:auto; border-radius:0; }
.gallery-lightbox-figure figcaption{ text-align:center; color:var(--slate-300); }
.gallery-lightbox-category{ display:block; font-size:.72rem; font-weight:700; letter-spacing:.1em; text-transform:uppercase; color:var(--blue-300); margin-bottom:.3rem; }
.gallery-lightbox-close{
  position:absolute; top:1.4rem; right:1.4rem; width:44px; height:44px; border-radius:0;
  background:rgba(255,255,255,.1); border:1px solid var(--border-dark); color:#fff;
  font-size:1.6rem; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
}
.gallery-lightbox-close:hover{ background:rgba(255,255,255,.18); }
.gallery-lightbox-arrow{
  position:absolute; top:50%; transform:translateY(-50%); width:52px; height:52px; border-radius:0;
  background:rgba(255,255,255,.08); border:1px solid var(--border-dark); color:#fff; cursor:pointer;
  display:flex; align-items:center; justify-content:center;
}
.gallery-lightbox-arrow:hover{ background:rgba(255,255,255,.18); }
.gallery-lightbox-arrow svg{ width:22px; height:22px; }
.gallery-lightbox-prev{ left:1.4rem; }
.gallery-lightbox-next{ right:1.4rem; }

/* ---------- Zone media (per-zone photos/videos, zone.php) — reuses the
   .gallery-tile / .gallery-lightbox classes above for visual consistency
   with the site Gallery; these two rules are the only zone-media-specific
   additions needed (video play-button overlay, and video iframe sizing
   in the lightbox, since the rules above only ever sized an <img>). ---------- */
.zone-media-video-tile{ background:var(--navy-800); }
.zone-media-play{
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center; pointer-events:none;
}
.zone-media-play svg{ width:56px; height:56px; filter:drop-shadow(0 6px 14px rgba(5,11,22,.45)); }
.gallery-lightbox-figure iframe{
  width:min(90vw, 1100px); aspect-ratio:16/9; height:auto; border:0; margin-inline:auto; border-radius:0;
}

/* ---------- Homepage video hero + "Chamber in Pictures" strip ---------- */
.hero-video{
  position:absolute; inset:-15% 0; width:100%; height:130%; object-fit:cover; z-index:0;
}
.picture-strip{ display:grid; grid-template-columns:repeat(6,1fr); gap:.9rem; }
.picture-strip-tile{ aspect-ratio:1/1; border-radius:0; overflow:hidden; }
.picture-strip-tile img{ width:100%; height:100%; object-fit:cover; transition:transform .4s ease; }
.picture-strip-tile:hover img{ transform:scale(1.08); }

/* ---------- Homepage showcase strip (big edge-to-edge photography,
   linking straight into Directory / Gallery / Opportunities) ---------- */
.showcase{ display:grid; grid-template-columns:repeat(2,1fr); }
.showcase-tile{ position:relative; display:block; aspect-ratio:16/9; overflow:hidden; }
.showcase-tile img{ width:100%; height:100%; object-fit:cover; transition:transform .6s cubic-bezier(.2,.8,.2,1); }
.showcase-tile:hover img{ transform:scale(1.05); }
.showcase-tile::before{
  content:''; position:absolute; inset:0;
  background:linear-gradient(0deg, rgba(5,11,22,.82) 0%, transparent 45%);
}
.showcase-cap{ position:absolute; left:1.8rem; right:1.8rem; bottom:1.8rem; z-index:2; color:#fff; }
.showcase-cap .tag{
  font-size:.7rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:var(--blue-300); display:block; margin-bottom:.5rem;
}
.showcase-cap h4{ font-family:var(--font-sans); font-size:1.35rem; font-weight:700; color:#fff; margin:0; }
.showcase-plus{
  position:absolute; top:1.8rem; right:1.8rem; z-index:2; width:30px; height:30px; color:#fff;
  opacity:0; transition:opacity .3s ease;
}
.showcase-tile:hover .showcase-plus{ opacity:1; }
@media (max-width:900px){ .showcase{ grid-template-columns:1fr; } .showcase-tile{ aspect-ratio:16/10; } }

/* ---------- Dark, bordered icon-grid variant of the pillar/feature
   cards — edge-divided cells instead of individually boxed cards. ---------- */
.icon-grid-dark{ background:var(--navy-900); color:#fff; }
.service-row{
  display:grid; grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--border-dark); border-left:1px solid var(--border-dark);
}
.service-cell{
  padding:2.6rem 2rem; border-right:1px solid var(--border-dark); border-bottom:1px solid var(--border-dark);
}
.service-cell .icon-chip{ margin-bottom:1.6rem; }
.service-cell h4{ font-size:1.02rem; color:#fff; margin-bottom:.7rem; }
.service-cell p{ font-size:.9rem; color:var(--slate-300); margin:0; }
@media (max-width:1100px){ .service-row{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:600px){ .service-row{ grid-template-columns:1fr; } }

/* ---------- Full-bleed photo CTA (homepage "Join the Chamber"),
   replacing a boxed banner card with a big, edge-to-edge moment. ---------- */
.cta-fullwidth{
  position:relative; min-height:60vh; display:flex; align-items:center; justify-content:flex-start;
  text-align:left; color:#fff; overflow:hidden;
}
.cta-fullwidth-bg{ position:absolute; inset:0; background-size:cover; background-position:center; }
.cta-fullwidth-bg::after{
  content:''; position:absolute; inset:0;
  background:radial-gradient(60% 70% at 80% 20%, rgba(76,141,255,.28), transparent 60%), rgba(5,11,22,.8);
}
.cta-fullwidth-inner{
  position:relative; z-index:2; max-width:720px; padding-inline:var(--gutter);
  /* Section is full-bleed (no .container), so its own padding alone would
     leave text flush near the viewport edge on wide screens instead of
     lining up with .container's left content edge. Add back the extra
     margin .container gets from being centered at --container-w. */
  margin-left:max(0px, calc((100% - var(--container-w)) / 2));
}
.cta-fullwidth h2{ color:#fff; }
.cta-fullwidth p{ color:var(--slate-300); font-size:1.05rem; }

/* ---------- Footer ---------- */
/* Dark navy footer (Elevare reference): brand+tagline and the link columns
   sit side by side in one left-aligned row, not stacked/centered. */
.site-footer{
  position:relative; overflow:hidden;
  background:linear-gradient(160deg, var(--navy-950), var(--navy-800)); color:var(--slate-300); padding-top:5rem;
}
/* Watermark emblem — upper-right, behind everything (z-index below the
   footer's own content stacking), sized off the footer's own height so it
   scales with however tall the content makes the footer. Positioned past
   the right edge by 30% of its own width so roughly that much is clipped
   by .site-footer's overflow:hidden, per spec ("show ~70%, hide the
   rest off the right"). Low opacity + no pointer-events so it never
   competes with or blocks real footer content. */
.footer-watermark{
  /* top+bottom (not height:%) so it reliably stretches to the footer's
     actual rendered height even though .site-footer's own height is
     auto/content-driven — a %-height on an abspos child doesn't resolve
     against an auto-height containing block, but top+bottom does (the
     used height is solved from the containing block's box either way). */
  position:absolute; top:4%; bottom:4%; right:0; width:auto;
  /* translate (not `right:` with a percentage) so the 30% shift is
     relative to the image's own rendered width, not the footer's —
     pushes 30% of it past the edge, where overflow:hidden clips it. */
  transform:translateX(30%);
  opacity:.06; pointer-events:none; user-select:none; z-index:0;
}
.footer-top, .footer-bottom{ position:relative; z-index:1; }
/* Head Office gets extra share (and Explore gives some back) so the
   africa.office@economiczoneschamber.com address — a single unbreakable
   token — has room to sit on one line instead of wrapping mid-word. */
/* Five columns: brand (wider, carries the office/contact block too so the
   four link columns beside it can all stay the same 3-4 item length
   instead of one long "Site" column and one short "Head Office" one). */
.footer-top{ display:grid; grid-template-columns:1.6fr repeat(4,1fr); gap:2.5rem; padding-bottom:3rem; }
/* Below ~1280px, drop to 2 columns with brand spanning the full row on
   top and the four link columns flowing 2x2 beneath it — brand no longer
   needs extra share once it's not sharing a row with the link columns. */
@media (max-width:1279px){
  .footer-top{ grid-template-columns:1fr 1fr; }
  .footer-brand{ grid-column:1 / -1; }
}
@media (max-width:700px){
  .footer-top{ grid-template-columns:1fr; }
}
.footer-brand .brand{ margin-bottom:1.1rem; }
.footer-brand p{ color:var(--slate-300); font-size:.92rem; max-width:34ch; }
.footer-sdg{ font-size:.78rem; letter-spacing:.05em; text-transform:uppercase; color:var(--blue-300); font-weight:600; }
.footer-col h4{ font-family:var(--font-sans); color:#fff; font-size:.85rem; letter-spacing:.08em; text-transform:uppercase; margin-bottom:1rem; }
.footer-col ul{ display:flex; flex-direction:column; gap:.7rem; font-size:.92rem; }
.footer-col a{ color:var(--slate-300); overflow-wrap:anywhere; }
.footer-col a:hover{ color:var(--blue-300); }
.footer-bottom{
  border-top:1px solid var(--border-dark); padding:1.6rem var(--gutter); display:flex; justify-content:space-between;
  font-size:.82rem; color:var(--slate-400); flex-wrap:wrap; gap:.5rem;
}
.footer-oneline{ font-family:var(--font-serif); font-style:italic; color:var(--slate-400); }

/* ---------- Event announcement modal (homepage, managed from Admin) ----------
   The dialog has no explicit width/height of its own — it shrink-wraps
   the image via the flex centering below, and the image scales down by
   max-width/max-height together (not width:100%+height:auto, which
   ignored the height cap and forced a scrollbar). That's the fix for
   "no scrollbar" as much as the max-height value is. */
.event-modal{
  position:fixed; inset:0; z-index:500; display:flex; align-items:center; justify-content:center;
  padding:3rem; opacity:0; pointer-events:none; transition:opacity .3s ease;
}
.event-modal.is-open{ opacity:1; pointer-events:auto; }
.event-modal-backdrop{ position:absolute; inset:0; background:rgba(5,11,22,.82); backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); }
.event-modal-dialog{
  position:relative; z-index:1; max-width:min(600px, 92vw); max-height:88vh;
  display:flex; box-shadow:var(--shadow-lg); transform:scale(.96); transition:transform .3s ease;
}
.event-modal.is-open .event-modal-dialog{ transform:scale(1); }
.event-modal-dialog a{ display:flex; }
.event-modal-dialog img{
  display:block; max-width:100%; max-height:88vh; width:auto; height:auto; object-fit:contain;
}
/* Fully clear of the dialog's corner (not just half-overlapping it), so
   it reads as a separate control sitting outside the image. */
.event-modal-close{
  position:absolute; top:-22px; right:-22px; width:44px; height:44px; border-radius:50%;
  background:#fff; color:var(--navy-900); border:0; display:flex; align-items:center; justify-content:center;
  cursor:pointer; box-shadow:var(--shadow-md); z-index:2;
}
.event-modal-close svg{ width:20px; height:20px; }

/* ---------- Scroll to top ----------
   Hidden by default and revealed by main.js past a scroll threshold, via
   .is-visible (not [hidden]) so opacity/transform can transition in
   rather than snapping abruptly. */
.scroll-top-btn{
  position:fixed; right:1.6rem; bottom:1.6rem; z-index:190;
  width:48px; height:48px; border-radius:0; border:1px solid var(--border-dark);
  background:rgba(8,19,42,.9); backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
  color:#fff; cursor:pointer; display:flex; align-items:center; justify-content:center;
  box-shadow:var(--shadow-md);
  opacity:0; visibility:hidden; transform:translateY(10px);
  transition:opacity .25s ease, transform .25s ease, visibility .25s, background-color .25s ease;
}
.scroll-top-btn.is-visible{ opacity:1; visibility:visible; transform:translateY(0); }
.scroll-top-btn:hover{ background:var(--blue-500); }
.scroll-top-btn svg{ width:20px; height:20px; }
@media (max-width:768px){
  .scroll-top-btn{ right:1.1rem; bottom:1.1rem; width:42px; height:42px; }
}

/* ---------- Scroll reveal ----------
   Reveal is opt-in via html.js (set by an early inline script in <head>)
   so content stays fully visible if JavaScript is unavailable/blocked. */
html.js .reveal{ opacity:0; transform:translateY(28px); transition:opacity .8s cubic-bezier(.2,.7,.2,1), transform .8s cubic-bezier(.2,.7,.2,1); }
html.js .reveal.is-visible{ opacity:1; transform:translateY(0); }
.reveal-delay-1{ transition-delay:.1s; }
.reveal-delay-2{ transition-delay:.2s; }
.reveal-delay-3{ transition-delay:.3s; }
.reveal-delay-4{ transition-delay:.4s; }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width:1100px){
  .stat-card{ grid-template-columns:repeat(2,1fr); }
  .stat-card .stat:nth-child(2){ border-right:none; }
  .stat-card .stat:nth-child(3), .stat-card .stat:nth-child(4){ border-top:1px solid var(--border-light); }
  .overlap-grid{ grid-template-columns:1fr; }
  .panel-photo{ min-height:320px; }
  .tier-grid{ grid-template-columns:repeat(3,1fr); }
  .partner-grid{ grid-template-columns:repeat(3,1fr); }
  .feature-grid{ grid-template-columns:repeat(2,1fr); }
  .zone-grid{ grid-template-columns:repeat(2,1fr); }
  .directory-toolbar{ grid-template-columns:1fr 1fr; }
  .directory-toolbar-actions{ grid-column:1 / -1; }
  .gallery-grid{ grid-template-columns:repeat(3,1fr); }
  .picture-strip{ grid-template-columns:repeat(3,1fr); }
}

@media (max-width:900px){
  .two-col{ grid-template-columns:1fr; }
  .two-col.reverse{ direction:ltr; }
  .two-col .img-wrap{ order:-1; aspect-ratio:16/10; }
  .contact-grid{ grid-template-columns:1fr; }
  .value-grid{ grid-template-columns:1fr 1fr; }
  .step-track{ grid-template-columns:1fr 1fr; row-gap:2.4rem; }
  .step-track::before{ display:none; }
}

/* The desktop nav (7 links + logo + CTA button, all non-wrapping) needs
   roughly 1030px of header width to fit without the browser silently
   shrinking something to make room — measured empirically, not guessed:
   below this the logo (the only flex child without flex-shrink:0) was
   found shrinking toward 0 width well before the row would ever visibly
   overflow. The hamburger has to take over above the visual-mobile
   breakpoint below, with headroom, rather than exactly at it. */
@media (max-width:1080px){
  .main-nav{
    position:fixed; inset:0; top:0; background:rgba(5,11,22,.98); backdrop-filter:blur(10px);
    display:flex; align-items:center; justify-content:center;
    /* auto, not visible: in landscape on a phone (~375-414px tall) 7 links
       at this gap/font-size are taller than the screen — without scroll
       the lowest links render off-screen with no way to reach them. */
    overflow-y:auto; padding-block:2rem;
    opacity:0; visibility:hidden; transform:translateY(-12px);
    transition:opacity .3s ease, transform .3s ease, visibility .3s;
    z-index:150;
  }
  .main-nav.open{ opacity:1; visibility:visible; transform:translateY(0); }
  .main-nav ul{ flex-direction:column; gap:1.6rem; text-align:center; margin:auto; }
  .main-nav a{ font-size:1.4rem; font-family:var(--font-serif); }
  .header-actions .btn-primary{ display:none; }
  .nav-toggle{ display:flex; }
}
/* Short viewports (landscape phones) get tighter nav spacing so the menu
   fits without scrolling in the common case, instead of relying on the
   scroll fallback above for every phone in landscape. */
@media (max-width:1080px) and (max-height:500px){
  .main-nav ul{ gap:.9rem; }
  .main-nav a{ font-size:1.15rem; }
}

@media (max-width:768px){
  /* Smaller stat cards need less of a pull-up on narrow screens — arrows
     and the scroll cue read this same variable so they stay clear of it
     automatically instead of needing their own position overrides here. */
  :root{ --stat-overlap:46px; }

  .hero{ min-height:80vh; padding-top:7.5rem; }
  .hero.hero-compact{ min-height:680px; padding-top:7.5rem; padding-bottom:3rem; }
  .stat-card{ grid-template-columns:1fr 1fr; }
  .tier-grid{ grid-template-columns:1fr 1fr; }
  .partner-grid{ grid-template-columns:1fr 1fr; }
  .feature-grid{ grid-template-columns:1fr; }
  .feature-grid.cols-3{ grid-template-columns:1fr; }
  .zone-grid{ grid-template-columns:1fr; }
  .gallery-grid{ grid-template-columns:repeat(2,1fr); }
  .picture-strip{ grid-template-columns:repeat(2,1fr); }
  .gallery-lightbox-figure img{ max-height:60vh; }
  .gallery-lightbox-arrow{ width:40px; height:40px; }
  .gallery-lightbox-prev{ left:.5rem; }
  .gallery-lightbox-next{ right:.5rem; }
  .directory-toolbar{ grid-template-columns:1fr; }
  .pillar-row{ grid-template-columns:1fr; gap:.6rem; }
  .form-row{ grid-template-columns:1fr; }
  .value-grid{ grid-template-columns:1fr; }
}

@media (max-width:520px){
  .stat-card{ grid-template-columns:1fr; }
  .stat-card .stat{ border-right:none !important; border-top:1px solid var(--border-light); }
  .stat-card .stat:first-child{ border-top:none; }
  .tier-grid{ grid-template-columns:1fr; }
  .partner-grid{ grid-template-columns:1fr 1fr; }
  .hero-ctas{ flex-direction:column; align-items:stretch; }
  .btn-row{ flex-direction:column; }
}
