/* ==========================================================================
   VCA banner
   Built from docs/research/banner-vca-audit.md. Every value below traces to a
   measurement in that audit — see it before changing anything here.
   ========================================================================== */

.vca-banner {
  /* Brand tokens, straight from assets/custom.css :root */
  /* One gutter drives the banner and the navigation, so every edge on the page
     lines up. The reference sets its content in about 6.8% from the frame. */
  --vca-navy: #073149;
  --vca-navy-deep: #04202f;
  --vca-teal: #27bfd4;
  --vca-mint: #c1dfdf;
  --vca-orange: #fe6710;
  --vca-warm: #ffc469;
  --vca-text: #f4f8f9;
  --vca-text-mute: rgba(214, 234, 238, 0.66);
  --vca-hairline: rgba(39, 191, 212, 0.26);
  /* The banner used to inherit this from the body:has() header handoff, which
     now only fires when the banner is the hero. Carrying the token here keeps
     the internal composition identical wherever the section is placed. */
  --vca-gutter: clamp(20px, 6.4vw, 116px);

  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(158deg, #031a27 0%, #052b3f 38%, var(--vca-navy) 72%, #0a3d58 100%);
  /* Clears the fixed 82px header; matches the reference 1.7916:1 canvas. */
  padding: 132px 0 168px;
  min-height: min(56.2vw, 860px);
  display: flex;
  align-items: center;
}

/* -------------------------------------------------------------- background */

.vca-bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.vca-bg > * { position: absolute; inset: 0; }

/* The field is built from the primary palette only — navy body, teal light.
   No grid, no tint in the corners, no warm cast anywhere. Depth comes from two
   broad teal lifts and a navy vignette, nothing else. */

/* A wide, very soft teal bloom behind the map, and a second low one at the
   lower left so the composition is lit diagonally rather than flatly. */
.vca-bg-glow {
  background:
    radial-gradient(
      64% 78% at 74% 40%,
      rgba(39, 191, 212, 0.2) 0%,
      rgba(39, 191, 212, 0.09) 34%,
      transparent 68%
    ),
    radial-gradient(
      58% 62% at 6% 96%,
      rgba(39, 191, 212, 0.15) 0%,
      rgba(15, 90, 118, 0.08) 40%,
      transparent 72%
    );
  animation: vca-glow-breathe 11s ease-in-out infinite;
}

/* Navy-only vignette. Deepens the top corners so the wordmark has a clean
   field, and settles the outer edges. */
.vca-bg-vignette {
  background:
    radial-gradient(58% 50% at 4% 0%, rgba(3, 22, 33, 0.82) 0%, transparent 68%),
    radial-gradient(100% 46% at 50% 0%, rgba(3, 22, 33, 0.5) 0%, transparent 74%),
    radial-gradient(70% 60% at 100% 100%, rgba(3, 22, 33, 0.42) 0%, transparent 70%);
}

/* ------------------------------------------------------------------ layout */

/* Same gutter as the navigation above it. */
.vca-shell {
  width: 100%;
  padding-inline: var(--vca-gutter, 32px) !important;
  --bs-gutter-x: 0;
}

.vca-inner {
  position: relative;
  /* Deliberately no z-index. A z-index here would open a stacking context and
     cut the map's screen blend off from the .vca-bg layers behind it, leaving
     the map's black field visible as a rectangle. DOM order already puts this
     above .vca-bg. */
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
  align-items: center;
  gap: clamp(24px, 3vw, 56px);
}

.vca-left { min-width: 0; }
.vca-right { min-width: 0; }

/* ---------------------------------------------------------------- wordmark */

/* The lockup now stacks: wordmark, then the grade line beneath it. */
.vca-lockup { display: inline-flex; flex-direction: column; align-items: flex-start; }

/* Recoleta at 600 is the display face for every title on the site, tracked at
   -0.025em. Matching it is what ties the banner to the rest of the page. */
.vca-wordmark {
  font-family: var(--font-display, "Recoleta", Georgia, serif);
  font-weight: 600;
  font-size: clamp(54px, 6.6vw, 112px);
  /* A line-height under 1 clips the cap and tail of a display serif once the
     gradient is clipped to the glyphs. Full leading plus a trim margin keeps
     the letterforms whole at every size. */
  line-height: 1.02;
  margin: -0.08em 0 -0.06em;
  padding-right: 0.06em;
  letter-spacing: -0.022em;
  background: linear-gradient(172deg, #ffffff 0%, #f2fbfc 38%, var(--vca-mint) 76%, #8fc4d0 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  position: relative;
  display: block;
  overflow: visible;
}

/* Replaces the stamp. Same eyebrow language as the page's "// DIAGNOSE"
   labels: teal, uppercase, widely tracked — but centred under the wordmark
   and flanked by rules so it reads as a certification mark, not a nav label. */
.vca-grade {
  display: flex;
  align-items: center;
  gap: clamp(9px, 0.9vw, 16px);
  width: 100%;
  margin-top: clamp(10px, 1.1vw, 20px);
  padding-left: 0.06em;
}

.vca-grade-rule {
  height: 1px;
  flex: 1 1 auto;
  min-width: 12px;
  background: linear-gradient(to right, transparent, var(--vca-teal), transparent);
  opacity: 0.85;
}
.vca-grade-rule:first-child {
  flex: 0 0 clamp(18px, 2.2vw, 44px);
  background: linear-gradient(to right, transparent, var(--vca-teal));
}

.vca-grade-text {
  flex: none;
  font-family: "Creato Display", Manrope, system-ui, sans-serif;
  font-weight: 700;
  font-size: clamp(10px, 0.92vw, 16px);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--vca-teal);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- headline */

/* Mirrors .home-v4-hero-title — the page's own hero setting. */
.vca-headline {
  margin: clamp(22px, 2.7vw, 44px) 0 0;
  max-width: 16em;
  font-family: var(--font-display, "Recoleta", Georgia, serif);
  font-weight: 600;
  font-size: clamp(21px, 2.34vw, 42px);
  line-height: 1.26;
  letter-spacing: -0.025em;
  color: var(--vca-text);
}

/* The emphasis is carried by the brand teal rather than by weight alone. */
.vca-headline b {
  font-weight: 600;
  color: var(--vca-teal);
}

.vca-nowrap { white-space: nowrap; }

.vca-arrow {
  display: inline-block;
  width: 0.78em;
  height: 0.78em;
  margin-left: 0.34em;
  vertical-align: -0.04em;
}
.vca-arrow svg { width: 100%; height: 100%; display: block; }
.vca-arrow circle { fill: none; stroke: currentColor; stroke-width: 1.5; opacity: 0.85; }
.vca-arrow path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------------------------------------------------------------- speakers */

/* The rotated label used to sit in a left gutter, which pushed the speaker row
   off the page's left edge. It now reads horizontally above the row so the
   wordmark, headline, label, portraits and footnote all share one edge. */
.vca-speakers {
  position: relative;
  margin-top: clamp(24px, 3.1vw, 52px);
}

.vca-hear-from {
  display: block;
  margin-bottom: clamp(10px, 1.1vw, 18px);
  font-family: "Creato Display", Manrope, system-ui, sans-serif;
  font-size: clamp(9px, 0.62vw, 12px);
  font-weight: 700;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--vca-teal);
  opacity: 0.85;
}

.vca-speaker-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(14px, 2.6vw, 46px);
  max-width: 780px;
}

