:root {
  --sans: "Sofia Sans Condensed", "Avenir Next Condensed", "Arial Narrow", sans-serif;
  --pen: "La Belle Aurore", "Bradley Hand", cursive;
  --edge: clamp(20px, 4.5vw, 72px);

  /* the springs: a quick squash, then an elastic settle (after more-nutrition.webflow.io) */
  --ease: cubic-bezier(.72, .17, .17, 1);
  --smooth: cubic-bezier(.32, .72, 0, 1);
  --bouncy: cubic-bezier(.34, 1.42, .64, 1);
  --elastic: linear(0, .5737 7.6%, .8382 11.87%, .9463 14.19%, 1.0292 16.54%, 1.0886 18.97%,
    1.1258 21.53%, 1.137 22.97%, 1.1424 24.48%, 1.1423 26.1%, 1.1366 27.86%, 1.1165 31.01%,
    1.0507 38.62%, 1.0219 42.57%, .9995 46.99%, .9872 51.63%, .9842 58.77%, 1.0011 81.26%, 1);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: #013cd6;
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
  touch-action: none;
}

body.grab { cursor: grab; }
body.grabbing { cursor: grabbing; user-select: none; }

.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}

/* --- a world: one blend's colour, grain and words -------------------------- */
/* --bg the page, --fg its ink, --tone the second colour of a headline,
   --chip the pouch's own colour (stat circles, price, socials), --chip-ink on it */
.world {
  position: fixed;
  inset: 0;
  background: var(--bg);
  color: var(--fg);
  visibility: hidden;
}
.world.shown { visibility: visible; }

.grain {
  position: absolute;
  inset: 0;
  background: url("assets/grain.png") repeat;
  background-size: 192px 192px;
  mix-blend-mode: soft-light;
  opacity: 0.5;
  pointer-events: none;
}

/* resets with no weight, so every class below wins */
:where(.world) :where(a, button) { color: inherit; font: inherit; text-decoration: none; }
:where(.world) :where(button) { background: none; border: 0; padding: 0; cursor: pointer; }

/* --- the hop: squash fast, then spring up and tilt ------------------------------
   scale squashes; transform, a moment later, is its exact inverse, so the two
   multiply back to 1 with a bounce. Each control tilts its own way (--hr). */
.jelly {
  transition:
    translate .725s var(--elastic),
    rotate .725s var(--elastic),
    scale .35s var(--ease),
    transform .35s var(--ease),
    box-shadow .35s var(--smooth);
}
@media (hover: hover) and (pointer: fine) {
  .hop:hover .jelly {
    translate: var(--hx, 0) var(--hy, -.3em) 0;
    rotate: var(--hr, -3deg);
    scale: .945 .915;
    transform: scale(1.0582, 1.0929);
    transition:
      translate .725s .1s var(--elastic),
      rotate .725s .1s var(--elastic),
      scale .15s .1s var(--ease),
      transform .35s .25s var(--bouncy),
      box-shadow .35s var(--smooth);
  }
}
.hop:focus-visible { outline: none; }
.hop:focus-visible .jelly { box-shadow: 0 0 0 3px var(--bg), 0 0 0 5px var(--fg); }

/* --- the header ------------------------------------------------------------- */
.top {
  position: absolute;
  top: 26px;
  left: var(--edge);
  right: var(--edge);
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}
.top .socials { justify-self: start; }

.nav { display: flex; gap: 6px; }
.pill {
  display: grid;
  font-size: 23px;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: .92;
}
.pill .jelly {
  padding: .14em .48em .24em;
  border-radius: 2em;
  background: color-mix(in srgb, var(--fg) 13%, transparent);
  white-space: nowrap;
}
.pill[aria-current="true"] .jelly { background: var(--fg); color: var(--bg); }

.shop { justify-self: end; display: flex; align-items: center; gap: 10px; }

