/* CanAsia Custom Theme — canasia.css
  Last updated: September 4, 2026
   Layout/visual rules only. Every colour, font, and radius value below reads
   from colors_and_type.css's role layer — never a hardcoded hex or px
   figure lifted straight from the live page. See that file for what each
   role means and which values are still open decisions.
*/

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-weight: var(--fw-regular);
  line-height: 1.6;
  min-height: 100vh;
  display: flex;
  overflow-x: hidden;
  flex-direction: column;
}

/* Gutters. This was `padding-inline: 0`, so every .container -- the topbar,
   the footer, the 404, the boarding pass -- ran flush to the viewport edge on
   anything narrower than 1200px. The max-width absorbs the padding so the
   *content* still caps at exactly --wrap-max, staying aligned with the
   homepage sections, which set their own gutters a different way. */
.container {
  max-width: calc(var(--wrap-max) + var(--sp-24) * 2);
  margin-inline: auto;
  padding-inline: var(--sp-24);
}

/* Title / H1 / H2 / H3 default — Veneer everywhere. VeneerThree ships as a
   single 400-weight face; any bold is browser fake-bold synthesis, which
   fills the texture cracks. See colors_and_type.css and llms.txt.
   h3 added Sept 5, 2026 — it previously had no shared baseline at all, so
   six different component rules each hand-set their own font-family/
   text-transform/line-height for "h3", drifting slightly (line-height .9,
   .98, 1, 1.1, 1.15 depending which one you looked at). Individual rules
   below now only need to set size/colour/margin. */
h1, h2, h3, .title, .h1, .h2, .h3 {
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  text-transform: uppercase;
  line-height: .9;
  letter-spacing: 0;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--bg-inverse);
  color: var(--fg-on-dark);
  padding: var(--sp-12) var(--sp-20);
  z-index: 1000;
}
.skip-link:focus { left: 0; }

/* ── Top bar ──────────────────────────────────────────────────────────── */

.topbar {
  background: var(--bg-raised);
  padding-block: var(--sp-16);
  position: relative;
  z-index: 100;
}
.topbar__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-32);
}
body.home .topbar--overlay {
  position: fixed;
  inset: 0 0 auto;
  background: transparent;
  width: 100%;
}
body.home .topbar--overlay.topbar--scrolled { background: var(--bg-inverse); }
body.home .topbar__menu a { color: var(--fg-on-dark); }
body.home .topbar__cta { background: var(--canasia-cta); color: var(--fg); }
body.home .topbar__cta:hover { background: var(--canasia-cta-tint); }
.topbar__logo-link {
  color: var(--fg);
  text-decoration: none;
  font-size: var(--type-label);
  font-weight: var(--fw-bold);
}
.topbar__logo-link img { width: 210px; max-width: 30vw; display: block; }
.topbar__nav { display: flex; align-items: center; margin-left: auto; }
.topbar__menu,
.site-footer__menu { display: flex; align-items: center; gap: var(--sp-32); list-style: none; margin: 0; padding: 0; }
.topbar__menu { gap: var(--sp-24); }
.topbar__menu a,
.site-footer__menu a,
.topbar__cta,
.hero__primary-cta,
.hero__secondary-cta { font-size: var(--type-label); text-transform: uppercase; letter-spacing: .04em; }
/* Rollover is a colour change only — elegant/simple, no filled chip
   background. On the dark home overlay, shift to sky; on a light interior
   topbar, shift to the brand blue. Both already pass contrast on their
   surface (sky on navy 10:1; primary blue on white/cream comfortably AA). */
body.home .topbar__menu a:hover,
body.home .topbar__menu a:focus-visible { color: var(--canasia-sky); text-decoration: none; }
.topbar__menu a:hover,
.topbar__menu a:focus-visible { color: var(--canasia-primary); text-decoration: none; }
.topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--sp-16);
  white-space: nowrap;
}

/* Topbar socials. The language switcher used to sit here and now lives only
   in the footer. Same outlined-circle idea as the footer's, sized down so it
   doesn't crowd the CTA beside it.

   The topbar renders on two very different grounds -- a transparent overlay
   on the dark hero for the home page, an opaque white bar everywhere else --
   so the icons invert per context rather than being fixed one way. */
.topbar__social { display: inline-flex; align-items: center; gap: var(--sp-8); list-style: none; margin: 0; padding: 0; }
.topbar__social a { display: grid; place-items: center; width: 34px; height: 34px; border: 1px solid var(--border-strong); border-radius: var(--radius-pill); transition: border-color var(--dur-std) var(--ease-standard), background-color var(--dur-std) var(--ease-standard); }
.topbar__social img { display: block; width: 16px; height: 16px; opacity: .75; transition: opacity var(--dur-std) var(--ease-standard); }
.topbar__social a:hover { border-color: var(--canasia-cta); background: var(--canasia-cta-tint); }
.topbar__social a:hover img { opacity: 1; }
.topbar__social a:focus-visible { outline: 2px solid var(--canasia-primary); outline-offset: 3px; }
/* On the home overlay the bar is transparent over the dark hero: white icons,
   a cream hairline, and no tinted fill on hover (a light chip would punch a
   hole in the hero). */
body.home .topbar__social a { border-color: var(--border-on-dark); }
body.home .topbar__social img { filter: brightness(0) invert(1); }
body.home .topbar__social a:hover { border-color: var(--canasia-cta); background: rgba(255, 131, 172, .14); }
body.home .topbar__social a:focus-visible { outline-color: var(--canasia-sky); }
.topbar__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: var(--fg);
  color: var(--bg-raised);
  border-radius: var(--radius-pill);
  padding: 10px 20px;
  text-decoration: none;
  font-family: var(--font-display);
  font-size: var(--type-label);
  font-weight: var(--fw-regular);
  text-transform: uppercase;
  letter-spacing: .08em;
  line-height: 1.2;
  white-space: nowrap;
}
.topbar__actions .topbar__cta { gap: 0; padding: 8px 14px; }
.topbar__actions { display: inline-flex; align-items: center; gap: var(--sp-16); }
.topbar__cta:hover { background: var(--canasia-primary); }
.topbar__menu a,
.site-footer__menu a,
.topbar__cta { text-decoration: none !important; }
.topbar__toggle { display: none; }
.primary-menu-open { overflow: hidden; }
.topbar__menu a,
.site-footer__menu a {
  color: var(--fg);
  text-decoration: none;
}
.topbar__menu a {
  display: inline-flex;
  padding: var(--sp-8) var(--sp-12);
  /* Same face + size as the buttons (Veneer, --type-label), not Inter —
     was inheriting the body font, so nav read as a different, more generic
     typeface than everything else in the topbar. Letter-spacing matched to
     .topbar__cta's .08em too — the shared selector above still says .04em,
     so this was quietly tracked tighter than the button next to it. */
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  letter-spacing: .08em;
  transition: color var(--dur-std) var(--ease-standard);
}
.topbar__contact {
  color: var(--fg-on-dark);
  font-size: var(--type-label);
  text-decoration: none;
}
.topbar__contact:hover { text-decoration: underline; }

@media (max-width: 1024px) {
  .topbar__menu { gap: 16px; }
  .topbar__actions { gap: 12px; }
  .topbar__cta { padding-inline: 16px; }
}

