/* Motion layer styles (pairs with js/fx.js). Uses only Knowura tokens. */

/* ---------- boot loader ---------- */
.loader { display: none; }
.is-loading .loader {
  position: fixed; inset: 0; z-index: 300;
  display: grid; grid-template-rows: 1fr auto; padding: 28px;
  color: var(--text); background: var(--dark);
  transition: clip-path 0.75s cubic-bezier(0.76, 0, 0.24, 1);
  clip-path: inset(0 0 0 0);
}
.is-loading { overflow: hidden; }
.loader-out .loader { clip-path: inset(0 0 100% 0); }
.loader-skip { position: absolute; top: 20px; right: 20px; z-index: 2; min-width: 88px; min-height: 48px; justify-content: center; }
.loader-log { list-style: none; margin: 0; padding: 0; font-size: 15px; color: var(--text-dim); align-self: start; }
.loader-log li { opacity: 0.15; transition: opacity 0.2s; }
.loader-log li.on { opacity: 1; }
.loader-log li.on::before { content: '[ok] '; color: var(--cyan); }
.loader-num {
  font-size: min(38vw, 48vh); line-height: 0.82; letter-spacing: -0.04em;
  color: var(--text); text-shadow: 8px 8px 0 var(--ink);
}
.loader-num::after { content: '%'; font-size: 0.25em; color: var(--cyan); text-shadow: none; }
.loader-bar { height: 10px; margin-top: 18px; border: 3px solid var(--ink); background: var(--panel-strong); box-shadow: var(--shadow-sm); }
.loader-bar i { display: block; height: 100%; background: var(--cyan); transform: scaleX(0); transform-origin: left; box-shadow: 0 0 18px var(--cyan); }

/* ---------- hero intro ---------- */
html.js:not(.is-intro) .tag,
html.js:not(.is-intro) .star,
html.js:not(.is-intro) .hero-copy > :not(.eyebrow) { opacity: 0; }
html.js:not(.is-intro) .hero-copy > .eyebrow { clip-path: inset(0 100% 0 0); }

.is-intro .tag-uday { animation: tagInU 1s cubic-bezier(0.2, 1.5, 0.35, 1) 0.05s both; }
.is-intro .tag-singh { animation: tagInS 1s cubic-bezier(0.2, 1.5, 0.35, 1) 0.22s both; }
@keyframes tagInU { from { opacity: 0; transform: translateY(-160px) rotate(-24deg) scale(0.6); } to { opacity: 1; transform: rotate(-5deg); } }
@keyframes tagInS { from { opacity: 0; transform: translateY(160px) rotate(20deg) scale(0.6); } to { opacity: 1; transform: rotate(3.5deg); } }
.is-intro .star { animation: starIn 0.8s cubic-bezier(0.2, 1.6, 0.4, 1) calc(0.35s + var(--t) * 0.2) both, twinkle 3.4s ease-in-out calc(var(--t) + 1.2s) infinite; }
@keyframes starIn { from { opacity: 0; transform: scale(0) rotate(-180deg); } to { opacity: 1; transform: scale(1) rotate(0deg); } }
.is-intro .hero-copy > * { animation: riseIn 0.9s cubic-bezier(0.2, 0.8, 0.2, 1) both; }
.is-intro .hero-copy > .eyebrow { animation: wipeIn 0.8s cubic-bezier(0.76, 0, 0.24, 1) 0.45s both; }
@keyframes wipeIn { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 -20px -20px 0); } }
.is-intro .hero-copy > :nth-child(2) { animation-delay: 0.58s; }
.is-intro .hero-copy > :nth-child(3) { animation-delay: 0.71s; }
@keyframes riseIn { from { opacity: 0; transform: translateY(40px); filter: blur(6px); } to { opacity: 1; transform: none; filter: none; } }

/* mouse parallax on the whole name stack */
.name-stack { translate: var(--px, 0) var(--py, 0); transition: translate 0.6s cubic-bezier(0.2, 0.8, 0.2, 1); }

