/* ═══════════════════════════════════════════════════════════════
   Thread Theory — shared motion system (all pages).
   Plain CSS on purpose: NOT part of the Tailwind build, so new
   animation classes here never need `npm run build:css`.
   Loaded BEFORE each page's inline <style> so page rules win ties.
   JS counterpart: motion.js
   ═══════════════════════════════════════════════════════════════ */

/* ── Custom gold cursor (shared; markup: .cursor-ring + .cursor-dot) ── */
@media (hover: hover) and (pointer: fine) {
  body { cursor: none; }
  a, button, input, textarea, .work-item, .tilt-card, .portfolio-item, .filter-pill { cursor: none; }
  .cursor-dot, .cursor-ring {
    position: fixed; top: 0; left: 0;
    border-radius: 9999px;
    pointer-events: none;
    z-index: 9998;
    will-change: transform;
  }
  .cursor-dot {
    width: 6px; height: 6px;
    background: #F0D040;
    box-shadow: 0 0 8px rgba(240,208,64,0.8);
  }
  .cursor-ring {
    width: 36px; height: 36px;
    border: 1px solid rgba(212,165,32,0.7);
    transition: width 0.3s cubic-bezier(0.16,1,0.3,1),
                height 0.3s cubic-bezier(0.16,1,0.3,1),
                background-color 0.3s ease, border-color 0.3s ease;
  }
  .cursor-ring.hover {
    width: 68px; height: 68px;
    background: rgba(212,165,32,0.10);
    border-color: rgba(240,208,64,0.9);
  }
  .cursor-ring.down { width: 28px; height: 28px; }
}
@media (hover: none), (pointer: coarse) {
  .cursor-dot, .cursor-ring { display: none; }
}

/* ── Page-transition loader mark (shared) ── */
.pt-mark {
  width: 58px; height: auto;
  filter: drop-shadow(0 0 14px rgba(240,208,64,0.35));
  animation: pt-pulse 1.6s ease-in-out infinite;
}
@keyframes pt-pulse {
  0%, 100% { opacity: 0.5; transform: scale(0.94); }
  50% { opacity: 1; transform: scale(1.04); }
}
/* Mobile: no pulsing loader (read as flashing on phones) — static logo only */
@media (max-width: 767px) {
  .pt-mark { animation: none; opacity: 1; transform: none; }
}

/* ── M1: Kinetic masked line-rise headlines ──
   Markup: <element data-kinetic> containing .kt-line > .kt-inner pairs.
   Gradient spans live INSIDE .kt-inner and are never transformed. */
.kt-line { display: block; overflow: hidden; }
.kt-inner {
  display: block;
  transform: translateY(112%);
  opacity: 0.001;
  transition: transform 0.95s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-kinetic].kt-go .kt-inner { transform: translateY(0); opacity: 1; }
[data-kinetic] .kt-line:nth-child(2) .kt-inner { transition-delay: 0.09s; }
[data-kinetic] .kt-line:nth-child(3) .kt-inner { transition-delay: 0.18s; }
[data-kinetic] .kt-line:nth-child(4) .kt-inner { transition-delay: 0.27s; }
/* Punctuation pop: the final mark lands after its line settles */
.kt-pop {
  display: inline-block;
  transform: scale(0.4);
  opacity: 0;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.35s ease;
  transition-delay: 0.55s;
}
[data-kinetic].kt-go .kt-pop { transform: scale(1); opacity: 1; }

/* ── M2: Clip-path unveil for portfolio tiles ──
   Double attribute selector beats the pages' [data-reveal]{opacity:0} tie. */
[data-reveal="unveil"][data-reveal] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
  will-change: clip-path;
}
/* img rules kept LOW specificity (0,1,1 / 0,2,1) so each page's
   :hover zoom rules (0,3,0+) always win after reveal */