@media (max-width: 760px) {
  /* VeneerThree's distressing is drawn at a fixed scale, so shrinking a
     heading doesn't shrink the speckle -- at mobile sizes it stops reading as
     texture and starts competing with the letterforms. The clean cut of the
     same family keeps the shapes and drops the grain. One token swap, so
     every Veneer heading follows without touching a single component. */
  :root { --font-display: "Veneer Clean", "Veneer", "Helvetica Neue", Arial, sans-serif; }
  .topbar { padding-block: var(--sp-24); }
  .topbar__logo-link img { width: 190px; max-width: 62vw; }
  .topbar__actions { display: none; }
  .topbar__nav {
    position: fixed;
    /* Was a hardcoded 76px, which never matched the real topbar (84px, and
       taller again since the mobile padding bump) -- so a strip of the page
       showed through above the open menu. --topbar-h is measured from the
       element itself in header.php; the 76px is only a pre-JS fallback. */
    inset: var(--topbar-h, 76px) 0 0;
    z-index: 90;
    display: block;
    /* Fixed inset sizes against the layout viewport, which on a phone can be
       taller than what's actually visible once the browser's address bar is
       showing -- the bottom of the menu (last link, or extra items on a
       longer menu) could render below the real fold with no way to reach it.
       max-height + overflow-y:auto guarantees every item stays reachable by
       scrolling within the menu itself, whatever the real device does. */
    max-height: calc(100dvh - var(--topbar-h, 76px));
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    background: var(--bg-inverse);
    padding: var(--sp-40) var(--sp-24);
    transform: translateY(-110%);
    transition: transform 220ms ease;
  }
  .primary-menu-open .topbar__nav { transform: translateY(0); }
  .topbar__menu { display: grid; gap: var(--sp-24); }
  /* --type-h1 used to be a tiny, orphaned 20-26px token, which happened to
     work here by accident. Now that it's a real 36-60px page-title size,
     a mobile menu link needs its own appropriately-sized reference. */
  .topbar__menu a { color: var(--fg-on-dark); font-family: var(--font-display); font-size: var(--type-h3); }
  .topbar__toggle {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    padding: 10px;
    border: 1px solid var(--border-strong, var(--border));
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--fg-on-dark);
  }
  .topbar__toggle img { width: 24px; height: 24px; filter: brightness(0); }
  body.home .topbar__toggle img { filter: brightness(0) invert(1); }
}

.eyebrow {
  font-size: var(--type-micro);
  font-weight: var(--fw-bold);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--canasia-primary);
  margin: 0;
}
/* Light-surface eyebrows use deep primary blue for AA contrast on cream;
   dark-surface eyebrows use sky. */
.home-section-eyebrow,
.trade-circuit__eyebrow,
.boarding-pass__eyebrow { color: var(--canasia-primary); }
.eyebrow--on-dark { color: var(--canasia-sky); }
.eyebrow--small { color: var(--canasia-sky); }

.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-16); margin-top: var(--sp-32); }
.hero__secondary-cta { color: var(--fg-on-dark); border: 1px solid var(--fg-muted); border-radius: var(--radius-pill); padding: 10px 20px; text-decoration: none; font-family: var(--font-display); font-weight: var(--fw-regular); text-transform: uppercase; letter-spacing: .08em; line-height: 1.2; }
.hero__secondary-cta:hover { background: var(--fg-on-dark); border-color: var(--fg-on-dark); color: var(--bg-inverse); }
/* ── Scroll-driven window ─────────────────────────────────────────────── */

.window-scroll { position: relative; height: 520vh; background: var(--bg-inverse); }
.window-stage { position: sticky; top: 0; height: 100svh; min-height: 620px; overflow: hidden; background: var(--bg-inverse); }
.window-glass,
.window-frame,
.window-top-fade,
.window-bottom { position: absolute; inset: 0; }
.window-glass { z-index: 1; overflow: hidden; }
.window-view { position: absolute; inset: -7%; background: var(--view-image) center / cover no-repeat; opacity: 0; transform: scale(1.14); will-change: opacity, transform; }
.window-view:first-child { opacity: 1; }
.window-clouds { position: absolute; inset: -4%; z-index: 10; background: url('assets-photos/window-views/sky-clouds.jpg') 8% 50% / 160% auto no-repeat; opacity: .35; pointer-events: none; }
.window-vignette { position: absolute; inset: 0; z-index: 11; background: radial-gradient(120% 100% at 50% 38%, transparent 52%, rgba(9,25,34,.28) 100%); pointer-events: none; }
.window-frame { z-index: 3; width: 100%; height: 100%; object-fit: cover; pointer-events: none; }
.window-top-fade { z-index: 4; inset: 0 0 auto; height: 240px; background: linear-gradient(180deg, rgba(6,19,27,.7), rgba(6,19,27,.32) 55%, transparent); pointer-events: none; }
.window-bottom { z-index: 5; display: flex; align-items: flex-end; justify-content: space-between; gap: var(--sp-32); padding: 120px max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)) var(--sp-56); background: linear-gradient(180deg, transparent, rgba(6,19,27,.48) 34%, rgba(6,19,27,.78) 70%, rgba(6,19,27,.88)); }
.window-copy { flex: 1 1 320px; max-width: 760px; min-width: 0; display: flex; flex-direction: column; gap: var(--sp-16); }
.window-heading { margin: 0; color: var(--fg-on-dark); font-family: var(--font-display); font-size: var(--type-display); font-weight: var(--fw-regular); line-height: .82; text-transform: uppercase; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
.window-caption { flex: 0 1 auto; max-width: 360px; display: flex; flex-direction: column; gap: 10px; align-items: flex-start; text-align: left; }
.window-label { margin: 0; color: var(--fg-on-dark); font-family: var(--font-display); font-size: var(--type-h3); line-height: 1.1; }
.window-meta { margin: 0; color: var(--canasia-sky); font-size: var(--type-micro); font-weight: var(--fw-black); letter-spacing: .14em; }
.window-dots { display: flex; gap: 7px; padding-top: 8px; }
.window-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fg-on-dark-muted); }
.window-dot.is-active { background: var(--fg-on-dark); }
.window-caption small { color: var(--fg-on-dark-muted); font-size: var(--type-micro); padding-top: 4px; }
.about-project,
.about-context,
.program-marketplace,
.delegations-partners { padding-block: var(--sp-80); }
.home-section-eyebrow { margin: 0; color: var(--canasia-primary); font-family: var(--font-mono); font-size: var(--type-micro); font-weight: var(--fw-bold); letter-spacing: .18em; line-height: 1.25; text-transform: uppercase; }
.home-section-eyebrow,
.home-section-eyebrow:first-child,
.home-section-eyebrow:last-child { color: var(--canasia-primary); font-family: var(--font-mono); font-size: var(--type-micro); font-weight: var(--fw-bold); letter-spacing: .18em; line-height: 1.25; text-transform: uppercase; }
.about-project h2,
.about-context h2,
.program-marketplace h2,
.delegations-partners h2 { margin-top: var(--sp-16); }
/* Section 03 sits on the light alternating band with the rest of the page.
   The stage panels keep the drawn, unfilled treatment -- so their interior
   is now cream, which is why the headings below are deep blue rather than
   sky: sky on cream is ~1.6:1 and fails AA. See llms.txt "Rendering notes
   (do not drift)" rule 1. The eyebrow needs no override here for the same
   reason -- the shared .home-section-eyebrow rule is already deep blue. */
.program-marketplace { padding: var(--sp-80) var(--sp-24); background: var(--bg-alt); color: var(--fg); }
.program-marketplace > *,
.delegations-partners > * { max-width: var(--wrap-max); margin-inline: auto; }
.program-marketplace__intro { max-width: var(--wrap-max); }
/* NOTE ON CASE: VeneerThree is a caps-only face -- it has no lowercase
   glyphs. `text-transform: none` on a Veneer heading therefore changed
   nothing; the text rendered as caps either way, and the declaration only
   made the CSS claim something untrue. Those declarations are gone, so the
   shared h1/h2/h3 `text-transform: uppercase` now applies here as everywhere
   else, and the CSS says what actually renders.

   This also makes the fallback correct: if Veneer fails to load, `uppercase`
   keeps the design intent, where `none` would have dropped to sentence case
   and looked broken. Content stays sentence-cased in ACF -- which is right,
   because screen readers announce the stored text, not the transformed
   glyphs. */
.program-marketplace__intro h2 { margin: var(--sp-16) 0 var(--sp-24); font-family: var(--font-display); font-size: var(--type-h2); line-height: .98; }
/* Dark/prominent, matching Sections 1 and 2's lead paragraphs -- this is
   the only paragraph in this section's intro block (no separate body line
   below it), so it should read with the same lead weight, not the muted
   secondary-text colour it had been using. */
.program-marketplace__intro > p:last-child { max-width: 650px; margin: 0; color: var(--fg); font-family: var(--font-sans); font-size: var(--type-body); line-height: 1.45; }

/* No rule above the stages. The two panels are already drawn objects sitting
   in open space, so a full-width hairline over them was a second, competing
   division doing the same job the whitespace does. Same reason there's none
   above the studio cluster. */
