/* ── Figma comes to art.edu ────────────────────────────────
   Scoped to .figma-body. Page signature is orchid pink — the
   Figma Campus Leader badge color. Other Figma scheme hues
   show up only as per-event row accents on the events list. */

.figma-body {
  /* signature pair: orchid pink (FCL badge) + flame red (Master's badge).
     used as a gradient across the page identity — nav glow, eyebrows,
     marks, CTA, mail, footer, F glow. */
  --figma-orchid:      #FF5DBA;   /* punchier pink, matches FCL badge */
  --figma-orchid-soft: #FFA1D9;
  --figma-orchid-deep: #C03C8E;
  --figma-flame:       #FF4555;   /* warm neon red from Master's badge */
  --figma-flame-deep:  #C8303F;
  --figma-glow:        linear-gradient(135deg, var(--figma-orchid) 0%, var(--figma-flame) 100%);
  --figma-red:         #FF3737;   /* keeps brand palette intact for the F-logo */
  --figma-pink:        #FF7262;   /* coral, classic Figma marketing hue */
  --figma-hotpink:     #FF01E5;
  --figma-purple:      #874FFF;
  --figma-cyan:        #00B6FF;
  --figma-green:       #67FF7F;
  --figma-lime:        #E4FF97;
  --figma-orange:      #FF7237;

  background: var(--void);
  color: var(--text);
  font-family: var(--f-body);
  overflow-x: hidden;
}

/* ── per-page nav breathe (cycles between orchid + flame) ──
   side-only glow, slightly above landing's opacity — orchid + flame
   are warm/dim on dark relative to other palette colors, so they
   need a small bump to read at all. still side-only / no halo / no
   stroke (Ivy doesn't want the ring around the rectangle). */
@keyframes figma-nav-breathe {
  0%, 100% {
    box-shadow:
      -16px 0 55px -13px rgb(218 102 218 / 0.20),
       16px 0 55px -13px rgb(255 122 0 / 0.20);
  }
  50% {
    box-shadow:
      -20px 0 65px -11px rgb(218 102 218 / 0.30),
       20px 0 65px -11px rgb(255 122 0 / 0.30);
  }
}
.figma-body .nav {
  /* nav glow retired 2026-06-06 — dark glass frame only, no halo */
  animation: none !important;
  box-shadow: none !important;
  /* parent style.css gives .foot z-index: 10000 — nav must beat
     that so the footer F never paints over the floating nav. */
  z-index: 100000 !important;
}
/* contain the footer F's halo so its filter shadow can't escape
   above the foot block into the nav region. */
.figma-foot { isolation: isolate; }

/* nav contact link picks up the gradient on hover */
.figma-body .nav__contact:hover {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

/* ── shared eyebrow (mono uppercase) ── */
.figma-eyebrow {
  display: inline-block;
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text-mute);
  margin-bottom: 18px;
}
.figma-eyebrow--accent {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
.figma-eyebrow--mute {
  color: var(--text-mute);
  font-size: 9px;
  letter-spacing: 0.28em;
}

/* shared section heading */
.figma-h2 {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(28px, 4vw, 44px);
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--text);
  max-width: 22ch;
  margin: 0;
}

/* ── playful Figma "pen-tool" mark ──
   Replaces the dull highlight bar. A clean orchid underline draws
   in left-to-right when the heading enters the viewport, then a
   small square anchor-point pops in at the end (Figma's vector
   pen tool aesthetic). Multi-line-safe via background-gradient.
   .is-visible class added by IntersectionObserver in figma-cl.js. */
.figma-mark {
  position: relative;
  font-style: normal;
  text-decoration: none;
  background-image: var(--figma-glow);
  background-repeat: no-repeat;
  background-size: 0% 3px;
  background-position: 0 calc(100% + 4px);
  padding-bottom: 8px;
  transition: background-size 0.9s cubic-bezier(.2,.8,.2,1) 0.15s;
}
.figma-mark.is-visible,
.figma-h2:hover .figma-mark {
  background-size: 100% 3px;
}
@media (prefers-reduced-motion: reduce) {
  .figma-mark { background-size: 100% 3px; transition: none; }
}

/* ── 1 · HERO ──────────────────────────────────────────────── */
.figma-hero {
  position: relative;
  /* fill the viewport so on tall screens the beats video stays
     below the fold. svh handles mobile browser bars. */
  min-height: 100vh;
  min-height: 100svh;
  /* bigger top padding pushes the eyebrow + title + sub + badge
     down toward center; the meta strip stays anchored at the
     bottom via justify-content: space-between, which also tightens
     the gap between content and meta. */
  padding: clamp(140px, 17vh, 220px) clamp(24px, 5vw, 72px) clamp(28px, 4vh, 56px);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: clamp(28px, 4vh, 56px);
}

.figma-hero__grid {
  display: grid;
  /* slightly wider badge column — text still gets the larger share */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(32px, 5vw, 80px);
  align-items: start; /* sit at top — never let media stretch text or vice versa */
  max-width: 1300px;
  margin: 0 auto;
  width: 100%;
}