/* ---------- scroll progress + nav ---------- */
.scroll-progress {
  position: fixed; top: 0; left: 0; right: 0; height: 4px; z-index: 60;
  background: var(--cyan); box-shadow: 0 0 14px var(--cyan);
  transform: scaleX(0); transform-origin: left; pointer-events: none;
}
.nav { transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1); }
.nav.nav-hidden { transform: translateY(-110%); }

/* ---------- custom cursor ---------- */
.has-cursor, .has-cursor a, .has-cursor button, .has-cursor [data-cursor] { cursor: none; }
.has-cursor input, .has-cursor textarea { cursor: text; }
.cursor-dot, .cursor-ring { position: fixed; top: 0; left: 0; z-index: 400; pointer-events: none; opacity: 0; transition: opacity 0.3s; }
.cursor-on .cursor-dot, .cursor-on .cursor-ring { opacity: 1; }
.cursor-dot { width: 8px; height: 8px; margin: -4px 0 0 -4px; background: var(--cyan); box-shadow: 0 0 10px var(--cyan); }
.cursor-ring {
  width: 38px; height: 38px; translate: -50% -50%;
  display: grid; place-items: center;
  border: 2px solid var(--cyan); border-radius: 10px;
  transition: opacity 0.3s, width 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), height 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), background 0.3s, border-radius 0.3s, border-color 0.3s;
}
.cursor-ring span { font-size: 13px; letter-spacing: 0.08em; color: var(--ink); opacity: 0; transition: opacity 0.2s; white-space: nowrap; }
.cursor-ring.is-hover { width: 58px; height: 58px; border-radius: 50%; background: rgba(34, 229, 255, 0.12); }
.cursor-ring.has-label { width: 92px; height: 92px; background: var(--cyan); border-color: var(--ink); box-shadow: var(--shadow-sm); }
.cursor-ring.has-label span { opacity: 1; }
.cursor-ring.is-text { width: 4px; height: 34px; border-radius: 2px; background: var(--cyan); }
.cursor-ring.is-down { width: 26px; height: 26px; }

/* magnetic buttons: keep the reference hover lift, add the pull */
.btn.magnetic { transform: translate(var(--mx, 0px), var(--my, 0px)); transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.12s ease, background 0.12s ease; }
.btn.magnetic:hover { transform: translate(calc(var(--mx, 0px) - 2px), calc(var(--my, 0px) - 2px)); }

/* ---------- project panels: clip reveal, tilt, glare ---------- */
.project { position: relative; transition: transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1); transform-style: preserve-3d; }
.project.is-tilting { transition: transform 0.12s linear; }
.project::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(600px circle at var(--gx, 50%) var(--gy, 50%), rgba(34, 229, 255, 0.13), transparent 45%);
  opacity: 0; transition: opacity 0.4s;
}
.project.is-tilting::after { opacity: 1; }
.js-reveal .project.reveal { opacity: 1; translate: 0 80px; clip-path: inset(18% 10% 18% 10% round 20px); transition: translate 1s cubic-bezier(0.2, 0.8, 0.2, 1), clip-path 1.1s cubic-bezier(0.76, 0, 0.24, 1), transform 0.7s cubic-bezier(0.2, 0.8, 0.2, 1); }
.js-reveal .project.reveal.in { translate: 0 0; clip-path: inset(-40px -40px -40px -40px round 20px); }
.project .kicker, .project h3, .project-copy > p, .project .features, .project .tags, .project-copy .btn, .project .badge { transition: opacity 0.8s, translate 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); }
.js-reveal .project.reveal:not(.in) :is(.kicker, h3, .project-copy > p, .features, .tags, .btn, .badge) { opacity: 0; translate: 0 30px; }
.project.in h3 { transition-delay: 0.25s; } .project.in .project-copy > p { transition-delay: 0.35s; }
.project.in .tags { transition-delay: 0.45s; } .project.in :is(.btn, .badge) { transition-delay: 0.55s; }
.project h3 { text-shadow: none; filter: drop-shadow(3px 3px 0 var(--ink)); background: linear-gradient(90deg, var(--text) 0 50%, var(--cyan) 50% 100%) 0 0 / 200% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; transition: background-position 0.6s cubic-bezier(0.76, 0, 0.24, 1), opacity 0.8s, translate 0.8s; }
.project:hover h3 { background-position: -100% 0; }

