/* ============================================================
   JuanUp 2026 — rebuilt from Figma Dev Mode (exact spec)
   Display: Outfit (Bold) · Body: Geist · Wordmark: self-hosted Inter (arrow alignment)
   Reference frame: 1440px, 80px side margins → 1280 content
   Sizes use clamp(min, Nvw, designPx) where N = designPx/1440*100
   ============================================================ */

:root {
  --cyan:      #00f2ff;   /* buttons, "2026", agenda heading, links */
  --ink:       #003366;   /* text on cyan buttons */
  --light:     #f0e2ee;   /* light body text on dark */
  --muted:     #d6c2d3;   /* sub text */
  --purple:    #4f2d91;   /* gradient top */
  --deep:      #1b075a;   /* dark sections */
  --blue:      #4540ff;   /* indigo cards / table */
  --dark-card: #230e67;   /* FAQ cards + FAQs title */

  --container: 1440px;
  --pad-x: clamp(20px, 5.6vw, 80px);
  --body: 'Geist', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  --display: 'Outfit', var(--body);
  --text-body: clamp(1.05rem, 1.53vw, 22px);   /* unified reading-copy size */
  --ease: cubic-bezier(.2, .7, .3, 1);   /* shared easing for all motion */
}

/* self-hosted + preloaded wordmark font (unique family so it's used
   explicitly and present at first paint — no fallback flash that would
   briefly misalign the arrow). Same Inter files = identical metrics. */
@font-face {
  font-family: 'InterWM'; font-style: normal; font-weight: 800;
  font-display: swap; src: url('assets/fonts/inter-extrabold.woff2') format('woff2');
}
@font-face {
  font-family: 'InterWM'; font-style: normal; font-weight: 900;
  font-display: swap; src: url('assets/fonts/inter-black.woff2') format('woff2');
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--body);
  color: #111;
  /* dark so sub-pixel section seams (fractional heights) blend invisibly
     instead of flashing white between the dark hero/intro/agenda sections */
  background: var(--deep);
  line-height: 1.4;
  overflow-x: clip;   /* clip (not hidden) so it doesn't break position:sticky */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
a { color: inherit; }

/* ---------- Interaction layer (Apple-grade polish) ---------- */
::selection { background: rgba(0, 242, 255, .28); color: #0a0a0a; }

/* keyboard focus: crisp cyan ring, never on mouse click */
:where(a, button):focus-visible {
  outline: 3px solid var(--cyan);
  outline-offset: 3px;
  border-radius: 6px;
}
.btn:focus-visible { outline-offset: 4px; }
:where(a, button):focus:not(:focus-visible) { outline: none; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--pad-x);
}

/* ---------- ↗ icon (Figma arrow1: M22 22V2H2M22 2L2 22) ---------- */
.ico--ne {
  display: inline-block;
  width: 1em; height: 1em;
  flex: none;
  background: currentColor;
  -webkit-mask: no-repeat center / contain;
          mask: no-repeat center / contain;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M22 22V2H2M22 2L2 22' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none'%3E%3Cpath d='M22 22V2H2M22 2L2 22' stroke='black' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.ico--sm { width: .55em; height: .55em; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  height: clamp(54px, 5.35vw, 77px);
  padding: 0 clamp(28px, 2.78vw, 40px);
  border-radius: 100px;
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.05rem, 2.22vw, 2rem);   /* 32px Get Tickets */
  letter-spacing: -.03em;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  border: 0;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease), filter .3s var(--ease), background .3s var(--ease);
  will-change: transform;
}
.btn .ico--ne { width: .62em; height: .62em; transition: transform .3s var(--ease); }
.btn:hover  { transform: translateY(-3px); }
.btn:hover .ico--ne { transform: translate(2px, -2px); }   /* arrow nudges along its diagonal */
.btn:active { transform: translateY(-1px) scale(.985); }

.btn--lg { font-size: clamp(1.25rem, 2.78vw, 2.5rem); }   /* 40px Join Now */