.program-stages { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-24) var(--sp-32); margin-top: var(--sp-56); align-items: stretch; }
/* Navy panels on the light band. The fill is what defines the edge, so there
   is no border -- a hairline round a filled panel just doubles the outline.
   Keeps the wide radius and generous padding from the unfilled version.

   Every colour below is the on-dark half of the role layer, because the
   panel interior is navy even though the section around it is cream. */
.program-stage { display: flex; flex-direction: column; padding: clamp(var(--sp-24), 2.6vw, var(--sp-40)); border-radius: var(--radius-lg); background: var(--bg-inverse); color: var(--fg-on-dark); }
.program-stage__meta-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: var(--sp-12); }
.program-stage__tag { color: var(--fg-on-dark-muted); font-family: var(--font-sans); font-size: var(--type-micro); font-weight: var(--fw-bold); letter-spacing: .1em; text-transform: uppercase; }
.program-stage__meta { color: var(--fg-on-dark-muted); font-family: var(--font-sans); font-size: var(--type-micro); }
/* Sky, not deep blue. With the navy fill back the heading sits on navy, where
   sky is ~10:1 -- deep blue on navy would be ~1.7:1 and unreadable. This is
   the same llms.txt rule 1/2 pair as before, just resolved the other way
   because the surface underneath it changed. */
.program-stage h3 { max-width: 480px; margin: var(--sp-16) 0 var(--sp-12); color: var(--canasia-sky); font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--type-h3); line-height: 1.05; }
.program-stage p { margin: 0; color: var(--fg-on-dark); font-family: var(--font-sans); font-size: var(--type-body); line-height: 1.4; }
.program-stage ul { list-style: none; display: grid; margin: var(--sp-24) 0 0; padding: 0; border-top: 1px solid var(--border-on-dark); color: var(--fg-on-dark); font-size: var(--type-small); font-weight: var(--fw-medium); }
.program-stage li { display: flex; align-items: center; gap: var(--sp-12); padding-block: var(--sp-12); border-bottom: 1px solid var(--border-on-dark); }
/* Icon files are solid-fill SVGs (fill="currentColor", which resolves to
   black through an <img> tag regardless of page CSS) -- invert them to white
   so they read on the navy panel, same technique as the partner bar. */
.program-stage li img { width: 20px; height: 20px; flex: 0 0 auto; filter: brightness(0) invert(1); }

/* Studio cluster: the marks are the argument this section is making -- these
   names are already here -- so they get the room. Heading above, full-width
   hairline grid below, replacing the old heading-left/roster-right split and
   its grey placeholder squares. */
.studio-cluster { margin-top: var(--sp-80); text-align: left; }
/* Deliberately below --type-h3. This is a lead-in to the logo grid, not a
   peer of the section's h2 above it -- at --type-h3 the two headings were
   competing, and the marks are what this block is actually for. Sits at
   --type-body so it reads as a line of text introducing the grid. */
.studio-cluster h3 { max-width: 760px; margin: 0 0 var(--sp-24); color: var(--fg); font-family: var(--font-display); font-size: var(--type-body); line-height: 1.15; }
/* Hairlines are drawn per tile (right + bottom) with the container closing
   the top and left edges -- not as a gap-and-background grid. A short final
   row then simply stops after its last tile, instead of trailing empty ruled
   cells across the rest of the width. */
.studio-cluster__grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); border-top: 1px solid var(--border-strong); border-left: 1px solid var(--border-strong); }
.studio-tile { display: flex; flex-direction: column; min-height: 186px; padding: var(--sp-24) var(--sp-16) var(--sp-20); border-right: 1px solid var(--border-strong); border-bottom: 1px solid var(--border-strong); }
.studio-tile__mark { display: flex; flex: 1 1 auto; align-items: center; justify-content: center; }
/* Capped on both axes, never height alone: the roster runs from a square
   glyph (The Coalition, 1:1) to a wordmark five and a half times as wide
   (EA), and a shared height would throw the wide ones clear across the cell.
   The width cap catches those first, so every mark lands at roughly the same
   optical weight rather than the same literal height.

   Inverted to white for the same reason the partner bar is: every file is
   one flat ink on transparency, so the whole roster flips with one filter
   and stays a single consistent treatment on the dark band. */
.studio-tile__mark img { max-width: 100%; max-height: 44px; width: auto; height: auto; object-fit: contain; }
.studio-tile__name { margin-top: var(--sp-20); color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-micro); font-weight: var(--fw-medium); letter-spacing: .1em; line-height: 1.4; text-align: center; text-transform: uppercase; }
/* Closing tile carries a count instead of a mark -- the membership is much
   larger than the nine logos that fit, and saying so is more honest than
   padding the grid out with filler marks. No caption underneath: the label
   is already part of the tile. */
.studio-tile--count .studio-tile__mark { flex-direction: column; gap: var(--sp-8); }
.studio-tile--count strong { color: var(--fg); font-family: var(--font-display); font-size: 2.5rem; font-weight: var(--fw-regular); line-height: .9; }
.studio-tile--count span { color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-micro); font-weight: var(--fw-medium); letter-spacing: .1em; line-height: 1.4; text-align: center; text-transform: uppercase; }
.delegations-partners { padding: var(--sp-80) var(--sp-24); background: var(--bg); color: var(--fg); }
.delegations-partners__intro { max-width: var(--wrap-max); }
.delegations-partners__intro h2 { margin: var(--sp-16) 0 var(--sp-24); font-family: var(--font-display); font-size: var(--type-h2); line-height: .98; text-transform: uppercase; }
/* Same reasoning as Section 3's intro paragraph -- one lone subhead line,
   should carry lead weight, not the muted secondary colour. */
.delegations-partners__intro > p:last-child { max-width: 700px; margin: 0; color: var(--fg); font-family: var(--font-sans); font-size: var(--type-body); line-height: 1.45; }
.delegation-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-16); margin-top: var(--sp-40); }
.delegation-card { min-height: 210px; padding: var(--sp-24); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-raised); }
.delegation-card__flag { display: block; margin-bottom: var(--sp-12); font-size: 28px; line-height: 1; }
/* H4 is Inter Bold, not Veneer -- matches the documented H4/Component role
   (colors_and_type.css) exactly, same as every other H4 on the site. */
/* h3, not h4: these sit directly under the section's own h2, so an h4 skipped
   a level in the document outline. The rule already overrides family, weight,
   size, line-height and transform, so the render is unchanged -- only the tag
   and this selector moved. */
.delegation-card h3 { max-width: 100%; margin: 0 0 var(--sp-12); font-family: var(--font-sans); font-size: var(--type-h4); font-weight: var(--fw-bold); line-height: 1.2; text-transform: uppercase; }
.delegation-card p { margin: 0; color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-small); line-height: 1.5; }
.trade-circuit { margin-top: var(--sp-40); padding: var(--sp-48); border-radius: var(--radius-md); background: var(--bg-raised); }
.trade-circuit__heading { display: flex; align-items: end; justify-content: space-between; gap: var(--sp-32); }
.trade-circuit__heading h3 { max-width: 620px; margin: var(--sp-16) 0 var(--sp-24); font-family: var(--font-display); font-size: var(--type-h3); line-height: .9; text-transform: uppercase; }
.trade-circuit__heading p { max-width: 280px; margin: 0 0 var(--sp-4); color: var(--fg-muted); font-size: var(--type-body); line-height: 1.35; }
.trade-circuit__eyebrow { color: var(--canasia-sky); font-family: var(--font-sans); font-size: var(--type-micro); font-weight: var(--fw-medium); letter-spacing: .2em; }
.trade-circuit__columns,
.trade-stop { display: grid; grid-template-columns: minmax(120px, .8fr) minmax(220px, 1.5fr) minmax(260px, 1.7fr) minmax(100px, .7fr); gap: var(--sp-24); }
.trade-circuit__columns { margin-top: var(--sp-32); padding: 0 var(--sp-16) var(--sp-12); border-bottom: 2px solid var(--fg); color: var(--fg-muted); font-size: var(--type-micro); letter-spacing: .18em; text-transform: uppercase; }
.trade-circuit__list { display: grid; }
.trade-stop { align-items: center; padding: var(--sp-16); border-bottom: 1px solid var(--border); }
.trade-stop time { font-family: var(--font-display); font-size: var(--type-label); letter-spacing: .04em; text-transform: uppercase; }
.trade-stop__event strong { display: block; font-family: var(--font-sans); font-size: var(--type-h4); line-height: 1.15; }
.trade-stop small { display: block; margin-top: var(--sp-4); color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-micro); letter-spacing: .08em; line-height: 1.4; text-transform: uppercase; }
.trade-stop p { margin: 0; color: var(--fg-muted); font-size: var(--type-label); line-height: 1.45; }
.trade-stop__status { color: var(--canasia-primary); font-family: var(--font-display); font-size: var(--type-micro); letter-spacing: .08em; text-transform: uppercase; }
.trade-stop--destination { margin-top: var(--sp-8); border: 0; border-radius: var(--radius-md); background: var(--bg-inverse); color: var(--fg-on-dark); }
.trade-stop--destination p { color: var(--fg-on-dark-muted); }
.trade-stop--destination small { color: var(--canasia-sky); }
.trade-stop--destination .trade-stop__status { color: var(--canasia-sky); }

