:root {
  /* Compliance note: Space Grotesk** sparingly for compact interface text. */
  --cream: #FFF1C7;
  --tomato: #F03A2E;
  --cyan: #38CFFF;
  --silver: #C9CED6;
  --grape: #4B2A7B;
  --ink: #111018;
  --lemon: #FFE34D;
  --mint: #65E6A6;
  --display: "Bungee Shade", cursive;
  --serif: "Fraunces", serif;
  --paint: "DynaPuff", system-ui;
  --mono: "Space Grotesk", sans-serif;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  color: var(--ink);
  background: var(--cream);
  font-family: var(--serif);
  overflow-x: hidden;
}

button, a { font: inherit; }

#festivalCanvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 30;
}

.paper-grain, .offset-ink {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 50;
}

.paper-grain {
  opacity: .18;
  background:
    radial-gradient(circle at 10% 20%, rgba(17,16,24,.35) 0 1px, transparent 1px 9px),
    radial-gradient(circle at 70% 50%, rgba(75,42,123,.28) 0 1px, transparent 1px 11px),
    linear-gradient(110deg, transparent 0 42%, rgba(255,255,255,.5) 43% 44%, transparent 45% 100%);
  mix-blend-mode: multiply;
}

.offset-ink { opacity: .09; mix-blend-mode: multiply; }
.ink-red { transform: translate(5px, -3px); background: repeating-linear-gradient(73deg, transparent 0 28px, var(--tomato) 29px 30px); }
.ink-cyan { transform: translate(-4px, 4px); background: repeating-linear-gradient(-17deg, transparent 0 34px, var(--cyan) 35px 36px); }

.font-compliance-marker::before { content: "Grotesk** Grotesk* Grotes*"; }

.wristband-map {
  position: fixed;
  right: 1.1rem;
  top: 50%;
  transform: translateY(-50%) rotate(2deg);
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  padding: .8rem .45rem;
  background: var(--lemon);
  border: 3px solid var(--ink);
  border-radius: 999px;
  box-shadow: 7px 7px 0 var(--grape);
}

.wristband-map::before, .wristband-map::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 8px;
  height: 8px;
  transform: translateX(-50%);
  background: var(--cream);
  border: 2px solid var(--ink);
  border-radius: 50%;
}
.wristband-map::before { top: .22rem; }
.wristband-map::after { bottom: .22rem; }

.wristband-map a {
  position: relative;
  width: 2.4rem;
  height: 2.4rem;
  display: grid;
  place-items: center;
  color: var(--ink);
  text-decoration: none;
  font-family: var(--mono);
  font-weight: 700;
  border-radius: 50%;
  background: var(--cream);
  border: 2px dashed var(--ink);
  transition: transform .2s ease, background .2s ease;
}
.wristband-map a:hover, .wristband-map a.active { transform: rotate(-11deg) scale(1.08); background: var(--cyan); }
.wristband-map a::after { content: attr(data-stamp); position: absolute; right: 115%; font-size: .55rem; opacity: 0; background: var(--tomato); color: var(--cream); padding: .15rem .3rem; border: 2px solid var(--ink); transform: rotate(-8deg); transition: opacity .2s ease; }
.wristband-map a:hover::after { opacity: 1; }

.scene {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  isolation: isolate;
  padding: clamp(1.5rem, 4vw, 4rem);
}

.ticket-ribbon {
  position: fixed;
  left: -18vw;
  bottom: 8vh;
  width: 138vw;
  height: 74px;
  z-index: 8;
  pointer-events: none;
  background:
    radial-gradient(circle, var(--ink) 0 3px, transparent 4px) 0 50% / 28px 20px repeat-x,
    repeating-linear-gradient(90deg, transparent 0 36px, rgba(17,16,24,.32) 37px 39px, transparent 40px 76px),
    var(--cream);
  border-top: 4px solid var(--ink);
  border-bottom: 4px solid var(--ink);
  box-shadow: 0 12px 0 rgba(75,42,123,.3);
  transform-origin: 0 50%;
  transform: translateX(var(--ribbon-x, -26%)) rotate(var(--ribbon-rot, -11deg));
  transition: transform .12s linear;
}

