/* Reward flow (?src=itu): intro, mystery box, reward screen. Tokens come from styles.css. */

/* ---------- font (İTÜ) ----------
   Baloo 2 ExtraBold (SIL OFL, assets/fonts/), one file per subset: latin has
   ç ö ü ı, latin-ext has ğ ş İ. Declared for weights 600–900 so every bold
   text uses it. Only downloaded when html[data-theme="itu"] uses it; the
   base game keeps the system font. Canvas text uses it via js/fonts.js. */
@font-face {
  font-family: "Baloo 2";
  src: url("assets/fonts/baloo-2-latin-800-normal.woff2") format("woff2");
  font-weight: 600 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Baloo 2";
  src: url("assets/fonts/baloo-2-latin-ext-800-normal.woff2") format("woff2");
  font-weight: 600 900;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
html[data-theme="itu"] {
  --font: "Baloo 2", ui-rounded, "SF Pro Rounded", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

/* ---------- intro ---------- */
#intro, #box { --orange: #ff8a00; }
.intro { background: var(--cream); cursor: pointer; overflow: hidden; }
.intro-frame {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  padding: calc(24px + var(--safe-top)) 24px calc(24px + var(--safe-bottom));
  text-align: center;
}
.intro[data-step="mystery"] [data-frame="mystery"],
.intro[data-step="swirl"] [data-frame="swirl"],
.intro[data-step="scribble"] [data-frame="scribble"],
.intro[data-step="brand"] [data-frame="brand"],
.intro[data-step="promise"] [data-frame="promise"],
.intro[data-step="ready"] [data-frame="ready"] { display: grid; }

/* 1–2: a two-arm spiral (ink + feast red) spins behind a "?", then sucks it
   in. The vortex is round and much larger than the screen, so rotating and
   scaling it never shows an edge; the inner layer spins non-stop across both
   steps so there is no jump when the step changes.
   Durations come from reward-config.js via --step-ms (set per step in playIntro). */
.intro-vortex {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 170vmax;
  height: 170vmax;
  margin: -85vmax 0 0 -85vmax;
  display: none;
  pointer-events: none;
}
.intro[data-step="mystery"] .intro-vortex,
.intro[data-step="swirl"] .intro-vortex { display: block; }
.intro-vortex-spin { width: 100%; height: 100%; will-change: transform; animation: vortexSpin 2.4s linear infinite; }
.intro-vortex-spin svg { display: block; width: 100%; height: 100%; }
.intro[data-step="mystery"] .intro-vortex { animation: vortexIn .9s cubic-bezier(.2, .8, .3, 1) both; }
.intro[data-step="swirl"] .intro-vortex { animation: vortexOut var(--step-ms, 1.5s) cubic-bezier(.6, 0, .9, .4) both; }
[data-frame="swirl"] .intro-q { animation: qOut var(--step-ms, 1.5s) cubic-bezier(.6, 0, .9, .4) both; }
.intro-q {
  position: relative;
  font: 900 min(40vw, 220px)/1 var(--font);
  color: var(--red);
  -webkit-text-stroke: 4px var(--ink);
  paint-order: stroke fill;
  background: var(--cream);
  border-radius: 50%;
  padding: 0 .15em;
  animation: bob 1.1s ease-in-out infinite;
}
@keyframes vortexSpin { to { transform: rotate(360deg); } }
@keyframes vortexIn { from { transform: scale(1.5) rotate(-90deg); opacity: 0; } }
@keyframes vortexOut { to { transform: scale(.02) rotate(540deg); } }
@keyframes qOut { to { transform: scale(0) rotate(540deg); opacity: 0; } }

/* 3: rings burst out of the centre where the spiral vanished: ink, feast red,
   gold, then cream, which leaves a clean cream page for the logo to pop onto.
   (The step keeps its old "scribble" id so the config/tests stay the same.) */
[data-frame="scribble"] { overflow: hidden; }
[data-frame="scribble"] i {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 160vmax;
  height: 160vmax;
  margin: -80vmax 0 0 -80vmax;
  border-radius: 50%;
  transform: scale(0);
  animation: ringBurst calc(var(--step-ms, .8s) * .62) cubic-bezier(.3, .7, .35, 1) both;
}
[data-frame="scribble"] i:nth-child(1) { background: var(--ink); }
[data-frame="scribble"] i:nth-child(2) { background: var(--red); animation-delay: calc(var(--step-ms, .8s) * .12); }
[data-frame="scribble"] i:nth-child(3) { background: var(--gold); animation-delay: calc(var(--step-ms, .8s) * .24); }
[data-frame="scribble"] i:nth-child(4) { background: var(--cream); animation-delay: calc(var(--step-ms, .8s) * .36); }
@keyframes ringBurst { to { transform: scale(1); } }

/* 4: feast leads, İTÜ students are addressed underneath */
.intro-brand { display: grid; justify-items: center; gap: 10px; animation: brandPop 1s cubic-bezier(.2, .9, .3, 1.4) both; }
.intro-brand .intro-logo { width: min(72vw, 380px, 70dvh); }
.intro-brand .intro-lead { font-size: clamp(22px, 7vw, 36px); }
.intro-logo { display: block; justify-self: center; width: clamp(120px, 42vw, 200px); height: auto; margin: 0 auto 6px; }
.intro-promise .intro-logo { margin-bottom: 10px; }
@keyframes brandPop { from { transform: scale(.4); opacity: 0; } }

/* 5–6: promise + ready */
.intro-promise { display: grid; gap: 4px; margin: 0; font: 900 clamp(30px, 9vw, 52px)/1.05 var(--font); color: var(--ink); text-transform: uppercase; }
.intro-promise small, .intro-lead { text-transform: none; color: var(--red-deep); font-size: clamp(16px, 4.5vw, 24px); font-weight: 900; }
.sparkle {
  position: relative;
  display: inline-block;
  justify-self: center;
  font-style: normal;
  color: var(--orange);
  -webkit-text-stroke: 1.5px var(--ink);
  paint-order: stroke fill;
  animation: sparkle 1.1s ease-in-out infinite, jitter .18s steps(2) infinite;
}
.sparkle::before, .sparkle::after { content: "✦"; position: absolute; top: -.2em; color: var(--gold); font-size: .5em; -webkit-text-stroke: 0; }
.sparkle::before { left: -.7em; }
.sparkle::after { right: -.7em; }
@keyframes sparkle { 50% { scale: 1.08; text-shadow: 0 0 18px rgba(255, 170, 40, .9); } }
@keyframes jitter { 50% { translate: 1px -1px; } }

.intro-ready { cursor: default; align-content: center; gap: 8px; max-width: 420px; margin: 0 auto; }
.intro-ready h1 { font-size: clamp(34px, 10vw, 56px); }
.intro-hot { font-size: clamp(34px, 10vw, 56px); font-weight: 900; }
.intro-ready .btn-primary { margin-top: 24px; font-size: 28px; }
/* the chef tossing food, so BAŞLA has a face and some energy */
.intro-chef {
  justify-self: center;
  width: auto;
  height: clamp(110px, 24dvh, 220px);
  margin: 4px 0;
  filter: drop-shadow(0 6px 0 rgba(58, 29, 16, .15));
  animation: chefIn .6s cubic-bezier(.2, .9, .3, 1.4) both, bob 2.2s ease-in-out .6s infinite;
}
@keyframes chefIn { from { scale: .3; opacity: 0; } }
.intro-ready h1, .reward-title, .reward-sub { text-wrap: balance; }

/* Short/landscape: size the headlines by height too, so longer (English) copy
   doesn't wrap to two lines each and push BAŞLA off-screen. */
@media (max-height: 500px) {
  .intro-ready { gap: 2px; max-width: 560px; }
  .intro-chef { display: none; } /* no room on landscape phones */
  .intro-ready h1, .intro-hot { font-size: min(10vw, 11dvh); }
  .intro-lead { font-size: min(4.5vw, 5.5dvh); }
  .intro-ready .btn-primary { margin-top: 10px; padding: 10px; font-size: min(28px, 8dvh); }
  .intro-logo { width: min(30vw, 20dvh); margin-bottom: 0; }
  .intro-promise { font-size: min(9vw, 11dvh); }
}

/* ---------- mystery box ---------- */
.box-screen { background: radial-gradient(circle at 50% 55%, #ffe7a3 0%, var(--cream) 60%); }
.box-wrap { display: grid; justify-items: center; gap: 18px; text-align: center; }
/* Gift box: feast-red polka-dot box, gold ribbon and bow, a gold "?" medal,
   a slowly turning sunburst behind it, twinkling stars and a shine sweep.
   The lid (with the bow) peeks up now and then, as if something wants out. */
.mystery-box {
  position: relative;
  isolation: isolate;
  container-type: inline-size; /* medal text sizes with the box (cqw) */
  width: min(56vw, 220px, 48dvh); /* height cap: must fit landscape phones */
  aspect-ratio: 1;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  animation: boxIdle 1.4s ease-in-out infinite;
}
/* sunburst: a pseudo-element, so it adds no layout box and never causes scrolling */
.mystery-box::before {
  content: "";
  position: absolute;
  inset: -42%;
  z-index: -1;
  border-radius: 50%;
  background: repeating-conic-gradient(rgba(255, 190, 30, .6) 0 9deg, rgba(255, 190, 30, 0) 9deg 22.5deg);
  -webkit-mask: radial-gradient(circle, #000 22%, transparent 68%);
  mask: radial-gradient(circle, #000 22%, transparent 68%);
  animation: raysSpin 12s linear infinite;
  pointer-events: none;
}
.box-body, .box-lid {
  position: absolute;
  left: 0;
  right: 0;
  border: 4px solid var(--ink);
  --dots: radial-gradient(circle, rgba(255, 255, 255, .3) 0 3.5px, transparent 4.5px) 0 0 / 20px 20px;
}
.box-body {
  bottom: 0;
  height: 64%;
  z-index: 1;
  overflow: hidden;
  border-radius: 10px 10px 22px 22px;
  background: var(--dots), linear-gradient(160deg, #ff5b4d, #e32620 60%, #b8121b);
  box-shadow: 0 8px 0 var(--ink), inset 0 -12px 0 rgba(0, 0, 0, .14);
}
/* shine sweeping across the box every few seconds */
.box-body::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, .5) 50%, transparent 60%) 150% 0 / 300% 100% no-repeat;
  animation: boxShine 3s ease-in-out infinite;
  pointer-events: none;
}
.box-lid {
  top: 14%;
  height: 24%;
  margin: 0 -7%;
  z-index: 2;
  border-radius: 14px;
  background: var(--dots), linear-gradient(160deg, #ff7b6c, #e8302a);
  box-shadow: 0 6px 0 var(--ink);
  animation: lidPeek 2.6s ease-in-out infinite;
  transition: transform .45s cubic-bezier(.2, .9, .3, 1.4);
}
.box-ribbon {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 20%;
  transform: translateX(-50%);
  border-inline: 3px solid var(--ink);
  background: linear-gradient(90deg, #eea800, #ffe27a 45%, #eea800);
}
.box-lid .box-ribbon { width: 17.6%; } /* the lid is wider: same ribbon width on screen */
.box-medal {
  position: absolute;
  left: 50%;
  top: 48%;
  width: 36%;
  aspect-ratio: 1;
  display: grid;
  place-items: center;
  transform: translate(-50%, -50%);
  border: 4px solid var(--ink);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff7c9, var(--gold) 45%, #f0a000);
  box-shadow: 0 3px 0 var(--ink);
  font: 900 40px/1 var(--font);
  font-size: 22cqw;
  color: var(--red);
  -webkit-text-stroke: 2px var(--ink);
  paint-order: stroke fill;
  animation: medalPulse 1.4s ease-in-out infinite;
}
/* bow: two gold loops and a knot, sitting on the lid (flies off with it) */
.box-bow {
  position: absolute;
  left: 50%;
  bottom: 88%;
  width: 60%;
  height: 78%;
  transform: translateX(-50%);
}
.box-bow::before, .box-bow::after {
  content: "";
  position: absolute;
  bottom: 0;
  width: 50%;
  height: 100%;
  border: 3.5px solid var(--ink);
  border-radius: 55% 55% 45% 45% / 70% 70% 30% 30%;
  background: radial-gradient(ellipse at 50% 70%, #d99000 0 22%, transparent 24%), linear-gradient(160deg, #ffe685, #f5b400);
}
.box-bow::before { left: 0; transform: rotate(-28deg); transform-origin: 100% 100%; }
.box-bow::after { right: 0; transform: rotate(28deg); transform-origin: 0 100%; }
.box-knot {
  position: absolute;
  left: 50%;
  bottom: -14%;
  z-index: 1;
  width: 26%;
  height: 46%;
  transform: translateX(-50%);
  border: 3.5px solid var(--ink);
  border-radius: 40%;
  background: linear-gradient(160deg, #ffe685, #eea800);
}
/* four-point stars twinkling around the box */
.box-twinkles { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.box-twinkles i {
  position: absolute;
  width: 13%;
  aspect-ratio: 1;
  background: #fff;
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
  filter: drop-shadow(0 0 4px var(--gold));
  animation: twinkle 1.6s ease-in-out infinite;
}
.box-twinkles i:nth-child(1) { left: -12%; top: 30%; }
.box-twinkles i:nth-child(2) { right: -10%; top: 6%; width: 10%; background: var(--gold); animation-delay: .4s; }
.box-twinkles i:nth-child(3) { right: -8%; bottom: 20%; width: 9%; animation-delay: .8s; }
.box-twinkles i:nth-child(4) { left: -4%; bottom: 0; width: 8%; background: var(--gold); animation-delay: 1.2s; }
@keyframes raysSpin { to { transform: rotate(360deg); } }
@keyframes boxShine { 0%, 45% { background-position: 150% 0; } 75%, 100% { background-position: -50% 0; } }
@keyframes lidPeek {
  0%, 70%, 100% { transform: none; }
  78% { transform: translateY(-14%) rotate(-3deg); }
  84% { transform: translateY(-4%) rotate(2deg); }
  90% { transform: translateY(-9%) rotate(-1deg); }
}
@keyframes medalPulse { 50% { transform: translate(-50%, -50%) scale(1.08); } }
@keyframes twinkle { 0%, 100% { transform: scale(.3) rotate(0); opacity: .2; } 50% { transform: scale(1) rotate(45deg); opacity: 1; } }
.box-burst { position: absolute; inset: -40%; z-index: 4; border-radius: 50%; background: radial-gradient(circle, #fff 0%, var(--gold) 30%, transparent 65%); opacity: 0; transform: scale(.2); pointer-events: none; }

/* Opening timeline, scaled to --open-ms (reward-config.js boxOpenMs):
   0–55 % shake builds up · 50 % flash · 55 % lid flies, light burst, particles. */
.box-sparks { position: absolute; left: 50%; top: 55%; z-index: 5; width: 0; height: 0; pointer-events: none; }
.box-spark {
  position: absolute;
  width: 10px;
  height: 10px;
  margin: -5px;
  border-radius: 2px;
  background: var(--gold);
  box-shadow: 0 0 8px #fff3b0;
  opacity: 0;
}
.box-spark:nth-child(3n) { background: #fff; }
.box-spark:nth-child(3n + 1) { background: var(--orange); }
.box-flash { position: fixed; inset: 0; background: #fff; opacity: 0; pointer-events: none; }

.box-screen.is-opening .mystery-box { animation: boxShake calc(var(--open-ms, 1.4s) * .55) cubic-bezier(.5, 0, 1, 1) both; }
.box-screen.is-opening .box-lid { animation: none; transition-delay: calc(var(--open-ms, 1.4s) * .55); transform: translateY(-160%) rotate(-18deg); }
.box-screen.is-opening .mystery-box::before { animation-duration: 1.6s; }
.box-screen.is-opening .box-twinkles i { animation-duration: .5s; }
.box-screen.is-opening .box-burst { animation: burst calc(var(--open-ms, 1.4s) * .4) ease-out calc(var(--open-ms, 1.4s) * .55) both; }
.box-screen.is-opening .box-spark { animation: spark calc(var(--open-ms, 1.4s) * .42) cubic-bezier(.2, .7, .4, 1) calc(var(--open-ms, 1.4s) * .55) both; }
.box-screen.is-opening .box-flash { animation: flash calc(var(--open-ms, 1.4s) * .3) ease-out calc(var(--open-ms, 1.4s) * .5) both; }
.box-screen.is-opening .hint { visibility: hidden; }

@keyframes boxIdle { 50% { transform: translateY(-6px) rotate(-2deg); } }
@keyframes boxShake {
  10% { transform: rotate(-2deg); } 20% { transform: rotate(2deg); }
  35% { transform: rotate(-5deg) scale(1.02); } 50% { transform: rotate(5deg) scale(1.03); }
  65% { transform: rotate(-9deg) scale(1.05); } 80% { transform: rotate(10deg) scale(1.07); }
  90% { transform: rotate(-12deg) scale(1.09); } 100% { transform: rotate(0) scale(1.12); }
}
@keyframes spark {
  0% { opacity: 1; transform: rotate(var(--a)) translateY(0) scale(1.2); }
  100% { opacity: 0; transform: rotate(var(--a)) translateY(calc(var(--d) * -1.6)) scale(.3); }
}
@keyframes flash { 0% { opacity: 0; } 30% { opacity: .85; } 100% { opacity: 0; } }
@keyframes burst { 60% { opacity: 1; } to { opacity: 0; transform: scale(1.4); } }

/* ---------- reward: download page ----------
   After the box opens: "Ödülün hazır!", the open gift glowing from inside,
   one big yellow "feast'i indir" button, App Store + Google Play badges.
   Fits one screen with no scrolling; sizes follow the viewport height too. */
.reward-screen {
  overflow: hidden;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background:
    radial-gradient(circle at 0 0, #ffe39a 0 13%, transparent 13.5%),
    radial-gradient(circle at 100% 100%, #ffd0d4 0 15%, transparent 15.5%),
    radial-gradient(circle at 0 100%, #ffeab8 0 11%, transparent 11.5%),
    radial-gradient(ellipse at 50% 48%, #fff1bf 0%, var(--cream) 62%);
}
/* hidden screen: stop every looping animation in it */
#reward:not(.is-active) *, #reward:not(.is-active) *::before, #reward:not(.is-active) *::after { animation-play-state: paused; }

.confetti { position: absolute; inset: 0; pointer-events: none; }
.confetti i {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: 16px;
  height: 6px;
  border-radius: 3px;
  background: var(--c);
  transform: rotate(var(--r));
  animation: confettiFloat 2.8s ease-in-out infinite alternate;
}
.confetti i:nth-child(odd) { animation-delay: -1.4s; }
.confetti i:nth-child(3n) { width: 13px; height: 13px; border-radius: 0; clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%); }
@keyframes confettiFloat { to { transform: rotate(calc(var(--r) + 30deg)) translateY(8px); } }

.reward-wrap {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 420px;
  display: grid;
  justify-items: center;
  gap: clamp(6px, 1.6dvh, 14px);
  text-align: center;
}
.reward-head { display: grid; gap: clamp(2px, .8dvh, 8px); }
.reward-title {
  margin: 0;
  font: 900 clamp(32px, min(11vw, 7dvh), 56px)/1 var(--font);
  color: var(--ink);
  letter-spacing: -.01em;
  animation: titlePop .7s cubic-bezier(.2, .9, .3, 1.5) both;
}
@keyframes titlePop { from { transform: scale(.4) rotate(-4deg); opacity: 0; } }
.reward-sub { margin: 0 auto; max-width: 30ch; font-weight: 800; font-size: clamp(15px, min(4.4vw, 2.5dvh), 19px); line-height: 1.3; color: var(--ink); }

/* The open gift: lid tilted back with the bow, light pouring out. Ribbon,
   bow, knot and twinkles reuse the closed box's pieces. */
.gift-open {
  position: relative;
  isolation: isolate;
  width: min(62vw, 30dvh, 280px);
  aspect-ratio: 1;
  animation: giftBob 2.4s ease-in-out infinite;
}
/* Sunburst. It turns by animating the gradient's start angle, not by
   rotating the element: a rotated square's corners poke past short
   landscape screens and make the page scrollable. */
@property --ray { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
.gift-open::before {
  content: "";
  position: absolute;
  inset: -30%;
  z-index: -1;
  border-radius: 50%;
  background: repeating-conic-gradient(from var(--ray), rgba(255, 190, 30, .5) 0 9deg, rgba(255, 190, 30, 0) 9deg 22.5deg);
  -webkit-mask: radial-gradient(circle, #000 20%, transparent 66%);
  mask: radial-gradient(circle, #000 20%, transparent 66%);
  animation: rayTurn 14s linear infinite;
  pointer-events: none;
}
@keyframes rayTurn { to { --ray: 360deg; } }
.gift-body, .gift-lid {
  position: absolute;
  border: 4px solid var(--ink);
  --dots: radial-gradient(circle, rgba(255, 255, 255, .3) 0 3.5px, transparent 4.5px) 0 0 / 20px 20px;
}
.gift-body {
  left: 12%;
  right: 12%;
  bottom: 4%;
  height: 50%;
  z-index: 2;
  border-radius: 6px 6px 20px 20px;
  background: var(--dots), linear-gradient(160deg, #ff5b4d, #e32620 60%, #b8121b);
  box-shadow: 0 7px 0 var(--ink), inset 0 -10px 0 rgba(0, 0, 0, .14);
}
.gift-body .box-ribbon { z-index: 0; }
/* the glowing opening on top of the box */
.gift-mouth {
  position: absolute;
  left: -4px;
  right: -4px;
  top: -16%;
  height: 24%;
  z-index: 1;
  border: 4px solid var(--ink);
  border-radius: 12px;
  background: radial-gradient(ellipse at 50% 60%, #fffbe0 0 18%, #ffd23f 40%, #ff9a1f 66%, #a3101a 100%);
  box-shadow: 0 0 22px 6px rgba(255, 214, 80, .75);
}
.gift-medal {
  position: absolute;
  left: 50%;
  top: 56%;
  z-index: 2;
  width: 34%;
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border: 4px solid var(--ink);
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #fff7c9, var(--gold) 45%, #f0a000);
  box-shadow: 0 3px 0 var(--ink);
}
.gift-medal::after { /* white four-point star */
  content: "";
  position: absolute;
  inset: 20%;
  background: #fff;
  clip-path: polygon(50% 0, 61% 39%, 100% 50%, 61% 61%, 50% 100%, 39% 61%, 0 50%, 39% 39%);
}
.gift-lid {
  left: 6%;
  width: 84%;
  top: 30%;
  height: 15%;
  z-index: 1;
  border-radius: 12px;
  background: var(--dots), linear-gradient(160deg, #ff7b6c, #e8302a);
  box-shadow: 0 5px 0 var(--ink);
  transform: translate(-6%, -36%) rotate(-20deg);
  transform-origin: 0 100%;
}
.gift-lid .box-ribbon { width: 18%; }
.gift-lid .box-bow { width: 64%; height: 130%; bottom: 86%; }
/* light beams fanning up out of the box */
.gift-beams {
  position: absolute;
  left: 50%;
  bottom: 44%;
  z-index: 3;
  width: 96%;
  height: 58%;
  transform: translateX(-50%);
  transform-origin: 50% 100%;
  background: radial-gradient(ellipse at 50% 100%, rgba(255, 252, 220, .95) 0, rgba(255, 214, 80, .55) 38%, transparent 72%);
  clip-path: polygon(36% 100%, 64% 100%, 100% 0, 0 0);
  animation: beams 1.6s ease-in-out infinite alternate;
  pointer-events: none;
}
.gift-open .box-twinkles { z-index: 4; }
@keyframes giftBob { 50% { transform: translateY(-5px); } }

/* İTÜ · Kadıköy · Beşiktaş · "ve yakında daha fazlası" pop in one by one
   around the gift, then bob slowly. Each word has its own delay (--d), tilt
   (--r) and float speed (--t), set inline in index.html. Separate scale /
   translate properties so the pop-in and the floating never fight. */
.gift-stage { position: relative; width: 100%; display: grid; place-items: center; }
.float-word {
  position: absolute;
  z-index: 5;
  padding: 4px 10px;
  border: 2.5px solid var(--ink);
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 3px 0 var(--ink);
  font: 900 clamp(12px, 3.4vw, 15px)/1.1 var(--font);
  color: var(--ink);
  white-space: nowrap;
  rotate: var(--r, 0deg);
  animation:
    wordIn .6s cubic-bezier(.2, .9, .3, 1.5) var(--d, 0s) both,
    wordFloat var(--t, 3.4s) ease-in-out calc(var(--d, 0s) + .6s) infinite alternate;
}
.float-more { max-width: 8.5em; white-space: normal; text-align: center; border-radius: 14px; background: var(--gold); }
@keyframes wordIn { from { scale: .2; opacity: 0; } }
@keyframes wordFloat { from { translate: 0 0; } to { translate: 0 -9px; } }
@keyframes beams { from { opacity: .65; transform: translateX(-50%) scaleY(.92); } to { opacity: 1; transform: translateX(-50%) scaleY(1.05); } }

.reward-actions { width: 100%; display: grid; justify-items: center; gap: clamp(8px, 1.6dvh, 12px); }
.reward-download {
  width: 100%;
  gap: 12px;
  padding: clamp(12px, 2.2dvh, 18px) 20px;
  border-radius: 999px;
  font-size: clamp(22px, min(7vw, 4.2dvh), 30px);
  background: linear-gradient(180deg, #ffe066, #ffc21a);
  color: var(--ink);
  animation: pulse 1.6s ease-in-out infinite;
}
.dl-icon { flex: none; width: 1.15em; height: 1.15em; }
.reward-tagline { margin: 0; font-weight: 700; font-size: 14px; color: var(--ink); opacity: .85; }
.reward-tagline .heart { color: var(--red); font-weight: 900; }
.reward-meta { margin: 0; display: flex; align-items: center; justify-content: center; gap: 14px; font-size: 13px; font-weight: 800; color: rgba(58, 29, 16, .6); }
.link-btn { border: 0; background: none; padding: 4px 2px; font: 800 13px var(--font); color: var(--ink); text-decoration: underline; cursor: pointer; }
.link-btn[hidden] { display: none; }
.reward-meta > * { white-space: nowrap; }

/* Short portrait phones (iPhone SE…): smaller gift, no tagline. */
@media (orientation: portrait) and (max-height: 620px) {
  .gift-open { width: min(52vw, 26dvh); }
  .reward-tagline { display: none; }
  .float-word { font-size: 11.5px; padding: 3px 8px; }
}
/* Landscape phones: gift on the left, text and buttons on the right. */
@media (orientation: landscape) and (max-height: 500px) {
  .reward-wrap {
    max-width: 720px;
    grid-template-columns: auto 1fr;
    grid-template-areas: "gift head" "gift actions";
    column-gap: 28px;
    align-items: center;
  }
  .gift-stage { grid-area: gift; width: min(44vw, 82dvh); }
  .gift-open { width: min(30vw, 54dvh); }
  .float-word { font-size: min(13px, 3.6dvh); }
  .reward-head { grid-area: head; }
  .reward-actions { grid-area: actions; }
  .reward-title { font-size: min(40px, 11dvh); }
  .reward-sub { font-size: min(16px, 4.4dvh); }
  .reward-download { font-size: min(24px, 7dvh); padding: min(10px, 2.4dvh) 16px; }
  .reward-tagline { display: none; }
}

/* ---------- polish (İTÜ flow) ---------- */
/* Keyboard focus: visible ring on every control in the flow (none before). */
:is(#intro, #box, #reward) :is(button, a):focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 4px;
  box-shadow: 0 0 0 7px var(--gold);
}
/* Box hint was 60 % opacity on cream: too faint to read. */
#box .hint { opacity: 1; font-size: 15px; color: var(--ink); }
/* Hover feedback on the download page. */
.reward-download:hover { filter: brightness(1.05) saturate(1.1); }
.link-btn:hover { color: var(--red-deep); }
/* The gift pops in when the download page opens (scale, so it does not
   fight the bobbing transform). */
.reward-screen.is-active .gift-open { animation: giftIn .7s cubic-bezier(.2, .9, .3, 1.5) both, giftBob 2.4s ease-in-out .7s infinite; }
@keyframes giftIn { from { scale: .2; opacity: 0; } }

/* ---------- retry ("Az kaldı!") ----------
   Lost before 45 s: same warm page as the download screen, the gift still
   locked, one big TEKRAR DENE button that starts a new round at once. */
.retry-screen {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background:
    radial-gradient(circle at 100% 0, #ffd0d4 0 14%, transparent 14.5%),
    radial-gradient(circle at 0 100%, #ffe39a 0 13%, transparent 13.5%),
    radial-gradient(ellipse at 50% 42%, #fff1bf 0%, var(--cream) 62%);
}
.retry-wrap { width: 100%; max-width: 380px; display: grid; justify-items: center; gap: clamp(8px, 1.8dvh, 14px); text-align: center; }
.retry-gift { position: relative; font-size: clamp(72px, 16dvh, 120px); line-height: 1; animation: retryShake 2.4s ease-in-out infinite; }
.retry-lock {
  position: absolute;
  right: -.12em;
  bottom: -.05em;
  font-size: .42em;
  filter: drop-shadow(0 2px 0 rgba(58, 29, 16, .25));
}
.retry-title { margin: 0; font: 900 clamp(34px, min(11vw, 7dvh), 52px)/1 var(--font); color: var(--ink); text-wrap: balance; }
.retry-sub { margin: 0; max-width: 28ch; font-weight: 800; font-size: clamp(15px, min(4.4vw, 2.6dvh), 19px); line-height: 1.3; color: var(--ink); text-wrap: balance; }
.retry-btn { margin-top: 6px; font-size: clamp(24px, min(7vw, 4.4dvh), 30px); }
.retry-tip { margin: 0; padding: 6px 12px; border: 2px dashed rgba(58, 29, 16, .35); border-radius: 12px; font-weight: 800; font-size: 13.5px; color: var(--ink); }
.retry-score { margin: 0; font-weight: 800; font-size: 13px; color: rgba(58, 29, 16, .6); }
#retry.is-active .retry-wrap > * { animation: retryIn .5s cubic-bezier(.2, .9, .3, 1.4) both; }
#retry.is-active .retry-wrap > :nth-child(2) { animation-delay: .08s; }
#retry.is-active .retry-wrap > :nth-child(3) { animation-delay: .16s; }
#retry.is-active .retry-wrap > :nth-child(4) { animation: retryIn .5s cubic-bezier(.2, .9, .3, 1.4) .24s both, pulse 1.6s ease-in-out .8s infinite; }
#retry.is-active .retry-wrap > :nth-child(n + 5) { animation-delay: .32s; }
#retry.is-active .retry-gift { animation: retryIn .5s cubic-bezier(.2, .9, .3, 1.4) both, retryShake 2.4s ease-in-out .5s infinite; }
#retry:not(.is-active) *, #retry:not(.is-active) *::before { animation-play-state: paused; }
@keyframes retryIn { from { opacity: 0; translate: 0 14px; } }
@keyframes retryShake { 0%, 70%, 100% { rotate: 0deg; } 76% { rotate: -8deg; } 82% { rotate: 7deg; } 88% { rotate: -4deg; } 94% { rotate: 2deg; } }
@media (orientation: landscape) and (max-height: 500px) {
  .retry-gift { font-size: min(80px, 20dvh); }
  .retry-tip { display: none; }
}

/* ---------- BAŞLA screen: faint thought bubbles ----------
   The everyday questions feast answers, drifting around the edges behind the
   content. Low opacity + no shadow so they fill the page without competing
   with the logo, the chef or BAŞLA. */
/* The bubble area is capped at 940 px and centred, so on a wide PC screen the
   bubbles stay close around the content instead of drifting to the far edges
   (on phones it is simply the full screen). Vertically it hugs the content too. */
.ready-bubbles {
  position: fixed;
  inset: 0;
  z-index: 0;
  width: 100%;
  max-width: 940px;
  max-height: 820px;
  margin: auto;
  overflow: hidden;
  pointer-events: none;
}
@media (min-width: 900px) {
  .ready-bubble { font-size: 14.5px; padding: 8px 14px; max-width: 250px; }
}
.intro-ready > :not(.ready-bubbles) { position: relative; z-index: 1; }
.ready-bubble {
  position: absolute;
  max-width: 38vw;
  padding: 7px 12px;
  border: 2px solid rgba(58, 29, 16, .55);
  border-radius: 16px;
  background: #fff;
  font: 800 13px/1.2 var(--font);
  color: var(--ink);
  opacity: .32;
  rotate: var(--r, 0deg);
  animation: bubbleFloat var(--t, 6s) ease-in-out infinite alternate;
}
/* little tail, alternating sides */
.ready-bubble::after {
  content: "";
  position: absolute;
  bottom: -7px;
  left: 18px;
  width: 11px;
  height: 11px;
  background: #fff;
  border: solid rgba(58, 29, 16, .55);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.ready-bubble:nth-child(even)::after { left: auto; right: 18px; }
.ready-bubble:nth-child(1) { left: 3%; top: 5%; --r: -4deg; --t: 6.5s; }
.ready-bubble:nth-child(2) { right: 3%; top: 12%; --r: 3deg; --t: 7s; }
.ready-bubble:nth-child(3) { left: 2%; top: 31%; --r: 3deg; --t: 5.5s; }
.ready-bubble:nth-child(4) { right: 2%; top: 38%; --r: -3deg; --t: 6.8s; }
.ready-bubble:nth-child(5) { left: 4%; top: 55%; --r: -2deg; --t: 7.4s; }
.ready-bubble:nth-child(6) { right: 3%; top: 61%; --r: 4deg; --t: 6.1s; }
.ready-bubble:nth-child(7) { left: 3%; bottom: 7%; --r: 3deg; --t: 6.9s; }
.ready-bubble:nth-child(8) { right: 4%; bottom: 4%; --r: -4deg; --t: 5.8s; }
@keyframes bubbleFloat { to { translate: 0 -10px; } }
.intro:not(.is-active) .ready-bubble { animation-play-state: paused; }
/* Narrow phones: smaller bubbles; landscape phones: no room, hide them. */
@media (max-width: 420px) {
  .ready-bubble { font-size: 11.5px; padding: 6px 10px; max-width: 42vw; opacity: .28; }
}
@media (orientation: landscape) and (max-height: 500px) {
  .ready-bubbles { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .ready-bubble { animation: none; }
}

/* ---------- explainer: "feast nedir?" (between the box and the prize) ----------
   Cut like @feast_tr's "feast nedir?" highlight: feast-red background with
   diagonal lines, white caption on top, the real app look inside a phone.
   Scenes switch on data-step (reward-ui.js playExplainer, durations in
   reward-config.js explainer): hook words → logo + "Nerede? Ne? Kaça?" →
   map with route → Reels-style dish feed under a "KAYDIR" sticker → chat
   (8 s in total: people give it about that long). Every cut punches the camera (.ex-cam.is-cut) and flashes
   white (.ex-flash.is-cut); screens inside the phone hard-cut, the phone
   swings to a new angle. No skipping: it plays through like a video. */
.explainer {
  --ex-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  overflow: hidden;
  color: #fff;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background:
    repeating-linear-gradient(135deg, rgba(255, 255, 255, .055) 0 2px, transparent 2px 15px),
    linear-gradient(172deg, #ff4b3e 0%, #ff2b3a 48%, #df1230 100%);
}
#explainer:not(.is-active) *, #explainer:not(.is-active) *::before, #explainer:not(.is-active) *::after { animation-play-state: paused; }
@property --n { syntax: '<integer>'; inherits: false; initial-value: 0; }

.ex-cam { position: absolute; inset: 0; }
.ex-cam.is-cut { animation: camPunch .4s cubic-bezier(.15, .9, .3, 1); }
@keyframes camPunch { from { scale: 1.16; filter: blur(3px); } }
.ex-flash { position: absolute; z-index: 9; inset: 0; background: #fff; opacity: 0; pointer-events: none; }
.ex-flash.is-cut { animation: exFlash .24s ease-out; }
@keyframes exFlash { from { opacity: .7; } }
/* the white swooshes from the highlight's background, drifting slowly */
.ex-swoosh {
  position: absolute;
  inset: -15%;
  pointer-events: none;
  background:
    radial-gradient(ellipse 60% 45% at 105% 62%, transparent 96%, rgba(255, 255, 255, .22) 97% 98.5%, transparent 99.5%),
    radial-gradient(ellipse 50% 40% at -8% 22%, transparent 96%, rgba(255, 255, 255, .16) 97% 98.5%, transparent 99.5%);
  animation: swoosh 7s ease-in-out infinite alternate;
}
@keyframes swoosh { to { rotate: 6deg; scale: 1.06; } }

/* Instagram-style story bars */
.ex-progress { position: absolute; z-index: 8; top: calc(10px + var(--safe-top)); left: 12px; right: 56px; display: flex; gap: 4px; max-width: 540px; margin: 0 auto; }
.ex-progress i { position: relative; flex: 1; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, .35); overflow: hidden; }
.ex-progress i::after { content: ""; position: absolute; inset: 0; background: #fff; transform: scaleX(0); transform-origin: left; }
.ex-progress i.is-done::after { transform: none; }
.ex-progress i.is-on::after { animation: exFill var(--step-ms, 2s) linear forwards; }
@keyframes exFill { to { transform: none; } }

.ex-scene, .ex-stage { position: absolute; inset: 0; display: none; }
.explainer[data-step="hook"] [data-scene="hook"],
.explainer[data-step="brand"] [data-scene="brand"] { display: grid; place-items: center; align-content: center; }
.explainer:is([data-step="map"], [data-step="reels"], [data-step="friends"]) .ex-stage { display: flex; }

/* 1. hook: "Bugün ne yesek?" one word per beat, then a shake */
.ex-hook {
  margin: 0;
  padding: 0 18px;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 .22em;
  font: 900 clamp(46px, 14vw, 104px)/.98 var(--font);
  text-align: center;
  text-shadow: 0 6px 0 rgba(110, 0, 12, .35);
  animation: exShake .3s linear .62s;
}
.ex-hook span { display: inline-block; animation: wordHit .2s cubic-bezier(.2, .9, .3, 1.7) calc(var(--i) * .15s) both; }
.ex-hook::after { content: "🤔"; display: inline-block; animation: wordHit .3s cubic-bezier(.2, .9, .3, 1.8) .52s both; }
@keyframes wordHit { from { scale: 2.4; opacity: 0; } }
@keyframes exShake {
  20% { translate: -7px 3px; rotate: -1.5deg; }
  40% { translate: 6px -4px; rotate: 1.2deg; }
  60% { translate: -4px 2px; }
  80% { translate: 3px -1px; }
}

/* 2. brand: white logo slams in, then Nerede? / Ne? / Kaça? flash one after another */
[data-scene="brand"] { gap: clamp(10px, 2.5dvh, 22px); }
.ex-logo { width: clamp(150px, 48vw, 260px); height: auto; filter: brightness(0) invert(1); animation: logoSlam .3s cubic-bezier(.2, .9, .3, 1.5) both, exShake .3s linear .3s; }
@keyframes logoSlam { from { scale: 3.2; opacity: 0; } }
.ex-words { margin: 0; display: grid; place-items: center; font: 900 clamp(50px, 15.5vw, 112px)/1 var(--font); text-shadow: 0 6px 0 rgba(110, 0, 12, .35); }
.ex-words span { grid-area: 1 / 1; }
.ex-words span:nth-child(1) { animation: wordHit .14s ease-out .32s both, wordOut .01s linear .57s forwards; }
.ex-words span:nth-child(2) { animation: wordHit .14s ease-out .58s both, wordOut .01s linear .82s forwards; }
.ex-words span:nth-child(3) { animation: wordHit .2s cubic-bezier(.2, .9, .3, 1.8) .83s both; color: var(--gold); }
@keyframes wordOut { to { opacity: 0; } }

/* 3–6. caption on top, the phone below; the phone swings to a new angle on each cut */
.ex-stage {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(8px, 2dvh, 18px);
  padding: calc(46px + var(--safe-top)) 16px calc(14px + var(--safe-bottom));
}
.ex-caption { position: relative; z-index: 7; margin: 0; width: 100%; max-width: 440px; min-height: 2.5em; display: grid; place-items: center; font: 700 clamp(19px, 5.6vw, 28px)/1.2 var(--ex-sans); text-align: center; text-shadow: 0 2px 8px rgba(90, 0, 10, .3); }
.ex-caption > span { grid-area: 1 / 1; max-width: 19ch; text-wrap: balance; visibility: hidden; }
.explainer[data-step="map"] [data-cap="map"],
.explainer[data-step="reels"] [data-cap="reels"],
.explainer[data-step="friends"] [data-cap="friends"] { visibility: visible; animation: capIn .35s cubic-bezier(.2, .9, .3, 1.2) .05s both; }
@keyframes capIn { from { translate: 0 60%; opacity: 0; filter: blur(5px); } }

.ex-phone-wrap { position: relative; flex: none; perspective: 1100px; animation: phoneFloat 2.8s ease-in-out infinite alternate; }
@keyframes phoneFloat { to { translate: 0 -8px; } }
.ex-phone {
  position: relative;
  width: min(62vw, 32dvh, 290px);
  aspect-ratio: 9 / 19;
  border: 7px solid #111;
  border-radius: 44px;
  background: #fff;
  box-shadow: 0 0 0 2px #3a3a3a, 0 34px 60px rgba(80, 0, 12, .45);
  overflow: hidden;
  container-type: inline-size;
  color: #111;
  transform: rotateY(var(--ry, 0deg)) rotateZ(var(--rz, 0deg)) scale(var(--sc, 1));
  transition: transform .7s cubic-bezier(.2, .9, .3, 1.3);
  animation: phoneIn .55s cubic-bezier(.2, .9, .3, 1.15) both;
}
@keyframes phoneIn { from { translate: 0 85vh; rotate: 18deg; } }
.explainer[data-step="map"] .ex-phone { --ry: -16deg; --rz: 4deg; }
.explainer[data-step="reels"] .ex-phone { --ry: 0deg; --rz: -3deg; --sc: 1.04; }
.explainer[data-step="friends"] .ex-phone { --ry: 14deg; --rz: -3deg; }
.ex-island { position: absolute; z-index: 6; top: 2.6cqi; left: 50%; width: 30%; height: 8cqi; translate: -50% 0; border-radius: 99px; background: #111; }

.ex-screen { position: absolute; inset: 0; display: none; overflow: hidden; }
.explainer[data-step="map"] .ex-map,
.explainer[data-step="reels"] .ex-reels,
.explainer[data-step="friends"] .ex-chat { display: block; }

/* the app's floating dark tab bar; the active tab turns red */
.ex-tabbar {
  position: absolute;
  z-index: 5;
  left: 6%;
  right: 6%;
  bottom: 4cqi;
  height: 13cqi;
  display: flex;
  justify-content: space-around;
  align-items: center;
  border-radius: 99px;
  background: rgba(22, 22, 26, .92);
}
.ex-tabbar svg { width: 6.5cqi; height: 6.5cqi; fill: none; stroke: #fff; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: stroke .2s; }
.explainer[data-step="map"] .ex-tabbar svg:nth-child(4),
.explainer[data-step="reels"] .ex-tabbar svg:nth-child(2) { stroke: var(--red); }
.explainer[data-step="friends"] .ex-tabbar { display: none; }

/* map: streets, route drawing to the pizza place, pins popping, "6 dk" pill */
.ex-map {
  background:
    linear-gradient(90deg, transparent 47%, #fff 47% 53%, transparent 53%),
    linear-gradient(0deg, transparent 28%, #fff 28% 32%, transparent 32%),
    linear-gradient(0deg, transparent 68%, #fff 68% 72%, transparent 72%),
    linear-gradient(28deg, transparent 40%, #fff 40% 42.5%, transparent 42.5%),
    repeating-linear-gradient(0deg, transparent 0 13cqi, rgba(0, 0, 0, .04) 13cqi 14cqi),
    repeating-linear-gradient(90deg, transparent 0 13cqi, rgba(0, 0, 0, .04) 13cqi 14cqi),
    #eceef1;
}
.ex-park { position: absolute; right: 6%; top: 40%; width: 34%; height: 18%; border-radius: 40%; background: #cfe9bf; }
.ex-route { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ex-route path { fill: none; stroke: var(--red); stroke-width: 5px; vector-effect: non-scaling-stroke; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; }
.explainer[data-step="map"] .ex-route path { animation: routeDraw .6s cubic-bezier(.6, 0, .3, 1) .35s forwards; }
@keyframes routeDraw { to { stroke-dashoffset: 0; } }
.ex-me { position: absolute; z-index: 2; left: 50%; top: 58%; width: 6cqi; height: 6cqi; translate: -50% -50%; border-radius: 50%; background: #2f7bff; border: 2px solid #fff; box-shadow: 0 0 0 5cqi rgba(47, 123, 255, .18); }
.ex-pin {
  position: absolute;
  z-index: 3;
  isolation: isolate;
  left: var(--x);
  top: var(--y);
  width: 12cqi;
  height: 12cqi;
  margin: -14cqi 0 0 -6cqi;
  display: grid;
  place-items: center;
  font-size: 5.6cqi;
}
.ex-pin::before { content: ""; position: absolute; inset: 0; z-index: -1; border: 2.5px solid #fff; border-radius: 50% 50% 50% 0; background: var(--red); box-shadow: 0 3px 8px rgba(0, 0, 0, .25); transform: rotate(-45deg); }
.explainer[data-step="map"] .ex-pin { animation: pinDrop .45s cubic-bezier(.3, 1.6, .5, 1) calc(.1s + var(--d)) both; }
@keyframes pinDrop { from { translate: 0 -30cqi; opacity: 0; } }
.ex-eta { position: absolute; z-index: 4; top: 15cqi; left: 50%; translate: -50% 0; padding: 1.8cqi 4cqi; border-radius: 99px; background: var(--red); color: #fff; font: 800 4.6cqi/1 var(--ex-sans); white-space: nowrap; box-shadow: 0 4px 12px rgba(200, 0, 20, .35); }
.explainer[data-step="map"] .ex-eta { animation: wordHit .3s cubic-bezier(.2, .9, .3, 1.7) .9s both; }

/* KAYDIR: the comic sticker from the highlight, slammed over the phone */
.ex-sticker {
  position: absolute;
  z-index: 7;
  left: 50%;
  top: 9%;
  display: none;
  font: 900 clamp(54px, 17vw, 104px)/1 var(--font);
  letter-spacing: .02em;
  white-space: nowrap;
  color: #fff;
  -webkit-text-stroke: 3px #111;
  paint-order: stroke fill;
  text-shadow: 0 3px 0 #a9bccf, 0 6px 0 #7b92ab, 0 9px 0 #52677f, 0 12px 0 #111, 0 20px 26px rgba(0, 0, 0, .35);
  translate: -50% 0;
  rotate: -7deg;
}
.explainer[data-step="reels"] .ex-sticker { display: block; animation: stickerSlam .32s cubic-bezier(.2, .9, .3, 1.7) .12s both, stickerWobble 1s ease-in-out .5s infinite alternate; }
@keyframes stickerSlam { from { scale: 3; opacity: 0; rotate: -18deg; } }
@keyframes stickerWobble { to { rotate: -3deg; scale: 1.04; } }

/* Reels-style feed: full-screen dishes snap upward, a thumb swipes, a like pops */
.ex-reels { background: #111; }
.ex-reel-track { height: 100%; }
.explainer[data-step="reels"] .ex-reel-track { animation: reelScroll var(--step-ms, 2.6s) both; }
@keyframes reelScroll {
  0%, 20% { transform: translateY(0); animation-timing-function: cubic-bezier(.55, 0, .2, 1.15); }
  30%, 46% { transform: translateY(-100%); animation-timing-function: cubic-bezier(.55, 0, .2, 1.15); }
  56%, 72% { transform: translateY(-200%); animation-timing-function: cubic-bezier(.55, 0, .2, 1.15); }
  82%, 100% { transform: translateY(-300%); }
}
.ex-reel { position: relative; height: 100%; overflow: hidden; isolation: isolate; background: #111; }
/* full-bleed portrait photo; slow Ken Burns push so each dish feels like video */
.ex-reel img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.explainer[data-step="reels"] .ex-reel img { animation: kenBurns 3s ease-out both; }
@keyframes kenBurns { from { scale: 1.12; } }
.ex-reel::before { content: ""; position: absolute; inset: 0 0 auto; z-index: 1; height: 22%; background: linear-gradient(rgba(0, 0, 0, .35), transparent); }
.ex-reel::after { content: ""; position: absolute; inset: 50% 0 0; z-index: 1; background: linear-gradient(transparent, rgba(0, 0, 0, .78)); }
.ex-reel-info { position: absolute; z-index: 2; left: 5cqi; right: 20cqi; bottom: 22cqi; display: grid; gap: 2cqi; color: #fff; font-family: var(--ex-sans); }
.ex-reel-name { font: 800 5.8cqi/1.1 var(--ex-sans); }
.ex-reel-price { justify-self: start; padding: 1cqi 2.6cqi; border-radius: 99px; background: rgba(255, 255, 255, .92); color: #111; font: 800 4.2cqi/1.2 var(--ex-sans); }
.ex-reel-btn { padding: 2.4cqi; border-radius: 3cqi; background: #ff6a2b; text-align: center; font: 700 4.2cqi/1 var(--ex-sans); }
.ex-reel-side { position: absolute; z-index: 2; right: 3.5cqi; bottom: 26cqi; display: grid; gap: 4.5cqi; justify-items: center; font: 400 6.5cqi/1 var(--ex-sans); color: #fff; text-shadow: 0 2px 6px rgba(0, 0, 0, .5); }
.explainer[data-step="reels"] .ex-reel:nth-child(2) .ex-like { animation: likePop .35s cubic-bezier(.2, .9, .3, 1.8) .9s both; }
@keyframes likePop { 50% { scale: 1.7; } to { color: #ff2d55; } }
.ex-reel:nth-child(2) .ex-reel-info::before { /* big heart burst on the double-tap */
  content: "♥";
  position: absolute;
  left: 50%;
  bottom: 52cqi;
  translate: -50% 0;
  font-size: 26cqi;
  color: #ff2d55;
  opacity: 0;
  text-shadow: 0 6px 20px rgba(0, 0, 0, .35);
}
.explainer[data-step="reels"] .ex-reel:nth-child(2) .ex-reel-info::before { animation: heartBurst .55s cubic-bezier(.2, .9, .3, 1.5) .76s both; }
@keyframes heartBurst { 0% { opacity: 0; scale: .2; } 30% { opacity: 1; scale: 1.15; } 70% { opacity: 1; scale: 1; } 100% { opacity: 0; scale: 1.1; translate: -50% -12cqi; } }
.ex-touch { position: absolute; z-index: 4; left: 56%; width: 12cqi; aspect-ratio: 1; border-radius: 50%; background: rgba(255, 255, 255, .6); box-shadow: 0 0 0 3cqi rgba(255, 255, 255, .18); opacity: 0; }
.explainer[data-step="reels"] .ex-touch { animation: touchSwipe var(--step-ms, 2.6s) linear both; }
@keyframes touchSwipe {
  0%, 11% { top: 72%; opacity: 0; } 13% { top: 72%; opacity: .9; } 22% { top: 34%; opacity: 0; }
  37% { top: 72%; opacity: 0; } 39% { top: 72%; opacity: .9; } 48% { top: 34%; opacity: 0; }
  63% { top: 72%; opacity: 0; } 65% { top: 72%; opacity: .9; } 74% { top: 34%; opacity: 0; }
  100% { top: 34%; opacity: 0; }
}

/* chat: the app's warm chat screen, messages pop in, a dish gets shared */
.ex-chat {
  padding: 13cqi 4.5cqi 18cqi;
  display: none;
  flex-direction: column;
  justify-content: flex-end;
  gap: 2.4cqi;
  background: radial-gradient(circle, rgba(255, 140, 60, .12) 1.5px, transparent 2px) 0 0 / 7cqi 7cqi, #fff3e6;
  font-family: var(--ex-sans);
}
.explainer[data-step="friends"] .ex-chat { display: flex; }
.ex-chat-head { position: absolute; top: 12cqi; left: 0; right: 0; display: flex; justify-content: center; align-items: center; gap: 2cqi; font: 800 4.4cqi/1 var(--ex-sans); }
.ex-chat-head span { display: grid; place-items: center; width: 8cqi; height: 8cqi; border-radius: 50%; background: var(--red); font-size: 4.2cqi; }
.ex-chat::after { content: ""; position: absolute; left: 4.5cqi; right: 4.5cqi; bottom: 5cqi; height: 10cqi; border-radius: 99px; background: #fff; box-shadow: 0 1px 4px rgba(0, 0, 0, .12); }
.ex-msg { margin: 0; max-width: 80%; align-self: flex-start; padding: 2.4cqi 3.6cqi; border-radius: 4.5cqi 4.5cqi 4.5cqi 1.2cqi; background: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, .1); font: 600 4.3cqi/1.25 var(--ex-sans); }
.ex-msg.ex-mine { align-self: flex-end; border-radius: 4.5cqi 4.5cqi 1.2cqi 4.5cqi; background: var(--red); color: #fff; }
.ex-share { width: 62%; padding: 1.4cqi; display: grid; gap: 1.4cqi; }
.ex-share img { width: 100%; aspect-ratio: 4 / 3; border-radius: 3.2cqi; object-fit: cover; }
.ex-share span { padding: 0 1.6cqi 1cqi; font: 700 3.7cqi/1.2 var(--ex-sans); }
.explainer[data-step="friends"] .ex-msg { animation: bubbleIn .35s cubic-bezier(.2, .9, .3, 1.6) both; }
.explainer[data-step="friends"] .ex-msg:nth-of-type(1) { animation-delay: .15s; }
.explainer[data-step="friends"] .ex-msg:nth-of-type(2) { animation-delay: .5s; }
.explainer[data-step="friends"] .ex-msg:nth-of-type(3) { animation-delay: .8s; }
.explainer[data-step="friends"] .ex-msg:nth-of-type(4) { animation-delay: 1.2s; }
@keyframes bubbleIn { from { scale: .3; opacity: 0; } }

/* Landscape phones: caption on the left, phone on the right. */
@media (orientation: landscape) and (max-height: 500px) {
  .ex-stage { flex-direction: row; gap: 6vw; padding-top: calc(30px + var(--safe-top)); }
  .ex-caption { width: 40vw; }
  .ex-phone { width: min(28vw, 38dvh); }
  .ex-sticker { font-size: min(64px, 16dvh); }
}

/* ---------- prize: the earbuds rise out of the open gift ---------- */
.pods {
  position: absolute;
  z-index: 4;
  left: 54%;
  bottom: 50%;
  width: 40%;
  overflow: visible;
  translate: -50% 0;
  filter: drop-shadow(0 0 14px rgba(255, 236, 160, .95)) drop-shadow(0 6px 0 rgba(58, 29, 16, .22));
}
.reward-screen.is-active .pods { animation: podsRise .8s cubic-bezier(.2, .9, .3, 1.4) .45s both, podsFloat 2.6s ease-in-out 1.25s infinite alternate; }
@keyframes podsRise { from { translate: -50% 70%; scale: .3; opacity: 0; } }
@keyframes podsFloat { to { translate: -50% -8px; } }
.reward-terms { font: 800 12.5px var(--font); color: rgba(58, 29, 16, .7); }
/* "×3": three pairs are given away */
.pods-badge {
  position: absolute;
  z-index: 5;
  right: 2%;
  top: 4%;
  padding: 4px 12px;
  border: 3px solid var(--ink);
  border-radius: 14px;
  background: var(--red);
  box-shadow: 0 4px 0 var(--ink);
  color: #fff;
  font: 900 clamp(22px, 7vw, 34px)/1 var(--font);
  rotate: 10deg;
}
.reward-screen.is-active .pods-badge { animation: wordHit .4s cubic-bezier(.2, .9, .3, 1.8) .9s both, giftBob 2s ease-in-out 1.3s infinite; }