.vca-speaker { min-width: 0; }

/* Held in plain greyscale for now. The teal-backdrop treatment is documented in
   the audit and can be reinstated once cut-out portraits exist. */
.vca-speaker-photo {
  margin: 0 0 clamp(10px, 1vw, 16px);
  aspect-ratio: 3 / 4;
  border-radius: clamp(10px, 1vw, 18px);
  overflow: hidden;
  border: 1px solid rgba(147, 197, 214, 0.22);
  background: #0a2b3d;
  position: relative;
  isolation: isolate;
  box-shadow:
    0 18px 38px rgba(2, 18, 28, 0.42),
    0 0 0 1px rgba(255, 255, 255, 0.04) inset;
}

.vca-speaker-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 20%;
  display: block;
  filter: grayscale(1) contrast(1.04);
  position: relative;
  z-index: 1;
}




/* Seats the figure on the panel rather than letting it float. */
.vca-speaker-photo::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 34%;
  background: linear-gradient(to top, rgba(6, 42, 60, 0.5), transparent);
  pointer-events: none;
  z-index: 3;
}

.vca-speaker-name {
  margin: 0;
  font-size: clamp(12px, 0.92vw, 17px);
  line-height: 1.3;
  color: #fff;
  font-weight: 400;
}
.vca-speaker-name b { font-weight: 700; }

.vca-speaker-role {
  margin: 2px 0 0;
  font-size: clamp(10px, 0.72vw, 13px);
  line-height: 1.35;
  font-style: italic;
  color: var(--vca-text-mute);
}

/* ---------------------------------------------------------------- footnote */

.vca-footnote {
  margin-top: clamp(22px, 3vw, 52px);
  font-size: clamp(12px, 0.86vw, 16px);
  font-weight: 600;
  line-height: 1.45;
  color: #fff;
}


/* --------------------------------------------------------------------- map */

/* Outer box reserves the gutters the labels sit in, above and below the map. */
.vca-map {
  position: relative;
  width: 100%;
  padding: 14% 0;
}

/* The stage carries the geography. Node coordinates and leader lengths are
   authored against this box, so the map must never be inset from it.

   No containment here on purpose: container-type/contain would open a stacking
   context, which isolates the map's screen blend and paints its black field
   instead of blending it away. Nodes span the stage so % lengths resolve. */
.vca-map-stage {
  position: relative;
  width: 100%;
  aspect-ratio: 974 / 616;
}

/* Solved against the asset's measured tones: the grey ocean clips to black and
   the landmass dots stay bright, then screen drops the black out. A radial mask
   softens the asset's hard rectangle into the field.

   (A luminance-mask treatment would colour the continents more faithfully, but
   needs the extruded map export — see the asset-gap note in the audit.) */
.vca-map-img {
  width: 100%;
  height: 100%;
  object-fit: fill;
  display: block;
  /* world-dots.svg is generated by scripts/build-map.mjs: even circles on a hex
     lattice, already the right colour, transparent everywhere else. Nothing to
     filter, blend or mask — so there is no rectangle left to hide. */
  filter: drop-shadow(0 0 12px rgba(120, 200, 220, 0.22));
  opacity: 0.97;
}


/* -------------------------------------------------------------- map  nodes */

/* Each node spans the whole stage; --x/--y place its parts. That keeps the
   leader's percentage height resolving against the map, not against a
   zero-height point. */
/* Above the map so the leaders stay legible where they cross the continents. */
.vca-node {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}

