/* Marketing Leadership Series, V2.
 *
 * Same brand tokens and the same verbatim copy as V1. The structure is rebuilt
 * around what converts on event pages:
 *  - Sticky registration rail that follows the scroll (Eventbrite's ticket panel)
 *  - The registration panel is a perforated ticket stub (Stripe Sessions)
 *  - Live countdown and a repeating detail ticker (Maze DiscoConf)
 *  - Divided fact bar under the title (Upwork Work Without Limits)
 *  - Agenda as a vertical timeline
 *
 * Brand corrections over V1: the hatched arc rings are present (canon calls
 * them non-negotiable and V1 shipped without them), and there is a grain
 * overlay so the large dark fields have texture.
 */

/* ============================================================ TOKENS */

:root {
  color-scheme: dark;

  --void:        #0E0526;
  --abyss:       #1A0840;
  /* Lifted from #2A1647. At four points of lightness above the field it was
     invisible as a section change, so .field-panel never earned its step. */
  --purple-800:  #33195A;
  --purple-700:  #4B2771;
  --purple-500:  #7746A1;

  --pink-700:    #B73AB0;
  --pink-500:    #FF1BC0;
  --pink-400:    #FF3D8E;

  --white:       #FFFFFF;
  --ink:         #2D1059;

  --text-100:    #F5F0FF;
  --text-200:    #E1D7F2;
  --text-300:    #B9A8D6;
  --text-400:    #9684B6;

  --panel:       rgba(255, 255, 255, 0.04);
  --panel-hi:    rgba(255, 255, 255, 0.07);
  --border:      rgba(255, 255, 255, 0.10);
  --border-hi:   rgba(255, 255, 255, 0.22);

  --grad-cta:    linear-gradient(90deg, var(--pink-700) 0%, var(--pink-500) 100%);

  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 24px;  --space-6: 32px;  --space-7: 48px;  --space-8: 64px;
  --space-9: 96px;  --space-10: 128px;

  --radius-sm: 6px;  --radius-md: 12px;  --radius-lg: 20px;
  --radius-xl: 28px; --radius-pill: 999px;

  --max: 1240px;
  /* ch is the width of "0", which is narrow in Quicksand, so 62ch measured
     nearer 76 characters. 54ch lands in the comfortable band. */
  --prose: 54ch;

  --display: Oswald, "Arial Narrow", system-ui, sans-serif;
  --body: Quicksand, ui-sans-serif, system-ui, -apple-system, sans-serif;

  --shadow: 0 40px 100px rgba(5, 1, 16, 0.7);
  --shadow-card: 0 20px 50px rgba(5, 1, 16, 0.45);
  --header-h: 68px;
  --rail-top: calc(var(--header-h) + 24px);

  /* One section rhythm value. Everything else derives from it. */
  --sec: 88px;
}
@media (max-width: 720px) { :root { --sec: 56px; } }

/* ============================================================ RESET */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--void);
  color: var(--text-200);
  font: 400 16px/1.6 var(--body);
  overflow-x: hidden;
  scroll-padding-top: calc(var(--header-h) + var(--space-5));
}

/* Fine grain over the page. Large flat dark fields band on cheap panels and
   read as plastic; a little noise fixes both. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: 1; pointer-events: none; opacity: 0.1;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

img, svg, video { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
button { font: inherit; }

:focus-visible { outline: 3px solid var(--pink-400); outline-offset: 3px; border-radius: var(--radius-sm); }

.skip-link {
  position: absolute; left: -9999px; top: var(--space-2);
  background: var(--white); color: var(--ink);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-pill); font-weight: 700; z-index: 300;
}
.skip-link:focus { left: var(--space-4); }

.vh { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ============================================================ TYPE */

h1, h2, h3, h4 {
  margin: 0;
  color: var(--text-100);
  font-family: var(--display);
  text-transform: uppercase;
  font-weight: 600;
}

/* Uppercase Oswald needs negative tracking once it is past about 60px, or the
   counters open up and it reads as builder default rather than typeset. */
.d1 { font-size: clamp(44px, 6.4vw, 96px); line-height: 0.94; letter-spacing: -0.025em; font-weight: 700; }
/* At 390px the tracked 44px minimum left literally no optical gutter. */
@media (max-width: 420px) { .d1 { font-size: 40px; } }
.d2 { font-size: clamp(30px, 3.8vw, 52px); line-height: 1.0;  letter-spacing: -0.012em; font-weight: 700; }
h2  { font-size: clamp(28px, 3.4vw, 46px); line-height: 1.06; letter-spacing: -0.005em; font-weight: 600; }
h3  { font-size: clamp(19px, 1.8vw, 24px); line-height: 1.18; letter-spacing: 0.02em;   font-weight: 600; }
h4  { font-size: 15px; line-height: 1.3; letter-spacing: 0.12em; font-weight: 500; }

p { margin: 0 0 var(--space-4); }
.lead { font-size: clamp(17px, 1.35vw, 21px); line-height: 1.5; color: var(--text-100); max-width: 44ch; }
.small { font-size: 14px; }
.muted { color: var(--text-300); }

.prose { max-width: var(--prose); }
/* A step between the 46px heading and the body, so a section is not "huge
   heading then small grey text". */
.prose p { color: var(--text-300); font-size: 17px; line-height: 1.65; }
.prose strong { color: var(--text-100); font-weight: 700; }
.prose h2 { margin-bottom: var(--space-4); }