/* In the news -- real posts via WP_Query, not hardcoded copy. Same card
   language as .delegation-card (bordered, --bg-raised, --radius-md) so it
   reads as part of the same system rather than a bolted-on blog widget. */
.news-section { padding: var(--sp-80) max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)); background: var(--bg-alt); color: var(--fg); }
.news-section > * { max-width: var(--wrap-max); margin-inline: auto; }
.news-section__intro h2 { margin: var(--sp-16) 0 0; }
.news-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-24); margin-top: var(--sp-40); }
.news-card { display: flex; flex-direction: column; overflow: hidden; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-raised); }
.news-card__image { display: block; aspect-ratio: 16 / 10; background: var(--fill-subtle); }
.news-card__image img { display: block; width: 100%; height: 100%; object-fit: cover; }
.news-card__body { display: flex; flex: 1 1 auto; flex-direction: column; gap: var(--sp-8); padding: var(--sp-24); }
.news-card__date { color: var(--fg-muted); font-family: var(--font-mono); font-size: var(--type-micro); letter-spacing: .08em; text-transform: uppercase; }
.news-card__body h3 { margin: 0; font-family: var(--font-display); font-size: var(--type-h3); font-weight: var(--fw-regular); line-height: 1.05; }
.news-card__body h3 a { color: var(--fg); text-decoration: none; }
.news-card__body h3 a:hover { color: var(--canasia-blue); }
.news-card__body p { margin: 0; color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-small); line-height: 1.5; }
.news-card__link { margin-top: auto; padding-top: var(--sp-8); color: var(--canasia-blue); font-family: var(--font-sans); font-size: var(--type-label); font-weight: var(--fw-bold); text-decoration: none; }
.news-card__link:hover { text-decoration: underline; }

/* Single news article -- featured image full-width, then a two-column
   read: article body left, a CTA + more-news card right. Content itself
   comes from the classic editor (Gutenberg is off site-wide), so the prose
   rules below cover plain paragraphs/headings/lists/blockquotes generically
   rather than any one post's specific markup. */
.single-post__container { padding-top: var(--sp-56); padding-bottom: var(--sp-80); }
/* Featured image full-width above the title, not beside it. */
.single-post__hero { margin: 0; background: var(--fill-subtle); }
.single-post__hero img { display: block; width: 100%; max-height: 520px; object-fit: cover; }
.single-post__header { margin-bottom: var(--sp-40); }
.single-post__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); gap: var(--sp-56); align-items: start; }
.single-post__title { max-width: 800px; margin: var(--sp-16) 0; font-family: var(--font-display); font-size: var(--type-display); line-height: .9; }
.single-post__meta { margin: 0; color: var(--fg-muted); font-family: var(--font-mono); font-size: var(--type-micro); letter-spacing: .08em; text-transform: uppercase; }
/* Lead/body split matches the homepage's own convention (e.g.
   .about-project__lead vs .about-project p): the article's opening
   paragraph reads dark and a size up, everything after it drops to the
   quieter muted-grey body colour used everywhere else on the site. */
.single-post__content { max-width: 640px; font-family: var(--font-sans); line-height: 1.7; }
.single-post__content p { margin: 0 0 var(--sp-20); color: var(--fg-muted); font-size: var(--type-small); line-height: 1.6; }
.single-post__content p:first-of-type { color: var(--fg); font-size: var(--type-body); line-height: var(--type-lead-lh); }
.single-post__content p:last-child { margin-bottom: 0; }
.single-post__content h2 { margin: var(--sp-40) 0 var(--sp-16); color: var(--fg); font-size: var(--type-h2); line-height: 1; }
.single-post__content h3 { margin: var(--sp-32) 0 var(--sp-12); color: var(--fg); font-size: var(--type-h3); line-height: 1.05; }
.single-post__content ul,
.single-post__content ol { margin: 0 0 var(--sp-20); padding-left: 1.2em; }
.single-post__content li { margin-bottom: var(--sp-8); }
.single-post__content a { color: var(--canasia-blue); }
.single-post__content blockquote { margin: var(--sp-24) 0; padding-left: var(--sp-20); border-left: 3px solid var(--border); color: var(--fg-muted); font-style: italic; }
.single-post__content img { max-width: 100%; height: auto; border-radius: var(--radius-sm); }
.single-post__back { display: inline-block; margin-top: var(--sp-40); color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-label); text-decoration: none; }
.single-post__back:hover { color: var(--fg); text-decoration: underline; }

.single-post__aside { display: flex; flex-direction: column; gap: var(--sp-24); }
.single-post__aside-card { padding: var(--sp-24); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg-raised); }
.single-post__aside-card .topbar__cta { display: inline-flex; margin-top: var(--sp-16); }
.single-post__aside-label { margin: 0 0 var(--sp-8); color: var(--fg-muted); font-family: var(--font-mono); font-size: var(--type-micro); letter-spacing: .08em; text-transform: uppercase; }
.single-post__aside-date { margin: 0; color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-small); }
.single-post__aside-more ul { list-style: none; margin: var(--sp-16) 0 0; padding: 0; display: grid; gap: var(--sp-12); }
.single-post__aside-more li { padding-bottom: var(--sp-12); border-bottom: 1px solid var(--border); }
.single-post__aside-more li:last-child { border-bottom: 0; padding-bottom: 0; }
.single-post__aside-more a { display: flex; align-items: center; gap: var(--sp-12); color: var(--fg); font-family: var(--font-sans); font-size: var(--type-small); font-weight: var(--fw-medium); line-height: 1.4; text-decoration: none; }
.single-post__aside-more a:hover { color: var(--canasia-blue); }
.single-post__aside-thumb { flex: 0 0 auto; width: 56px; height: 56px; border-radius: var(--radius-sm); overflow: hidden; background: var(--fill-subtle); }
.single-post__aside-thumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.single-post__aside-more-title { min-width: 0; }
/* Partner bar: no cards, no chips. Every file in /assets-partner/ is
   pre-normalised to one flat ink on real transparency, so a single invert
   renders the whole set as clean white silhouettes and the row holds
   together on its own -- it no longer needs a box treatment propping it up.
   (The old chip existed because Web Summit's file had a baked-in white
   background; the replacement file has real alpha, so it's gone.) */
/* Content-sized columns, not equal thirds -- "Presented by" carries a
   wide combined logo and needs real room, while "Supported by" needs
   very little. Forcing three equal 1fr columns is what pushed the wide
   one onto a second line; letting each card claim only the width its
   own logos need keeps every card on one line at any realistic content
   width (checked against all three cards' current combined logo widths
   plus gaps well under the row's max-width). */
.partner-cards { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--sp-32); padding: var(--sp-64) max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)); background: var(--bg-inverse); }
.partner-card { display: flex; flex: 0 1 auto; flex-direction: column; gap: var(--sp-20); }
.partner-card span { color: var(--fg-on-dark-muted); font-size: var(--type-micro); font-weight: var(--fw-bold); letter-spacing: .16em; line-height: 1; text-transform: uppercase; }
.partner-card strong { color: var(--fg-on-dark); font-family: var(--font-sans); font-size: 1.0625rem; font-weight: var(--fw-bold); letter-spacing: -.01em; white-space: nowrap; }
.partner-card__logos { display: flex; align-items: center; flex-wrap: nowrap; gap: var(--sp-16); min-height: 48px; }
/* "Province of BC" and the Kabam mark share one label, so they need a real
   separator -- previously a middot glued to the end of the text, which read
   as punctuation rather than a divider. */