.figma-hero__text {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.figma-hero__title {
  font-family: var(--f-display);
  font-weight: 700;
  font-size: clamp(48px, 9vw, 120px);
  line-height: 0.95;
  letter-spacing: -0.025em;
  color: var(--text);
  margin: 0;
}

/* hero title entrance: opacity-only fade. the old translateY + blur
   entrance was visibly jittery against the WebGL badge loading on the
   right — main thread was busy with the badge while the title was
   trying to animate transform+filter, so "art.edu" especially landed
   with a late "tiny lift" rather than settling cleanly. opacity-only
   compositor-friendly fades let the lines settle in place. */
.figma-hero__line {
  display: block;
  opacity: 0;
  animation: figma-line-in 0.5s ease-out forwards;
}
.figma-hero__line:nth-child(1) { animation-delay: 0.1s; }
.figma-hero__line:nth-child(2) { animation-delay: 0.22s; }
.figma-hero__line:nth-child(3) { animation-delay: 0.34s; }
@keyframes figma-line-in {
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .figma-hero__line { opacity: 1; animation: none; }
}

/* art.edu — gradient text, no glow blur */
.figma-hero__em {
  font-style: normal;
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}

.figma-hero__sub {
  font-family: var(--f-mono);
  font-size: clamp(13px, 1.4vw, 16px);
  line-height: 1.6;
  color: var(--text-dim);
  margin: 8px 0 0;
  max-width: 56ch;
  /* opacity-only fade matching the title lines above. the long
     1.05s delay is gone — paragraph appears right after the third
     title line, so the whole hero text settles in under a second. */
  opacity: 0;
  animation: figma-sub-in 0.5s ease-out 0.45s forwards;
}
@keyframes figma-sub-in {
  to { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .figma-hero__sub { opacity: 1; animation: none; }
}
/* the "+" between the two clauses picks up the page gradient and
   sits a touch larger so it reads as a system-design connector,
   not a typo. screen readers get the "and" via .sr-only. */
.figma-hero__plus {
  display: inline-block;
  font-family: var(--f-display);
  font-size: 1.25em;
  line-height: 1;
  font-weight: 600;
  vertical-align: -0.06em;
  margin: 0 0.18em;
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
.sr-only {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* badge stage on right -- explicit (capped) height so it can never
   grow infinitely on wide viewports (a min-height + align: stretch
   combo earlier caused a feedback loop with the canvas resize). dual-
   tone backdrop pulls from both signature colors. */
.figma-hero__media {
  position: relative;
  /* tall enough for the badge to swing freely on big screens, but
     short enough on 14" laptops that the meta strip still fits in
     the viewport below it. */
  height: clamp(440px, 56vh, 760px);
  max-height: 760px;
  border-radius: var(--radius);
  overflow: hidden;
  /* solid hex background-color (NOT a var, NOT inside the shorthand)
     so the element ALWAYS has a dark base — even if color-mix() in
     the gradients below fails during first paint, you see this. fixes
     the white-rectangle flash during page navigation. */
  background-color: #0e0e14;
  /* ── the Figma canvas ─────────────────────────────────────────────
     The badges hang on the surface every designer knows: an infinite
     dotted Figma canvas. Base = dark + a soft centre vignette for depth;
     the DOTS themselves carry the art.edu title gradient (pink → red)
     and live on ::before so they can be masked into the dot pattern.
     The multiplayer cursors live in .figma-canvas-deco. */
  background-image:
    radial-gradient(ellipse 72% 62% at 50% 44%, transparent 52%, oklch(0.05 0.01 280 / 0.55) 100%);
  background-size: 100% 100%;
  background-position: center;
  cursor: grab;
  isolation: isolate;
}
/* the dot grid, coloured by the art.edu gradient — a linear pink→red
   fill revealed only through a 1px dot mask, so every dot is tinted by
   its position in the gradient (top-left pink → bottom-right red). */
.figma-hero__media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: var(--figma-glow);
  opacity: 0.5;
  /* dot mask INTERSECTED with a centre vignette (2026-06-07) so the dots
     fade out toward the corners/edges instead of tiling to a hard rim. */
  -webkit-mask-image:
    radial-gradient(circle, #000 1px, transparent 1.6px),
    radial-gradient(ellipse 76% 66% at 50% 45%, #000 32%, transparent 82%);
          mask-image:
    radial-gradient(circle, #000 1px, transparent 1.6px),
    radial-gradient(ellipse 76% 66% at 50% 45%, #000 32%, transparent 82%);
  -webkit-mask-size: 26px 26px, 100% 100%;
          mask-size: 26px 26px, 100% 100%;
  -webkit-mask-position: center, center;
          mask-position: center, center;
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
}

/* ── Figma multiplayer cursors ────────────────────────────────────
   Two named cursors parked on the canvas behind the badges — the
   single most recognizable "this is Figma" signal (presence). Static,
   low-key, brand-colored. Sits above the dot grid but below the badge
   stage so a swinging badge passes in front. pointer-events: none so
   the drag interaction is untouched. */
.figma-canvas-deco {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  border-radius: inherit;
}
.fig-cursor {
  position: absolute;
  display: inline-flex;
  align-items: flex-start;
  gap: 3px;
  /* opacity moved off the whole cursor (2026-06-07) — it was making the
     label pills see-through so the dots bled through. Now only the arrow
     is dialed back; the pill stays fully opaque + readable. */
}
.fig-cursor svg {
  fill: currentColor;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.45));
  flex: none;
  opacity: 0.62;
}
.fig-cursor__tag {
  font-family: var(--f-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.01em;
  line-height: 1;
  padding: 3px 7px 4px;
  border-radius: 7px 7px 7px 2px;
  color: #fff;
  white-space: nowrap;
  transform: translateY(3px);
}
/* Figma cursor = orchid pink (top), art.edu cursor = flame red — the two
   colors from the art.edu title gradient. */
.fig-cursor--a { top: 15%; left: 9%; color: var(--figma-orchid); }
.fig-cursor--a .fig-cursor__tag { background: var(--figma-orchid); }
.fig-cursor--b { bottom: 17%; right: 10%; color: var(--figma-flame); }
.fig-cursor--b .fig-cursor__tag { background: var(--figma-flame); }
@media (max-width: 940px) {
  /* narrower stage — pull the cursors toward the corners so they
     don't crowd the badge */
  .fig-cursor--a { top: 8%; left: 5%; }
  .fig-cursor--b { bottom: 10%; right: 6%; }
}

.figma-badges__stage {
  position: relative;
  width: 100%;
  height: 100%;
}
.figma-badges__stage canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
  touch-action: none;
  /* canvas stays invisible until the badge is fully prepped offstage:
     GLB loaded, all textures GPU-uploaded via the auto-cycle, physics
     settled into its gentle sway. then fades in over 0.8s. before
     this, the user saw a lone lanyard string, the badge popping in,
     and the auto-cycle visibly flipping between textures. */
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.8s ease;
}
.figma-badges__stage canvas.is-ready {
  opacity: 1;
  pointer-events: auto;
}
.figma-badges__hint {
  position: absolute;
  /* nudged up a touch (14 → 20px, 2026-06-07) so it lands between dot
     rows instead of sitting on top of one. */
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  font-family: var(--f-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.3em;
  color: var(--text-mute);
  opacity: 0;
  transition: opacity 0.6s var(--ease) 0.2s;
  pointer-events: none;
  z-index: 2;
}
.figma-hero__media:hover .figma-badges__hint { opacity: 1; }

/* hero meta strip -- Role / School / Year + scroll cue */
.figma-meta {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 24px;
  max-width: 1300px;
  margin: 0 auto;
  width: 100%;
  padding-top: clamp(24px, 4vh, 48px);
  border-top: 1px solid var(--rule);
}
.figma-meta > div { display: grid; gap: 6px; align-content: start; }
.figma-meta dt {
  font-family: var(--f-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.24em;
  color: var(--text-mute);
}
.figma-meta dd {
  font-family: var(--f-mono);
  font-size: 13px;
  color: var(--text-dim);
  margin: 0;
  line-height: 1.4;
}
.figma-meta__cue { justify-self: end; align-self: end; }
.figma-hero__scroll {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text-dim);
  text-decoration: none;
  transition: color 0.3s var(--ease);
}
.figma-hero__scroll:hover { color: var(--figma-orchid); }
.figma-hero__scroll svg { animation: figma-scroll-bob 2.4s ease-in-out infinite; }
@keyframes figma-scroll-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(3px); }
}

@media (max-width: 860px) {
  .figma-hero__grid { grid-template-columns: 1fr; }
  .figma-hero__media { aspect-ratio: 4 / 3; height: auto; max-height: 70vh; }
  .figma-meta { grid-template-columns: 1fr 1fr; gap: 18px 24px; }
  .figma-meta__cue { grid-column: 1 / -1; justify-self: start; }
}

/* ── 2 · SETUP ─────────────────────────────────────────────── */
.figma-setup {
  padding: clamp(80px, 12vh, 140px) clamp(24px, 5vw, 72px);
}
.figma-setup__inner {
  /* visually centered case-story column. wider section frame, but
     each direct child is constrained + auto-margined so headlines,
     paragraphs, asides, numbers, and timeline all sit in the
     middle of the page rather than hugging the left edge. */
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  gap: 28px;
  justify-items: center;
}
.figma-setup__inner > * {
  width: 100%;
  max-width: 720px;
  margin-left: auto;
  margin-right: auto;
}
/* timeline + numbers strip want a touch more room than body text. */
.figma-setup__inner > .figma-timeline,
.figma-setup__inner > .figma-numbers__grid {
  max-width: 820px;
}
/* acceptance figure stays compact — memento-scale, not hero-scale. */
.figma-setup__inner > .figma-acceptance {
  max-width: 360px;
}
.figma-setup p {
  font-family: var(--f-body);
  font-size: clamp(15px, 1.4vw, 17px);
  line-height: 1.7;
  color: var(--text-dim);
  max-width: 60ch;
  margin: 0;
}
/* in-paragraph emphasis. drop italic + bold and use the page
   gradient color only — subtle but on-brand. */
.figma-highlight {
  font-style: normal;
  font-weight: inherit;
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
/* body-text "+" connector, gradient-painted, sits a touch larger
   than its neighbors so it reads as a system-design connector. */
.figma-plus {
  display: inline-block;
  font-family: var(--f-display);
  font-size: 1.15em;
  line-height: 1;
  font-weight: 600;
  vertical-align: -0.05em;
  margin: 0 0.18em;
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
/* neutral variant: plain white + body weight — used in captions
   where the gradient would clash with the photo behind. the bolder
   weight inherited from .figma-plus reads as emphasis when there's
   no color shift to back it up; drop it back to body weight here. */
.figma-plus--neutral {
  background: none;
  -webkit-background-clip: initial;
  background-clip: initial;
  color: var(--text);
  font-weight: inherit;
}

/* ── how-it-started timeline ─────────────────────────────────
   the path from Config 2023 (virtual, summer) to Config 2026
   (in-person, june). split into two halves with a story-paragraph
   slotted between application and acceptance.
   vertical layout with three columns: date | dot+spine | body.
   gradient orchid→flame spine connects every milestone. each
   item reveals on viewport entry (IntersectionObserver in JS).
   peak (CL acceptance) gets a larger gradient dot + halo. future
   (Config 2026) gets a dashed outline dot. */
.figma-timeline-head {
  display: grid;
  gap: 6px;
  margin: clamp(28px, 4vh, 48px) 0 0;
}
.figma-timeline-head__title {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(18px, 1.8vw, 22px);
  line-height: 1.25;
  letter-spacing: -0.005em;
  color: var(--text);
  margin: 0;
  max-width: 36ch;
}
.figma-timeline-head__title em {
  font-style: normal;
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
}
/* the second half of the timeline reads as a continuation — same
   layout, slightly tighter top padding so the paragraph that comes
   before it still feels connected. */
.figma-timeline--continued {
  margin-top: clamp(22px, 3vh, 36px);
}
.figma-timeline {
  list-style: none;
  margin: clamp(28px, 4vh, 48px) 0;
  padding: clamp(20px, 3vh, 32px) 0 clamp(20px, 3vh, 32px) clamp(8px, 2vw, 24px);
  position: relative;
  display: grid;
  gap: clamp(14px, 2vh, 22px);
  max-width: 64ch;
}
/* the spine: a vertical gradient sitting in the middle column. */
.figma-timeline::before {
  content: "";
  position: absolute;
  left: calc(clamp(8px, 2vw, 24px) + 142px); /* match dot column center */
  top: 24px;
  bottom: 24px;
  width: 2px;
  background: linear-gradient(180deg,
    color-mix(in oklch, var(--figma-orchid) 70%, transparent) 0%,
    color-mix(in oklch, var(--figma-orchid) 55%, transparent) 50%,
    color-mix(in oklch, var(--figma-flame) 60%, transparent) 100%);
  border-radius: 1px;
  pointer-events: none;
  z-index: 0;
}
.figma-timeline__item {
  display: grid;
  grid-template-columns: 132px 22px 1fr;
  align-items: start;
  gap: 0 clamp(12px, 1.5vw, 22px);
  position: relative;
  z-index: 1;
  /* reveal anim is opt-in via .is-visible */
  opacity: 0;
  transform: translateY(14px);
  filter: blur(4px);
  transition:
    opacity 0.7s var(--ease),
    transform 0.7s cubic-bezier(.2, .85, .25, 1),
    filter 0.7s var(--ease);
}
.figma-timeline__item.is-visible {
  opacity: 1;
  transform: none;
  filter: blur(0);
}
.figma-timeline__date {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text-mute);
  text-align: right;
  padding-top: 6px;
  white-space: nowrap;
}
.figma-timeline__dot {
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  margin: 8px auto 0;
  background: var(--void);
  border: 2px solid color-mix(in oklch, var(--figma-orchid) 60%, transparent);
  box-shadow: 0 0 0 4px var(--void); /* mask the spine behind the dot */
  transition:
    background 0.4s var(--ease),
    box-shadow 0.4s var(--ease),
    border-color 0.4s var(--ease),
    transform 0.3s var(--ease);
  z-index: 2;
}
.figma-timeline__item.is-visible .figma-timeline__dot {
  background: var(--figma-orchid);
  border-color: var(--figma-orchid);
  box-shadow:
    0 0 0 4px var(--void),
    0 0 12px color-mix(in oklch, var(--figma-orchid) 50%, transparent);
}
.figma-timeline__body {
  padding: 0 0 6px;
  max-width: 56ch;
}
.figma-timeline__cat {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--figma-orchid);
  display: inline-block;
}
.figma-timeline__title {
  font-family: var(--f-display) !important;
  font-weight: 500 !important;
  font-size: clamp(15px, 1.5vw, 18px) !important;
  line-height: 1.3 !important;
  letter-spacing: -0.005em !important;
  color: var(--text) !important;
  margin: 4px 0 4px !important;
  max-width: 36ch !important;
}
.figma-timeline__body p {
  font-family: var(--f-body) !important;
  font-size: 13px !important;
  line-height: 1.55 !important;
  color: var(--text-mute) !important;
  margin: 0 !important;
  max-width: 50ch !important;
}

/* peak milestone: bigger gradient dot, gradient cat label. */
.figma-timeline__item--peak .figma-timeline__dot {
  width: 16px;
  height: 16px;
  margin: 6px auto 0;
}
.figma-timeline__item--peak.is-visible .figma-timeline__dot {
  background: var(--figma-glow);
  border-color: transparent;
  box-shadow:
    0 0 0 4px var(--void),
    0 0 0 5px color-mix(in oklch, var(--figma-orchid) 30%, transparent),
    0 0 22px color-mix(in oklch, var(--figma-orchid) 60%, transparent),
    0 0 36px color-mix(in oklch, var(--figma-flame) 35%, transparent);
  animation: figma-timeline-peak-pulse 3.4s ease-in-out infinite;
}
@keyframes figma-timeline-peak-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.15); }
}
.figma-timeline__item--peak .figma-timeline__cat {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  font-weight: 600;
}
.figma-timeline__item--peak .figma-timeline__title {
  font-size: clamp(16px, 1.7vw, 20px) !important;
}

/* future event: dashed outline dot, mute the body */
.figma-timeline__item--future .figma-timeline__dot {
  background: transparent !important;
  border-style: dashed;
  border-color: color-mix(in oklch, var(--figma-flame) 60%, transparent) !important;
  box-shadow: 0 0 0 4px var(--void) !important;
}
.figma-timeline__item--future .figma-timeline__cat {
  color: var(--figma-flame);
}

/* hover any item: dot warms to flame, title picks up gradient. */
.figma-timeline__item:hover .figma-timeline__dot {
  transform: scale(1.25);
  border-color: var(--figma-flame);
}
.figma-timeline__item.is-visible:hover .figma-timeline__dot {
  background: var(--figma-flame);
  box-shadow:
    0 0 0 4px var(--void),
    0 0 16px color-mix(in oklch, var(--figma-flame) 60%, transparent);
}
.figma-timeline__item:hover .figma-timeline__title {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent !important;
  transition: none;
}

@media (max-width: 700px) {
  /* on small screens: drop the date column, dot moves to the left,
     date sits as a small mono pill above the title. */
  .figma-timeline { padding-left: 0; }
  .figma-timeline::before { left: 6px; }
  .figma-timeline__item {
    grid-template-columns: 14px 1fr;
    gap: 0 14px;
  }
  .figma-timeline__date {
    grid-column: 2;
    text-align: left;
    padding-top: 0;
    margin-bottom: 4px;
  }
  .figma-timeline__dot { margin-top: 4px; }
}

@media (prefers-reduced-motion: reduce) {
  .figma-timeline__item { transition: opacity 0.3s ease; transform: none; filter: none; }
  .figma-timeline__item--peak.is-visible .figma-timeline__dot { animation: none; }
}

/* art.edu / AAU clarifier — small mono aside with an orchid
   border-left tab. defines the shorthand once so the rest of
   the page can use it freely. */
.figma-aside {
  font-family: var(--f-mono) !important;
  font-size: 12px !important;
  line-height: 1.55 !important;
  color: var(--text-mute) !important;
  letter-spacing: 0.02em !important;
  padding: 4px 0 4px 16px !important;
  border-left: 2px solid color-mix(in oklch, var(--figma-orchid) 60%, transparent) !important;
  max-width: 56ch !important;
  margin: 4px 0 !important;
  display: grid !important;
  gap: 2px !important;
}
.figma-aside__line { display: block; }
.figma-aside__sym {
  color: var(--figma-orchid);
  margin-right: 6px;
}

/* acceptance email banner. solo variant (--solo) drops the portrait
   side cell entirely so the email banner spans the column width. */
.figma-acceptance {
  margin: clamp(20px, 3vh, 40px) 0 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) 220px;
  gap: clamp(20px, 3vw, 36px);
  align-items: end;
}
.figma-acceptance--solo {
  display: block;
  /* dialed back so the banner doesn't dominate the column. centered
     in the text-flow with breathing room above + below. */
  max-width: 540px;
  margin: clamp(20px, 3vh, 40px) auto;
}
/* overlap layout: cl-intro IG post sits at the bottom, full width.
   the acceptance email banner floats on top, slightly tilted, partly
   overlapping the top edge of the intro. on hover the banner tilts
   the OTHER way and lifts a touch — small playful interaction. */