.vca-node-dot,
.vca-node-dot::before,
.vca-node-dot::after { position: absolute; border-radius: 50%; }

.vca-node-dot {
  left: var(--x);
  top: var(--y);
  width: 9px;
  height: 9px;
  transform: translate(-50%, -50%);
  background: var(--vca-orange);
  box-shadow:
    0 0 0 3px rgba(254, 103, 16, 0.3),
    0 0 16px 4px rgba(254, 103, 16, 0.6);
}

/* Bright core. */
.vca-node-dot::before {
  content: "";
  inset: 2.5px;
  background: var(--vca-warm);
}

/* Expanding halo. */
.vca-node-dot::after {
  content: "";
  left: 50%;
  top: 50%;
  width: 34px;
  height: 34px;
  margin: -17px 0 0 -17px;
  border: 1.5px solid var(--vca-warm);
  opacity: 0;
  animation: vca-pulse 2.4s ease-out infinite;
  animation-delay: var(--delay, 0ms);
}

/* Drawn as a repeating gradient rather than a dashed border so the dashes can
   flow along the leader once it has drawn in. */
.vca-node-line {
  position: absolute;
  left: var(--x);
  width: 1px;
  height: var(--len);
  background-image: linear-gradient(
    to bottom,
    var(--vca-teal) 0 6px,
    transparent 6px 14px
  );
  background-size: 1px 14px;
  background-repeat: repeat-y;
  opacity: 1;
  transform-origin: top center;
  filter: drop-shadow(0 0 3px rgba(4, 32, 47, 0.9));
}

.vca-node[data-dir="up"] .vca-node-line {
  bottom: calc(100% - var(--y));
  transform-origin: bottom center;
}
.vca-node[data-dir="down"] .vca-node-line {
  top: var(--y);
  transform-origin: top center;
}

.vca-node-label {
  position: absolute;
  left: calc(var(--x) + var(--shift, 0%));
  transform: translateX(-50%);
  width: max-content;
  max-width: 15ch;
  text-align: center;
  line-height: 1.2;
}

.vca-node[data-dir="up"] .vca-node-label {
  bottom: calc(100% - var(--y) + var(--len) + 10px);
}
.vca-node[data-dir="down"] .vca-node-label {
  top: calc(var(--y) + var(--len) + 10px);
}

.vca-pct {
  display: block;
  font-size: clamp(15px, 1.55vw, 28px);
  font-weight: 700;
  line-height: 1.05;
  color: var(--vca-orange);
  letter-spacing: -0.01em;
}

.vca-place {
  display: block;
  margin-top: 3px;
  font-size: clamp(9px, 0.85vw, 15px);
  font-weight: 400;
  line-height: 1.32;
  color: rgba(232, 245, 248, 0.9);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- entrance */

.vca-banner.vca-armed .vca-wordmark::after {
  content: "VCA";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, 0.92) 50%, transparent 62%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  background-size: 260% 100%;
  animation: vca-sheen 1.1s ease-out 0.25s 1 both;
  pointer-events: none;
}

.vca-banner.vca-armed .vca-grade { animation: vca-grade-in 0.72s cubic-bezier(0.22, 0.9, 0.3, 1) 0.34s both; }
.vca-banner.vca-armed .vca-headline { animation: vca-rise 0.5s ease-out 0.18s both; }
.vca-banner.vca-armed .vca-map-img { animation: vca-rise 0.9s ease-out both; }
.vca-banner.vca-armed .vca-footnote { animation: vca-rise 0.5s ease-out 0.5s both; }

.vca-banner.vca-armed .vca-speaker {
  animation: vca-rise 0.56s ease-out both;
  animation-delay: calc(0.3s + var(--i, 0) * 0.12s);
}

.vca-banner.vca-armed .vca-node-line {
  animation:
    vca-draw 0.52s ease-out both var(--delay, 0ms),
    vca-dash 1.6s linear infinite calc(var(--delay, 0ms) + 520ms);
}

.vca-banner.vca-armed .vca-node-label {
  animation: vca-label-in 0.42s ease-out both calc(var(--delay, 0ms) + 380ms);
}

.vca-banner.vca-armed .vca-node-dot {
  animation: vca-pop 0.4s ease-out both var(--delay, 0ms);
}

@keyframes vca-glow-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.86; }
}

@keyframes vca-pulse {
  0% { opacity: 0.55; transform: scale(0.25); }
  70% { opacity: 0; transform: scale(1.15); }
  100% { opacity: 0; transform: scale(1.15); }
}

@keyframes vca-sheen {
  from { background-position: 180% 0; }
  to { background-position: -80% 0; }
}

/* The rules draw outward from the text as the label settles. */
@keyframes vca-grade-in {
  from { opacity: 0; clip-path: inset(0 42% 0 0); }
  to { opacity: 1; clip-path: inset(0 0 0 0); }
}

@keyframes vca-rise {
  from { opacity: 0; transform: translateY(12px); }
  to { opacity: 1; transform: none; }
}

