/*
 * Crochet-derived motion and decoration (DESIGN.md §8).
 * base.css switches every animation off under prefers-reduced-motion; motion.js also skips its effects.
 */

:root {
  /* One loop of a crochet chain stitch, leaning like a pulled-through loop.
     Tiles overlap at the edges so the loops read as interlocked. */
  --chain-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='11' height='10' viewBox='0 0 11 10'%3E%3Cellipse cx='5.5' cy='5' rx='5.6' ry='2.7' transform='rotate(-24 5.5 5)' fill='none' stroke='black' stroke-width='1.6'/%3E%3C/svg%3E");
  --chain-draw-duration: 1400ms;
}

/* Chain stitch line. Use on a pseudo-element or an empty span. */
.chain,
.hero::after,
.page-head::after,
.site-footer::before {
  content: '';
  display: block;
  height: 10px;
  background: var(--color-coral-500);
  -webkit-mask: var(--chain-mask) repeat-x left center / 11px 10px;
  mask: var(--chain-mask) repeat-x left center / 11px 10px;
  clip-path: inset(0 100% 0 0);
}

.is-drawn.chain,
.hero.is-drawn::after,
.page-head.is-drawn::after,
.site-footer.is-drawn::before {
  animation: chain-crochet var(--chain-draw-duration) steps(48, end) forwards;
}

@keyframes chain-crochet {
  to {
    clip-path: inset(0 0 0 0);
  }
}

.hero::after {
  position: absolute;
  inset: auto 0 var(--space-3);
  opacity: 0.55;
}

.page-head::after {
  width: 5.5rem;
  margin-top: var(--space-5);
}

.site-footer {
  position: relative;
}

.site-footer::before {
  position: absolute;
  inset: var(--space-4) 0 auto;
  background: var(--color-coral-500);
  opacity: 0.6;
}

/* Scroll reveal (classes added by motion.js only, so content is visible without JavaScript). */

.reveal {
  opacity: 0;
  translate: 0 1.25rem;
  transition:
    opacity 600ms var(--ease-out) var(--reveal-delay, 0ms),
    translate 600ms var(--ease-out) var(--reveal-delay, 0ms);
}

.reveal.is-revealed {
  opacity: 1;
  translate: 0 0;
}

/* Handwritten notes are "written" left to right. */
.reveal-write {
  clip-path: inset(-20% 100% -20% 0);
}

.reveal-write.is-revealed {
  animation: hand-write 900ms cubic-bezier(0.5, 0, 0.3, 1) var(--reveal-delay, 0ms) forwards;
}

.hero .hand {
  animation: hand-write 900ms cubic-bezier(0.5, 0, 0.3, 1) 250ms both;
}

@keyframes hand-write {
  from {
    clip-path: inset(-20% 100% -20% 0);
  }
  to {
    clip-path: inset(-20% -5% -20% 0);
  }
}

/* Bags hang and sway a little, as if on a hook. The individual rotate property leaves transforms free. */

.sway,
.tryon-teaser__bag,
.hero__stage,
.gallery__preview,
.tryon__empty-bag,
.custom__bag {
  transform-origin: 50% 8%;
  animation: bag-sway 6.5s ease-in-out infinite;
}

/* The hero stage also has an entrance; run both. */
.hero__stage {
  animation:
    bag-settle var(--duration-slow) var(--ease-out) both,
    bag-sway 6.5s ease-in-out var(--duration-slow) infinite;
}

@keyframes bag-sway {
  0%,
  100% {
    rotate: -1.6deg;
  }
  50% {
    rotate: 1.6deg;
  }
}

.tinted-bag.is-wobbling {
  animation: bag-wobble 520ms var(--ease-out);
}

@keyframes bag-wobble {
  0% {
    scale: 1;
  }
  30% {
    scale: 1.045 0.965;
  }
  60% {
    scale: 0.985 1.02;
  }
  100% {
    scale: 1;
  }
}

/* The chosen yarn ball rolls when it is picked. */
.yarn__input:checked + .yarn__ball {
  animation: yarn-roll 650ms var(--ease-out);
}

@keyframes yarn-roll {
  from {
    rotate: -200deg;
  }
  to {
    rotate: 0deg;
  }
}

/* Buttons: a running stitch appears inside on hover, like topstitching. */

.button--primary,
.button--secondary {
  position: relative;
}

.button--primary::after,
.button--secondary::after {
  content: '';
  position: absolute;
  inset: 4px;
  border: 1.5px dashed currentColor;
  border-radius: inherit;
  opacity: 0;
  scale: 0.96;
  transition:
    opacity var(--duration-fast) ease,
    scale var(--duration-base) var(--ease-out);
  pointer-events: none;
}