.btn--cyan {
  background: var(--cyan);
  color: var(--ink);
  box-shadow: 7px 7px 20.4px 5px rgba(0,0,0,.05);
}
.btn--cyan:hover { box-shadow: 0 18px 38px -10px rgba(0,242,255,.6); filter: brightness(1.04); }

.btn--ink {
  background: var(--deep);
  color: #fff;
  box-shadow: 7px 7px 20.4px 5px rgba(0,0,0,.05);
}
.btn--ink:hover { background: #2a0f7a; }

.btn--outline {
  background: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 2px rgba(255,255,255,.55);   /* ring = border, no layout shift */
}
.btn--outline:hover { background: rgba(255,255,255,.10); box-shadow: inset 0 0 0 2px #fff; }

.btn--block { width: 100%; justify-content: center; }

/* =========================================================
   HERO  (gradient #4f2d91 -> #1b075a, design height 1017)
   ========================================================= */
.hero {
  position: relative;
  isolation: isolate;
  background: linear-gradient(180deg, var(--purple) 0%, var(--deep) 100%);
  color: #fff;
  overflow: hidden;
  /* wave band sits below the meta row (matches the design: meta on clean
     purple, waves entirely below, band ~327px at 1440) */
  padding-bottom: clamp(120px, 23.5vw, 338px);
}
/* Exact Figma masked-wave composite. The layer is wider than the hero and
   its sides are faded to transparent, so neither the image's mask edges nor
   the drift animation can ever reveal a hard edge or side gap. */
/* Wave band sized as a fraction of the HERO (not the viewport), so it always
   fills the lower hero and reaches the bottom at any width. `cover` keeps it
   full-bleed; the mask fades it in at the top and out at the bottom, so it is
   never hard-clipped at the hero→intro edge. */
.hero__waves {
  /* The wave strip is cropped to where the artwork is fully transparent at top
     AND bottom, so the curves fade in/out by their own alpha — no hard cut at
     either edge (no mask needed). Drawn at natural aspect (width %, height auto)
     and pushed just below the fold so the dense waves sit at the hero bottom
     like Figma; the soft fade-out is clipped by the hero's overflow. 106% width
     gives ~Figma scale and clips the strand termini off the sides. */
  position: absolute; left: 0; right: 0; bottom: 0; height: 48%;
  z-index: 0; pointer-events: none;
  background: url("assets/waves-strip.webp") no-repeat;
  background-size: 106% auto;
  background-position: 50% 100%;
  /* the strip's own alpha fades the TOP; this dissolves only the last sliver so
     the bright waves don't get sliced by the hero→intro section seam (both are
     --deep, so the fade is invisible) — no hard cut, no purple gap */
  -webkit-mask-image: linear-gradient(180deg, #000 0 90%, transparent 100%);
          mask-image: linear-gradient(180deg, #000 0 90%, transparent 100%);
  animation: waveDrift 19s ease-in-out infinite;
  will-change: background-position;
}
@keyframes waveDrift {        /* gentle horizontal flow; stays within the 6%
                                 overflow so an edge is never exposed */
  0%, 100% { background-position: 34% 100%; }
  50%      { background-position: 66% 100%; }
}
/* dissolve the waves into the bottom colour at the hero edge so they are
   never hard-clipped at the hero→intro boundary (above waves, below text) */
.hero__inner { position: relative; z-index: 1; padding-top: clamp(28px, 2.2vw, 32px); }

.brand { width: clamp(132px, 12vw, 174px); height: auto; }

/* hero wordmark — live Inter text; the arrow is an inline SVG positioned in
   em over the U's right leg, so the arrow↔U relationship is identical at
   every breakpoint by construction. JuanUp: Inter ExtraBold · 2026: Inter Black */
.hero__lead { margin-top: clamp(36px, 4.6vw, 66px); }
.wordmark {
  margin: 0;
  display: flex; align-items: baseline; flex-wrap: wrap;
  gap: clamp(10px, 1.1vw, 16px);
  font-family: var(--body);
  line-height: .92;
  font-size: clamp(2.9rem, 11.3vw, 163px);
}
.wm-juan { color: #fff; font-family: 'InterWM', var(--body); font-weight: 800; letter-spacing: -.07em; }
.wm-u { position: relative; display: inline-block; }
.wm-arrow {
  position: absolute;
  /* Figma arrow asset is 94.6×75.7 (≈ .581em × .465em at the 162.79px design
     size): mostly arrowhead + a short stub. The long "stem" is the U's own
     right leg — the arrow only sits atop it, it does NOT replace it. */
  left: 88%; bottom: .60em;
  transform: translateX(-50%);
  width: .581em; height: .465em;
  color: #fff;
}
.wm-year {
  color: var(--cyan); font-family: 'InterWM', var(--body); font-weight: 900; letter-spacing: -.05em;
  /* pale cyan outline stroke (outside the fill) + outer glow, per Figma */
  -webkit-text-stroke: .018em #c8f9ff;
  paint-order: stroke fill;
  text-shadow: 0 0 18px rgba(0,242,255,.75), 0 0 48px rgba(0,242,255,.45);
}
.hero__actions {
  margin-top: clamp(34px, 4.4vw, 64px);
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(12px, 1.4vw, 20px);
}

/* hero meta */
.hero__meta {
  margin-top: clamp(34px, 4.8vw, 70px);
  display: flex; justify-content: space-between; align-items: flex-start;
  gap: 32px; flex-wrap: wrap;
}
.hero__tagline { margin: 0; max-width: 36ch; font-size: clamp(1.05rem, 2.22vw, 32px); line-height: 1.4; }
.hero__tagline span { color: var(--light); font-weight: 400; }
.hero__tagline strong { display: block; color: var(--light); font-weight: 700; }
/* Figma left-aligns the meta lines on a shared left edge (date, "Whitespace",
   "Makati" all start at x=0 in node 1:188), ragged on the right — NOT
   right-aligned. The block itself sits on the right of the hero via the
   space-between flex row; only its internal text is left-aligned. */
.hero__when { text-align: left; }
/* Figma meta block (node 1:186): flex column, gap 8px between the date and the
   place. Date = Inter Medium 24px (line-box 29px → lh 1.21); place = Inter Bold
   40px, two lines, box 96px → lh 1.2. The date had no explicit line-height and
   inherited the body's ~1.5, inflating the gap; pinning both to Figma metrics
   restores the tight 8px box-to-box spacing. */
.hero__date { margin: 0 0 8px; color: var(--light); font-weight: 500; line-height: 1.21; font-size: clamp(.9rem, 1.67vw, 24px); }
.hero__place {
  margin: 0; font-weight: 700; font-size: clamp(1.4rem, 2.78vw, 40px); line-height: 1.2; color: var(--light);
}
.hero__place .ico--ne { color: var(--light); vertical-align: baseline; }

/* mobile: scale the wordmark up so "JuanUp 2026" spans the full width on one
   line (overrides the clamp's smaller min); arrow is in em, so it scales too */
@media (max-width: 600px) {
  .wordmark { font-size: 14.5vw; flex-wrap: nowrap; gap: .1em; }
}

/* =========================================================
   INTRO  (bg #1b075a)
   ========================================================= */
.intro { background: var(--deep); color: #fff; padding-block: clamp(72px, 9.8vw, 141px); }
.intro__grid { display: grid; grid-template-columns: 1fr; gap: clamp(36px, 5vw, 72px); align-items: start; }
.intro__eyebrow { margin: 0 0 8px; font-family: var(--body); font-weight: 400; color: var(--light); font-size: clamp(1.5rem, 3.05vw, 44px); }
.intro__title { margin: 0; font-family: var(--display); font-weight: 700; letter-spacing: -.03em; color: #fff; line-height: 1; font-size: clamp(2.4rem, 5vw, 72px); }

.card--indigo {
  background: var(--blue);
  color: #fff;
  border-radius: 0 50px 50px 50px;   /* top-left sharp */
  padding: clamp(40px, 4.7vw, 68px);
  box-shadow: 7px 7px 20.4px 5px rgba(0,0,0,.05);
}
.card__title { margin: 0 0 22px; font-family: var(--display); font-weight: 700; letter-spacing: -.03em; line-height: 1; font-size: clamp(1.7rem, 3.33vw, 48px); }
.card__title strong { font-weight: 800; }
.card__body { margin: 0 0 16px; font-family: var(--body); font-weight: 500; color: var(--light); line-height: 1.5; font-size: var(--text-body); }
.card__body:last-of-type { margin-bottom: clamp(26px, 2.6vw, 38px); }

@media (min-width: 900px) {
  /* Left text pins while scrolling and releases at the bottom of the right
     card: the grid's height == the (taller) card's height, so a sticky head
     unsticks exactly when its container's bottom is reached. */
  .intro__head {
    padding-top: clamp(8px, 2vw, 28px);
    position: sticky;
    top: clamp(24px, 4vw, 48px);
    align-self: start;   /* keep the column at content height, not row height */
  }
  .intro__grid { grid-template-columns: 540fr 669fr; gap: clamp(40px, 5vw, 71px); }
}

/* =========================================================
   EXPERIENCE  (white)
   ========================================================= */
.exp { background: #fff; padding-block: clamp(48px, 6.5vw, 100px); }
.exp__grid { display: grid; grid-template-columns: 1fr; gap: clamp(32px, 4vw, 60px); align-items: center; }
.exp__media { display: flex; justify-content: center; }

/* ring asset (600) with crowd photo circle (430) centered */
.ring {
  position: relative;
  width: clamp(300px, 41.7vw, 600px);
  aspect-ratio: 1;
  display: grid; place-items: center;
  overflow: hidden;        /* contains the rotating swirl — it can never bleed onto the text */
  isolation: isolate;
}
/* swirl rotates slowly on its own; the photo underneath stays still */
.ring::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: url("assets/ring.webp") center / contain no-repeat;
  animation: ringSpin 44s linear infinite;
}
.ring__photo {
  position: relative; z-index: 1;
  width: 71.7%; height: 71.7%;     /* 430 / 600 */
  border-radius: 50%;
  background: url("assets/a-342.jpg") center / cover;
  transition: transform .5s var(--ease);
}
.exp__media:hover .ring__photo { transform: scale(1.04); }
@keyframes ringSpin { to { transform: rotate(360deg); } }

.exp__copy { position: relative; z-index: 1; }
.exp__title { margin: 0 0 18px; font-family: var(--display); font-weight: 700; color: var(--deep); line-height: 1.05; font-size: clamp(2rem, 3.33vw, 48px); }
.exp__intro { margin: 0 0 22px; font-family: var(--body); color: #000; line-height: 1.5; font-size: var(--text-body); }
.exp__list { margin: 0 0 34px; padding-left: 1.4em; font-family: var(--body); color: #000; line-height: 1.5; font-size: var(--text-body); }
.exp__list li { margin-bottom: 14px; }
.exp__list li::marker { color: #000; }

@media (min-width: 900px) {
  .exp__grid { grid-template-columns: 600fr 667fr; gap: clamp(40px, 2.3vw, 33px); }
}

/* =========================================================
   AGENDA  (bg #1b075a)
   ========================================================= */
.agenda {
  position: relative; isolation: isolate; overflow: clip;   /* clip (not hidden) so the sticky head still works */
  background: var(--deep); color: #fff;
  padding-block: clamp(72px, 9vw, 130px);
}
.agenda__wave {
  /* Overshoot past the left edge so the wave runs full-bleed off it. The
     overshoot (7%) is larger than the drift animation's rightward nudge, so the
     left edge can never pull inward and reveal a gap; the section's overflow:clip
     trims the off-screen part. Right edge stays put (-7% + 52% = 45% as before). */
  position: absolute; left: -7%; bottom: 8%; width: 52%; z-index: 0;
  pointer-events: none;
  /* exact Figma agenda wave on matching #1b075a; fade the top/right edges
     so the crop boundary (and the drift) never shows a hard line */
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%), linear-gradient(270deg, transparent 0, #000 16%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(180deg, transparent 0, #000 22%), linear-gradient(270deg, transparent 0, #000 16%);
          mask-composite: intersect;
  animation: agendaWave 24s ease-in-out infinite;
  will-change: transform;
}
@keyframes agendaWave {
  0%, 100% { transform: translate(0, 0); }
  50%      { transform: translate(2.5%, -1.6%); }
}
/* on mobile the wave overlaps the schedule card — hide it */
@media (max-width: 700px) {
  .agenda__wave { display: none; }
}
.agenda__grid { display: grid; grid-template-columns: 1fr; gap: clamp(36px, 4vw, 56px); align-items: start; }
.agenda__title { margin: 0 0 22px; font-family: var(--display); font-weight: 700; color: var(--cyan); line-height: 1; font-size: clamp(2.6rem, 4.72vw, 68px); }
.agenda__desc { margin: 0; max-width: 33ch; font-family: var(--body); font-weight: 500; color: var(--light); line-height: 1.5; font-size: var(--text-body); }

.agenda__card { background: var(--blue); border-radius: clamp(28px, 3.5vw, 50px); padding: clamp(26px, 3vw, 44px); }
.schedule { list-style: none; margin: 0 0 26px; padding: 0; }
.schedule__row {
  display: grid;
  grid-template-columns: clamp(80px, 8.5vw, 112px) 1fr;
  gap: clamp(12px, 1.6vw, 22px);
  padding: clamp(11px, 1.35vw, 18px) 4px;
  align-items: start;
}
.schedule__time { font-family: var(--display); font-weight: 600; color: #fff; font-size: var(--text-body); display: flex; flex-direction: column; }
.schedule__onwards { color: var(--muted); font-family: var(--body); font-weight: 400; font-size: .72em; margin-top: 2px; }
.schedule__what { font-family: var(--body); font-weight: 400; color: var(--light); line-height: 1.5; font-size: var(--text-body); }
.schedule__what b { font-weight: 700; }
.schedule__what .semi { font-weight: 600; }
.schedule__sub { display: block; margin-top: 6px; color: var(--muted); font-size: clamp(.85rem, 1.1vw, 16px); }

@media (min-width: 960px) {
  .agenda__grid { grid-template-columns: 546fr 690fr; gap: clamp(36px, 3vw, 44px); }
  /* sticky head: the bottom margin shortens its travel so it releases up around
     the wave instead of riding all the way down to the Get Tickets button.
     Increase to release earlier, decrease to release later. */
  .agenda__head { position: sticky; top: 40px; margin-bottom: clamp(200px, 25vw, 360px); }
}

/* =========================================================
   FAQ  (white)
   ========================================================= */
.faq { background: #fff; padding-block: clamp(64px, 8vw, 120px); }
.faq__title { margin: 0 0 clamp(32px, 3.5vw, 50px); text-align: center; font-family: var(--display); font-weight: 700; letter-spacing: -.03em; color: var(--dark-card); font-size: clamp(3rem, 6.94vw, 100px); }
.faq__grid { display: grid; grid-template-columns: 1fr; gap: clamp(8px, 1vw, 12px); max-width: 1216px; margin-inline: auto; }
.faq__card {
  background: var(--dark-card); color: #fff; border-radius: 26px;
  padding: clamp(28px, 2.8vw, 40px);
  transform-style: preserve-3d;            /* enables the JS-driven 3D tilt */
  transition: transform .4s cubic-bezier(.2,.7,.3,1);
  will-change: transform;
}
.faq__q { margin: 0 0 16px; font-family: var(--display); font-weight: 700; line-height: 1.1; font-size: clamp(1.3rem, 2.22vw, 32px); }
.faq__a { margin: 0; font-family: var(--body); font-weight: 400; color: var(--light); line-height: 1.5; font-size: var(--text-body); }
.faq__a a {
  color: var(--cyan); text-decoration: underline; text-underline-offset: 3px;
  word-break: break-word; transition: color .2s ease, text-underline-offset .2s ease;
}
.faq__a a:hover { color: #7df7ff; text-underline-offset: 5px; }

@media (min-width: 820px) { .faq__grid { grid-template-columns: 1fr 1fr; } }

/* =========================================================
   CLOSING  (gradient #1b075a -> #4f2d91)
   ========================================================= */
.closing {
  position: relative; isolation: isolate; overflow: hidden;
  background: linear-gradient(180deg, var(--deep) 0%, var(--purple) 100%);
  color: #fff;
  padding-block: clamp(60px, 7.5vw, 112px);
}
.closing__arrow {
  /* arrow.png watermark: rising from the bottom, centred, spanning the section.
     The png already has its ~4% opacity baked into its alpha, so we do NOT add
     a CSS opacity here (that would multiply it down to nothing). */
  position: absolute; right: 40px; bottom: 0;
  height: clamp(260px, 36vw, 460px); width: auto;
  z-index: -1; pointer-events: none;
}
.closing__title { margin: 0 0 16px; font-family: var(--display); font-weight: 700; line-height: 1.04; max-width: 16ch; font-size: clamp(2.1rem, 5vw, 72px); }
.closing__sub { margin: 0 0 clamp(28px, 3vw, 40px); font-family: var(--body); color: var(--light); font-size: clamp(1.15rem, 2.36vw, 34px); }
@media (min-width: 1140px) { .closing__title { max-width: none; white-space: nowrap; } }

/* =========================================================
   SPONSORS  (white)
   ========================================================= */
/* purple band so the hero wave fades into it (no white cut); the white card is
   inset, leaving purple margins on the sides */
.sponsors { background: var(--deep); padding-block: clamp(40px, 5.5vw, 88px); }
.sponsors__panel {
  background: #fff;
  border-radius: clamp(28px, 3.4vw, 52px);
  padding: clamp(44px, 6vw, 90px) clamp(22px, 4vw, 64px);
}
.sponsors__title {
  text-align: center; margin: 0 auto clamp(40px, 5.5vw, 72px);
  font-family: var(--display); font-weight: 700; letter-spacing: -.02em;
  color: var(--deep); line-height: 1.1; font-size: clamp(1.5rem, 3.4vw, 44px);
}
.sponsors__title .nowrap { white-space: nowrap; }   /* keep "Made It Happen" together */
.tier { margin-bottom: clamp(44px, 5.5vw, 72px); }
.tier:last-child { margin-bottom: 0; }
.tier__label {
  text-align: center; margin: 0 0 clamp(22px, 2.8vw, 36px);
  font-family: var(--display); font-weight: 600; color: var(--blue);
  font-size: clamp(1.05rem, 1.7vw, 22px); letter-spacing: -.01em;
}
.tier__grid {
  list-style: none; margin: 0 auto; padding: 0; max-width: 940px;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: clamp(24px, 3.4vw, 52px);
}
.tier__grid li {
  flex: 0 0 auto;
  width: clamp(140px, 24vw, 250px);
  min-height: clamp(54px, 6.2vw, 78px);
  display: flex; align-items: center; justify-content: center;
}
.tier__grid img {
  max-height: clamp(38px, 4.6vw, 54px);
  max-width: 100%; width: auto; object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
  .btn:hover, .faq__card:hover, .exp__media:hover .ring__photo { transform: none; }
}

/* =========================================================
   ENTRANCE REVEAL  (fade + rise as elements scroll into view)
   Hidden state is gated behind `html.js` so the page degrades
   gracefully to fully visible if JS is off/fails. JS toggles
   `.is-in`; per-section stagger is applied via inline delay.
   ========================================================= */
.reveal { transition: opacity .7s var(--ease), transform .7s var(--ease); }
html.js .reveal:not(.is-in) { opacity: 0; transform: translateY(28px); }
html.js .reveal.is-in      { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  /* show everything immediately; transitions are already disabled above */
  html.js .reveal:not(.is-in) { opacity: 1; transform: none; }
}