.eyebrow {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin: 0 0 var(--space-4);
  font-family: var(--display); font-size: 12px; font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--pink-400);
}
.eyebrow::before { content: ""; width: 22px; height: 1px; background: var(--pink-500); flex: none; }

.accent { color: var(--pink-500); }

/* ============================================================ LAYOUT */

.wrap { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--space-5); }

.section { position: relative; padding: var(--sec) 0; }
.section-sm { position: relative; padding: calc(var(--sec) * 0.7) 0; }
/* Two full sections back to back read as one long void, so the join is tighter
   than either section's own rhythm. */
.section + .section { padding-top: calc(var(--sec) * 0.7); }

.head { max-width: 760px; margin-bottom: var(--space-6); }
.head.center { margin-left: auto; margin-right: auto; text-align: center; }
.head h2 { margin-bottom: var(--space-4); }
.head > p:last-child { margin-bottom: 0; }

.field-deep { background: var(--abyss); }
.field-void { background: var(--void); }
/* Where a lit field meets a flat one the orb was sliced off dead straight.
   Declaring the edge makes it read as a step rather than a truncation. */
.field-deep, .field-void, .field-panel { border-top: 1px solid var(--border); }
.orbfield + .orbfield { border-top: 1px solid var(--border); }
.field-panel { background: var(--purple-800); }
/* Adjacent same-tone sections still need an edge. */
.field-deep + .field-deep { border-top: 1px solid var(--border); }

/* Two distinct radial orbs with a dark gap between them, per canon. */
.orbfield { position: relative; isolation: isolate; }
.orbfield::before {
  content: ""; position: absolute; inset: 0; z-index: -2; pointer-events: none;
  background:
    radial-gradient(52% 46% at 18% 14%, rgba(192, 64, 168, 0.4)  0%, rgba(192, 64, 168, 0) 70%),
    radial-gradient(50% 48% at 84% 86%, rgba(119, 70, 161, 0.46) 0%, rgba(119, 70, 161, 0) 72%),
    var(--abyss);
}
/* Mirrored instance. Repeating one orb signature five times down a page is
   what makes a site read as tiled; alternating keeps canon and breaks the tile. */
.orbfield--b::before {
  background:
    radial-gradient(50% 46% at 82% 16%, rgba(192, 64, 168, 0.36) 0%, rgba(192, 64, 168, 0) 70%),
    radial-gradient(52% 48% at 16% 84%, rgba(119, 70, 161, 0.44) 0%, rgba(119, 70, 161, 0) 72%),
    var(--abyss);
}

/* Hatched arc rings. Canon device, missing from V1.
   They live inside .arcs, which does the clipping. The section itself must NOT
   clip, because a clipping ancestor kills position:sticky on the rail. */
.arcs { position: absolute; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.arc {
  position: absolute;
  /* Capped: 70% of a 5,000px section is a circle wider than the viewport. */
  height: min(70%, 460px);
  aspect-ratio: 1 / 1; width: auto;
  opacity: 0.24;
  -webkit-mask: radial-gradient(circle, transparent 0 30%, #000 30% 50%, transparent 50%);
          mask: radial-gradient(circle, transparent 0 30%, #000 30% 50%, transparent 50%);
  background-image: repeating-linear-gradient(135deg, rgba(255,255,255,0.9) 0 1.2px, transparent 1.2px 7px);
}
.arc--tl { top: 0;    left: 0;  transform: translate(-50%, -50%); }
.arc--tr { top: 0;    right: 0; transform: translate(50%, -50%); }
.arc--bl { bottom: 0; left: 0;  transform: translate(-50%, 50%); }
.arc--br { bottom: 0; right: 0; transform: translate(50%, 50%); }
@media (max-width: 720px) { .arc { opacity: 0.16; } }

/* ============================================================ BUTTONS */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border: 0; border-radius: var(--radius-pill);
  font-family: var(--display);
  /* 19px at 700 clears WCAG's large-text threshold (18.66px bold), which is
     what lets the canon CTA gradient stay exactly as specified. White on the
     #FF1BC0 end measures 3.40:1, under AA for normal text but fine for large. */
  font-size: 19px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none;
  cursor: pointer; position: relative; overflow: hidden;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.btn-primary {
  background: var(--grad-cta); color: var(--white);
  box-shadow: 0 14px 34px rgba(255, 27, 192, 0.28);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 20px 46px rgba(255, 27, 192, 0.44); }

/* A slow sheen on the primary CTA. Draws the eye to the one thing that matters
   without moving anything the reader is trying to read. */
/* Only the ticket's own submit and the closing CTA get the sheen. Four of them
   animating in one viewport is not "one dominant pink moment". */
.ticket .hs-button::after,
.ticket .btn-primary::after,
.callout .btn-primary::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 35%, rgba(255,255,255,0.3) 50%, transparent 65%);
  transform: translateX(-120%);
  animation: sheen 5.5s ease-in-out infinite;
}
.ticket .hs-button, .ticket .btn-primary, .callout .btn-primary { position: relative; overflow: hidden; }
@keyframes sheen {
  0%, 62% { transform: translateX(-120%); }
  82%, 100% { transform: translateX(120%); }
}
@media (prefers-reduced-motion: reduce) { .btn-primary::after { display: none; } }

.btn-ghost { background: transparent; color: var(--text-100); border: 1px solid var(--border-hi); }
.btn-ghost:hover { background: var(--panel-hi); border-color: var(--pink-400); }

.btn-sm { padding: var(--space-3) var(--space-5); font-size: 15px; letter-spacing: 0.08em; }
/* Small primaries are normal-size text, so they cannot lean on the large-text
   exemption the 19px CTA uses. Solid --pink-700 gives white 4.95:1 and stays
   inside the canon accent ramp. */
.btn-sm.btn-primary { background: var(--pink-700); }
.btn-block { width: 100%; }

/* ============================================================ HEADER */

.site-header {
  position: sticky; top: 0; z-index: 100; height: var(--header-h);
  /* Pulled up over the first section so the hero's field runs behind it and
     there is no hard step at the 68px baseline. */
  margin-bottom: calc(var(--header-h) * -1);
  display: flex; align-items: center;
  /* Transparent at rest. A tinted bar over the hero's lit field produced a hard
     horizontal seam at 68px on every page. */
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.2s ease, border-color 0.2s ease, backdrop-filter 0.2s ease;
}
.site-header.is-scrolled {
  background: rgba(11, 4, 30, 0.92);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border-bottom-color: var(--border);
}
/* The header clips the CTA's glow into a smear along its bottom edge. */
.site-header .btn-primary { box-shadow: none; }

.header-inner {
  width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 var(--space-5);
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-5);
}