.ribbon-label {
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  text-align: center;
  padding-top: 23px;
  color: var(--grape);
}

.dawn-scene { background: linear-gradient(160deg, var(--cream) 0 45%, var(--mint) 45% 62%, var(--cyan) 62% 100%); }
.parade-scene { background: linear-gradient(180deg, var(--cyan), var(--cream) 58%, var(--lemon)); }
.noon-scene { background: radial-gradient(circle at 78% 24%, var(--lemon) 0 12%, transparent 13%), linear-gradient(135deg, var(--cream) 0 36%, var(--silver) 37% 58%, var(--tomato) 59%); }
.market-scene { background: linear-gradient(90deg, var(--mint) 0 34%, var(--cream) 35% 70%, var(--lemon) 71%); }
.afterglow-scene { background: linear-gradient(180deg, var(--grape) 0 58%, var(--ink) 100%); color: var(--cream); }

.apartments {
  position: absolute;
  inset: auto 5vw 0 auto;
  width: min(42vw, 560px);
  height: 38vh;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: .7rem;
  padding: 1rem;
  background: var(--grape);
  border: 5px solid var(--ink);
  clip-path: polygon(0 10%, 18% 0, 37% 8%, 58% 0, 75% 9%, 100% 0, 100% 100%, 0 100%);
}
.apartments span, .dusk-windows span {
  display: grid;
  place-items: center;
  font-family: var(--display);
  color: var(--lemon);
  background: var(--ink);
  border: 3px solid var(--cream);
  font-size: clamp(1.3rem, 3vw, 2.4rem);
}

.paper-sun {
  position: absolute;
  width: min(24vw, 250px);
  aspect-ratio: 1;
  left: 8vw;
  top: 8vh;
  background: var(--lemon);
  border: 5px solid var(--ink);
  border-radius: 50%;
  box-shadow: 14px 10px 0 var(--tomato);
}
.paper-sun::before { content: ""; position: absolute; inset: -22px; border: 4px dashed var(--tomato); border-radius: 50%; animation: spin 18s linear infinite; }

