/*
  Dispatch motion layer.
  Holds only what the Designer cannot: keyframes, staggered nth-child timing,
  descendant hovers, and states toggled by scripts/main.js. Every static style
  lives in webcontra.css. Everything below is scoped to .motion-ready, which
  scripts/motion-boot.js sets only when reduced motion is not requested.
*/

@keyframes dsp-grow-y {
  from { transform: scaleY(0); }
  to { transform: scaleY(1); }
}

@keyframes dsp-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes dsp-fade-up {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

@keyframes dsp-wipe {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

@keyframes dsp-line-in {
  from { opacity: 0; transform: translateY(0.5em); clip-path: inset(0 0 100% 0); }
  to { opacity: 1; transform: none; clip-path: inset(-20% -5% -30% -5%); }
}

@keyframes dsp-spin-in {
  from { opacity: 0; transform: rotate(-135deg) scale(0.3); }
  to { opacity: 1; transform: rotate(45deg) scale(1); }
}

@keyframes dsp-type {
  from { width: 0; }
  to { width: 25ch; }
}

@keyframes dsp-caret {
  0%, 100% { border-right-color: #f2692d; }
  50% { border-right-color: transparent; }
}

@keyframes dsp-dots {
  from { background-position: 0 0; }
  to { background-position: -60px 0; }
}

@keyframes dsp-draw {
  from { stroke-dashoffset: 1; }
  to { stroke-dashoffset: 0; }
}

@keyframes dsp-arc-sway {
  0%, 100% { transform: translateX(0); }
  50% { transform: translateX(7px); }
}

@keyframes dsp-shine {
  from { background-position: 100% 0; }
  to { background-position: 0% 0; }
}

@keyframes dsp-tab-in {
  from { opacity: 0; transform: translateX(-28px); }
  to { opacity: 1; transform: none; }
}

@keyframes dsp-mark-in {
  from { opacity: 0; transform: rotate(-180deg) scale(0.3); }
  to { opacity: 1; transform: none; }
}

@keyframes dsp-play-nudge {
  0%, 78%, 100% { transform: translateX(0); }
  86% { transform: translateX(3px); }
  92% { transform: translateX(-1px); }
}

@keyframes dsp-letter-rise {
  from { transform: translateY(112%); }
  to { transform: translateY(0); }
}

/* Streams the wordmark's halftone left to right; 60px is a whole number of 5px dots, so it loops seamlessly. */
@keyframes dsp-halftone {
  from { background-position: 0 0, 0 0; }
  to { background-position: 60px 0, 0 0; }
}

/* Hovers the Style panel cannot express: a child reacting to its parent. */
.side-nav-link:hover .side-nav-index,
.side-nav-link:focus-visible .side-nav-index {
  color: #f2692d;
}

/* ---------- Hero, on load ---------- */

.motion-ready .hero > .gutter {
  transform-origin: top;
  animation: dsp-grow-y 1.4s cubic-bezier(0.7, 0, 0.2, 1) both;
}
.motion-ready .hero > .gutter:nth-child(5) { animation-delay: 0.08s; }

.motion-ready .side-nav-item {
  animation: dsp-fade-up 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.motion-ready .side-nav-item:nth-child(1) { animation-delay: 0.30s; }
.motion-ready .side-nav-item:nth-child(2) { animation-delay: 0.36s; }
.motion-ready .side-nav-item:nth-child(3) { animation-delay: 0.42s; }
.motion-ready .side-nav-item:nth-child(4) { animation-delay: 0.48s; }
.motion-ready .side-nav-item:nth-child(5) { animation-delay: 0.54s; }
.motion-ready .side-nav-item:nth-child(6) { animation-delay: 0.60s; }
.motion-ready .side-nav-item:nth-child(7) { animation-delay: 0.66s; }
.motion-ready .side-nav-item:nth-child(8) { animation-delay: 0.72s; }

.motion-ready .hero-ticker {
  animation: dsp-wipe 1.1s cubic-bezier(0.7, 0, 0.2, 1) 0.15s both;
}
.motion-ready .ticker-diamond {
  animation: dsp-spin-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) 0.25s both;
}
.motion-ready .ticker-text {
  width: 0;
  padding-right: 4px;
  border-right: 1px solid transparent;
  animation:
    dsp-type 1.3s steps(25, end) 0.65s forwards,
    dsp-caret 1s step-end 0.65s infinite;
}
.motion-ready .ticker-dots {
  animation:
    dsp-fade 1s ease 1.3s both,
    dsp-dots 4.5s linear 1.3s infinite;
}

.motion-ready .hero-title-line {
  animation: dsp-line-in 1.15s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.motion-ready .hero-title-line:nth-child(1) { animation-delay: 0.45s; }
.motion-ready .hero-title-line:nth-child(2) { animation-delay: 0.6s; }

.motion-ready .hero-lede {
  animation: dsp-fade-up 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 0.9s both;
}

.motion-ready .button.cta-button {
  animation:
    dsp-fade-up 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) 1.05s backwards,
    dsp-shine 1.2s cubic-bezier(0.2, 0.7, 0.2, 1) 1.9s;
}

.motion-ready .arc-art {
  transform: translate3d(calc(var(--arc-x, 0) * -16px), calc(var(--arc-y, 0) * -6px), 0) scale(1.05);
  transition: transform 1.1s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.motion-ready .arc-art path {
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation:
    dsp-draw 1.9s cubic-bezier(0.65, 0, 0.35, 1) forwards,
    dsp-arc-sway 8s ease-in-out infinite;
}
.motion-ready .arc-art path:nth-child(1) { animation-delay: 0.50s, 2.4s; }
.motion-ready .arc-art path:nth-child(2) { animation-delay: 0.60s, 2.8s; }
.motion-ready .arc-art path:nth-child(3) { animation-delay: 0.70s, 3.2s; }
.motion-ready .arc-art path:nth-child(4) { animation-delay: 0.80s, 3.6s; }
.motion-ready .arc-art path:nth-child(5) { animation-delay: 0.90s, 4.0s; }
.motion-ready .arc-art path:nth-child(6) { animation-delay: 1.00s, 4.4s; }
.motion-ready .arc-art path:nth-child(7) { animation-delay: 1.10s, 4.8s; }
.motion-ready .arc-art path:nth-child(8) { animation-delay: 1.20s, 5.2s; }

.motion-ready .link-group-title,
.motion-ready .link-item {
  animation: dsp-fade-up 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.motion-ready .link-group-title { animation-delay: 0.8s; }
.motion-ready .link-item:nth-child(1) { animation-delay: 0.88s; }
.motion-ready .link-item:nth-child(2) { animation-delay: 0.93s; }
.motion-ready .link-item:nth-child(3) { animation-delay: 0.98s; }
.motion-ready .link-item:nth-child(4) { animation-delay: 1.03s; }
.motion-ready .link-item:nth-child(5) { animation-delay: 1.08s; }
.motion-ready .link-item:nth-child(6) { animation-delay: 1.13s; }
.motion-ready .link-group.is-social .link-group-title { animation-delay: 0.9s; }
.motion-ready .link-group.is-social .link-item:nth-child(1) { animation-delay: 0.98s; }
.motion-ready .link-group.is-social .link-item:nth-child(2) { animation-delay: 1.03s; }
.motion-ready .link-group.is-social .link-item:nth-child(3) { animation-delay: 1.08s; }
.motion-ready .link-group.is-social .link-item:nth-child(4) { animation-delay: 1.13s; }
.motion-ready .link-group.is-social .link-item:nth-child(5) { animation-delay: 1.18s; }
.motion-ready .link-group.is-social .link-item:nth-child(6) { animation-delay: 1.23s; }

/* ---------- Status band, when scrolled into view ---------- */

.motion-ready .band-tab {
  animation: dsp-tab-in 1s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.motion-ready .brand-mark {
  animation: dsp-mark-in 1.3s cubic-bezier(0.2, 0.8, 0.2, 1) 0.35s both;
}
.motion-ready .brand-mark-play {
  transform-box: fill-box;
  animation: dsp-play-nudge 3.4s ease-in-out 2.2s infinite;
}
.motion-ready .band-top {
  animation: dsp-wipe 1s cubic-bezier(0.7, 0, 0.2, 1) 0.1s both;
}
.motion-ready .wordmark {
  animation: dsp-wipe 1.15s cubic-bezier(0.7, 0, 0.2, 1) 0.2s both;
}
.motion-ready .stat,
.motion-ready .band-copy {
  animation: dsp-fade-up 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
.motion-ready .stat:nth-child(1) { animation-delay: 0.7s; }
.motion-ready .stat:nth-child(2) { animation-delay: 0.8s; }
.motion-ready .band-copy { animation-delay: 0.9s; }

.motion-ready .wordmark-letter {
  animation:
    dsp-letter-rise 1.3s cubic-bezier(0.16, 1, 0.3, 1) backwards,
    dsp-halftone 4.5s linear infinite;
}
.motion-ready .wordmark-letter:nth-child(1) { animation-delay: 0.55s, 0s; }
.motion-ready .wordmark-letter:nth-child(2) { animation-delay: 0.61s, 0s; }
.motion-ready .wordmark-letter:nth-child(3) { animation-delay: 0.67s, 0s; }
.motion-ready .wordmark-letter:nth-child(4) { animation-delay: 0.73s, 0s; }
.motion-ready .wordmark-letter:nth-child(5) { animation-delay: 0.79s, 0s; }
.motion-ready .wordmark-letter:nth-child(6) { animation-delay: 0.85s, 0s; }
.motion-ready .wordmark-letter:nth-child(7) { animation-delay: 0.91s, 0s; }
.motion-ready .wordmark-letter:nth-child(8) { animation-delay: 0.97s, 0s; }

/* Tickets Solved odometer. scripts/main.js builds these reels inside the locked counter,
   so they never exist in the page source. Sizes follow the Style panel's .stat-value
   through 1lh and tabular figures, so changing the font size there still works. */
.odo {
  display: inline-flex;
  align-items: flex-start;
  vertical-align: top;
}
.odo-digit {
  display: block;
  height: 1lh;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 16%, #000 84%, transparent 100%);
}
.odo-strip {
  display: block;
  will-change: transform;
}
.odo-strip > span,
.odo-sep {
  display: block;
  height: 1lh;
}
.odo-label {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.motion-ready .site-footer {
  animation: dsp-fade 1.2s ease 0.2s both;
}

/* Hold the band and footer until main.js marks them in view. */
.motion-ready .status-band .band-tab,
.motion-ready .status-band .brand-mark,
.motion-ready .status-band .band-top,
.motion-ready .status-band .wordmark,
.motion-ready .status-band .stat,
.motion-ready .status-band .band-copy,
.motion-ready .status-band .wordmark-letter,
.motion-ready .site-footer {
  animation-play-state: paused;
}
.motion-ready .status-band.is-inview .band-tab,
.motion-ready .status-band.is-inview .brand-mark,
.motion-ready .status-band.is-inview .band-top,
.motion-ready .status-band.is-inview .wordmark,
.motion-ready .status-band.is-inview .stat,
.motion-ready .status-band.is-inview .band-copy,
.motion-ready .status-band.is-inview .wordmark-letter,
.motion-ready .site-footer.is-inview {
  animation-play-state: running;
}