/* The SGM logo is the only mark. The typographic "Marketing Leadership /
   Series" lockup that used to sit beside it was a stand-in, since the series
   has no mark of its own, and it read as filler rather than identity. */
.brand { display: flex; align-items: center; text-decoration: none; min-width: 0; }
.brand-sgm { height: 30px; width: auto; }

.nav { display: flex; align-items: center; gap: var(--space-6); }
.nav a {
  font-family: var(--display); font-size: 12px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; text-decoration: none;
  color: var(--text-300); transition: color 0.15s ease;
}
.nav a:hover, .nav a.is-current { color: var(--text-100); }

.nav-toggle {
  display: none; min-height: 44px; min-width: 44px;
  background: transparent; border: 1px solid var(--border-hi);
  border-radius: var(--radius-sm); color: var(--text-100);
  padding: var(--space-2) var(--space-4); cursor: pointer;
  font-family: var(--display); font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase;
}

@media (max-width: 900px) {
  .brand-sgm { height: 26px; }
  .nav-toggle { display: block; }
  .site-header { background: rgba(11, 4, 30, 0.9); }
  .nav {
    position: absolute; top: var(--header-h); left: 0; right: 0;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--space-4) var(--space-5) var(--space-6);
    background: rgba(11, 4, 30, 0.99); border-bottom: 1px solid var(--border);
    display: none;
  }
  .nav.is-open { display: flex; }
  .nav a { padding: var(--space-4) 0; border-bottom: 1px solid var(--border); font-size: 15px; }
  .nav .btn { margin-top: var(--space-4); }
}

/* ============================================================ HERO */

/* No overflow:hidden here. The arcs are clipped by .arcs instead, because a
   clipping ancestor stops position:sticky working on the rail. */
.hero { position: relative; padding: calc(var(--header-h) + var(--space-7)) 0 var(--sec); }
@media (max-width: 900px) { .hero { padding: calc(var(--header-h) + var(--space-5)) 0 var(--space-7); } }

/* Event pages: copy left, sticky ticket rail right. The left column carries the
   hero AND the argument below it, which is what gives the rail travel to stick
   through and fills what was otherwise 600px of dead field beside the form. */
.hero-rail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 396px;
  gap: var(--space-6);
  align-items: start;
}
@media (max-width: 1040px) { .hero-rail { grid-template-columns: 1fr; gap: var(--space-7); } }

/* Bottom-anchored. The ticket is taller than a laptop viewport, and a
   top-anchored sticky on an over-tall element pins its head and pushes the
   submit button off screen for the whole page. Anchoring the bottom keeps the
   CTA and the privacy line in view while the head scrolls away. */
.rail { position: sticky; top: auto; bottom: var(--space-5); }
/* Sit the ticket at the bottom of the grid row, so the slack in a tall left
   column falls above it rather than as dead field beneath it. */
@media (min-width: 1041px) { .rail { align-self: end; } }
@media (max-width: 1040px) { .rail { position: static; } }

.hero-copy > *:last-child { margin-bottom: 0; }
/* The argument is now the hero's supporting text, not a second section, so it
   loses its eyebrow and drops well below the h1 in the hierarchy. */
.hero-copy .prose { margin-top: var(--space-6) !important; max-width: 58ch; }
/* Media runs the full column, prose holds a reading measure. Two deliberate
   edges rather than three accidental ones. */
.hero-copy .media-pair, .hero-copy .framed { max-width: none; }
/* Capped: a portrait crop at full column width ran to nearly 1,000px tall and
   dominated everything above it. */
.hero-copy .framed { max-height: 520px; }
.hero-copy .framed img { width: 100%; height: 100%; object-fit: cover; }
.hero-copy .prose h2 { font-size: clamp(20px, 1.8vw, 26px); letter-spacing: 0.01em; }
.hero-copy .prose .eyebrow { display: none; }
.hero-copy .factbar { border-bottom: 0; }
.hero-copy > p { max-width: var(--prose); }
.hero-copy h1 { margin-bottom: var(--space-6); }
.hero-copy .lead { margin-bottom: var(--space-5); }
.hero-copy .muted { max-width: 44ch; }