/* the bag: a circle with its count */
.bag { display: grid; position: relative; }
.bag .jelly {
  position: relative;
  width: 2.75rem; height: 2.75rem;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--chip);
  color: var(--chip-ink);
}
.bag svg, .cycle svg { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.bag svg { width: 21px; height: 21px; }
.bag .count {
  position: absolute;
  top: -5px; right: -6px;
  min-width: 21px; height: 21px;
  padding: 0 5px 2px;
  border-radius: 11px;
  background: var(--fg);
  color: var(--bg);
  font-size: 15px;
  font-weight: 700;
  line-height: 21px;
  text-align: center;
}
.bag.bump .jelly { animation: bump .7s var(--elastic); }
@keyframes bump { 0% { scale: .8 .7; } 100% { scale: 1; } }

/* --- the button: a pill, and a circle that hands over from left to right --------- */
.btn {
  position: relative;
  display: flex;
  align-items: stretch;
  font-size: 18px;
  user-select: none;
  --btn: var(--fg);
  --btn-ink: var(--bg);
}
.btn.pale { --btn: var(--chip); --btn-ink: var(--chip-ink); font-size: 16px; }
.btn-bg {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  padding: .3125em .9375em .5625em;
  border-radius: 12.5em;
  background: var(--btn);
  color: var(--btn-ink);
}
.btn-text {
  font-size: 1.75em;
  font-weight: 500;
  letter-spacing: -.02em;
  line-height: .8;
  white-space: nowrap;
}
.cycle {
  width: 2.5em;
  height: 2.5em;
  display: grid;
  pointer-events: none;
}
.cycle.second { position: absolute; top: 0; right: 0; }
.cycle-bg, .cycle svg { grid-area: 1 / 1; }
.cycle-bg { border-radius: 50%; background: var(--btn); }
.cycle svg {
  z-index: 1;
  place-self: center;
  width: .9em;
  height: .9em;
  color: var(--btn-ink);
}

.btn-bg { transition: translate .8s var(--elastic), rotate .8s var(--elastic), scale .35s var(--ease), transform .35s var(--ease), box-shadow .35s var(--smooth); }
.cycle-bg { transition: scale .75s var(--elastic), opacity .15s ease-out; }
.cycle.first svg {
  transition: translate .3s .15s var(--bouncy), rotate .3s .15s var(--bouncy), scale .3s .1s var(--ease), opacity .15s .15s ease-out, filter .15s .15s ease-out;
}
.cycle.second .cycle-bg { scale: 0; opacity: 0; transition: scale .75s var(--elastic), opacity .15s .1s ease-out; }
.cycle.second svg {
  translate: -.75em .75em 0;
  rotate: -90deg;
  filter: blur(.4rem);
  opacity: 0;
  scale: .6;
  transition: translate .75s var(--elastic), rotate .75s var(--elastic), scale .3s var(--ease), opacity .15s .05s ease-out, filter .15s .05s ease-out;
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover .btn-bg {
    translate: -2.5em -.3em 0;
    rotate: var(--hr, -4deg);
    scale: .945 .915;
    transform: scale(1.0582, 1.0929);
    transition: translate .8s .1s var(--elastic), rotate .8s .1s var(--elastic), scale .15s .1s var(--ease), transform .35s .25s var(--bouncy), box-shadow .35s var(--smooth);
  }
  .btn:hover .cycle.first .cycle-bg { scale: 0; opacity: 0; transition: scale .35s var(--ease), opacity .15s .15s ease-out; }
  .btn:hover .cycle.first svg {
    translate: -.75em .75em 0;
    rotate: 90deg;
    filter: blur(.4rem);
    opacity: 0;
    scale: .6;
    transition: translate .75s .1s var(--elastic), rotate .75s .1s var(--elastic), scale .25s .1s var(--ease), opacity .1s .15s ease-out, filter .1s .15s ease-out;
  }
  .btn:hover .cycle.second .cycle-bg { scale: 1; opacity: 1; transition: scale .75s .1s var(--elastic), opacity .15s ease-out; }
  .btn:hover .cycle.second svg {
    translate: 0 0 0; rotate: 0deg; filter: blur(0); opacity: 1; scale: 1;
    transition: translate .3s .2s var(--bouncy), rotate .5s .2s var(--elastic), scale .3s .15s var(--ease), opacity .15s .2s ease-out, filter .15s .2s ease-out;
  }
}
.btn:focus-visible { outline: none; }
.btn:focus-visible .btn-bg { box-shadow: 0 0 0 3px var(--bg), 0 0 0 5px var(--fg); }
.btn.done .cycle svg { rotate: 0deg; }

/* --- the words left of the pouch ---------------------------------------------- */
.panel {
  position: absolute;
  top: 50%;
  left: var(--edge);
  width: var(--panel-w, 420px);
  transform: translateY(calc(-50% + var(--rise, 0px)));
  opacity: var(--fade, 1);
}
.name {
  font-size: var(--name-size, 140px);
  font-weight: 700;
  letter-spacing: -.035em;
  line-height: .76;
  text-transform: uppercase;
  margin: 0 0 .1em -.03em;
  white-space: nowrap;
}
.name span { display: inline-block; }
.blend {
  font-size: clamp(30px, 3.1vw, 46px);
  font-weight: 600;
  letter-spacing: -.03em;
  line-height: .86;
  color: var(--tone);
  margin: 0;
}
.squiggle { display: block; width: 62%; height: 14px; margin: 6px 0 22px; color: var(--tone); overflow: visible; }
.copy {
  font-size: clamp(18px, 1.45vw, 22px);
  font-weight: 450;
  line-height: 1.12;
  letter-spacing: -.005em;
  max-width: 26ch;
  margin: 0;
}
.buy { display: flex; align-items: center; gap: 14px; margin-top: 30px; }
.price {
  flex: none;
  width: 4.6rem; height: 4.6rem;
  border-radius: 50%;
  background: var(--chip);
  color: var(--chip-ink);
  display: grid;
  place-content: center;
  text-align: center;
  rotate: -9deg;
}
.price b { font-size: 31px; font-weight: 700; letter-spacing: -.04em; line-height: .8; }
.price small { font-size: 12.5px; font-weight: 500; line-height: 1; margin-top: 4px; }

/* --- the stat circles, strung on a line that runs behind the pouch ------------- */
.string { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.string path {
  fill: none;
  stroke: var(--chip);
  stroke-width: clamp(8px, .9vw, 14px);
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.6s var(--smooth);
}
.in .string path, .string.in path { stroke-dashoffset: 0; }

.stat {
  position: absolute;
  left: 0; top: 0;
  width: var(--d, 122px); height: var(--d, 122px);
  margin: calc(var(--d, 122px) / -2) 0 0 calc(var(--d, 122px) / -2);
  border-radius: 50%;
  background: var(--chip);
  color: var(--chip-ink);
  display: grid;
  place-content: center;
  text-align: center;
  scale: 0;
  transition: scale .75s var(--elastic);
}
.stat.in { scale: 1; }
.stat b {
  font-size: calc(var(--d, 122px) * .36);
  font-weight: 700;
  letter-spacing: -.045em;
  line-height: .78;
}
.stat b small { font-size: .5em; letter-spacing: -.02em; margin-left: .05em; }
.stats { list-style: none; margin: 0; padding: 0; }
.stat span { font-size: calc(var(--d, 122px) * .13); font-weight: 500; letter-spacing: -.01em; line-height: 1; margin-top: .3em; }

/* --- pen notes ----------------------------------------------------------------- */
.note {
  position: absolute;
  left: 0; top: 0;
  font-family: var(--pen);
  font-size: clamp(19px, 1.55vw, 24px);
  line-height: 1.05;
  color: var(--fg);
  white-space: nowrap;
  pointer-events: none;
}
.note p { margin: 0; rotate: var(--r, -5deg); opacity: 0; translate: 0 .4em; transition: opacity .5s ease-out .15s, translate .9s var(--elastic) .15s; }
.note svg { position: absolute; overflow: visible; color: var(--fg); }
.note svg path { fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset .9s var(--smooth) .35s; }
.note.in p { opacity: .92; translate: 0 0; }
.note.in svg path { stroke-dashoffset: 0; }
.squiggle path { fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1s var(--smooth) .3s; }
.squiggle.in path { stroke-dashoffset: 0; }

/* --- arriving: words rise and circles pop as the colour passes them ------------- */
.rise { transition: translate .9s var(--elastic), opacity .4s ease-out; }
.rise:not(.in) { translate: 0 .5em; opacity: 0; }
.name .rise:not(.in) { translate: 0 .35em; }

/* --- the foot: the blends; the socials (top left) ---------------------------------- */
.foot {
  position: absolute;
  left: var(--edge);
  right: var(--edge);
  bottom: 26px;
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 24px;
}
.index { list-style: none; margin: 0; padding: 0; display: flex; gap: 6px; }
.index .num { font-weight: 700; margin-right: .2em; }

.socials { display: flex; gap: 5px; }
.social { display: grid; }
.social .jelly {
  width: 2.75rem; height: 2.75rem;
  border-radius: 50%;
  display: grid; place-items: center;
  background: var(--chip);
  color: var(--chip-ink);
}
.social svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.social svg .solid { fill: currentColor; stroke: none; }
.social svg .cut { fill: var(--chip); stroke: none; }

/* --- the rising colour's leading edge, and the pouch ------------------------ */
#froth {
  position: fixed;
  inset: 0;
  pointer-events: none;
  opacity: 0.45;
  visibility: hidden;
}
#stage {
  position: fixed;              /* placed and sized round the pouch by main.js */
  left: 0;
  top: 0;
  pointer-events: none;
  z-index: 10;
  opacity: 0;
  transition: opacity 1.2s ease;
}
#stage.ready { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .jelly, .btn-bg, .cycle-bg, .cycle svg, .stat, .rise, .note p { transition-duration: .01s !important; transition-delay: 0s !important; }
  .hop:hover .jelly, .btn:hover .btn-bg { translate: none; rotate: none; scale: none; transform: none; }
  .string path, .note svg path, .squiggle path { transition: none; }
}