@keyframes vca-pop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.2); }
  to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes vca-draw {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes vca-dash {
  from { background-position: 0 0; }
  to { background-position: 0 -14px; }
}

@keyframes vca-label-in {
  from { opacity: 0; transform: translateX(-50%) translateY(6px); }
  to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* The stats band carries a negative top margin and a 96px dome, so it curves up
   into whatever sits above it — the mirror of .header-bottom::after at the top.
   The banner keeps that handoff and simply reserves room for it. */
.vca-banner + .home-v3-stats { position: relative; z-index: 2; }

/* A second, wider arc sits just behind the stats dome so the curve reads as a
   layered sweep rather than a single hard edge. */
.vca-banner::after {
  content: "";
  position: absolute;
  left: -6%;
  right: -6%;
  bottom: -58px;
  height: 150px;
  border-radius: 50% 50% 0 0 / 110px 110px 0 0;
  background: linear-gradient(to bottom, rgba(39, 191, 212, 0.16), rgba(39, 191, 212, 0.05));
  border-top: 1px solid rgba(39, 191, 212, 0.3);
  z-index: 1;
  pointer-events: none;
}

/* ------------------------------------------------------------- responsive */

@media (max-width: 1199px) {
  .vca-inner { grid-template-columns: 1fr; gap: 34px; }
  .vca-banner { min-height: 0; padding: 116px 0 150px; }
  .vca-headline { max-width: none; font-size: clamp(19px, 3.1vw, 30px); }
  .vca-wordmark { font-size: clamp(48px, 8.4vw, 80px); }
  .vca-stamp { width: clamp(72px, 11.6vw, 110px); }
  .vca-speaker-list { max-width: 620px; }
  .vca-right { order: 2; }
}

@media (max-width: 767px) {
  .vca-banner { padding: 100px 0 132px; }
  .vca-speaker-list { gap: 12px; }
  /* Deeper gutters so the six labels clear the landmass entirely. */
  .vca-map { padding: 32% 0; }
  .vca-place { font-size: 8.5px; line-height: 1.28; white-space: nowrap; }
  .vca-pct { font-size: 12px; }
  .vca-node-label { max-width: none; }
  .vca-node-dot { width: 7px; height: 7px; }
  .vca-node-dot::after { width: 24px; height: 24px; margin: -12px 0 0 -12px; }
  /* The authored per-node lengths are percentages of the map, so they scale
     down on their own. Flattening them to one value is what pushed the labels
     back onto the landmass — leave them alone and let the gutters do the work. */
  .vca-bg-ember {
    background: radial-gradient(
      120% 70% at 0% 104%,
      rgba(224, 78, 24, 0.9) 0%,
      rgba(190, 60, 19, 0.44) 30%,
      rgba(120, 36, 12, 0.16) 56%,
      transparent 78%
    );
  }
}

@media (prefers-reduced-motion: reduce) {
  .vca-banner *,
  .vca-banner *::before,
  .vca-banner *::after {
    animation: none !important;
    transition: none !important;
  }
  .vca-banner.vca-armed .vca-node-line { transform: scaleY(1); }
}

/* ==========================================================================
   Header handoff
   The banner runs full-bleed to the top of the document and the navigation
   sits directly on it, so the field reads as one surface rather than a dark
   block beneath a white bar. Scoped with :has() so pages without the banner
   keep the stock white header.
   ========================================================================== */

/* The reference sets its content roughly 6.8% in from the frame edge. One
   token drives the banner and the navigation so the logo, the wordmark and the
   map's right edge all sit on the same two lines. */
body:has(main > .vca-banner:first-of-type) {
  --vca-gutter: clamp(20px, 6.4vw, 116px);
}

/* Neutralise the theme's own gutters, then apply ours once. */
body:has(main > .vca-banner:first-of-type) .header-absolute .header-bottom {
  padding-inline: var(--vca-gutter) !important;
}
body:has(main > .vca-banner:first-of-type) .header-absolute .container-fluid,
body:has(main > .vca-banner:first-of-type) .header-absolute .row,
body:has(main > .vca-banner:first-of-type) .header-absolute .col-12 {
  padding-inline: 0 !important;
  margin-inline: 0 !important;
  --bs-gutter-x: 0;
}

body:has(main > .vca-banner:first-of-type) .tj-header-area.header-6.style-6.header-absolute,
body:has(main > .vca-banner:first-of-type) .tj-header-area.header-absolute,
body:has(main > .vca-banner:first-of-type) .tj-header-area.header-absolute .header-bottom {
  background-color: transparent !important;
  border-bottom: 0 !important;
  box-shadow: none !important;
}

/* The white dome belongs to the white header; with the header transparent it
   would cut a light crescent out of the banner. */
body:has(main > .vca-banner:first-of-type) .header-absolute .header-bottom::after { display: none; }
body:has(main > .vca-banner:first-of-type) .header-absolute .header-bottom::before { display: none; }

body:has(main > .vca-banner:first-of-type) .header-absolute .mainmenu ul:not(.sub-menu) > li > a,
body:has(main > .vca-banner:first-of-type) .header-absolute .menu_btn,
body:has(main > .vca-banner:first-of-type) .header-absolute .header-grid-icon {
  color: #ffffff;
}

body:has(main > .vca-banner:first-of-type) .header-absolute .mainmenu ul:not(.sub-menu) > li > a:hover {
  color: var(--brand-teal, #27bfd4);
}

/* Separator between the nav cluster and the CTA. */
body:has(main > .vca-banner:first-of-type) .header-absolute .header_right_info > *:first-child::after {
  background-color: rgba(255, 255, 255, 0.24);
}

/* A hairline instead of a hard edge, so the nav is seated without boxing it. */
body:has(main > .vca-banner:first-of-type) .header-absolute .header-wrapper {
  position: relative;
}
body:has(main > .vca-banner:first-of-type) .header-absolute .header-wrapper::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    rgba(39, 191, 212, 0.34) 22%,
    rgba(39, 191, 212, 0.34) 78%,
    transparent
  );
}

/* --------------------------------------------------------------- header CTA
   On its own navy sticky header the site styles this pill as charcoal with an
   orange icon, filling orange only on hover — secondary weight, so it does not
   compete with the floating orange CTA. The banner's header is dark for the
   same reason, so it takes the same treatment rather than the light-header
   version, which is solid orange. */

body:has(main > .vca-banner:first-of-type) .header-absolute .header-workshop-cta {
  background: var(--brand-charcoal, #333134);
  color: #fff !important;
  border: 1px solid rgba(255, 255, 255, 0.14);
}

body:has(main > .vca-banner:first-of-type) .header-absolute .header-workshop-cta::before {
  background: var(--brand-orange, #fe6710);
}

body:has(main > .vca-banner:first-of-type) .header-absolute .header-workshop-cta .pill-icon {
  background: var(--brand-orange, #fe6710);
  color: #fff;
}

body:has(main > .vca-banner:first-of-type) .header-absolute .header-workshop-cta:hover {
  color: #fff !important;
  border-color: transparent;
}

/* ==========================================================================
   VCA banner v2 — "dispute tape" artwork
   Rebuilt 12 Aug 2026 to match docs/design-references/banner-vca-v2-artwork.jpg.
   The .vcb-* layer replaces the world-map composition with the key-takeaways
   panel and the supplied prop imagery. The v1 .vca-* component rules above
   stay untouched — the Learn page webinar block still uses them.
   ========================================================================== */

.vca-banner.vcb {
  /* Flat deep navy with broad diagonal wash — no teal glow in the v2 art. */
  background: linear-gradient(140deg, #182c42 0%, #12253a 48%, #0e1f31 100%);
  display: block;
  /* Content decides the height; the v1 hero-scale floor leaves dead navy
     under the prop imagery. */
  min-height: 0;
}

.vca-banner.vcb::after { display: none; }

/* The reference field is nearly flat: deep navy carrying two very wide, very
   soft light sweeps. A fine hairline grain replaces the old coarse stripes,
   and the sweeps drift slowly so the field breathes without shouting. */
.vcb-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(112deg,
      rgba(255, 255, 255, 0.013) 0 1px,
      transparent 1px 110px),
    radial-gradient(85% 95% at 100% 105%, rgba(2, 14, 24, 0.5) 0%, transparent 58%),
    radial-gradient(70% 80% at 0% -5%, rgba(2, 14, 24, 0.42) 0%, transparent 52%);
}

.vcb-bg::before {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(112deg, transparent 26%, rgba(126, 196, 224, 0.05) 40%, transparent 56%),
    linear-gradient(112deg, transparent 58%, rgba(255, 255, 255, 0.03) 72%, transparent 88%);
  background-repeat: no-repeat;
  background-size: 240% 100%;
  background-position: 0% 0;
  animation: vcb-bg-drift 38s ease-in-out infinite alternate;
}

@keyframes vcb-bg-drift {
  from { background-position: 0% 0; }
  to { background-position: 100% 0; }
}

/* Seating: the v2 banner runs flush to its bottom edge so the prop imagery
   can sit on it, exactly as in the artwork. */
.vca-banner.vcb.vca-mid { padding: 76px 0 0; }

.vcb-inner {
  position: relative;
  width: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, 1fr);
  gap: clamp(32px, 4vw, 76px);
  align-items: stretch;
}

.vcb-left {
  min-width: 0;
  padding-bottom: 40px;
}

/* Learn-page hero seat: same composition as the mid-page banner, but it runs
   under the fixed header at the top of the document, so it clears it. */
.vca-banner.vcb-hero { padding: 124px 0 0; }

/* ------------------------------------------------------------------- chip */

.vcb-status {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
}

/* The on-demand "coming soon" state rides next to the chip — warm gradient,
   dark text, unmistakably a status and not a button. */
.vcb-chip-state {
  display: inline-flex;
  align-items: center;
  padding: 11px 18px;
  border-radius: 999px;
  background: linear-gradient(120deg, var(--vca-warm), var(--vca-orange));
  color: #04202f;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
}

.vcb-chip {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  padding: 10px 24px;
  border: 1.5px solid rgba(84, 200, 224, 0.55);
  border-radius: 999px;
  color: #fff;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1;
}

.vcb-chip-play {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 19px;
  border-radius: 5px;
  background: #fff;
  color: #12253a;
  font-size: 8px;
  animation: vcb-play-pulse 3.2s ease-out infinite;
}

@keyframes vcb-play-pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.35); }
  55% { box-shadow: 0 0 0 9px rgba(255, 255, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
}

/* ----------------------------------------------------------------- lockup */

.vcb-lockup-frame {
  position: relative;
  /* Block-level with shrink-wrap width: inline-level here would let the chip
     share its line box whenever the column is wide enough. */
  display: block;
  width: fit-content;
  margin: 24px 0 20px;
  overflow: hidden;
}

.vcb-lockup {
  display: block;
  width: clamp(340px, 30vw, 560px);
  height: auto;
}

/* A light sweep crosses the lockup once as the banner arms — the image-based
   twin of the v1 wordmark sheen. */
.vcb-lockup-frame::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 34%, rgba(255, 255, 255, 0.38) 50%, transparent 66%);
  /* no-repeat matters: a repeating tile puts a second copy of the sweep in
     view once the animation parks off-canvas — a permanent white wash. */
  background-repeat: no-repeat;
  background-size: 260% 100%;
  background-position: 180% 0;
  mix-blend-mode: overlay;
  pointer-events: none;
}