.kicker {
  display: inline-block;
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-5);
  border: 1px solid var(--border-hi); border-radius: var(--radius-pill);
  background: var(--panel);
  font-family: var(--display); font-size: 11px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-200);
}
@media (max-width: 520px) { .kicker { border-radius: var(--radius-md); } }

/* ============================================================ COUNTDOWN */

.countdown { display: flex; gap: var(--space-4); margin: var(--space-7) 0 0; padding: 0; list-style: none; }
.countdown li {
  flex: 1; text-align: center;
  padding: var(--space-4) var(--space-2);
  background: var(--panel-hi); border: 1px solid var(--border-hi);
  border-radius: var(--radius-md);
}
.countdown b {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: clamp(26px, 3vw, 40px); line-height: 1; color: var(--text-100);
  font-variant-numeric: tabular-nums;
}
.countdown span {
  display: block; margin-top: var(--space-2);
  font-family: var(--display); font-size: 10px; font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--text-300);
}
.countdown[hidden] { display: none; }

/* ============================================================ FACT BAR */

.factbar {
  display: grid; grid-template-columns: repeat(4, 1fr);
  margin: var(--space-6) 0 0; padding: 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.factbar > div { padding: var(--space-5) var(--space-5) var(--space-5) 0; border-right: 1px solid var(--border); }
.factbar > div:last-child { border-right: 0; }
.factbar > div + div { padding-left: var(--space-5); }
.factbar dt {
  margin-bottom: var(--space-2);
  font-family: var(--display); font-size: 10px; font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--text-400);
}
.factbar dd { margin: 0; color: var(--text-100); font-weight: 600; font-size: 15px; line-height: 1.3; text-wrap: balance; }
@media (max-width: 760px) {
  .factbar { grid-template-columns: repeat(2, 1fr); }
  .factbar > div:nth-child(2n) { border-right: 0; }
  .factbar > div:nth-child(-n+2) { border-bottom: 1px solid var(--border); }
  .factbar > div + div { padding-left: 0; }
  .factbar > div:nth-child(2n) { padding-left: var(--space-5); }
}

/* ============================================================ TICKET STUB

   The registration panel is a ticket: notches punched out of both edges by a
   mask on the element itself, and a perforated rule between the head and the
   form. Masking rather than painting circles matters, because painted circles
   read as beads glued on rather than holes. */

.ticket {
  --perf-y: 226px;
  position: relative;
  display: grid;
  grid-template-rows: var(--perf-y) auto;
  /* Darker at the head end, so the punched notches have something to punch
     through against the lit hero field behind. */
  background: linear-gradient(168deg, rgba(40, 18, 72, 0.92) 0%, rgba(18, 6, 44, 0.96) 100%);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow);
  -webkit-mask:
    radial-gradient(circle 13px at 0 var(--perf-y), transparent 98%, #000 100%),
    radial-gradient(circle 13px at 100% var(--perf-y), transparent 98%, #000 100%);
          mask:
    radial-gradient(circle 13px at 0 var(--perf-y), transparent 98%, #000 100%),
    radial-gradient(circle 13px at 100% var(--perf-y), transparent 98%, #000 100%);
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}
/* The mask clips a border, so the outline is drawn as an inset ring instead. */
.ticket::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  box-shadow: inset 0 0 0 1px var(--border-hi); pointer-events: none; z-index: 2;
}

.ticket-head { align-self: start; padding: var(--space-6) var(--space-6) var(--space-5); }
/* The instruction outranks the price, because the price is "Free" on every page. */
.ticket-head h2 { font-size: clamp(24px, 2.2vw, 32px); margin-bottom: var(--space-2); }
.ticket-head p { margin: 0; color: var(--text-300); font-size: 15px; }

.ticket-price { display: flex; align-items: baseline; gap: var(--space-3); margin-bottom: var(--space-4); }
.ticket-price b {
  font-family: var(--display); font-weight: 700; font-size: 26px; line-height: 1;
  text-transform: uppercase; color: var(--text-100);
}
.ticket-price span { font-size: 14px; color: var(--text-300); }

/* The rule is drawn on the body's top edge, which is the grid row boundary,
   which is exactly the notch centre. */
.ticket-perf { display: none; }

.ticket-body { position: relative; padding: var(--space-6); }
.ticket-body::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0;
  height: 1px;
  background-image: linear-gradient(90deg, var(--border-hi) 0 6px, transparent 6px 12px);
  background-size: 12px 1px;
}
/* Heads without the "seats are limited" pill are ~48px shorter. */
.ticket--short { --perf-y: 178px; }
@media (max-width: 1040px) {
  .ticket { --perf-y: 268px; }
  .ticket--short { --perf-y: 222px; }
}
/* The HubSpot form injects at window.load. Reserving the height stops roughly
   800px of layout shift on the one surface that has to convert. */
@media (min-width: 1041px) { .hs-reserve { min-height: 760px; } }
@media (max-width: 1040px) { .hs-reserve { min-height: 600px; } }

.ticket-note {
  display: inline-flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-4); margin-bottom: var(--space-5);
  border: 1px solid rgba(255, 27, 192, 0.42);
  border-radius: var(--radius-pill); background: rgba(255, 27, 192, 0.09);
  font-family: var(--display); font-size: 11px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-100);
}
.ticket-note::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--pink-500);
  animation: pulse 2.4s infinite;
}
@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(255, 27, 192, 0.55); }
  70%  { box-shadow: 0 0 0 9px rgba(255, 27, 192, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 27, 192, 0); }
}