.partner-card__divider { flex: 0 0 auto; width: 1px; height: 26px; background: rgba(243, 245, 248, .34); }
.partner-logo { height: 30px; width: auto; flex: 0 0 auto; filter: brightness(0) invert(1); }
/* Stacked lockups fit the same art across more lines, so matching their box
   height to a single-line wordmark's would halve the actual letterforms. But
   how much extra they need depends on how many lines they stack into, and
   sharing one height between them made XP27 the loudest thing on the bar:

   Web Summit stacks three short lines, so 48px leaves each line small and it
   sits level with the wordmarks. XP27 is only two lines around a large XP
   glyph, so the same 48px scaled that glyph up until it dominated the row.
   It gets its own, shorter box. */
.partner-logo--stacked { height: 48px; }
.partner-logo--wordmark-stack { height: 32px; }
/* A standalone glyph with no wordmark attached reads small at wordmark
   height. */
.partner-logo--mark { height: 34px; }

.about-project { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(300px, .85fr); gap: var(--sp-32) clamp(48px, 8vw, 120px); padding: var(--sp-80) max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)); background: var(--bg-alt); color: var(--fg); }
.about-project__heading { grid-column: 1; grid-row: 1; }
.about-project__copy { grid-column: 1; grid-row: 2; max-width: 720px; }
/* Section 1 keeps the bigger Title-scale heading on purpose -- it's the
   first statement after the hero and reads as the page's real opening
   line. Sections 2-4 all step down to type-h2 instead. */
.about-project h2 { max-width: 680px; margin: var(--sp-16) 0 var(--sp-24); color: var(--fg); font-family: var(--font-display); font-size: var(--type-display); line-height: .84; }
.about-project p { margin: 0 0 var(--sp-20); color: var(--fg-muted); font-size: var(--type-small); line-height: 1.55; }
/* Lead paragraph reads dark/prominent like Section 2's own lead -- it had
   no colour override, so it was silently falling back to .about-project
   p's muted grey and reading identically to the body paragraph below it,
   losing the lead/body hierarchy that Section 2 already gets right. */
.about-project__lead { color: var(--fg) !important; font-size: var(--type-body) !important; line-height: var(--type-lead-lh) !important; }
.about-project strong { color: var(--fg); }
.about-project__pitch { margin-top: var(--sp-24); padding: var(--sp-24); border-left: 2px solid var(--canasia-sky); border-radius: 0 var(--radius-md) var(--radius-md) 0; background: var(--bg-raised); }
.about-project__pitch span { display: block; margin-bottom: var(--sp-12); color: var(--fg-muted); font-size: 11px; font-weight: var(--fw-black); letter-spacing: .16em; }
.about-project__pitch p { margin: 0; color: var(--fg); font-size: var(--type-label); line-height: 1.45; }
/* Sections 01 + 02: paired plane-window pills — identical geometry.
   Pill shape (border-radius large enough to force semicircular caps on
   the short axis) reads like a real porthole, unlike a pure oval. */
/* Ring one step darker than the local background (Grey 4 vs. --bg-alt's
   Grey 5) -- visible as a quiet frame instead of either an invisible match
   or a bold accent colour. */
.about-project__image { grid-column: 2; grid-row: 1 / span 2; width: min(100%, 480px); aspect-ratio: 4/5; margin: var(--sp-32) auto 0; align-self: start; border: 12px solid var(--canasia-grey-4); border-radius: 999px; overflow: hidden; background: var(--border); }
.about-project__image img { display: block; width: 100%; height: 100%; object-fit: cover; border: 0; border-radius: 0; }
.about-project__stats { display: flex; gap: clamp(var(--sp-32), 6vw, var(--sp-80)); margin-top: var(--sp-40); padding-top: var(--sp-24); border-top: 1px solid var(--border); }
.about-project__stats div { display: grid; gap: var(--sp-8); }
.about-project__stats span { color: var(--fg-muted); font-family: var(--font-mono); font-size: var(--type-micro); letter-spacing: .16em; text-transform: uppercase; }
.about-project__stats strong { color: var(--canasia-blue); font-family: var(--font-display); font-weight: var(--fw-regular); font-size: var(--type-h2); line-height: .9; text-transform: uppercase; }
.about-context { display: grid; grid-template-columns: minmax(360px, .95fr) minmax(0, 1.05fr); gap: var(--sp-32) var(--sp-64); padding: var(--sp-80) max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)); background: var(--bg); color: var(--fg); }
.about-context__heading { grid-column: 2; grid-row: 1; }
.about-context__copy { grid-column: 2; grid-row: 2; max-width: 680px; }
.about-context__heading h2,
.about-context h2 { max-width: 720px; margin: var(--sp-16) 0 var(--sp-24); font-family: var(--font-display); font-size: var(--type-h2); font-weight: var(--fw-regular); line-height: .98; text-transform: uppercase; }
.about-context p { margin: 0 0 var(--sp-20); color: var(--fg); font-family: var(--font-sans); line-height: 1.5; }
.about-context__lead { font-size: var(--type-lead); line-height: var(--type-lead-lh); }
/* .about-context__body is one class (0,1,0); the shared ".about-context p"
   rule above is class+element (0,1,1) -- higher specificity always wins
   regardless of source order, so the muted colour here was silently
   losing to the base rule's dark fg every time. !important forces it,
   same fix already used for .about-project__lead's equivalent trap. */
.about-context__body { font-size: var(--type-small); line-height: 1.55; color: var(--fg-muted) !important; }
.about-context strong { color: var(--fg); }
.about-context__metrics { grid-column: 2; grid-row: 3; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-16); max-width: 680px; }
.about-context__metrics article { display: flex; flex-direction: column; gap: var(--sp-12); padding: var(--sp-24); border: 1px solid var(--border-strong); border-radius: var(--radius-md); background: var(--bg-raised); }
.about-context__metrics strong,
.about-context__metrics h2 { color: var(--canasia-blue); font-family: var(--font-display); font-size: var(--type-h2); font-weight: var(--fw-regular); line-height: .9; margin: 0; text-transform: uppercase; }
.about-context__metrics span { max-width: 18ch; margin-top: var(--sp-20); color: var(--fg-muted); font-size: var(--type-label); line-height: 1.3; }
/* Same idea as .about-project__image's ring -- one step darker than the
   local (light, cream) section background, not matched to the card's own
   dark navy fill. Reads as a quiet light frame around the dark porthole
   instead of vanishing or fighting the navy inside it. */
.about-context__pitch { grid-column: 1; grid-row: 1 / span 3; display: flex; flex-direction: column; justify-content: center; align-self: center; width: min(100%, 480px); aspect-ratio: 4/5; gap: var(--sp-24); margin: 0; padding: clamp(var(--sp-32), 5vw, var(--sp-64)); border: 12px solid var(--canasia-grey-4); border-radius: 999px; background: var(--bg-inverse); text-align: center; }
.about-context__pitch span,
.about-context__pitch h3 { display: block; margin: 0 0 var(--sp-20); color: var(--canasia-sky); font-family: var(--font-display); font-size: var(--type-h3); font-weight: var(--fw-regular); line-height: 1; text-transform: uppercase; letter-spacing: 0; }
.about-context__pitch small { color: var(--fg-on-dark-muted); font-family: var(--font-mono); font-size: var(--type-micro); line-height: 1.5; }
.about-context__pitch p { margin: 0; color: var(--fg-on-dark); font-family: var(--font-sans); font-size: var(--type-lead); font-weight: var(--fw-regular); line-height: 1.4; }

/* Tablet step for the two logo rows specifically. Seven studio tiles and
   four partner groups both stop holding their marks well before the site's
   760px breakpoint -- the cells get narrower than the wordmarks in them. */
@media (max-width: 1180px) {
  .studio-cluster__grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  /* .partner-cards is content-sized flex now (see base rule) -- it wraps
     to a new line on its own once a row doesn't fit, no forced column
     count needed here. */
  .partner-cards { row-gap: var(--sp-40); }
}