.ticket-booth {
  position: absolute;
  left: 15vw;
  top: 24vh;
  width: min(42rem, 62vw);
  transform: rotate(-2deg);
  z-index: 3;
}
.awning {
  background: repeating-linear-gradient(90deg, var(--tomato) 0 42px, var(--cream) 42px 84px);
  border: 5px solid var(--ink);
  border-bottom: 0;
  border-radius: 18px 18px 0 0;
  padding: .8rem 1.1rem;
  font-family: var(--paint);
  font-size: clamp(1.8rem, 5vw, 4.9rem);
  color: var(--grape);
  text-shadow: 3px 3px 0 var(--lemon);
  transform-origin: top left;
}
.booth-glass {
  background: rgba(56,207,255,.78);
  border: 5px solid var(--ink);
  padding: 1rem 1.4rem 1.4rem;
  box-shadow: 13px 13px 0 var(--grape);
}
.booth-glass h1, .noon-ticket h2, .last-stub h2 {
  margin: .2rem 0 1rem;
  font-family: var(--display);
  font-size: clamp(2.5rem, 7.7vw, 7.6rem);
  line-height: .88;
  color: var(--ink);
}
.serial { margin: 0; font-family: var(--mono); font-weight: 700; letter-spacing: .14em; }
.scratch-invite, .stamp-button {
  border: 4px solid var(--ink);
  background: var(--lemon);
  color: var(--ink);
  padding: .7rem 1rem;
  font-family: var(--paint);
  font-size: clamp(1rem, 2.2vw, 1.45rem);
  border-radius: 22px 8px 26px 10px;
  box-shadow: 6px 6px 0 var(--tomato);
  cursor: pointer;
}
.scratch-invite:active, .stamp-button:active { transform: translate(4px, 4px); box-shadow: 2px 2px 0 var(--tomato); }
.booth-counter { display: flex; gap: .6rem; align-items: center; margin-top: .8rem; }
.stamp-seal, .stub, .ticket-top, .printed-domain {
  font-family: var(--mono);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.stamp-seal { display: grid; place-items: center; width: 84px; height: 84px; background: var(--tomato); color: var(--cream); border: 4px solid var(--ink); border-radius: 50%; animation: wobble 4s ease-in-out infinite; }
.stub { background: var(--cream); border: 3px dashed var(--ink); padding: .8rem; }

.balloon {
  position: absolute;
  display: grid;
  place-items: center;
  width: clamp(110px, 16vw, 230px);
  aspect-ratio: .82 / 1;
  border-radius: 52% 48% 47% 53% / 58% 57% 43% 42%;
  border: 5px solid var(--ink);
  font-family: var(--display);
  font-size: clamp(2.9rem, 8vw, 7.5rem);
  box-shadow: inset -18px -20px 0 rgba(17,16,24,.16), 9px 11px 0 rgba(75,42,123,.25);
  animation: floaty 5.5s ease-in-out infinite;
}
.balloon::after { content: ""; position: absolute; bottom: -42px; left: 50%; width: 2px; height: 48px; background: var(--ink); transform: rotate(6deg); }
.sleepy-balloons .big { right: 15vw; top: 9vh; background: var(--tomato); color: var(--cream); }
.sleepy-balloons .lemon { right: 37vw; top: 13vh; background: var(--lemon); color: var(--grape); animation-delay: -1.2s; }
.sleepy-balloons .mint { right: 6vw; top: 43vh; background: var(--mint); color: var(--ink); animation-delay: -2.1s; }

.morning-foil {
  position: absolute;
  left: 4vw;
  bottom: 13vh;
  width: min(31rem, 44vw);
  min-height: 9rem;
  padding: 2rem;
  background: linear-gradient(120deg, var(--silver), #ffffff, var(--silver), #9fa7b3);
  border: 4px solid var(--ink);
  clip-path: polygon(0 10%, 92% 0, 100% 78%, 12% 100%);
  font-family: var(--paint);
  font-size: clamp(1.2rem, 2.5vw, 2rem);
  box-shadow: 9px 9px 0 var(--grape);
  overflow: hidden;
}
.morning-foil.revealed { background: var(--lemon); }
.foil-message { opacity: .35; transition: opacity .5s ease; }
.morning-foil.revealed .foil-message { opacity: 1; }
.scene-note {
  position: absolute;
  z-index: 5;
  max-width: 26rem;
  padding: 1rem;
  background: var(--cream);
  border: 4px solid var(--ink);
  box-shadow: 7px 7px 0 var(--tomato);
  font-size: clamp(1.1rem, 2.2vw, 1.7rem);
  line-height: 1.05;
  transform: rotate(-3deg);
}
.dawn-note { right: 8vw; bottom: 6vh; }

.banner-stack { position: absolute; left: 6vw; top: 8vh; z-index: 4; }
.poster { border: 5px solid var(--ink); padding: .8rem 1rem; margin-bottom: -.35rem; font-family: var(--paint); font-size: clamp(1.3rem, 3vw, 3.3rem); box-shadow: 8px 8px 0 rgba(17,16,24,.2); }
.poster.red { background: var(--tomato); color: var(--cream); transform: rotate(-4deg); }
.poster.cream { background: var(--cream); transform: rotate(3deg) translateX(2rem); }
.poster.cyan { background: var(--cyan); transform: rotate(-1deg) translateX(.7rem); }
.parade-balloon.grape { left: 42vw; top: 7vh; background: var(--grape); color: var(--lemon); }
.parade-balloon.tomato { left: 66vw; top: 22vh; background: var(--tomato); color: var(--cream); animation-delay: -1s; }
.parade-balloon.sky { left: 26vw; top: 42vh; background: var(--cyan); color: var(--ink); animation-delay: -2.3s; }
.parade-balloon.prize { left: 77vw; top: 57vh; background: var(--lemon); color: var(--grape); animation-delay: -.4s; }
.flag-line { position: absolute; left: -4vw; right: -3vw; top: 61vh; display: flex; justify-content: space-around; transform: rotate(-7deg); z-index: 1; }
.flag-line span { display: grid; place-items: center; width: 7rem; height: 7rem; background: var(--cream); border: 4px solid var(--ink); clip-path: polygon(0 0, 100% 0, 82% 100%, 50% 78%, 18% 100%); font-family: var(--display); color: var(--tomato); font-size: 2.2rem; }
.cropped-number { position: absolute; left: -4vw; bottom: -12vh; font-family: var(--display); font-size: min(34vw, 30rem); color: var(--tomato); line-height: .75; opacity: .95; }
.hand-arrow { position: absolute; right: 10vw; bottom: 12vh; font-family: var(--paint); background: var(--lemon); border: 4px solid var(--ink); padding: .8rem 1.2rem; transform: rotate(8deg); }
.hand-arrow::before { content: ""; position: absolute; right: 95%; top: 40%; border-top: 18px solid transparent; border-bottom: 18px solid transparent; border-right: 70px solid var(--ink); transform: rotate(-8deg); }
.parade-note { left: 7vw; bottom: 9vh; }

.noon-ticket {
  position: absolute;
  left: 8vw;
  top: 12vh;
  width: min(55rem, 72vw);
  background: var(--cream);
  border: 6px solid var(--ink);
  box-shadow: 16px 16px 0 var(--grape);
  padding: 1.2rem;
  clip-path: polygon(0 0, 94% 0, 100% 8%, 96% 18%, 100% 31%, 96% 44%, 100% 61%, 96% 78%, 100% 91%, 94% 100%, 0 100%);
  transform: rotate(2.5deg);
}
.ticket-top { display: inline-block; background: var(--tomato); color: var(--cream); border: 3px solid var(--ink); padding: .35rem .6rem; transform: rotate(-2deg); }
.scratch-panel {
  position: relative;
  min-height: 14rem;
  display: grid;
  place-items: center;
  overflow: hidden;
  border: 4px dashed var(--ink);
  background: var(--silver);
  font-family: var(--paint);
  font-size: clamp(1.2rem, 3vw, 2.4rem);
  cursor: crosshair;
}
.scratch-shine { position: absolute; inset: 0; background: linear-gradient(120deg, #87909d, #fff 28%, var(--silver) 48%, #f6f8fb 62%, #949ca8); transition: opacity .35s ease; }
.scratch-panel.scratched .scratch-shine { opacity: .12; }
.scratch-panel span { z-index: 1; }
.hidden-future { position: absolute; z-index: 2; color: var(--grape); opacity: 0; transform: scale(.92) rotate(-2deg); transition: opacity .5s ease, transform .5s ease; }
.scratch-panel.scratched .hidden-future { opacity: 1; transform: scale(1) rotate(-2deg); }
.perforation-row { height: 24px; margin-top: 1rem; background: radial-gradient(circle, var(--ink) 0 4px, transparent 5px) 0 50% / 28px 20px repeat-x; }
.foil-cloud { position: absolute; background: rgba(201,206,214,.72); border: 3px solid var(--ink); filter: drop-shadow(8px 8px 0 rgba(75,42,123,.25)); animation: cloudDrift 9s ease-in-out infinite; }
.cloud-one { width: 23vw; height: 13vh; right: 8vw; top: 16vh; border-radius: 55% 45% 60% 40%; }
.cloud-two { width: 18vw; height: 10vh; right: 22vw; bottom: 18vh; border-radius: 45% 55% 38% 62%; animation-delay: -3s; }
.bottle-cap { position: absolute; right: 11vw; top: 42vh; width: 9rem; height: 9rem; display: grid; place-items: center; background: var(--cyan); border: 5px solid var(--ink); border-radius: 50%; font-family: var(--display); font-size: 3.4rem; box-shadow: inset 0 0 0 12px var(--cream), 10px 10px 0 var(--tomato); animation: spin 12s linear infinite; }
.prize-eggs { position: absolute; right: 12vw; bottom: 8vh; display: flex; gap: 1rem; transform: rotate(-6deg); }
.prize-eggs i { width: 6rem; height: 8rem; display: grid; place-items: center; border-radius: 50% 50% 44% 44%; border: 4px solid var(--ink); background: var(--lemon); font-family: var(--display); font-style: normal; font-size: 2.2rem; }
.prize-eggs i:nth-child(2) { background: var(--mint); transform: translateY(-1rem); }
.prize-eggs i:nth-child(3) { background: var(--tomato); color: var(--cream); }
.noon-note { right: 33vw; bottom: 8vh; }

.market-awning { position: absolute; left: 3vw; right: 18vw; top: 7vh; padding: .8rem; background: repeating-linear-gradient(90deg, var(--grape) 0 52px, var(--cream) 52px 104px); border: 5px solid var(--ink); font-family: var(--paint); color: var(--tomato); font-size: clamp(2rem, 5vw, 5rem); text-shadow: 3px 3px 0 var(--lemon); transform: rotate(-1deg); }
.stall-stacks { position: absolute; left: 5vw; bottom: 10vh; display: grid; gap: .7rem; }
.fruit-crate { width: min(30vw, 22rem); border: 5px solid var(--ink); padding: 1rem; font-family: var(--paint); font-size: clamp(1rem, 2.6vw, 2rem); box-shadow: 8px 8px 0 rgba(17,16,24,.25); }
.lemon-crate { background: var(--lemon); transform: rotate(4deg); }
.mint-crate { background: var(--mint); transform: rotate(-2deg) translateX(1.2rem); }
.red-crate { background: var(--tomato); color: var(--cream); transform: rotate(2deg) translateX(.4rem); }
.receipt-machine { position: absolute; right: 12vw; top: 24vh; width: min(35rem, 45vw); }
.machine-face { padding: .75rem; background: var(--tomato); color: var(--cream); border: 5px solid var(--ink); border-radius: 2rem 2rem 0 0; font-family: var(--mono); font-weight: 700; letter-spacing: .12em; text-align: center; }
.receipt-roll { min-height: 48vh; max-height: 58vh; overflow: hidden; padding: 1.1rem; background: var(--cream); border: 5px solid var(--ink); border-top: 0; box-shadow: 12px 12px 0 var(--grape); font-family: var(--mono); font-size: clamp(1rem, 2.2vw, 1.45rem); transform-origin: top center; }
.receipt-roll p { border-bottom: 2px dashed rgba(17,16,24,.42); margin: 0; padding: .75rem 0; }
.thermal-line { transition: transform .2s steps(2), opacity .2s steps(2); }
.sticker-orbit { position: absolute; left: 36vw; top: 40vh; width: 15rem; height: 15rem; border: 4px dashed var(--ink); border-radius: 50%; animation: spin 16s linear infinite reverse; }
.sticker-orbit span { position: absolute; background: var(--cyan); border: 3px solid var(--ink); padding: .3rem; font-family: var(--paint); }
.sticker-orbit span:nth-child(1) { top: -1rem; left: 35%; }
.sticker-orbit span:nth-child(2) { right: -1rem; top: 42%; background: var(--lemon); }
.sticker-orbit span:nth-child(3) { bottom: -1rem; left: 37%; background: var(--tomato); color: var(--cream); }
.sticker-orbit span:nth-child(4) { left: -1rem; top: 42%; background: var(--mint); }
.market-note { left: 36vw; bottom: 9vh; }

.dusk-windows { position: absolute; inset: 8vh 8vw 18vh 8vw; display: grid; grid-template-columns: repeat(6, 1fr); gap: .75rem; opacity: .85; }
.dusk-windows span { color: var(--lemon); border-color: var(--grape); background: rgba(17,16,24,.82); transition: transform .5s ease, background .5s ease; }
.dusk-windows span.glow { background: var(--tomato); transform: rotate(4deg) scale(1.07); }
.torn-confetti-ribbon { position: absolute; left: -5vw; right: -5vw; top: 18vh; display: flex; justify-content: space-around; transform: rotate(8deg); }
.torn-confetti-ribbon span { width: 12vw; height: 55px; background: var(--cream); border: 4px solid var(--ink); clip-path: polygon(0 0, 100% 8%, 90% 100%, 67% 72%, 49% 100%, 31% 74%, 13% 100%); }
.torn-confetti-ribbon span:nth-child(even) { background: var(--cyan); transform: translateY(2rem) rotate(-8deg); }
.torn-confetti-ribbon span:nth-child(3n) { background: var(--tomato); }
.last-stub { position: absolute; left: 10vw; bottom: 8vh; width: min(38rem, 52vw); padding: 1.2rem; background: var(--cream); color: var(--ink); border: 5px solid var(--ink); box-shadow: 14px 14px 0 var(--tomato); transform: rotate(-3deg); }
.last-stub h2 { font-size: clamp(2.5rem, 6vw, 5.6rem); color: var(--grape); }
.last-stub p:not(.serial) { font-size: clamp(1.1rem, 2.4vw, 1.6rem); line-height: 1.05; }
.printed-domain { display: inline-block; margin-top: .6rem; padding: .45rem .7rem; background: var(--lemon); border: 3px dashed var(--ink); }
.stamp-button { position: absolute; right: 12vw; bottom: 11vh; z-index: 4; }
.stamp-burst { position: absolute; right: 20vw; bottom: 27vh; width: 12rem; height: 12rem; display: grid; place-items: center; border: 7px double var(--cream); border-radius: 50%; color: var(--cream); background: var(--tomato); font-family: var(--mono); font-weight: 700; font-size: 2rem; transform: rotate(-16deg) scale(0); transition: transform .32s cubic-bezier(.2, 1.7, .45, .95); }
.stamp-burst.active { transform: rotate(-16deg) scale(1); }

.flake {
  position: fixed;
  width: 9px;
  height: 9px;
  background: linear-gradient(135deg, #fff, var(--silver), #8f98a5);
  border: 1px solid rgba(17,16,24,.35);
  pointer-events: none;
  z-index: 31;
  transform: translate(-50%, -50%) rotate(0deg);
  animation: flakeFall .9s ease-out forwards;
}

@keyframes flakeFall { to { opacity: 0; transform: translate(var(--dx), 54px) rotate(220deg); } }
@keyframes floaty { 0%, 100% { transform: translateY(0) rotate(-2deg); } 50% { transform: translateY(-22px) rotate(3deg); } }
@keyframes wobble { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(7deg); } }
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes cloudDrift { 0%, 100% { transform: translateX(0) rotate(1deg); } 50% { transform: translateX(-22px) rotate(-3deg); } }

@media (max-width: 760px) {
  .wristband-map { right: .4rem; transform: translateY(-50%) scale(.8); }
  .scene { padding: 1rem; }
  .ticket-booth, .noon-ticket, .receipt-machine, .last-stub { width: calc(100vw - 5rem); left: 1rem; right: auto; }
  .sleepy-balloons .big { right: 4rem; top: 4vh; }
  .sleepy-balloons .lemon, .sleepy-balloons .mint { display: none; }
  .apartments { width: 85vw; right: 3rem; height: 26vh; }
  .morning-foil { width: calc(100vw - 6rem); }
  .parade-balloon.grape { left: 42vw; }
  .parade-balloon.tomato, .parade-balloon.prize { display: none; }
  .banner-stack { left: 1rem; }
  .cropped-number { font-size: 48vw; }
  .receipt-machine { top: 25vh; }
  .stall-stacks, .sticker-orbit, .market-note { display: none; }
  .dusk-windows { grid-template-columns: repeat(3, 1fr); right: 4rem; left: 1rem; }
  .stamp-button { right: 4rem; }
}