.ticket-foot { margin: var(--space-4) 0 0; font-size: 12px; color: var(--text-300); }
.ticket-foot a { color: var(--text-200); }

.form-fallback { font-size: 14px; color: var(--text-300); }

/* ---- HubSpot embed skinning. Their class names, kept in one block. ---- */
.hbspt-form { font-family: var(--body); }
.hs-form-field { margin-bottom: var(--space-3); }

.hs-form-field > label {
  display: block; margin-bottom: var(--space-2);
  font-family: var(--display); font-size: 11px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-300);
}
/* Only the label wrapper is a block. Making every span a block put HubSpot's
   required asterisk on its own line under all seven fields. */
.hs-form-field > label > span { display: inline; }
.hs-form-field .hs-form-required { color: var(--pink-400); margin-left: 2px; }

.hbspt-form input[type="text"],
.hbspt-form input[type="email"],
.hbspt-form input[type="tel"],
.hbspt-form select,
.hbspt-form textarea,
.hs-input {
  width: 100% !important; max-width: 100% !important;
  padding: var(--space-3) var(--space-4);
  /* A near-black fill reads as a hole punched in the ticket. A light wash reads
     as a recessed field inside the object. */
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-hi); border-radius: var(--radius-md);
  color: var(--text-100); font: 400 16px/1.4 var(--body);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.hbspt-form .hs-input:focus { border-color: var(--pink-400); background: rgba(255, 255, 255, 0.09); outline: none; }
.hbspt-form .hs-input::placeholder { color: var(--text-400); }
.hbspt-form input[type="checkbox"], .hbspt-form input[type="radio"] { width: auto !important; margin-right: var(--space-2); }
.hbspt-form .hs-form-booleancheckbox-display,
.hbspt-form .hs-richtext,
.hbspt-form .legal-consent-container { font-size: 13px; line-height: 1.5; color: var(--text-300); }
.hbspt-form .hs-richtext a { color: var(--text-200); }
.hbspt-form .hs-button,
.hbspt-form input[type="submit"] {
  width: 100%; padding: var(--space-4) var(--space-6); margin-top: var(--space-4);
  border: 0; border-radius: var(--radius-pill);
  background: var(--grad-cta); color: var(--white);
  font-family: var(--display); font-size: 19px; font-weight: 700;
  letter-spacing: 0.06em; text-transform: uppercase; cursor: pointer;
  box-shadow: 0 14px 34px rgba(255, 27, 192, 0.28);
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.hbspt-form .hs-button:hover { transform: translateY(-2px); box-shadow: 0 20px 46px rgba(255, 27, 192, 0.44); }
.hbspt-form .hs-error-msg { color: var(--pink-400); font-size: 13px; }
.hbspt-form ul.no-list { list-style: none; padding: 0; margin: var(--space-1) 0 0; }
.hbspt-form .submitted-message { color: var(--text-100); font-size: 16px; }

/* ============================================================ NATIVE FORMS */

.audit-form .field { margin-bottom: var(--space-3); }
.audit-form label {
  display: block; margin-bottom: var(--space-2);
  font-family: var(--display); font-size: 11px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-300);
}
.audit-form input[type="text"],
.audit-form input[type="email"],
.audit-form input[type="url"] {
  width: 100%; padding: var(--space-3) var(--space-4);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-hi); border-radius: var(--radius-md);
  color: var(--text-100); font: 400 16px/1.4 var(--body);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.audit-form input:focus { border-color: var(--pink-400); background: rgba(255, 255, 255, 0.09); outline: none; }
.audit-form input::placeholder { color: var(--text-400); }
.audit-form .btn { margin-top: var(--space-4); }

/* Off-screen rather than display:none, which some bots skip. */
.form-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-status { margin: var(--space-3) 0 0; font-size: 14px; min-height: 1px; }
.form-status.is-error { color: var(--pink-400); }

.audit-done {
  padding: var(--space-5);
  border: 1px solid rgba(255, 27, 192, 0.3); border-radius: var(--radius-md);
  background: rgba(255, 27, 192, 0.07);
}
.audit-done[hidden] { display: none; }
.audit-done h3 { margin-bottom: var(--space-2); font-size: 19px; }
.audit-done p { margin: 0; color: var(--text-300); font-size: 15px; }

.ticks { list-style: none; margin: var(--space-5) 0; padding: 0; }
.ticks li { position: relative; padding-left: var(--space-7); margin-bottom: var(--space-3); color: var(--text-200); font-size: 15px; }
.ticks li::before {
  content: ""; position: absolute; left: 0; top: 0.42em;
  width: 16px; height: 9px;
  border-left: 2px solid var(--pink-500); border-bottom: 2px solid var(--pink-500);
  transform: rotate(-45deg);
}

/* ============================================================ CONFIRM BAR */

.confirm {
  background: linear-gradient(90deg, rgba(183, 58, 176, 0.24) 0%, rgba(20, 6, 48, 0.5) 100%);
  border-bottom: 1px solid rgba(255, 27, 192, 0.3);
  /* Pays back the header's negative margin. Any section that can be the first
     child of main has to do this, not just .hero. */
  padding: calc(var(--header-h) + var(--space-4)) 0 var(--space-4);
}
.confirm-inner { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.confirm-copy { flex: 1; min-width: 240px; }
.confirm-copy strong {
  display: block;
  font-family: var(--display); font-size: 16px; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-100); margin-bottom: 2px;
}
.confirm-copy span { color: var(--text-200); font-size: 14px; }
.confirm-tick {
  display: grid; place-items: center; flex: none;
  width: 30px; height: 30px; border-radius: 50%;
  background: var(--grad-cta); color: var(--white); font-size: 15px; font-weight: 700;
}