@media (max-width: 760px) {
  .window-stage { min-height: 560px; }
  /* Stacked, and pinned to the bottom of the window. .window-copy is
     `flex: 1 1 320px` for the desktop two-column layout; left alone in a
     column it grows to fill the stage and strands the headline at the top
     with a void under it. flex-end plus a non-growing copy block sits the
     whole group above the caption, where the gradient is densest and the
     type is most readable. */
  .window-bottom { flex-direction: column; align-items: stretch; justify-content: flex-end; padding: var(--sp-56) var(--sp-24) var(--sp-40); }
  .window-copy { flex: 0 0 auto; }
  /* No mobile override needed — --type-display's own clamp already reaches
     its 48px floor at 480px and below, computed with a real rem+vw formula
     rather than this rule's old bare-vw clamp. */
  .window-caption { max-width: none; }
  .program-marketplace { padding-block: var(--sp-64); }
  .program-stages { grid-template-columns: 1fr; gap: var(--sp-40); margin-top: var(--sp-48); }
  .studio-cluster { margin-top: var(--sp-56); }
  .studio-cluster__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .studio-tile { min-height: 156px; padding: var(--sp-20) var(--sp-16) var(--sp-16); }
  .delegations-partners { padding-block: var(--sp-64); }
  .delegation-grid { grid-template-columns: 1fr; margin-top: var(--sp-32); }
  .delegation-card { min-height: 0; }
  .trade-circuit { margin-top: var(--sp-32); padding: var(--sp-32); }
  .trade-circuit__heading { display: block; }
  .trade-circuit__heading h3 { font-size: var(--type-h3); }
  .trade-circuit__heading p { margin-top: var(--sp-20); }
  .trade-circuit__columns { display: none; }
  .trade-stop { display: grid; grid-template-columns: 1fr auto; gap: var(--sp-8) var(--sp-16); align-items: start; padding-inline: 0; }
  .trade-stop time,
  .trade-stop__event,
  .trade-stop p { grid-column: 1 / -1; }
  .trade-stop__status { grid-column: 2; grid-row: 1; }
  /* Two up, not one. Four single-file rows ran 568px tall -- most of a phone
     screen of logos before any content. The marks are small enough to pair,
     and the labels are short. */
  .partner-cards { gap: var(--sp-32) var(--sp-20); padding-inline: var(--sp-24); }
  .partner-card { flex: 1 1 calc(50% - var(--sp-20)); }
  .partner-card__logos { flex-wrap: wrap; gap: var(--sp-12); }
  /* At half-width the paired cards can't keep both marks on one line -- DigiBC
     plus Creative BC alone need ~181px in a 154px card -- so they wrap. That
     leaves the divider stranded at the end of the first line with nothing after
     it. A divider only means anything between two items on the same line, so
     it goes when they stack. */
  .partner-card__divider { display: none; }
  .partner-logo { height: 24px; }
  .partner-logo--stacked { height: 38px; }
  .partner-logo--wordmark-stack { height: 26px; }
  .partner-logo--mark { height: 26px; }
  .partner-card strong { font-size: var(--type-small); }
  .about-project { grid-template-columns: 1fr; padding: var(--sp-64) var(--sp-24); }
  .about-context { grid-template-columns: 1fr; padding: var(--sp-64) var(--sp-24); }
  .about-project__heading,
  .about-project__copy,
  .about-project__image,
  .about-context__heading,
  .about-context__copy,
  .about-context__metrics,
  .about-context__pitch { grid-column: auto; grid-row: auto; }
  .about-project__image { order: -1; }
  .about-project__stats { gap: var(--sp-24); }
  .about-project__image img,
  .about-context__image img { width: 100%; }
  .about-context__metrics { grid-template-columns: 1fr 1fr; }
  .about-context__pitch { width: min(100%, 420px); aspect-ratio: 4/5; gap: var(--sp-24); padding: var(--sp-32); margin-inline: auto; }
  .news-section { padding-block: var(--sp-64); }
  .contact-page { grid-template-columns: 1fr; padding: var(--sp-64) var(--sp-24); }
  .contact-page__form { padding: var(--sp-24); }
  .news-grid { grid-template-columns: 1fr; margin-top: var(--sp-32); }
  .single-post__hero img { max-height: 280px; }
  .single-post__container { padding-top: var(--sp-40); padding-bottom: var(--sp-64); }
  .single-post__grid { grid-template-columns: 1fr; gap: var(--sp-32); }
  .boarding-pass { grid-template-columns: 1fr; }
  .boarding-pass__rail { min-height: 72px; }
  .boarding-pass__rail span { transform: none; }
  .boarding-pass__main { padding: var(--sp-32) var(--sp-24); }
  .boarding-pass h2 { max-width: 62%; }
  .boarding-pass__intro { max-width: 82%; font-size: var(--type-label); }
  .boarding-pass__barcode { top: var(--sp-24); right: var(--sp-24); width: 64px; height: 64px; }
  .boarding-pass__details { align-items: stretch; flex-wrap: wrap; gap: var(--sp-20) var(--sp-24); }
  .boarding-pass__cta { margin-left: 0; }
  .registration-form { padding: var(--sp-24); }
  .registration-form .gform_wrapper .gform_fields { grid-template-columns: 1fr; }
  .site-footer { padding-block: var(--sp-24); }
  .site-footer__inner { align-items: flex-start; flex-direction: column; }
}

/* ── Founding Partners strip (hero, Partnership section, footer) ───────── */


/* ── Sections ─────────────────────────────────────────────────────────── */

.section { padding-block: var(--sp-80); text-align: center; }
.section--tight { padding-block: var(--sp-56); }
.section--alt { background: var(--bg-alt); }
.section--inverse { background: var(--bg-inverse); color: var(--fg-on-dark); }
/* Gutter comes from .container now (.registration-panel is one), so this
   doesn't add its own -- the two would double up. */
.section--closing { text-align: center; }
.registration-panel { max-width: var(--wrap-max); }
/* Dashed perforation along the card's own bottom edge -- visible whether
   the form below is open or closed, reading as "tear here" on a boarding
   pass rather than only appearing once you've already clicked. */
.boarding-pass { display: block; overflow: hidden; max-width: 1080px; margin: 0 auto; border-bottom: 2px dashed var(--canasia-grey-4); background: var(--bg-raised); border-radius: var(--radius-md) var(--radius-md) 0 0; color: var(--fg); text-align: left; }
.boarding-pass__rail { display: none; }
.boarding-pass__main { position: relative; padding: var(--sp-40); }
.boarding-pass__eyebrow { margin: 0 0 var(--sp-20); color: var(--fg-muted); font-size: var(--type-micro); font-weight: var(--fw-medium); letter-spacing: .2em; text-transform: uppercase; }
.boarding-pass h2 { max-width: 52%; margin: var(--sp-16) 0 var(--sp-24); color: var(--fg); font-family: var(--font-display); font-size: var(--type-display); line-height: .82; text-wrap: balance; text-transform: uppercase; }
.boarding-pass__intro { max-width: 520px; margin: var(--sp-24) 0 0; color: var(--fg-muted); font-size: var(--type-body); line-height: 1.35; }
.boarding-pass__rule { height: 1px; margin-block: var(--sp-32); background: var(--border); }
.boarding-pass__details { display: flex; align-items: end; gap: clamp(var(--sp-24), 5vw, var(--sp-80)); }
.boarding-pass__details div { display: grid; gap: var(--sp-8); }
.boarding-pass__details span { color: var(--fg-muted); font-size: var(--type-micro); font-weight: var(--fw-medium); letter-spacing: .18em; text-transform: uppercase; }
/* H4, not H3 -- these are label+value pairs (GATE/BOARDS/CLASS), same role
   as the delegation-card titles, not a subsection heading. Was --type-h3
   (Veneer, up to 32px), which read oversized next to its own 12px label. */