.button--primary::after {
  border-color: rgb(255 255 255 / 0.7);
}

@media (hover: hover) {
  .button--primary:hover:not(:disabled)::after,
  .button--secondary:hover:not(:disabled)::after {
    opacity: 0.8;
    scale: 1;
  }
}

/* Desktop navigation: the underline is sewn in. */

.site-nav__link {
  border-bottom: 0;
  padding-bottom: 0.4rem;
  background-image: repeating-linear-gradient(90deg, var(--color-coral-500) 0 6px, transparent 6px 10px);
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: 0% 2px;
  transition: background-size 450ms var(--ease-out);
}

.site-nav__link:hover,
.site-nav__link[aria-current='page'] {
  background-size: 100% 2px;
}

/* Menu button: the three lines are running stitches; the thread runs on hover. */

.icon-stitch path {
  stroke-dasharray: 2.6 2.2;
}

@media (hover: hover) {
  .site-header__menu:hover .icon-stitch path {
    animation: thread-run 700ms linear infinite;
  }
}

@keyframes thread-run {
  to {
    stroke-dashoffset: -4.8;
  }
}

/* Navigation drawer: links arrive one by one and the separators crochet themselves. */

.drawer-nav li {
  opacity: 0;
  translate: -1rem 0;
}

.drawer.is-open .drawer-nav li {
  animation: nav-in 420ms var(--ease-out) calc(120ms + var(--i, 0) * 60ms) forwards;
}

@keyframes nav-in {
  to {
    opacity: 1;
    translate: 0 0;
  }
}

.drawer-nav__link {
  position: relative;
  border-bottom: 0;
}

.drawer-nav__link::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 8px;
  background: var(--color-blush-300);
  -webkit-mask: var(--chain-mask) repeat-x left center / 9px 8px;
  mask: var(--chain-mask) repeat-x left center / 9px 8px;
  clip-path: inset(0 100% 0 0);
}

.drawer.is-open .drawer-nav__link::after {
  animation: chain-crochet 700ms steps(28, end) calc(200ms + var(--i, 0) * 60ms) forwards;
}

.drawer-nav__link[aria-current='page']::after {
  background: var(--color-coral-500);
}

/* Bag icon and count react when something is added. */

.cart-button.is-bumped {
  animation: bag-bump 520ms var(--ease-out);
}

@keyframes bag-bump {
  0%,
  100% {
    scale: 1;
  }
  35% {
    scale: 1.25;
    rotate: -8deg;
  }
  70% {
    scale: 0.95;
    rotate: 4deg;
  }
}

.cart-button__count.is-popping {
  animation: count-pop 400ms var(--ease-out);
}

@keyframes count-pop {
  50% {
    scale: 1.45;
  }
}

/* Yarn burst and flying yarn ball (created by motion.js). */

.yarn-burst {
  position: fixed;
  inset: 0;
  z-index: var(--layer-toast);
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}

.yarn-burst path {
  fill: none;
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: thread-out 900ms var(--ease-out) forwards;
}

@keyframes thread-out {
  55% {
    stroke-dashoffset: 0;
    opacity: 1;
  }
  100% {
    stroke-dashoffset: 0;
    opacity: 0;
  }
}

.yarn-flyer {
  position: fixed;
  z-index: var(--layer-toast);
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 28%, rgb(255 255 255 / 0.5), transparent 46%),
    repeating-linear-gradient(38deg, rgb(0 0 0 / 0.14) 0 1.5px, transparent 1.5px 5px),
    var(--yarn);
  box-shadow: 0 4px 10px rgb(43 18 22 / 0.3);
  pointer-events: none;
}

/* Floating yarn balls in the home hero. */

.hero-sky {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hero-sky__item {
  position: absolute;
  bottom: -3rem;
  width: var(--size);
  height: var(--size);
  opacity: 0;
  animation: float-up var(--duration) linear var(--delay) infinite;
}

.hero-sky__item svg {
  width: 100%;
  height: 100%;
  animation: spin var(--spin) linear infinite;
}

.hero-sky.is-paused .hero-sky__item,
.hero-sky.is-paused .hero-sky__item svg {
  animation-play-state: paused;
}

@keyframes float-up {
  0% {
    transform: translate(0, 0);
    opacity: 0;
  }
  10% {
    opacity: 0.55;
  }
  85% {
    opacity: 0.45;
  }
  100% {
    transform: translate(var(--drift), -110vh);
    opacity: 0;
  }
}

@keyframes spin {
  to {
    rotate: 360deg;
  }
}

/* Hero content sits above the particles. */
.hero__inner {
  z-index: 1;
}