/* --- phones and narrow windows: words above the pouch, circles below ------------- */
@media (max-width: 820px) {
  .top { grid-template-columns: 1fr auto; top: 18px; }
  .nav, .shop .btn { display: none; }
  .panel { top: 76px; left: var(--edge); right: var(--edge); width: auto; transform: translateY(var(--rise, 0px)); text-align: center; }
  .name { margin-left: 0; }
  .squiggle { display: none; }
  .copy, .buy { display: none; }
  .string, .note { display: none; }
  .stat { --d: min(21vw, 92px); }
  .foot { bottom: 18px; justify-content: center; }
  .index .label-name { display: none; }
  .pill { font-size: 21px; }
}

/* --- the loader: the first blend's colours, a chunky bar filling up, and the count ----- */
#loader {
  position: fixed;
  inset: 0;
  z-index: 20;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: clamp(14px, 2.4vw, 24px);
  background: #013cd6;
  color: #fc99b4;
  font-family: var(--sans);
  transition: visibility 0s linear .7s;
}
#loader::before {          /* the page's own grain, so lifting it changes only the count and bar */
  content: "";
  position: absolute;
  inset: 0;
  background: url("assets/grain.png") repeat;
  background-size: 192px 192px;
  mix-blend-mode: soft-light;
  opacity: .5;
}
.load-num, .load-bar { position: relative; }
.load-num {
  margin: 0;
  font-weight: 800;
  font-size: clamp(110px, 17vw, 220px);
  line-height: .78;
  letter-spacing: -.03em;
  font-variant-numeric: tabular-nums;
}
.load-num small { font-size: .36em; margin-left: .05em; }
.load-bar {
  width: min(600px, 80vw);
  height: clamp(56px, 7.2vw, 80px);
  padding: clamp(6px, .8vw, 9px);
  border: clamp(6px, .75vw, 9px) solid currentColor;
  border-radius: clamp(16px, 2vw, 24px);
}
.load-bar i { display: block; width: 0; height: 100%; border-radius: clamp(7px, .9vw, 11px); background: currentColor; }
/* done: a squash, then up and away */
#loader.done { visibility: hidden; }
#loader.done::before { opacity: 0; transition: opacity .3s .35s; }
#loader.done .load-num, #loader.done .load-bar { animation: load-off .55s cubic-bezier(.5, 0, .75, 0) forwards; }
#loader.done .load-bar { animation-delay: .05s; }
@keyframes load-off {
  0% { scale: 1; }
  30% { scale: 1.05 .92; }
  100% { scale: .9; translate: 0 -40px; opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  #loader.done .load-num, #loader.done .load-bar { animation: none; opacity: 0; transition: opacity .3s; }
}