[data-reveal="unveil"] img {
  transform: scale(1.06);
}
[data-reveal="unveil"][data-reveal].revealed {
  clip-path: inset(0 0 0% 0);
  /* keep transform/opacity transitions so work.html's filter fades still run */
  transition: clip-path 1.05s cubic-bezier(0.16, 1, 0.3, 1),
              transform 0.5s cubic-bezier(0.16, 1, 0.3, 1),
              opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
[data-reveal="unveil"].revealed img {
  transform: scale(1);
  transition: transform 1.2s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ── M4: Services process timeline — line draws, dots ignite ──
   Piggybacks the existing data-reveal `.revealed` on the container. */
.tl-track { position: relative; background: rgba(212,165,32,0.15); }
.tl-fill {
  position: absolute; inset: 0;
  background: linear-gradient(90deg, #F0D040, #D4A520);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1.9s cubic-bezier(0.16, 1, 0.3, 1) 0.15s;
}
.revealed .tl-fill, [data-reveal].revealed ~ * .tl-fill { transform: scaleX(1); }
.tl-dot-wrap {
  display: inline-block;
  transform: scale(1);
  transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.tl-dot {
  display: block;
  width: 12px; height: 12px;
  border-radius: 9999px;
  background: rgba(212,165,32,0.25);
  transition: background-color 0.4s ease, box-shadow 0.4s ease;
}
.tl-num { transition: color 0.4s ease, opacity 0.4s ease; }
/* Ignition cascade — delays matched to the line's arrival at each stop */
.revealed .tl-step:nth-child(1) .tl-dot { transition-delay: 0.35s; }
.revealed .tl-step:nth-child(2) .tl-dot { transition-delay: 0.7s; }
.revealed .tl-step:nth-child(3) .tl-dot { transition-delay: 1.05s; }
.revealed .tl-step:nth-child(4) .tl-dot { transition-delay: 1.4s; }
.revealed .tl-step:nth-child(5) .tl-dot { transition-delay: 1.75s; }
.revealed .tl-step:nth-child(1) .tl-num { transition-delay: 0.35s; }
.revealed .tl-step:nth-child(2) .tl-num { transition-delay: 0.7s; }
.revealed .tl-step:nth-child(3) .tl-num { transition-delay: 1.05s; }
.revealed .tl-step:nth-child(4) .tl-num { transition-delay: 1.4s; }
.revealed .tl-step:nth-child(5) .tl-num { transition-delay: 1.75s; }
.revealed .tl-dot {
  background: #D4A520;
  box-shadow: 0 0 12px rgba(240,208,64,0.7);
}
.revealed .tl-num { color: #D4A520; opacity: 1; }
/* Mobile stacked timeline: short stub under each dot draws on reveal */
.tl-stub {
  width: 2px; height: 2.25rem;
  margin: 0.4rem auto 0;
  background: linear-gradient(180deg, #D4A520, rgba(212,165,32,0.05));
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 0.8s cubic-bezier(0.16, 1, 0.3, 1) 0.3s;
}
[data-reveal].revealed .tl-stub { transform: scaleY(1); }
[data-reveal].revealed .tl-dot {
  background: #D4A520;
  box-shadow: 0 0 12px rgba(240,208,64,0.7);
  transition-delay: 0.25s;
}

/* ── M6: CTA light sweep (overlay injected by motion.js into [data-sweep]) ── */
.cta-sweep {
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,0.14) 50%, transparent 58%);
  transform: translateX(-120%);
  z-index: 1;
}
.cta-sweep.sweep-run {
  transition: transform 1.7s cubic-bezier(0.16, 1, 0.3, 1);
  transform: translateX(120%);
}
@media (max-width: 767px) {
  .cta-sweep {
    background: linear-gradient(105deg, transparent 42%, rgba(255,255,255,0.08) 50%, transparent 58%);
  }
}

/* ── M7: Running timecode chip (injected by motion.js, desktop only) ── */
#tt-timecode {
  position: fixed;
  right: 1.5rem; bottom: 1.25rem;
  z-index: 90;
  pointer-events: none;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.18em;
  font-variant-numeric: tabular-nums;
  color: rgba(255,255,255,0.55);
  background: rgba(14,14,14,0.55);
  border: 1px solid rgba(212,165,32,0.25);
  padding: 0.45rem 0.7rem;
  opacity: 0;
  transition: opacity 0.6s ease;
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}
#tt-timecode .tc-label { color: #D4A520; font-weight: 900; margin-right: 0.5em; }
#tt-timecode.tc-on { opacity: 1; }
#tt-timecode .tc-rec {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 9999px;
  background: #D4A520;
  margin-right: 0.55em;
  vertical-align: 1px;
  animation: tc-blink 1.2s steps(1) infinite;
}
@keyframes tc-blink { 50% { opacity: 0.25; } }
@media (max-width: 1023px) {
  #tt-timecode { display: none; }
}

/* ── M3: Philosophy scrub (index desktop; JS drives filter/transform) ── */
.philo-scrub img { transition: none !important; will-change: transform, filter; }

/* ── M8: Filter enter animation (work.html) ── */
.portfolio-item.entering {
  opacity: 0;
  transform: scale(0.92);
}

/* ── Reduced motion: every system above settles to final state ── */
@media (prefers-reduced-motion: reduce) {
  .pt-mark { animation: none; opacity: 1; transform: none; }
  .kt-inner { transform: none !important; opacity: 1 !important; transition: none !important; }
  .kt-pop { transform: none !important; opacity: 1 !important; transition: none !important; }
  [data-reveal="unveil"][data-reveal] { clip-path: none !important; }
  [data-reveal="unveil"][data-reveal] img { transform: none !important; }
  .tl-fill { transform: scaleX(1) !important; transition: none !important; }
  .tl-stub { transform: scaleY(1) !important; transition: none !important; }
  .tl-dot { background: #D4A520 !important; box-shadow: none !important; transition: none !important; }
  .tl-num { color: #D4A520 !important; opacity: 1 !important; }
  .cta-sweep { display: none !important; }
  #tt-timecode { display: none !important; }
  #tt-timecode .tc-rec { animation: none; }
  .portfolio-item.entering { opacity: 1; transform: none; }
}