.vca-banner.vca-armed .vcb-lockup-frame::after {
  animation: vca-sheen 1.2s ease-out 0.5s 1 both;
}

/* --------------------------------------------------------------- headline */

.vcb-headline {
  margin: 0;
  max-width: 44ch;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-weight: 400;
  font-size: clamp(20px, 1.85vw, 30px);
  line-height: 1.4;
  color: rgba(255, 255, 255, 0.94);
}

.vcb-headline b {
  font-weight: 700;
  color: var(--vca-teal);
}

.vcb-headline .vca-arrow { color: #fff; }

/* --------------------------------------------------------------- speakers */

/* The label reads horizontally above the row — same call as v1: the chip,
   lockup, headline, portraits and CTA all share one left edge. */
.vcb-speakers {
  margin-top: 28px;
}

.vcb-hear {
  display: block;
  margin-bottom: 14px;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--vca-teal);
  opacity: 0.9;
}

.vcb-speaker-list {
  display: flex;
  gap: clamp(14px, 1.7vw, 26px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.vcb-speaker { min-width: 0; }

.vcb-speaker-photo {
  width: clamp(116px, 10.8vw, 168px);
  aspect-ratio: 1;
  margin: 0 0 12px;
  border-radius: 20px;
  overflow: hidden;
}

.vcb-speaker-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1);
}