.figma-acceptance.figma-acceptance--overlap,
.figma-setup__inner > .figma-acceptance.figma-acceptance--overlap {
  position: relative !important;
  display: block !important;
  width: 100% !important;
  max-width: 360px !important;
  /* extra top margin gives the oversized banner room to bleed
     above the intro without colliding with the bootcamp paragraph */
  margin: clamp(80px, 10vh, 130px) auto clamp(20px, 3vh, 40px) !important;
  isolation: isolate;
  cursor: default;
}
.figma-acceptance--overlap .figma-acceptance__intro {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
  filter:
    brightness(0.84)
    contrast(0.95)
    saturate(0.96)
    drop-shadow(0 10px 26px rgba(0, 0, 0, 0.5));
  position: relative;
  z-index: 1;
}
.figma-acceptance--overlap .figma-acceptance__email {
  position: absolute;
  /* banner only modestly wider than the CL intro — width 130% of
     the 360px figure ≈ 470px, so it overhangs each side by ~55px.
     visible + obvious, doesn't dominate. height stays auto so the
     4:1 aspect ratio keeps it short against the square intro.
     top -15% drops the banner lower over the intro — sits closer
     to the intro's top edge while still clearly overlapping. */
  top: -15%;
  left: 50%;
  width: 130%;
  /* global `img { max-width: 100% }` (style.css:97) was capping this
     at the figure's 360px, which is why previous width bumps "didn't
     stick" — every value past 100% got clamped to the parent. */
  max-width: none;
  height: auto;
  transform: translateX(-50%) rotate(-4deg);
  transform-origin: center;
  border-radius: 8px;
  filter:
    brightness(0.84)
    contrast(0.95)
    saturate(0.96)
    drop-shadow(0 14px 32px rgba(0, 0, 0, 0.6));
  z-index: 2;
}
/* hover: jitter shake — rotation oscillates around its rest tilt
   with small vertical jitter. plays continuously while hovered. */
