/* ============================================================
   PuraUse — interactive ingredients + motion layer
   ============================================================ */

/* ------------------------------------------------------------
   Interactive ingredients
   ------------------------------------------------------------ */

.ingx {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
}

.ingx__stage {
  position: relative;
  aspect-ratio: 1 / 0.92;
  width: 100%;
  /* Node coordinates are authored across the full 0–100% box; these two
     squeeze the whole cluster inward on narrow screens so the outermost
     labels never hang off the edge. */
  --inset: 0%;
  --span: 1;
}

/* The wipe at the centre */
.ingx__wipe {
  position: absolute;
  left: 50%; top: 50%;
  width: 52%;
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 20px 38px rgba(32, 48, 43, .16));
  animation: ingxBreathe 9s ease-in-out infinite;
}
.ingx__wipe .pack { width: 100%; height: auto; display: block; }

@keyframes ingxBreathe {
  0%, 100% { transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  50%      { transform: translate(-50%, -50%) scale(1.035) rotate(-1.2deg); }
}

/* Each ingredient */
.ingx__node {
  position: absolute;
  left: calc(var(--inset) + var(--x) * var(--span));
  top: var(--y);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: clamp(92px, 12vw, 132px);
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: center;
  /* translate(-50%,-50%) lives on the inner wrapper so the drift
     animation can own this transform without fighting it. */
  transform: translate(-50%, -50%);
  animation: ingxDrift calc(11s + var(--i) * 1.6s) ease-in-out infinite;
  animation-delay: calc(var(--i) * -2.1s);
  transition: filter var(--t-base) var(--e-out);
  z-index: 2;
}

@keyframes ingxDrift {
  0%, 100% { translate: 0 0; }
  33%      { translate: 4px -7px; }
  66%      { translate: -5px 5px; }
}

.ingx__bead {
  width: clamp(54px, 7vw, 76px);
  height: clamp(54px, 7vw, 76px);
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: inherit;
  box-shadow: 0 2px 6px rgba(32,48,43,.06), 0 10px 24px rgba(32,48,43,.08);
  transition: transform var(--t-slow) var(--e-soft), box-shadow var(--t-slow) var(--e-soft);
}
.ingx__bead svg { width: 44%; height: 44%; }

.ingx__label {
  font-size: var(--fs-xs);
  line-height: 1.3;
  color: var(--ink-70);
  transition: color var(--t-base) var(--e-out), opacity var(--t-base) var(--e-out);
}

.ingx__node:hover .ingx__bead,
.ingx__node:focus-visible .ingx__bead { transform: scale(1.12); }
.ingx__node.is-active .ingx__bead {
  transform: scale(1.16);
  box-shadow: 0 4px 10px rgba(32,48,43,.08), 0 18px 40px rgba(32,48,43,.16);
}
.ingx__node.is-active .ingx__label { color: var(--ink); font-weight: 700; }

/* While one is open, the others step back. */
.ingx.is-open .ingx__node:not(.is-active) { filter: saturate(.5); }
.ingx.is-open .ingx__node:not(.is-active) .ingx__label { opacity: .45; }
.ingx.is-open .ingx__wipe { opacity: .78; }

/* The explanation panel */
.ingx__detail {
  border-radius: var(--r-lg);
  padding: clamp(1.5rem, 3vw, 2.25rem);
  min-height: clamp(210px, 26vw, 260px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  transition: background var(--t-slow) var(--e-soft);
}
.ingx__sub {
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-55);
  display: block;
  margin-bottom: 0.625rem;
}
.ingx__name {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.125rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
  margin: 0 0 0.75rem;
}
.ingx__why { font-size: var(--fs-sm); line-height: 1.7; color: var(--ink-80); margin: 0; }
.ingx__hint {
  font-size: var(--fs-xs);
  color: var(--ink-40);
  margin-top: 1.125rem;
  display: flex;
  align-items: center;
  gap: 0.4375rem;
}
.ingx__hint svg { width: 14px; height: 14px; }

@media (max-width: 860px) {
  .ingx { grid-template-columns: 1fr; gap: 1.25rem; }
  .ingx__stage { max-width: 460px; margin-inline: auto; }
}
@media (max-width: 620px) {
  .ingx__stage { --inset: 11%; --span: 0.78; }
  .ingx__node { width: 86px; }
  .ingx__label { font-size: 0.6875rem; }
}

/* ------------------------------------------------------------
   Site-wide motion
   ------------------------------------------------------------ */

/* Headline words rise in, one after another. */
.js [data-words] > .word {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.5em);
}
.js [data-words].is-in > .word {
  opacity: 1;
  transform: none;
  transition: opacity 560ms var(--e-soft), transform 560ms var(--e-soft);
  transition-delay: calc(var(--w) * 55ms);
}

/* Reveal variants, so sections do not all arrive the same way. */
.js [data-reveal="left"]  { transform: translateX(-18px); }
.js [data-reveal="right"] { transform: translateX(18px); }
.js [data-reveal="scale"] { transform: scale(.965); }
.js [data-reveal].is-in   { transform: none; }

/* The hero pack breathes very slightly, so the page is never quite still. */
.hero__packwrap .pack { animation: heroFloat 11s ease-in-out infinite; }
@keyframes heroFloat {
  0%, 100% { transform: translateY(0) rotate(0deg); }
  50%      { transform: translateY(-10px) rotate(-0.6deg); }
}

/* Swatches lift and settle. */
.swatch__art .pack { transition: transform var(--t-slow) var(--e-soft); }
.swatch:hover .swatch__art .pack { transform: translateY(-6px) rotate(-1.5deg) scale(1.04); }

/* Buttons get a soft sheen on hover. */
.btn--solid { position: relative; overflow: hidden; }
.btn--solid::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, transparent 35%, rgba(255,255,255,.22) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform 720ms var(--e-soft);
  pointer-events: none;
}
.btn--solid:hover::after { transform: translateX(120%); }

/* The drag hint breathes until the tray is touched. */
.tray__hint svg { animation: hintNudge 2.6s ease-in-out infinite; }
@keyframes hintNudge {
  0%, 100% { transform: translateX(0); opacity: .7; }
  50%      { transform: translateX(3px); opacity: 1; }
}

/* Quiz options settle in one after another. */
.quiz__options .quiz__opt {
  animation: optIn 420ms var(--e-soft) both;
  animation-delay: calc(var(--o, 0) * 55ms);
}
@keyframes optIn {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* Section rules draw themselves in. */
.js .rules .rule-item { position: relative; }
.js .rules .rule-item::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 1px;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 900ms var(--e-soft);
}
.js .rules .rule-item.is-in::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .ingx__wipe,
  .ingx__node,
  .hero__packwrap .pack,
  .tray__hint svg,
  .quiz__options .quiz__opt { animation: none !important; }
  .js [data-words] > .word { opacity: 1 !important; transform: none !important; }
  .btn--solid::after { display: none; }
  .js .rules .rule-item::after { display: none; }
}