/* ============================================================ MARQUEE

   A repeating band of the event's own details. Tinted, not filled: canon says
   pink is never a background wash, and a solid gradient band out-shouted the
   CTA sitting above it. */

.marquee {
  position: relative; overflow: hidden; padding: var(--space-4) 0;
  background: linear-gradient(90deg, rgba(183,58,176,0.16), rgba(255,27,192,0.16)), var(--void);
  border-top: 1px solid rgba(255, 27, 192, 0.3);
  border-bottom: 1px solid rgba(255, 27, 192, 0.3);
}
.marquee-track { display: flex; width: max-content; animation: slide 40s linear infinite; }
.marquee span {
  display: inline-flex; align-items: center; flex: none;
  padding: 0 var(--space-5);
  font-family: var(--display); font-weight: 600; font-size: 15px;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink-400);
  white-space: nowrap;
}
.marquee span::after {
  content: ""; width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255, 61, 142, 0.6); margin-left: var(--space-5);
}
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) { .marquee-track { animation: none; } }

/* ============================================================ CARDS */

.grid { display: grid; gap: var(--space-5); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); }

.field-panel .card { background: rgba(9, 3, 24, 0.28); }
.card {
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-lg); padding: var(--space-6);
}
.card h3 { margin-bottom: 0; }
.card p { margin: 0; }
/* Subgrid aligns the body copy across a row without reserving empty space
   under the cards whose heading is one line. */
@media (min-width: 601px) {
  .grid-3 .card { display: grid; grid-template-rows: subgrid; grid-row: span 2; gap: var(--space-3); }
}
@media (max-width: 600px) { .card h3 { margin-bottom: var(--space-3); } }

.learn { display: grid; gap: var(--space-4); padding: 0; margin: 0; list-style: none; counter-reset: n; }
@media (min-width: 800px) { .learn { grid-template-columns: 1fr 1fr; gap: var(--space-5); } }

.learn li {
  position: relative; counter-increment: n;
  padding: var(--space-6) var(--space-6) var(--space-6) var(--space-8);
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-lg); color: var(--text-300);
  overflow: hidden; transition: border-color 0.2s ease, transform 0.2s ease, background 0.2s ease;
}
.learn li:hover { border-color: var(--border-hi); transform: translateY(-3px); background: var(--panel-hi); }
.learn li::before {
  content: counter(n, decimal-leading-zero);
  position: absolute; top: var(--space-6); left: var(--space-6);
  font-family: var(--display); font-weight: 700; font-size: 15px;
  letter-spacing: 0.04em; color: var(--text-400);
}
.learn li::after {
  content: counter(n, decimal-leading-zero);
  /* Was 108px hanging off the card edge, which sliced every numeral in half
     and read as a rendering artefact rather than a device. */
  position: absolute; right: var(--space-5); bottom: -14px;
  font-family: var(--display); font-weight: 700; font-size: 76px; line-height: 1;
  color: rgba(255, 255, 255, 0.045); pointer-events: none;
}
.learn strong { color: var(--text-100); font-weight: 700; }

/* On a 342px card the absolute number floated 48px away from its own sentence
   in an L-shaped hole, and the ghost numeral read as a smudge. */
@media (max-width: 720px) {
  .learn li { padding: var(--space-5); }
  .learn li::before { position: static; display: block; margin-bottom: var(--space-2); }
  .learn li::after { display: none; }
}

/* ============================================================ TIMELINE */

.timeline { position: relative; padding-left: var(--space-8); }
.timeline::before {
  content: ""; position: absolute; left: 7px; top: 10px; bottom: 10px; width: 1px;
  background: linear-gradient(180deg, var(--pink-500), rgba(255,27,192,0.12));
}
.tl-row { position: relative; padding-bottom: var(--space-7); }
.tl-row:last-child { padding-bottom: 0; }
.tl-row::before {
  content: ""; position: absolute; left: calc(var(--space-8) * -1 + 2px); top: 6px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--pink-500); box-shadow: 0 0 0 4px rgba(255, 27, 192, 0.16);
}
.tl-time {
  display: block; margin-bottom: var(--space-2);
  font-family: var(--display); font-size: 13px; font-weight: 600;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink-400);
}
.tl-row h3 { margin-bottom: var(--space-3); }
.tl-row p { margin: 0; color: var(--text-300); }

/* ============================================================ SPEAKERS */

/* Three auto-fit tracks across 1192px left 238px of empty field between heads,
   which read as stragglers rather than a panel. */
.speakers {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-6); max-width: 780px; margin-inline: auto;
}
@media (max-width: 640px) { .speakers { grid-template-columns: 1fr; max-width: 300px; } }
.speaker { text-align: center; }
.speaker-photo {
  position: relative; width: 100%; max-width: 168px; margin: 0 auto var(--space-4);
  border-radius: 50%; padding: 3px;
  /* Was the CTA gradient, which made three headshots the loudest pink in view. */
  background: linear-gradient(180deg, var(--purple-500), var(--purple-700));
}
.speaker-photo img { width: 100%; aspect-ratio: 1/1; border-radius: 50%; object-fit: cover; display: block; }
.speaker h3 { font-size: 20px; margin-bottom: var(--space-1); }
.speaker p { margin: 0; font-size: 13px; color: var(--text-300); font-weight: 600; letter-spacing: 0.04em; }