.figma-acceptance--overlap:hover .figma-acceptance__email,
.figma-acceptance--overlap:focus-visible .figma-acceptance__email {
  animation: figma-acceptance-jitter 0.55s ease-in-out infinite;
}
@keyframes figma-acceptance-jitter {
  0%, 100% { transform: translateX(-50%) rotate(-4deg)  translateY(0); }
  20%      { transform: translateX(-50%) rotate(-8deg)  translateY(-3px); }
  40%      { transform: translateX(-50%) rotate(-1deg)  translateY(-2px); }
  60%      { transform: translateX(-50%) rotate(-7deg)  translateY(-4px); }
  80%      { transform: translateX(-50%) rotate(-2deg)  translateY(-1px); }
}
/* allow the email to overflow the figure bounds */
.figma-acceptance--overlap { overflow: visible !important; }
@media (prefers-reduced-motion: reduce) {
  .figma-acceptance--overlap:hover .figma-acceptance__email { animation: none; }
}
/* (orphan acceptance __email + __portrait styles removed — the
   --mixed layout above is the source of truth for the email image) */

/* ── 3 · EVENTS list (about-page pattern, glitch hover) ── */
.figma-events {
  padding: clamp(60px, 10vh, 120px) clamp(24px, 5vw, 72px);
}
.figma-events__inner {
  max-width: 1000px;
  margin: 0 auto;
}
.figma-events .figma-h2 {
  margin-bottom: clamp(36px, 6vh, 64px);
}
.figma-events__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
}
.figma-event {
  position: relative;
}
.figma-event__row {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 24px;
  padding: 22px 0;
  border-top: 1px solid var(--rule);
  text-decoration: none;
  color: var(--text);
  transition: color 0.4s var(--ease);
  z-index: 1;
}
.figma-event:last-child .figma-event__row {
  border-bottom: 1px solid var(--rule);
}