.vcb-speaker-name {
  margin: 0;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 15px;
  font-weight: 400;
  color: #fff;
}

.vcb-speaker-name b { font-weight: 700; }

.vcb-speaker-role {
  margin: 3px 0 0;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 12px;
  font-style: italic;
  color: rgba(255, 255, 255, 0.68);
}

/* ------------------------------------------------------------------- foot */

.vcb-foot {
  display: flex;
  align-items: center;
  gap: 44px;
  margin-top: 30px;
}

.vcb-when {
  font-family: var(--font-body, "Creato Display", sans-serif);
  color: #fff;
  display: grid;
  gap: 8px;
}

.vcb-when-row { margin: 0; display: flex; align-items: center; gap: 10px; font-size: 17px; }
.vcb-when-row i { color: rgba(255, 255, 255, 0.85); }
.vcb-when-label { text-transform: uppercase; font-size: 14px; letter-spacing: 0.06em; }
.vcb-when-row b { font-weight: 800; letter-spacing: 0.02em; }

.vcb-cta-wrap {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

.vcb-register {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  border: 0;
  cursor: pointer;
  padding: 14px 30px;
  border-radius: 14px;
  background: var(--vca-orange);
  color: #fff;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: clamp(16px, 1.35vw, 21px);
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-decoration: none;
  box-shadow: 0 12px 32px rgba(254, 103, 16, 0.32);
  transition: transform 0.2s ease, box-shadow 0.2s ease, background-color 0.2s ease;
}

.vcb-register:hover {
  background: #e85a08;
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 16px 38px rgba(254, 103, 16, 0.42);
}

.vcb-register:focus-visible { outline: 2px solid var(--vca-teal); outline-offset: 3px; }

/* A shine crosses the CTA every few seconds so the eye keeps returning to it. */
.vcb-register {
  position: relative;
  overflow: hidden;
}

.vcb-register::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255, 255, 255, 0.34) 50%, transparent 62%);
  background-repeat: no-repeat;
  background-size: 280% 100%;
  background-position: 190% 0;
  animation: vcb-cta-sheen 5.5s ease-in-out 2s infinite;
  pointer-events: none;
}

@keyframes vcb-cta-sheen {
  0% { background-position: 190% 0; }
  32% { background-position: -90% 0; }
  100% { background-position: -90% 0; }
}

/* -------------------------------------------------------------- takeaways */

.vcb-right {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.vcb-takeaways { margin-top: 8px; }

/* Not a button. The solid orange slab competed with Register Now, so the
   header takes the site's own eyebrow language — "// DIAGNOSE" et al — and
   orange stays reserved for the single CTA. */
.vcb-tk-title {
  margin: 6px 0 22px;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: clamp(14px, 1.15vw, 18px);
  font-weight: 700;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--vca-teal);
}

.vcb-tk-title::before { content: "// "; }

.vcb-tk-title::after {
  content: "";
  display: block;
  width: 46px;
  height: 2px;
  margin-top: 12px;
  background: linear-gradient(to right, var(--vca-teal), transparent);
}

.vcb-tk-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 16px;
}

.vcb-tk-list li {
  position: relative;
  padding-left: 32px;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: clamp(15px, 1.3vw, 19px);
  font-weight: 300;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
}

.vcb-tk-list li b { font-weight: 700; color: #fff; }

.vcb-tk-list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.45em;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--vca-orange);
  animation: vcb-dot-pulse 3.6s ease-out infinite;
}

.vcb-tk-list li:nth-child(2)::before { animation-delay: 1.2s; }
.vcb-tk-list li:nth-child(3)::before { animation-delay: 2.4s; }

@keyframes vcb-dot-pulse {
  0% { box-shadow: 0 0 0 0 rgba(254, 103, 16, 0.4); }
  50% { box-shadow: 0 0 0 8px rgba(254, 103, 16, 0); }
  100% { box-shadow: 0 0 0 0 rgba(254, 103, 16, 0); }
}