/* ---------- section titles ---------- */
.section-title { position: relative; display: inline-block; }
.section-title::after { content: ''; display: block; height: 6px; margin-top: 10px; background: var(--cyan); border: 2px solid var(--ink); box-shadow: var(--shadow-sm); transform: scaleX(0); transform-origin: left; transition: transform 1s cubic-bezier(0.76, 0, 0.24, 1) 0.2s; }
.section-title.seen::after { transform: scaleX(1); }

/* tags pop in */
.js-reveal .reveal:not(.in) .tag-chip { opacity: 0; transform: scale(0.6); }
.tag-chip { transition: opacity 0.4s, transform 0.5s cubic-bezier(0.2, 1.6, 0.4, 1), background 0.2s; }
.reveal.in .tag-chip:nth-child(2) { transition-delay: 0.06s; } .reveal.in .tag-chip:nth-child(3) { transition-delay: 0.12s; }
.reveal.in .tag-chip:nth-child(4) { transition-delay: 0.18s; } .reveal.in .tag-chip:nth-child(5) { transition-delay: 0.24s; }
.tag-chip:hover { background: rgba(47, 107, 255, 0.3); }

/* ---------- marquees ---------- */
.marquee {
  position: relative; z-index: 1; overflow: hidden; white-space: nowrap;
  padding: 14px 0; border-block: 3px solid var(--ink); background: var(--cyan); color: var(--ink);
  transform: rotate(-2deg) scale(1.04); box-shadow: 0 8px 0 var(--ink);
}
.mq-track { display: inline-flex; align-items: center; gap: 28px; will-change: transform; }
.mq-item { font-size: clamp(26px, 4vw, 48px); line-height: 1; text-transform: uppercase; letter-spacing: 0.02em; }
.mq-star { width: 0.9em; height: 0.9em; font-size: clamp(26px, 4vw, 48px); flex: none; }
.mq-a { margin: 30px 0 10px; }
.mq-cross { position: relative; height: clamp(170px, 20vw, 240px); margin: 40px 0 0; overflow: hidden; }
.mq-cross .marquee { position: absolute; left: -5%; right: -5%; top: 50%; }
.mq-b { background: var(--blue); color: var(--text); transform: translateY(-50%) rotate(4deg); }
.mq-b .mq-item { text-shadow: 3px 3px 0 var(--ink); }
.mq-c { background: var(--dark); color: var(--cyan); transform: translateY(-50%) rotate(-4deg); }

/* ---------- timeline draws itself ---------- */
.timeline::before { transform: scaleY(var(--draw, 0)); transform-origin: top; transition: transform 0.1s linear; box-shadow: 0 0 14px var(--blue); }
.timeline li::after { transition: transform 0.5s cubic-bezier(0.2, 1.6, 0.4, 1) 0.15s, box-shadow 0.4s; }
.js-reveal .timeline li.reveal:not(.in)::after { transform: scale(0) rotate(45deg); }
.timeline li.in::after { box-shadow: 0 0 16px var(--cyan); }
.tl-card { transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.3s; }
.tl-card:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-lg); }

/* ---------- quotes: words light up while scrolling ---------- */
.quote p .w { opacity: 0.18; transition: opacity 0.35s, color 0.35s, text-shadow 0.35s; }
.quote p .w.lit { opacity: 1; }
.quote p .w.lit:last-child { color: var(--cyan); text-shadow: 0 0 18px rgba(34, 229, 255, 0.6); }
.quote { transition: transform 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); }
.quote:hover { transform: scale(1.02); }