/* on hover: a small image fades in centered in the row, slightly
   tilted with a soft drop-shadow. picks up the row's accent color
   as a subtle outline so each row has its own moment. */
.figma-event__peek {
  position: absolute;
  top: 50%;
  left: 50%;
  /* per-event rotation set via --peek-tilt below; this rule just
     stages the start state. */
  --peek-tilt: -2deg;
  transform: translate(-50%, -50%) scale(0.92) rotate(var(--peek-tilt));
  width: clamp(180px, 22vw, 240px);
  aspect-ratio: 4 / 3;
  border-radius: 10px;
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  filter: blur(4px);
  transition:
    opacity 0.35s var(--ease),
    transform 0.5s cubic-bezier(.2, .8, .25, 1),
    filter 0.35s var(--ease);
  z-index: 2;
  box-shadow:
    0 18px 36px rgba(0, 0, 0, 0.55),
    0 0 0 1px color-mix(in oklch, var(--row-accent, var(--figma-orchid)) 30%, transparent),
    0 0 32px color-mix(in oklch, var(--row-accent, var(--figma-orchid)) 18%, transparent);
}
/* alternating tilts per event — left, right, left, right, left —
   so the peek images feel hand-pinned, not machine-stamped. */
.figma-events__list .figma-event:nth-child(1) .figma-event__peek { --peek-tilt: -3deg; }
.figma-events__list .figma-event:nth-child(2) .figma-event__peek { --peek-tilt:  2.5deg; }
.figma-events__list .figma-event:nth-child(3) .figma-event__peek { --peek-tilt: -1.5deg; }
.figma-events__list .figma-event:nth-child(4) .figma-event__peek { --peek-tilt:  3.5deg; }
.figma-events__list .figma-event:nth-child(5) .figma-event__peek { --peek-tilt: -2.5deg; }
.figma-event__peek img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* matcha-rave is a wide group photo. zoom in further (1.5×) and
   push the visible window right so the Figma sign + Ivy beneath it
   are what reads on hover. cuts the left edge of the room — fine. */
.figma-event__peek--matcha img {
  object-position: 78% 40%;
  transform: scale(1.5);
  transform-origin: 78% 40%;
}
/* playground was an end-of-event group shot. zoom (1.75×) + shift
   left so the right side crops out. y at 75% pushes the visible
   window DOWN so we see less ceiling and more of the people. */
.figma-event__peek--playground img {
  object-position: 35% 65%;
  transform: scale(1.75);
  transform-origin: 35% 65%;
}
.figma-event:hover .figma-event__peek {
  opacity: 1;
  filter: blur(0);
  transform: translate(-50%, -50%) scale(1) rotate(var(--peek-tilt));
}
@media (max-width: 600px) {
  .figma-event__peek { display: none; } /* row stacks on mobile, peek would crowd it */
}
@media (prefers-reduced-motion: reduce) {
  .figma-event__peek { transition: opacity 0.2s ease; }
  .figma-event:hover .figma-event__peek { transform: translate(-50%, -50%); }
}
.figma-event__name {
  position: relative;
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(20px, 2.6vw, 30px);
  letter-spacing: -0.005em;
  color: var(--text-dim);
  transition: color 0.3s var(--ease);
}
.figma-event__type {
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-mute);
  text-align: right;
  white-space: nowrap;
  transition: color 0.3s var(--ease);
}

/* hover: ev-name takes the row's data-color accent. clean single
   color shift, no chromatic glitch — calmer + more confident. */
.figma-event__row:hover .figma-event__name { color: var(--row-accent, var(--figma-orchid)); }
.figma-event__row:hover .figma-event__type { color: var(--text-dim); }

/* per-event accent color */
.figma-event { --row-accent: var(--figma-orchid); }
.figma-event[data-color="orchid"]  { --row-accent: var(--figma-orchid); }
.figma-event[data-color="hotpink"] { --row-accent: var(--figma-hotpink); }
.figma-event[data-color="green"]   { --row-accent: var(--figma-green); }
.figma-event[data-color="cyan"]    { --row-accent: var(--figma-cyan); }
.figma-event[data-color="purple"]  { --row-accent: var(--figma-purple); }

/* feature row gets a subtle dot to mark it as the headliner */
.figma-event--feature .figma-event__name::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--row-accent);
  box-shadow: 0 0 8px var(--row-accent);
  margin-right: 12px;
  vertical-align: middle;
  animation: figma-blink 2.4s ease-in-out infinite;
}
@keyframes figma-blink {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.45; }
}

.figma-events__caption {
  margin: clamp(28px, 4vh, 48px) 0 0;
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
}
.figma-events__caption a {
  color: var(--text-dim);
  /* dotted underline removed 2026-06-07 — the → and hover colour carry it */
  text-decoration: none;
  transition: color 0.3s var(--ease);
}
.figma-events__caption a:hover {
  color: var(--figma-orchid);
}

@media (max-width: 600px) {
  .figma-event__row { flex-direction: column; align-items: flex-start; gap: 4px; padding: 18px 0; }
  .figma-event__type { text-align: left; }
}

/* ── 3.5 · TREASURE ISLAND breather ────────────────────────
   single wide photo with a small caption pill at the bottom-left
   (matching the beats video pattern). cropped left so the awkward
   bottom-right is out of frame. modest height so we don't zoom in
   on the (young) crowd. */
.figma-island {
  padding: clamp(40px, 6vh, 80px) clamp(24px, 5vw, 72px);
}
.figma-island__fig {
  position: relative;
  margin: 0 auto;
  max-width: 1100px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--void-2);
  isolation: isolate;
  box-shadow:
    0 24px 56px rgba(0, 0, 0, 0.55),
    0 0 0 1px oklch(1 0 0 / 0.04);
}
.figma-island__fig img {
  display: block;
  width: 100%;
  height: clamp(260px, 35vh, 445px);
  object-fit: cover;
  /* push the visible window to the LEFT so the awkward bottom-right
     person is cropped out. y bumped 56% → 62% so the bottom of the
     scene isn't cropped off too tight. */
  object-position: 30% 62%;
}
/* caption pinned TOP-LEFT. lighter gradient — just enough darkness
   for legibility, not so much that the sky goes flat. */
.figma-island__cap {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  padding: 22px 28px 70px;
  display: grid;
  gap: 8px;
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 0.25) 50%,
    transparent 100%);
  pointer-events: none;
  z-index: 1;
}
.figma-island__cap .figma-eyebrow { margin-bottom: 0; }
.figma-island__cap p {
  font-family: var(--f-body);
  font-size: clamp(14px, 1.3vw, 16px);
  line-height: 1.55;
  color: var(--text);
  margin: 0;
  max-width: 60ch;
}
@media (max-width: 700px) {
  .figma-island__fig img { height: clamp(205px, 35vh, 335px); }
}