/* ------------------------------------------------------------------ props */

.vcb-takeaways {
  position: relative;
  z-index: 1;
}

.vcb-props {
  /* Fills the column and sinks to the banner's bottom edge — the pedestal
     stands on it. Tucked up under the bullets so the column reads as one
     composition instead of a header, a void, and a corner image. */
  position: relative;
  z-index: 0;
  margin: auto -6% 0 auto;
  padding-top: 6px;
  width: min(138%, 1000px);
}

.vcb-props img {
  display: block;
  width: 100%;
  height: auto;
}

/* Once the entrance settles, the composition floats gently. */
@keyframes vcb-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-9px); }
}

/* --------------------------------------------------------------- entrance */

.vca-banner.vca-armed .vcb-chip { animation: vca-rise 0.5s ease-out 0.08s both; }
.vca-banner.vca-armed .vcb-lockup-frame { animation: vca-rise 0.6s ease-out 0.16s both; }
.vca-banner.vca-armed .vcb-headline { animation: vca-rise 0.5s ease-out 0.26s both; }
.vca-banner.vca-armed .vcb-hear { animation: vca-rise 0.5s ease-out 0.34s both; }
.vca-banner.vca-armed .vcb-foot { animation: vca-rise 0.56s ease-out 0.66s both; }
.vca-banner.vca-armed .vcb-tk-title { animation: vca-rise 0.5s ease-out 0.24s both; }

/* Bullets slide in from the right, one after another. */
.vca-banner.vca-armed .vcb-tk-list li { animation: vcb-tk-in 0.55s cubic-bezier(0.22, 0.9, 0.3, 1) both; }
.vca-banner.vca-armed .vcb-tk-list li:nth-child(1) { animation-delay: 0.38s; }
.vca-banner.vca-armed .vcb-tk-list li:nth-child(2) { animation-delay: 0.52s; }
.vca-banner.vca-armed .vcb-tk-list li:nth-child(3) { animation-delay: 0.66s; }

@keyframes vcb-tk-in {
  from { opacity: 0; transform: translateX(26px); }
  to { opacity: 1; transform: none; }
}

/* The props rise in, then keep floating; scroll parallax rides on the figure
   itself (banner-vca.js) so the two transforms never fight. */
.vca-banner.vca-armed .vcb-props img {
  animation:
    vcb-props-in 0.8s cubic-bezier(0.22, 0.9, 0.3, 1) 0.45s both,
    vcb-float 7s ease-in-out 2.4s infinite;
}

@keyframes vcb-props-in {
  from { opacity: 0; transform: translateY(36px) scale(0.965); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------- responsive */

/* Big desktops: hand the right column more width so the composition can fill
   it instead of shrinking into the bottom corner. */
@media (min-width: 1600px) {
  .vcb-inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); }
  .vcb-props { width: min(132%, 1120px); margin-right: -8%; }
}

@media (max-width: 1199px) {
  .vcb-inner { grid-template-columns: 1fr; gap: 40px; }
  .vca-banner.vcb.vca-mid { padding: 60px 0 0; }
  .vcb-left { padding-bottom: 0; }
  .vcb-lockup { width: clamp(300px, 52vw, 480px); }
  .vcb-headline { max-width: none; }
  .vcb-props { width: min(620px, 98%); margin-right: 0; }
}

@media (max-width: 767px) {
  .vca-banner.vcb.vca-mid { padding: 48px 0 0; }
  .vcb-chip { padding: 9px 18px; font-size: 12px; }
  .vcb-lockup { width: min(420px, 92%); }
  .vcb-speakers { gap: 10px; }
  .vcb-speaker-list { gap: 10px; }
  .vcb-speaker-photo { width: clamp(80px, 23vw, 120px); border-radius: 14px; }
  .vcb-speaker-name { font-size: 13px; }
  .vcb-speaker-role { font-size: 10.5px; }
  .vcb-foot { flex-direction: column; align-items: flex-start; gap: 24px; }
  .vcb-props { width: 100%; }
}

.vcb-register-chevrons { width: 0.9em; height: 0.65em; display: inline-block; }

/* ==========================================================================
   Coming-soon video player — Learn hero's right-column anchor. A glass
   16:9 frame over the campaign art, with a pulsing play control and a
   waiting progress bar. Clicking it opens the registration dialog.
   ========================================================================== */

/* The hero doesn't run flush to its bottom edge once the player replaces the
   prop imagery — glass needs air around it. */
.vca-banner.vcb-hero { padding-bottom: 64px; }

.vcb-player-wrap {
  margin: auto 0;
  padding-top: 30px;
}

.vcb-player {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: 20px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(255, 255, 255, 0.05);
  box-shadow:
    0 28px 70px rgba(2, 14, 24, 0.55),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
  cursor: pointer;
  transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;
}