.boarding-pass__details strong { color: var(--fg); font-family: var(--font-sans); font-size: var(--type-h4); font-weight: var(--fw-bold); letter-spacing: .04em; text-transform: uppercase; }
.boarding-pass__cta { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-8); min-width: 190px; padding: var(--sp-12) var(--sp-24); background: var(--canasia-cta); border: 0; border-radius: var(--radius-pill); color: var(--fg); font-family: var(--font-display); font-size: var(--type-label); font-weight: var(--fw-regular); text-transform: uppercase; letter-spacing: .08em; line-height: 1.2; text-decoration: none; cursor: pointer; }
.boarding-pass__cta:hover { background: var(--canasia-cta-tint); }
.boarding-pass__cta[aria-expanded="true"]::after { content: "✕"; font-weight: var(--fw-bold); }
.boarding-pass__cta[aria-expanded="false"]::after { content: "→"; font-weight: var(--fw-bold); }
.boarding-pass__barcode { position: absolute; top: var(--sp-40); right: var(--sp-40); width: 116px; height: 64px; border-radius: 0; background: repeating-linear-gradient(90deg, var(--fg) 0 2px, transparent 2px 5px); }
.registration-form { max-width: 1080px; margin: 0 auto; padding: var(--sp-32); background: var(--bg-raised); border-radius: 0 0 var(--radius-md) var(--radius-md); text-align: left; }
.registration-form .gform_wrapper { margin: 0; }
.registration-form .gform_wrapper form { display: grid; gap: var(--sp-16); }
.registration-form .gform_wrapper .gform_fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-12); }
.registration-form .gform_wrapper .gfield { margin: 0; }
.registration-form .gform_wrapper .gfield--type-checkbox,
.registration-form .gform_wrapper .gfield--type-radio { grid-column: 1 / -1; }
.registration-form .gform_wrapper label { color: var(--fg); font-size: var(--type-micro); font-weight: var(--fw-bold); line-height: 1.25; }
.registration-form .gform_wrapper input,
.registration-form .gform_wrapper select,
.registration-form .gform_wrapper textarea { width: 100%; border: 1px solid var(--canasia-grey-5); border-radius: var(--radius-sm); background: var(--canasia-cream); color: var(--fg); padding: var(--sp-8) var(--sp-12); font: inherit; }
.registration-form .gform_wrapper input:focus,
.registration-form .gform_wrapper select:focus,
.registration-form .gform_wrapper textarea:focus { outline: 2px solid var(--canasia-sky); outline-offset: 2px; }
.registration-form .gform_wrapper input[type="checkbox"],
.registration-form .gform_wrapper input[type="radio"] { width: auto; }
.registration-form .gform_wrapper .gform_footer { margin: 0; text-align: right; }
.registration-form .gform_wrapper input[type="submit"],
.registration-form .gform_wrapper button[type="submit"] { width: auto; min-width: 220px; padding: var(--sp-12) var(--sp-24); border: 0; border-radius: var(--radius-pill); background: var(--canasia-cta); color: var(--fg); font-family: var(--font-display); font-size: var(--type-label); font-weight: var(--fw-regular); text-transform: uppercase; letter-spacing: .08em; line-height: 1.2; cursor: pointer; }
.registration-form .gform_wrapper input[type="submit"]:hover,
.registration-form .gform_wrapper button[type="submit"]:hover { background: var(--canasia-cta-tint); }
.registration-form .gform_wrapper .gfield_checkbox,
.registration-form .gform_wrapper .gfield_radio { display: flex; flex-wrap: wrap; gap: var(--sp-8); margin: var(--sp-4) 0 0; }
.registration-form .gform_wrapper .gfield_checkbox label,
.registration-form .gform_wrapper .gfield_radio label { display: inline-flex; align-items: center; width: auto; padding: var(--sp-8) var(--sp-12); border: 1px solid var(--canasia-grey-5); border-radius: var(--radius-pill); background: var(--canasia-cream); font-size: var(--type-micro); font-weight: var(--fw-regular); }
.registration-form .gform_wrapper .gfield_checkbox input,
.registration-form .gform_wrapper .gfield_radio input { margin-right: var(--sp-4); }

/* ── Scroll reveal — presentation system shared across the site, same
   architecture as every other current-pattern brand's theme (Intersection
   Observer adds .is-visible once, staggered by .d1/.d2/.d3; reduced motion
   and no-JS both fall back to fully visible via the noscript-safe default
   opacity below only being applied once JS confirms it can animate — see
   the script in footer.php). ─────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(16px); transition: opacity 500ms ease, transform 500ms ease; }
.reveal.is-visible { opacity: 1; transform: none; }
.reveal.d1 { transition-delay: 80ms; }
.reveal.d2 { transition-delay: 160ms; }
.reveal.d3 { transition-delay: 240ms; }

.section__heading {
  /* fw-bold removed Sept 5, 2026 — Veneer ships one weight (400); a bold
     request here was silent browser fake-bold synthesis, against the
     site's own canonical rule (see colors_and_type.css). */
  font-family: var(--font-display);
  font-size: var(--type-h2);
  font-weight: var(--fw-regular);
  margin: var(--sp-12) 0 0;
  color: var(--fg);
}
.section__heading--on-dark { color: var(--fg-on-dark); }

.section__intro,
.section__body {
  max-width: 62ch;
  margin: var(--sp-20) auto 0;
  font-size: var(--type-body);
}

.body-copy p { margin: 0 0 var(--sp-16); }
.body-copy p:last-child { margin-bottom: 0; }
.body-copy--on-dark { color: var(--fg-on-dark); }

.funding-note {
  margin: var(--sp-20) auto 0;
  font-size: var(--type-label);
  color: var(--fg-muted);
}

/* ── 404 ──────────────────────────────────────────────────────────────── */
/* Sits on the inverse band so a lost visitor still lands on something that
   looks like the site, rather than the unstyled index.php fallback. */
.error-404 { display: flex; align-items: center; min-height: 60vh; }
.error-404__inner { max-width: 640px; }
.error-404 h1 { margin: var(--sp-16) 0 var(--sp-24); color: var(--fg-on-dark); font-family: var(--font-display); font-size: var(--type-h1); line-height: .95; }
.error-404__body { margin: 0 0 var(--sp-32); color: var(--fg-on-dark-muted); font-family: var(--font-sans); font-size: var(--type-body); line-height: 1.5; }
.error-404__actions { display: flex; flex-wrap: wrap; gap: var(--sp-16); }

/* Text link with an arrow, not a filled pill. Used where a link is a way
   onward rather than the page's call to action -- a pill there competes with
   the one real CTA. The arrow nudges on hover so the affordance is motion,
   not a colour change alone. */
.text-link { display: inline-flex; align-items: center; gap: var(--sp-8); color: var(--canasia-primary); font-family: var(--font-sans); font-size: var(--type-label); font-weight: var(--fw-bold); text-decoration: none; }
.text-link span { transition: transform var(--dur-std) var(--ease-standard); }
.text-link:hover { text-decoration: underline; }
.text-link:hover span { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) { .text-link span { transition: none; } }

/* ── Contact page ─────────────────────────────────────────────────────── */
.contact-page { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); gap: var(--sp-32) clamp(var(--sp-48), 6vw, var(--sp-96)); padding: var(--sp-80) max(var(--sp-24), calc((100vw - var(--wrap-max)) / 2)); background: var(--bg); color: var(--fg); align-items: start; }
.contact-page h1 { margin: var(--sp-16) 0 var(--sp-24); color: var(--fg); font-family: var(--font-display); font-size: var(--type-h1); line-height: .95; }
.contact-page__lead { margin: 0 0 var(--sp-24); max-width: 46ch; color: var(--fg-muted); font-size: var(--type-body); line-height: 1.5; }
.contact-page__direct { margin: 0; color: var(--fg-muted); font-size: var(--type-small); }
.contact-page__direct a { color: var(--canasia-primary); font-weight: var(--fw-bold); }
.contact-page__form { padding: clamp(var(--sp-24), 3vw, var(--sp-40)); border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--bg-raised); }

/* ── News archive ─────────────────────────────────────────────────────── */
.news-section--archive h1 { margin: var(--sp-16) 0 0; font-family: var(--font-display); font-size: var(--type-h1); line-height: .95; }
.news-section__lead { max-width: 60ch; margin: var(--sp-16) 0 0; color: var(--fg-muted); font-size: var(--type-body); line-height: 1.5; }
.news-section__empty { margin: var(--sp-40) 0 0; color: var(--fg-muted); font-size: var(--type-body); }
.news-pagination { margin-top: var(--sp-48); }
.news-pagination .nav-links { display: flex; flex-wrap: wrap; gap: var(--sp-12); }
.news-pagination a, .news-pagination span { display: inline-flex; align-items: center; padding: var(--sp-8) var(--sp-16); border: 1px solid var(--border); border-radius: var(--radius-pill); color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-small); font-weight: var(--fw-medium); text-decoration: none; }
.news-pagination a:hover { border-color: var(--canasia-primary); color: var(--canasia-primary); }
.news-pagination .current { background: var(--fg); border-color: var(--fg); color: var(--fg-on-dark); }