/* ── 2.75 · CONFIG 2025 (in-person bridge) ─────────────────
   asymmetric mosaic: 4 rows of varied 2-up grids + a centered
   solo, capped heights so portrait/landscape coexist cleanly. */
.figma-config {
  padding: clamp(60px, 10vh, 120px) clamp(24px, 5vw, 72px) clamp(80px, 12vh, 140px);
}
.figma-config__inner {
  max-width: 1100px;
  margin: 0 auto;
  display: grid;
  gap: clamp(20px, 3vh, 36px);
}
.figma-config__head {
  display: grid;
  gap: 14px;
  max-width: 60ch;
}
.figma-config p {
  font-family: var(--f-body);
  font-size: clamp(14px, 1.3vw, 16px);
  line-height: 1.7;
  color: var(--text-dim);
  margin: 0;
  max-width: 60ch;
}

.figma-config__row {
  display: grid;
  gap: clamp(8px, 1vw, 14px);
  height: clamp(260px, 32vw, 380px);
}
.figma-config__row--tall {
  height: clamp(360px, 50vw, 540px);
}
.figma-config__row--hero  { grid-template-columns: 2fr 1fr; }
.figma-config__row--bal   { grid-template-columns: 1fr 2fr; }
.figma-config__row--even  { grid-template-columns: 1fr 1fr; }
.figma-config__row--solo  {
  grid-template-columns: 1fr;
  max-width: 480px;
  margin: 0 auto;
  height: auto;
  aspect-ratio: 9 / 12;
}

.figma-config__cell {
  position: relative;
  margin: 0;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--void-2);
  isolation: isolate;
  transition: transform 0.6s var(--ease);
}
/* playful per-cell tilts so the imperfect alignment between photos
   reads as intentional polaroid scatter, not a layout bug. */
/* hero-row first cell tilt is gentler than the others — at -1.1deg
   the rotation was clipping the lower-left of the image (the woman
   on the left of the projected screen lost her arm). -0.4deg keeps
   the polaroid feel without eating subjects. */
.figma-config__row--hero .figma-config__cell:first-child  { transform: rotate(-0.4deg); }
.figma-config__row--hero .figma-config__cell:last-child   { transform: rotate(0.7deg); }
.figma-config__row--bal  .figma-config__cell:first-child  { transform: rotate(0.9deg); }
.figma-config__row--bal  .figma-config__cell:last-child   { transform: rotate(-0.6deg); }
.figma-config__row--even .figma-config__cell:first-child  { transform: rotate(-0.8deg); }
.figma-config__row--even .figma-config__cell:last-child   { transform: rotate(1.0deg); }
.figma-config__row--solo .figma-config__cell             { transform: rotate(-0.5deg); }
@media (prefers-reduced-motion: reduce) {
  .figma-config__row .figma-config__cell { transform: none !important; }
}
.figma-config__cell img,
.figma-config__cell video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* page-wide brightness knockdown — pushed further so the config
     row reads as moody, not headache-bright. */
  filter: brightness(0.72) contrast(0.96) saturate(0.94);
}
/* hero row · first cell · talk image — the two figures on the left
   of the source frame were getting cropped by default centering.
   pin the crop to the LEFT edge so they sit in view. */
.figma-config__row--hero .figma-config__cell:first-child img {
  object-position: 0% 50%;
}
/* additional dark overlay on every config cell so the entire section
   sits behind a uniform tonal scrim. captions stay above (z 3). */
.figma-config__cell::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  pointer-events: none;
  z-index: 2;
  border-radius: inherit;
}
/* lift any caption above the overlay so the text stays readable. */
.figma-config__cell figcaption { z-index: 3 !important; }
/* Tommy + Ivy: lean slightly toward Ivy on the left so she stays
   in frame — full center clipped her edge a touch. extra scale-down
   pulls back from the crop a touch, framing them in a thin void
   border (matches the cell's --void-2 background) without changing
   the layout. */
.figma-config__cell--tommy img {
  object-position: 38% center;
  transform: scale(0.93);
}

/* countdown cycler — 4 images + 1 video stacked in the same cell,
   cross-fading. active slide at opacity 1, others at 0. JS rotates
   the .is-active class every ~3.2s (longer for the video so it has
   time to play). fade is gentle but obvious. */
.figma-config__cell--countdown {
  position: relative;
}
.figma-config__cell--countdown figcaption {
  z-index: 2; /* above the cycling slides */
}
.figma-config__countdown-slide {
  position: absolute !important;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 1s var(--ease);
  z-index: 0;
}
.figma-config__countdown-slide.is-active {
  opacity: 1;
  z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
  .figma-config__countdown-slide { transition: opacity 0.3s ease; }
}

/* moscone swap: top-right cell stacks the still photo + a video.
   the photo is shown as the entry, then the video cross-fades in
   after a delay (JS) and plays its full duration. same pattern as
   the countdown but a one-shot, not a cycler. */
.figma-config__cell--moscone {
  position: relative;
}
.figma-config__swap-slide {
  position: absolute !important;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
  z-index: 0;
  filter: brightness(0.72) contrast(0.96) saturate(0.94);
}
.figma-config__swap-slide.is-active {
  opacity: 1;
  z-index: 1;
}
@media (prefers-reduced-motion: reduce) {
  .figma-config__swap-slide { transition: opacity 0.3s ease; }
}
.figma-config__cell figcaption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 24px 18px 14px;
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text);
  background: linear-gradient(180deg, transparent 0%, rgba(0,0,0,0.65) 70%, rgba(0,0,0,0.85) 100%);
  pointer-events: none;
  z-index: 1;
}

/* closing line under the mosaic — Config 2026 link, LEFT-aligned
   to the image edge (not centered). */
.figma-config__next {
  font-family: var(--f-mono);
  font-size: clamp(12px, 1.2vw, 14px);
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-mute);
  margin-top: clamp(16px, 2vh, 28px) !important;
  text-align: left;
}
.figma-config__link {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  text-decoration: none;
  border-bottom: 1px dotted color-mix(in oklch, var(--figma-orchid) 50%, transparent);
  padding-bottom: 1px;
  transition: border-color 0.3s var(--ease);
}
.figma-config__link:hover {
  border-color: var(--figma-flame);
}

@media (max-width: 720px) {
  .figma-config__row,
  .figma-config__row--hero,
  .figma-config__row--bal,
  .figma-config__row--even {
    grid-template-columns: 1fr;
    height: auto;
  }
  .figma-config__row > .figma-config__cell {
    aspect-ratio: 4 / 3;
  }
  .figma-config__row--solo { aspect-ratio: 9 / 12; }
}


/* ── NUMBERS strip — inline variant within how-it-started ─── */
.figma-numbers__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 4vw, 56px);
  border-top: none;
  padding-top: clamp(28px, 5vh, 48px);
  margin: 0;
  position: relative;
}
/* inline: tucked between the asides and the timeline. extra
   breathing room above + below so it reads as its own beat between
   the text and the timeline, not jammed against either. */