.vcb-player:hover,
.vcb-player:focus-visible {
  transform: translateY(-3px);
  border-color: rgba(255, 255, 255, 0.3);
  box-shadow:
    0 34px 80px rgba(2, 14, 24, 0.6),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

.vcb-player:focus-visible { outline: 2px solid var(--vca-teal); outline-offset: 3px; }

/* Campaign art, dimmed behind the glass. */
.vcb-player-poster {
  position: absolute;
  inset: 0;
  display: block;
  background: linear-gradient(160deg, #1b3048 0%, #102337 55%, #0c1c2d 100%);
}

.vcb-player-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 70%;
  opacity: 0.42;
  filter: saturate(0.9);
  transition: opacity 0.3s ease, transform 0.5s ease;
}

.vcb-player:hover .vcb-player-poster img {
  opacity: 0.52;
  transform: scale(1.025);
}

/* Frosted light across the pane, with a slow travelling sheen. */
.vcb-player-glass {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(115deg, rgba(255, 255, 255, 0.14) 0%, rgba(255, 255, 255, 0.03) 34%, transparent 60%),
    radial-gradient(120% 90% at 50% 115%, rgba(2, 14, 24, 0.55) 0%, transparent 55%);
}

.vcb-player-glass::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(105deg, transparent 40%, rgba(255, 255, 255, 0.1) 50%, transparent 60%);
  background-repeat: no-repeat;
  background-size: 260% 100%;
  background-position: 180% 0;
  animation: vcb-player-sheen 6.5s ease-in-out 1.5s infinite;
}

@keyframes vcb-player-sheen {
  0% { background-position: 180% 0; }
  38% { background-position: -80% 0; }
  100% { background-position: -80% 0; }
}

/* ------------------------------------------------------------ centrepiece */

.vcb-player-center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
  padding-bottom: 40px;
}

.vcb-player-play {
  display: inline-grid;
  place-items: center;
  width: clamp(58px, 5.6vw, 78px);
  aspect-ratio: 1;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.4);
  background: rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(8px);
  color: #fff;
  font-size: clamp(16px, 1.5vw, 22px);
  padding-left: 4px;
  animation: vcb-player-pulse 3s ease-out infinite;
  transition: transform 0.25s ease, background-color 0.25s ease;
}

.vcb-player:hover .vcb-player-play {
  transform: scale(1.08);
  background: rgba(254, 103, 16, 0.85);
  border-color: rgba(255, 255, 255, 0.55);
}

@keyframes vcb-player-pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.3); }
  55% { box-shadow: 0 0 0 18px rgba(255, 255, 255, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); }
}

.vcb-player-coming {
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: clamp(15px, 1.3vw, 19px);
  font-weight: 800;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 2px 14px rgba(2, 14, 24, 0.6);
}

.vcb-player-sub {
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: clamp(12px, 0.95vw, 14px);
  color: rgba(255, 255, 255, 0.72);
}

/* ------------------------------------------------------------ control bar */

.vcb-player-bar {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  display: flex;
  align-items: center;
  gap: 14px;
  height: 46px;
  padding: 0 18px;
  border-radius: 13px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(6, 18, 30, 0.48);
  backdrop-filter: blur(10px);
  color: rgba(255, 255, 255, 0.85);
  font-size: 12px;
}

.vcb-player-track {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
  overflow: hidden;
}

/* Indeterminate: the fill patrols the track while there is nothing to play. */
.vcb-player-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 22%;
  border-radius: 999px;
  background: linear-gradient(to right, var(--vca-teal), #7fdceb);
  animation: vcb-player-wait 2.6s ease-in-out infinite alternate;
}

@keyframes vcb-player-wait {
  from { left: 0%; }
  to { left: 78%; }
}

.vcb-player-time {
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: rgba(255, 255, 255, 0.7);
  white-space: nowrap;
}

.vcb-player-ico { width: 17px; height: 17px; opacity: 0.8; flex: none; }

/* --------------------------------------------------------------- entrance */

.vca-banner.vca-armed .vcb-player-wrap { animation: vca-rise 0.7s ease-out 0.42s both; }

@media (max-width: 1199px) {
  .vca-banner.vcb-hero { padding-bottom: 56px; }
  .vcb-player-wrap { padding-top: 22px; }
}

@media (max-width: 767px) {
  .vca-banner.vcb-hero { padding-bottom: 44px; }
  .vcb-player { border-radius: 14px; }
  .vcb-player-bar { left: 8px; right: 8px; bottom: 8px; height: 40px; padding: 0 13px; gap: 10px; }
  .vcb-player-center { padding-bottom: 30px; gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .vcb-player,
  .vcb-player-play,
  .vcb-player-poster img { transition: none; animation: none; }
  .vcb-player-glass::after,
  .vcb-player-fill { animation: none; }
}

/* Hero-scale takeaways: on the Learn hero this is the primary reading
   content, so it takes hero-grade type — which also lets the column fill
   its height instead of pooling empty space above the player. */
.vcb-hero .vcb-tk-title {
  font-size: clamp(15px, 1.25vw, 20px);
  margin-bottom: 28px;
}

.vcb-hero .vcb-tk-list { gap: 22px; }

.vcb-hero .vcb-tk-list li {
  font-size: clamp(16px, 1.45vw, 21px);
  padding-left: 34px;
  line-height: 1.55;
}

.vcb-hero .vcb-tk-list li::before { top: 0.48em; width: 12px; height: 12px; }

/* The player hugs the takeaways with one comfortable gap; whatever height is
   left over falls to the bottom of the section, where it reads as padding
   rather than a hole in the column. */
.vcb-hero .vcb-player-wrap {
  margin: 44px 0 auto;
  padding-top: 0;
}

.vcb-player-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 26px;
  margin: 16px 0 0;
  font-family: var(--font-body, "Creato Display", sans-serif);
  font-size: 13px;
  color: rgba(255, 255, 255, 0.62);
}

.vcb-player-meta span { display: inline-flex; align-items: center; gap: 8px; }
.vcb-player-meta i { color: var(--vca-teal); font-size: 11px; }