/* ── Gravity Forms ────────────────────────────────────────────────────── */
/* The form is the site's one conversion point and was rendering in Gravity's
   own defaults -- a different type scale, different focus ring and different
   error colour from everything around it. These rules are also what put the
   semantic tokens to work: --canasia-error for validation, --cta-light for
   the success message. They were defined and unused, which is why an audit
   kept flagging them as dead. */
.gform_wrapper form { display: grid; gap: var(--sp-20); }
.gform_wrapper .gfield_label { display: block; margin-bottom: var(--sp-8); color: var(--fg); font-family: var(--font-sans); font-size: var(--type-small); font-weight: var(--fw-bold); }
.gform_wrapper .gfield_required { color: var(--canasia-error); margin-left: 2px; }
.gform_wrapper input[type="text"],
.gform_wrapper input[type="email"],
.gform_wrapper input[type="tel"],
.gform_wrapper input[type="url"],
.gform_wrapper textarea,
.gform_wrapper select { width: 100%; padding: var(--sp-12) var(--sp-16); border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--bg-raised); color: var(--fg); font-family: var(--font-sans); font-size: var(--type-small); line-height: 1.4; transition: border-color var(--dur-std) var(--ease-standard), box-shadow var(--dur-std) var(--ease-standard); }
.gform_wrapper input:focus-visible,
.gform_wrapper textarea:focus-visible,
.gform_wrapper select:focus-visible { outline: none; border-color: var(--canasia-primary); box-shadow: 0 0 0 3px rgba(29, 85, 126, .18); }
.gform_wrapper .gfield_checkbox li, .gform_wrapper .gfield_radio li { display: flex; align-items: flex-start; gap: var(--sp-8); margin-bottom: var(--sp-8); }
.gform_wrapper .gfield_checkbox label, .gform_wrapper .gfield_radio label { color: var(--fg-muted); font-family: var(--font-sans); font-size: var(--type-small); font-weight: var(--fw-regular); }
.gform_wrapper .gform_footer { margin-top: var(--sp-8); }
.gform_wrapper .gform_button { display: inline-flex; align-items: center; padding: var(--sp-12) var(--sp-32); border: 0; border-radius: var(--radius-pill); background: var(--cta); color: var(--fg); font-family: var(--font-display); font-size: var(--type-label); font-weight: var(--fw-regular); text-transform: uppercase; letter-spacing: .08em; cursor: pointer; transition: background-color var(--dur-std) var(--ease-standard); }
.gform_wrapper .gform_button:hover { background: var(--cta-hover); }
.gform_wrapper .gform_button:focus-visible { outline: 2px solid var(--canasia-primary); outline-offset: 3px; }
/* Validation. Gravity's defaults are a red that is not this brand's red. */
.gform_wrapper .gfield_error input,
.gform_wrapper .gfield_error textarea,
.gform_wrapper .gfield_error select { border-color: var(--error); box-shadow: 0 0 0 3px rgba(193, 53, 21, .14); }
.gform_wrapper .validation_message,
.gform_wrapper .gfield_validation_message { margin-top: var(--sp-8); color: var(--error); font-family: var(--font-sans); font-size: var(--type-micro); font-weight: var(--fw-medium); }
.gform_wrapper .gform_validation_errors { padding: var(--sp-16); border: 1px solid var(--error); border-left-width: 3px; border-radius: var(--radius-sm); background: rgba(193, 53, 21, .06); color: var(--error); font-size: var(--type-small); }
.gform_wrapper .gform_confirmation_message { padding: var(--sp-24); border-left: 3px solid var(--canasia-cta); border-radius: var(--radius-sm); background: var(--cta-light); color: var(--fg); font-size: var(--type-body); line-height: 1.5; }

/* ── Cards ────────────────────────────────────────────────────────────── */



/* ── CTA button ───────────────────────────────────────────────────────── */

.btn-pill {
  display: inline-block;
  background: var(--cta);
  color: var(--fg-on-dark);
  font-family: var(--font-display);
  font-weight: var(--fw-regular);
  font-size: var(--type-label);
  text-transform: uppercase;
  letter-spacing: .08em;
  line-height: 1.2;
  text-decoration: none;
  border-radius: var(--radius-pill);
  padding: 10px 20px;
  margin-top: var(--sp-32);
}
.topbar__cta,
.hero__primary-cta,
.hero__secondary-cta,
.btn-pill { font-size: var(--type-label); padding: 8px 14px; }
.btn-pill:hover { background: var(--cta-hover); }

/* ── Footer ───────────────────────────────────────────────────────────── */

.site-footer {
  background: var(--bg-inverse);
  color: var(--fg-on-dark);
  padding-block: var(--sp-32);
  border-top: 1px solid rgba(243, 245, 248, 0.12);
  margin-top: auto;
}
.site-footer__inner { display: flex; align-items: flex-start; gap: var(--sp-12); }
/* Icon badge is brand blue now, never the CTA pink -- pink is for calls to
   action; this is just the mark. */
.site-footer__mark { display: grid; place-items: center; flex: 0 0 auto; width: 20px; height: 20px; padding: 3px; border-radius: var(--radius-sm); background: var(--canasia-blue); margin-top: 2px; }
.site-footer__mark img { display: block; width: 100%; height: 100%; }
/* One flowing line -- tagline, copyright, every utility link, and the
   social icons all in the same row (wrapping together on narrow screens)
   at one uniform size/weight, instead of two visually different groups
   competing for the same right-hand corner GTranslate's own floating
   widget also sits in. */
.site-footer__line { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-8) var(--sp-16); min-width: 0; color: var(--fg-on-dark-muted); font-family: var(--font-sans); font-size: 11px; }
.site-footer__utility-link { color: inherit; font: inherit; text-decoration: none; white-space: nowrap; transition: color var(--dur-std) var(--ease-standard); }
.site-footer__utility-link:hover { color: var(--fg-on-dark); }
/* Outlined circles, quiet at rest, CTA pink on hover -- the treatment from
   Lara's own site. A ring rather than a filled chip keeps four marks from
   turning into four pink blobs in a footer that is otherwise all hairlines.
   Icon and ring shift together so the whole target responds, not just the
   glyph. */
.site-footer__social { display: flex; align-items: center; gap: var(--sp-12); list-style: none; margin: 0; padding: 0; }
.site-footer__social a { display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid var(--border-on-dark); border-radius: var(--radius-pill); transition: border-color var(--dur-std) var(--ease-standard), background-color var(--dur-std) var(--ease-standard); }
.site-footer__social img { display: block; width: 14px; height: 14px; filter: brightness(0) invert(1); opacity: .65; transition: opacity var(--dur-std) var(--ease-standard); }
.site-footer__social a:hover { border-color: var(--canasia-cta); background: rgba(255, 131, 172, .12); }
.site-footer__social a:hover img { opacity: 1; }
.site-footer__social a:focus-visible { outline: 2px solid var(--canasia-sky); outline-offset: 3px; }
/* ── Generic page fallback (page.php / index.php) ────────────────────── */

.page-main { padding-block: var(--sp-64); }
.page-header { text-align: center; margin-bottom: var(--sp-32); }
.page-title {
  /* A page's own Title must read as bigger than a same-page H2 — was
     accidentally the exact same size as one (--type-h2). See
     colors_and_type.css → Type roles. */
  font-family: var(--font-display);
  font-size: var(--type-h1);
  font-weight: var(--fw-regular);
  margin: 0;
}
.page-content { max-width: 68ch; margin: 0 auto; }

/* ── Focus states ─────────────────────────────────────────────────────
   Shared keyboard-visible focus ring. Uses sky-blue on both surfaces
   because it reads as an interactive signal, not brand identity. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--canasia-sky);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.skip-link:focus {
  position: fixed;
  top: var(--sp-12);
  left: var(--sp-12);
  z-index: 1000;
  padding: var(--sp-8) var(--sp-16);
  background: var(--bg-inverse);
  color: var(--fg-on-dark);
  border-radius: var(--radius-sm);
  text-decoration: none;
}