.figma-numbers__grid--inline {
  padding-top: clamp(40px, 7vh, 76px);
  gap: clamp(16px, 3vw, 36px);
  margin: clamp(48px, 8vh, 96px) 0 clamp(48px, 8vh, 96px) !important;
}
.figma-numbers__grid--inline dd {
  font-size: clamp(28px, 4vw, 48px);
}
/* keep multi-token numbers ("+2 CLs") on a single line — the
   non-breaking space here would have been ideal but the cell width
   sometimes still forces a break, so nowrap is the firm fix. */
.figma-numbers__grid dd {
  white-space: nowrap;
}
/* gradient hairline above the four metrics — picks up the page
   identity instead of the generic --rule color. */
.figma-numbers__grid::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in oklch, var(--figma-orchid) 70%, transparent) 20%,
    color-mix(in oklch, var(--figma-flame) 70%, transparent) 80%,
    transparent 100%);
}
/* center each cell so a one-character number ("5") doesn't leave
   a huge dead zone next to a wider one ("+2 CLs"). visual rhythm
   reads even across the row. */
.figma-numbers__grid > div {
  display: grid;
  gap: 10px;
  justify-items: center;
  text-align: center;
}
.figma-numbers__grid dt {
  font-family: var(--f-mono);
  font-size: 9px;
  text-transform: uppercase;
  letter-spacing: 0.26em;
  color: var(--text-mute);
}
.figma-numbers__grid dd {
  font-family: var(--f-display);
  font-weight: 600;
  font-size: clamp(36px, 5vw, 64px);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--text);
  margin: 0;
}
/* sub-line under a number for breakdowns ("1 referred + 2 advocated") */
.figma-numbers__sub {
  display: block;
  font-family: var(--f-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--text-mute);
  margin-top: 8px;
  text-transform: none;
  font-weight: 400;
}
@media (max-width: 720px) {
  .figma-numbers__grid { grid-template-columns: repeat(2, 1fr); gap: 28px; }
}

/* ── beats · giant communal beat-maker video moment ─────────
   sits right under the hero. extra padding above + below so the
   video feels like its own breath between hero and events. */
.figma-beats {
  padding: clamp(120px, 15vh, 220px) clamp(24px, 5vw, 72px) clamp(72px, 10vh, 140px);
}
.figma-beats__fig {
  position: relative;
  margin: 0 auto;
  max-width: 1100px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--void-2);
  isolation: isolate;
  box-shadow:
    0 24px 56px rgba(0, 0, 0, 0.55),
    0 0 0 1px oklch(1 0 0 / 0.04);
}
.figma-beats__video {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
/* caption pinned TOP-LEFT (matching the treasure island pattern) so
   the same UI language carries through the page. */
.figma-beats__cap {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  padding: 22px 28px 80px;
  display: grid;
  gap: 8px;
  background: linear-gradient(180deg,
    rgba(0, 0, 0, 0.85) 0%,
    rgba(0, 0, 0, 0.55) 40%,
    transparent 100%);
  pointer-events: none;
  z-index: 1;
}
.figma-beats__cap .figma-eyebrow { margin-bottom: 0; }
.figma-beats__cap p {
  font-family: var(--f-body);
  font-size: clamp(14px, 1.3vw, 16px);
  line-height: 1.55;
  color: var(--text);
  margin: 0;
  max-width: 60ch;
}
@media (max-width: 700px) {
  .figma-beats__video { aspect-ratio: 4 / 3; }
}

/* sound toggle — small floating button in the top-right of the
   beats video. shows a muted-speaker by default, swaps to a
   speaker-with-waves when audio is on. picks up the page gradient
   on hover so it stays in voice. */
.figma-beats__sound {
  position: absolute;
  top: 14px;
  right: 14px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 999px;
  border: 1px solid color-mix(in oklch, var(--figma-orchid) 30%, transparent);
  background: color-mix(in oklch, var(--void) 65%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text);
  cursor: pointer;
  z-index: 2;
  transition:
    border-color 0.3s var(--ease),
    color 0.3s var(--ease),
    background 0.3s var(--ease);
}
.figma-beats__sound:hover {
  border-color: var(--figma-orchid);
  background: color-mix(in oklch, var(--figma-orchid) 14%, var(--void));
}
.figma-beats__sound-icon {
  display: block;
  flex: 0 0 auto;
}
/* default: muted icon visible, on icon hidden */
.figma-beats__sound-icon--on { display: none; }
.figma-beats__sound[aria-pressed="true"] .figma-beats__sound-icon--off { display: none; }
.figma-beats__sound[aria-pressed="true"] .figma-beats__sound-icon--on  { display: block; }

/* ── 6 · SIGN-OFF ────────────────────────────────────────── */
.figma-signoff {
  /* generous breathing room — "what comes next" was crashing into
     the footer and the section above. lifted both top and bottom. */
  padding: clamp(160px, 22vh, 240px) clamp(24px, 5vw, 72px) clamp(200px, 26vh, 280px);
  max-width: 880px;
  margin: 0 auto;
  display: grid;
  gap: 24px;
  text-align: center;
  justify-items: center;
}
.figma-signoff p {
  font-family: var(--f-display);
  font-weight: 500;
  font-size: clamp(22px, 3vw, 32px);
  line-height: 1.35;
  letter-spacing: -0.01em;
  color: var(--text);
  margin: 0;
  max-width: 32ch;
}

/* Up-next CTA — outline by default, fills with gradient on hover. */
.figma-next {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 14px 22px;
  /* match the nav + footer CTA shape (was 999px pill) — Ivy wants
     consistent rounded-rect geometry across all the CTAs */
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-family: var(--f-mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.2em;
  color: var(--figma-orchid);
  background:
    linear-gradient(var(--void), var(--void)) padding-box,
    var(--figma-glow) border-box;
  text-decoration: none;
  transition: color 0.3s var(--ease), background 0.3s var(--ease);
}
.figma-next:hover {
  color: var(--void);
  background:
    var(--figma-glow) padding-box,
    var(--figma-glow) border-box;
}
.figma-next::after {
  content: "→";
  font-size: 14px;
  letter-spacing: 0;
  transition: transform 0.3s var(--ease);
}
.figma-next:hover::after { transform: translateX(3px); }

/* ── FOOTER (figma-cl variant) ──────────────────────────────
   the centerpiece: a hand-built interactive Figma F. five SVG
   shapes using the Figma brand colors. each shape plays a tone
   in C major (C E G C E) on hover via Web Audio API. no audio
   files — synth with sine oscillators + ADSR envelopes. */

/* hide the parent footer's "Let's build something w/ soul" h2;
   on this page the F-logo IS the headline. also hide the parent
   bloom -- this footer doesn't use it. */
.figma-foot .foot__title { display: none !important; }
.figma-foot .foot__bloom { display: none !important; }

/* override the parent's massive 180-420px gap between flex children.
   each block gets its own breathing margin so the F doesn't feel
   smashed against the eyebrow above it or the hint below. */
.figma-foot .foot__content {
  gap: 0 !important;
  align-items: center;
  text-align: center;
}
.figma-foot .foot__content > .eyebrow {
  margin: clamp(0px, 1vh, 16px) 0 clamp(36px, 6vh, 72px); /* push F further from eyebrow */
}
/* hint is now absolutely positioned over the F (see later block).
   no longer needs flow-based margin. */
.figma-foot .foot__middle {
  width: auto;
  align-items: center;
  margin: clamp(36px, 5vh, 64px) 0 clamp(60px, 9vh, 100px); /* CTA breathes apart from links */
}
.figma-foot .foot__bottom {
  margin-top: auto;
  width: 100%;
}

/* the F sits centered as its own block */
.figma-foot .figma-f-mark {
  align-self: center;
  margin: 0 auto;
}

/* the F itself */
.figma-f-mark {
  /* big interactive figma F. button so it can capture pointer
     events + focus for keyboard users without breaking semantics. */
  appearance: none;
  border: 0;
  background: transparent;
  padding: 0;
  margin: 0;
  cursor: pointer;
  display: block;
  width: clamp(180px, 26vw, 320px);
  /* brand-color halo retired 2026-06-06 — the F's own colored shapes
     carry the footer; no glow bleeding behind the logo. */
}
.figma-f {
  width: 100%;
  height: auto;
  overflow: visible;
}
/* shapes stay STATIC by default — no lift, no glow on hover. on
   hover/press they get a subtle SVG inner shadow at the edges so
   the shape reads as "pushed in," but nothing moves. no scale,
   no transform = no 1px gaps between adjacent shapes. */
.figma-f__shape {
  transition: filter 0.18s var(--ease);
  cursor: pointer;
  outline: none; /* kill the ugly default browser focus square */
  -webkit-tap-highlight-color: transparent;
}
.figma-f__shape:focus,
.figma-f__shape:focus-visible {
  outline: none;
}
/* keyboard focus = subtle brightness lift, no outline rectangle */
.figma-f__shape:focus-visible {
  filter: brightness(1.18);
}
/* hover OR press: directional inner shadow at the top-left so the
   shape reads "pressed in" (matches the AirPods Max 2 swatch
   pattern). filter ref is defined inside the SVG (#figma-f-inset).
   no lift, no glow, no transform. */
.figma-f__shape:hover,
.figma-f__shape.is-pressed {
  filter: url(#figma-f-inset);
}
/* the F button itself shouldn't show a focus rectangle either */
.figma-f-mark:focus,
.figma-f-mark:focus-visible {
  outline: none;
}
/* fill + halo color per shape — currentColor lets drop-shadow pick up the brand color */
.figma-f__shape[data-color="red"]    { fill: var(--figma-red);    color: var(--figma-red); }
.figma-f__shape[data-color="orange"] { fill: var(--figma-orange); color: var(--figma-orange); }
.figma-f__shape[data-color="purple"] { fill: var(--figma-purple); color: var(--figma-purple); }
.figma-f__shape[data-color="blue"]   { fill: var(--figma-cyan);   color: var(--figma-cyan); }
.figma-f__shape[data-color="green"]  { fill: var(--figma-green);  color: var(--figma-green); }

/* ambient breathing pulse on the whole F when idle */
.figma-f-mark { animation: figma-f-breathe 7s ease-in-out infinite; }
@keyframes figma-f-breathe {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.015); }
}

@media (prefers-reduced-motion: reduce) {
  .figma-f-mark { animation: none; }
  .figma-f__shape { transition: none; }
  .figma-f__shape.is-pressed { filter: none; }
}

/* mail link picks up the gradient text by default. on hover the
   gradient fills the whole pill (mimics .figma-next above the
   footer) — background-clip flips from text to padding-box, text
   inverts to void, no glow. */
.figma-foot__mail {
  background: var(--figma-glow);
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  transition: color 0.35s var(--ease), background-clip 0.35s var(--ease),
              -webkit-background-clip 0.35s var(--ease), border-color 0.35s var(--ease);
}
.figma-foot__mail:hover {
  /* re-assert the figma-glow gradient explicitly so the global
     .foot__mail:hover (pink→orange) doesn't shadow it. */
  background: var(--figma-glow);
  background-clip: padding-box;
  -webkit-background-clip: padding-box;
  color: var(--void);
  border-color: transparent;
  box-shadow: none;
}
.figma-foot__mail::before { color: var(--figma-orchid) !important; }
.figma-foot__mail::after  { color: var(--figma-flame)  !important; }

/* hint floats centered over the F's middle row (purple + blue
   shapes), styled like the beats__sound pill so the whole UI
   speaks the same language. fades in when the foot enters
   viewport, fades out on first interaction (or after timeout). */
.figma-f-wrap {
  position: relative;
  display: inline-block;
  align-self: center;
}
.figma-foot__hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid color-mix(in oklch, var(--figma-orchid) 30%, transparent);
  background: color-mix(in oklch, var(--void) 65%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  font-family: var(--f-mono);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text);
  pointer-events: none;       /* never block hover on the F itself */
  opacity: 0;                 /* hidden until JS reveals on viewport entry */
  transition: opacity 0.5s var(--ease);
  z-index: 5;
  margin: 0;
}
.figma-foot__hint.is-visible { opacity: 1; }