/* ---------- mega footer ---------- */
.mega {
  display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: center;
  margin: 0 0 32px; font-size: clamp(54px, 13vw, 200px); line-height: 1; text-decoration: none;
  color: transparent; -webkit-text-stroke: 2px var(--text-dim);
}
.mega .ch { display: inline-block; transition: color 0.25s, -webkit-text-stroke-color 0.25s, transform 0.4s cubic-bezier(0.2, 1.6, 0.4, 1); }
.mega:hover .ch { color: var(--cyan); -webkit-text-stroke-color: var(--ink); text-shadow: 6px 6px 0 var(--ink); animation: wave 0.7s cubic-bezier(0.2, 0.8, 0.2, 1) calc(var(--i) * 40ms); }
.mega .ch:hover { transform: translateY(-12px) rotate(-6deg); }
@keyframes wave { 40% { transform: translateY(-22px); } }
.mega-star { width: 0.6em; height: 0.6em; margin-left: 0.15em; color: var(--cyan); filter: drop-shadow(0 0 16px var(--cyan)); animation: spin 6s linear infinite; }
.footer { padding-top: 80px; }

/* ---------- reduced motion: keep it calm ---------- */
@media (prefers-reduced-motion: reduce) {
  .mega-star, .mq-track { animation: none; }
  .quote p .w { opacity: 1; }
  .js-reveal .project.reveal { clip-path: none; translate: 0 0; }
  .nav, .name-stack { transition: none; }
  /* the hero name, stars and copy just appear (no drop-in / spin-in / rise-in) */
  .is-intro .tag, .is-intro .star, .is-intro .hero-copy > *, .is-intro .hero-copy > .eyebrow { animation: none; opacity: 1; filter: none; clip-path: none; }
  .mq-track { transform: none !important; }
  .loader-num, .loader-bar i { transition: none; }
}

@media (max-width: 640px) {
  .mq-cross { height: 230px; }
  .mq-b { transform: translateY(-50%) rotate(9deg); }
  .mq-c { transform: translateY(-50%) rotate(-9deg); }
}

/* inside a live Knowura frame the real cursor takes over (the page can't see the mouse over an iframe) */
.has-cursor:has(.browser.is-live) :is(.cursor-dot, .cursor-ring) { opacity: 0 !important; }
.has-cursor .browser.is-live, .has-cursor .browser.is-live * { cursor: auto; }

/* ---------- ocean background ---------- */
/* Performance: the glass panels blur whatever is behind them every frame, so a moving background makes the
   whole page lag. The water therefore drifts only while you are at the top of the page and freezes once you
   scroll (.is-scrolled, set in fx.js). One layer, compositor-only transform, no parallax, no blend modes. */
.ocean { position: fixed; inset: 0; z-index: -2; overflow: hidden; pointer-events: none; background: var(--dark); contain: strict; }
.ocean i {
  position: absolute; inset: -4%;
  background: url('../assets/ocean-bg.webp') center / cover no-repeat;
  will-change: transform;
  animation: swell 40s ease-in-out infinite alternate;
}
@keyframes swell { from { transform: scale(1.02) translate3d(-2%, 0.5%, 0); } to { transform: scale(1.1) translate3d(2%, -1.5%, 0); } }
.is-scrolled .ocean i { animation-play-state: paused; will-change: auto; }
@media (max-width: 860px), (pointer: coarse) { .ocean i { animation: none; background-image: url('../assets/ocean-bg-sm.webp'); } } /* phones: 24 KB version */
@media (prefers-reduced-motion: reduce) { .ocean i { animation: none; } }

/* readability over the water */
.hero .tagline, .eyebrow, .section-title, .about-card p { text-shadow: 0 2px 14px rgba(0, 0, 0, 0.75); }