/* ============================================================ EVENT CARDS */

.event-card {
  display: flex; flex-direction: column; position: relative;
  background: var(--panel); border: 1px solid var(--border);
  border-radius: var(--radius-lg); overflow: hidden;
  transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease;
}
.event-card:hover { transform: translateY(-5px); border-color: var(--border-hi); box-shadow: var(--shadow-card); }
.event-card-media { position: relative; }
/* Cropped to 21:9 and offset left, because the source artwork has a neon
   "BOOK YOUR PLACE NOW" button baked into the bottom of the image. A painted
   CTA sitting above the real one is a click people lose. */
.event-card-media img { width: 100%; aspect-ratio: 1600 / 668; object-fit: cover; }
/* On the thank-you page one of the two cards is removed by script, and a lone
   card in a two-up grid left half the row empty. */
.grid-2 > .event-card:only-child { max-width: 640px; margin-inline: auto; }
.event-card-date {
  position: absolute; top: var(--space-4); left: var(--space-4);
  display: grid; place-items: center; width: 60px; padding: var(--space-2) 0;
  background: rgba(9, 3, 24, 0.92); border: 1px solid var(--border-hi);
  border-radius: var(--radius-md); backdrop-filter: blur(6px);
}
.event-card-date b { font-family: var(--display); font-weight: 700; font-size: 24px; line-height: 1; color: var(--text-100); }
.event-card-date span {
  font-family: var(--display); font-size: 10px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--pink-400); margin-top: 2px;
}
.event-card-body { display: flex; flex-direction: column; flex: 1; padding: var(--space-6); }
.event-card-body h3 { margin-bottom: var(--space-3); font-size: clamp(21px, 2vw, 27px); }
.event-card-body p { color: var(--text-300); flex: 1; }
.event-card .btn { align-self: flex-start; margin-top: var(--space-5); }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.tag {
  display: inline-block; padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill); border: 1px solid var(--border-hi);
  font-family: var(--display); font-size: 10px; font-weight: 500;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--text-200);
}
.tag-accent { border-color: rgba(255, 27, 192, 0.5); background: rgba(255, 27, 192, 0.1); color: var(--text-100); }

/* ============================================================ STATS */

.stats {
  display: grid; grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  overflow: hidden; background: var(--panel);
}
.stats > div { padding: var(--space-6) var(--space-5); border-right: 1px solid var(--border); }
.stats > div:last-child { border-right: 0; }
.stats b {
  display: block; font-family: var(--display); font-weight: 700;
  font-size: clamp(26px, 2.4vw, 34px); line-height: 1.05;
  text-transform: uppercase; color: var(--text-100); margin-bottom: var(--space-3);
}
.stats span { font-size: 13px; color: var(--text-300); line-height: 1.4; }
@media (max-width: 860px) {
  .stats { grid-template-columns: repeat(2, 1fr); }
  .stats > div:nth-child(2n) { border-right: 0; }
  .stats > div:nth-child(-n+2) { border-bottom: 1px solid var(--border); }
}

/* ============================================================ MEDIA */

.media-pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); }
@media (max-width: 600px) { .media-pair { grid-template-columns: 1fr; } }
.media-pair img { width: 100%; aspect-ratio: 1/1; object-fit: cover; border-radius: var(--radius-lg); }

.photo-strip { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); align-items: start; }
.photo-strip img { width: 100%; aspect-ratio: 4/5; object-fit: cover; border-radius: var(--radius-lg); }
/* margin, not transform: a transform does not affect layout, so the overhang
   was eating the section's bottom padding. */
.photo-strip img:nth-child(odd) { margin-top: var(--space-5); }
@media (max-width: 720px) {
  .photo-strip { grid-template-columns: repeat(2, 1fr); }
  .photo-strip img:nth-child(odd) { margin-top: 0; }
}

.framed { border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-card); }
/* Where a framed image shares a stretched row with a tall text column, fill the
   row rather than floating a short photo in the middle of it. */
.grid-2 > .framed { align-self: stretch; }
.grid-2 > .framed img { width: 100%; height: 100%; object-fit: cover; }
.grid-2 > .media-pair { align-self: stretch; }
.grid-2 > .media-pair img { height: 100%; aspect-ratio: auto; min-height: 220px; }
@media (max-width: 720px) {
  .grid-2 > .media-pair img { aspect-ratio: 1 / 1; height: auto; }
}

/* The cross-promo card sat at 620px in a 1192px container with the whole right
   half empty. Head left, card right. */
.promo { display: grid; grid-template-columns: 1fr 620px; gap: var(--space-7); align-items: center; }
.promo .head { margin-bottom: 0; }
@media (max-width: 1000px) { .promo { grid-template-columns: 1fr; gap: var(--space-6); } }

/* ============================================================ CALLOUT */

.callout {
  position: relative; overflow: hidden;
  max-width: 880px; margin-inline: auto;
  /* 315deg, so the magenta corner sits opposite the section orb rather than
     stacking two magenta washes with no dark gap between them. */
  background: linear-gradient(315deg, rgba(183, 58, 176, 0.2) 0%, rgba(20, 6, 48, 0.62) 100%);
  border: 1px solid rgba(255, 27, 192, 0.3);
  border-radius: var(--radius-xl);
  padding: var(--space-8) var(--space-7);
  text-align: center;
}
.callout h2 { margin-bottom: var(--space-4); }
.callout p { max-width: 52ch; margin-left: auto; margin-right: auto; color: var(--text-200); }
.callout > p:last-of-type { max-width: none; margin-bottom: 0; }
.callout .eyebrow { justify-content: center; }