/* music notes that drift from the cursor while hovering the F.
   each note pops in, floats up with a small horizontal drift, and
   fades out. JS sets color (one of the 5 brand hues) and --note-drift
   on the inline style. */
.figma-f__note {
  position: absolute;
  font-family: 'Apple Color Emoji', 'Segoe UI Symbol', 'Noto Sans Symbols', system-ui, sans-serif;
  font-size: 24px;
  line-height: 1;
  font-weight: 800;
  pointer-events: none;
  user-select: none;
  transform: translate(-50%, -50%) scale(0.5);
  opacity: 0;
  z-index: 10;
  animation: figma-f-note-float 2.4s cubic-bezier(.2, .6, .3, 1) forwards;
}
@keyframes figma-f-note-float {
  0%   {
    opacity: 0;
    transform: translate(-50%, -50%) scale(0.5) rotate(-8deg);
  }
  12%  {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1.1) rotate(-2deg);
  }
  /* hold phase — full-opacity drift up for ~40% of the run so the
     note lingers visibly before fading. */
  55%  {
    opacity: 1;
    transform:
      translate(calc(-50% + calc(var(--note-drift, 0px) * 0.45)), calc(-50% - 36px))
      scale(1.02) rotate(2deg);
  }
  100% {
    opacity: 0;
    transform:
      translate(calc(-50% + var(--note-drift, 0px)), calc(-50% - 110px))
      scale(0.85)
      rotate(8deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .figma-f__note { display: none; }
}

/* back-to-top: gradient default + brighter on hover.
   default state already shows the page color so it doesn't read as
   the previous page's lilac. */
.figma-body .to-top {
  border-color: color-mix(in oklch, var(--figma-orchid) 50%, transparent);
  color: var(--figma-orchid);
}
.figma-body .to-top:hover {
  border-color: var(--figma-orchid);
  background: transparent; /* no hazy fill — just the border + arrow brighten */
  color: var(--figma-orchid);
}
.figma-body .to-top:hover svg {
  stroke: var(--figma-orchid);
}