/* ============================================================ STICKY BAR */

.sticky-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: none; align-items: center; justify-content: space-between; gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  padding-bottom: calc(var(--space-3) + env(safe-area-inset-bottom, 0px));
  background: rgba(9, 3, 24, 0.97);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  border-top: 1px solid var(--border);
}
.sticky-bar-label {
  min-width: 0;
  font-family: var(--display); font-size: 10px; font-weight: 500;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--text-300); line-height: 1.3;
}
.sticky-bar-label b { display: block; color: var(--text-100); font-size: 13px; font-weight: 600; letter-spacing: 0.08em; }
.sticky-bar .btn { flex: none; white-space: nowrap; padding: var(--space-3) var(--space-4); font-size: 14px; }

/* Mobile: always on, because the ticket is a long way down the page.
   Desktop: revealed by script once the ticket has scrolled out of view, so the
   page never has two competing registration CTAs on screen at once, and never
   has none. */
@media (max-width: 1040px) {
  body.has-bar { padding-bottom: 74px; }
  body.has-bar .sticky-bar { display: flex; }
}
@media (min-width: 1041px) {
  body.has-bar.ticket-gone .sticky-bar {
    display: flex;
    left: auto; right: var(--space-5); bottom: var(--space-5);
    width: auto; gap: var(--space-5);
    border: 1px solid var(--border-hi); border-radius: var(--radius-pill);
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-6);
    box-shadow: var(--shadow);
    animation: bar-in 0.32s ease both;
  }
}
@keyframes bar-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

/* ============================================================ FOOTER */

/* Flat panel, no orbfield. .orbfield sets isolation:isolate, so its ::before at
   z-index -2 painted over the element's own background and --purple-800 never
   rendered, leaving the footer tonally identical to every section above it. */
.site-footer {
  position: relative; background: var(--purple-800);
  border-top: 1px solid var(--border);
  padding: var(--space-8) 0 var(--space-6);
  color: var(--text-300); font-size: 14px;
}
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: var(--space-7); margin-bottom: var(--space-7); }
@media (max-width: 780px) { .footer-grid { grid-template-columns: 1fr; gap: var(--space-6); } }
/* text-400 on the lifted panel measured 4.37:1 at 11px. */
.site-footer h4 { font-size: 11px; letter-spacing: 0.22em; color: var(--text-300); margin-bottom: var(--space-4); }
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: var(--space-3); }
.site-footer a { color: var(--text-300); text-decoration: none; }
.site-footer a:hover { color: var(--text-100); text-decoration: underline; }
@media (max-width: 780px) {
  .site-footer li { margin-bottom: var(--space-4); }
  .site-footer a { display: inline-block; padding: var(--space-1) 0; }
}
.footer-logo { height: 30px; width: auto; margin-bottom: var(--space-4); }
.footer-marks { display: flex; align-items: center; gap: var(--space-5); margin-top: var(--space-5); }
.footer-marks img { height: 54px; width: auto; }
.footer-base {
  display: flex; flex-wrap: wrap; gap: var(--space-4);
  justify-content: space-between; align-items: center;
  padding-top: var(--space-5); border-top: 1px solid var(--border);
  font-size: 13px; color: var(--text-300);
}

/* ============================================================ COOKIE */

.cookie {
  position: fixed; left: var(--space-4); right: var(--space-4); bottom: var(--space-4);
  z-index: 120; max-width: 500px; margin: 0 auto; padding: var(--space-5);
  background: rgba(20, 6, 48, 0.98); border: 1px solid var(--border-hi);
  border-radius: var(--radius-lg); box-shadow: var(--shadow);
  font-size: 14px; color: var(--text-200);
}
.cookie[hidden] { display: none; }
.cookie p { margin-bottom: var(--space-4); }
.cookie-actions { display: flex; gap: var(--space-3); flex-wrap: wrap; }
@media (max-width: 1040px) { body.has-bar .cookie { bottom: 82px; } }

/* ============================================================ REVEAL */

/* Visible by default; only hidden once the inline head script confirms JS runs,
   so a script error can never leave a section blank. */
.reveal { transition: opacity 0.55s ease, transform 0.55s ease; }
.js .reveal { opacity: 0; transform: translateY(20px); }
.js .reveal.on { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .js .reveal { opacity: 1; transform: none; } }

/* ------------------------------------------------------------------ */
/* Thank you, variant A                                               */
/* ------------------------------------------------------------------ */
/* The confirmation owns the fold, centred, with the audit in its own band
   below. Only this page uses these three rules. */
.ty-head { max-width: 820px; }
.ty-head .lead { margin-left: auto; margin-right: auto; margin-bottom: var(--space-6); }
/* .btn sets display, so the attribute alone does not hide the button. */
#ty-ics[hidden] { display: none; }
.ty-next { margin-top: var(--space-8); }

/* ------------------------------------------------------------------ */
/* Long-form document pages                                           */
/* ------------------------------------------------------------------ */
/* The privacy notice is one column of body copy in a full-width wrap.
   Pinned left at the event pages' 54ch measure it read as a layout that
   had failed, so a document page centres its column instead. */
.page-doc { max-width: 62ch; margin-left: auto; margin-right: auto; }
.page-doc h3 { margin-top: var(--space-6); }
