/* =========================================================
   CraftCoding — shared visual layer (fx.css)
   Loaded AFTER each page's inline <style>, so it can refine it.
   Everything here is progressive: no JS / old browser = original look.
   ========================================================= */

:root{
  --fx-ease: cubic-bezier(.2,.8,.2,1);
  --spot-rgb: 155,124,249;           /* violet, overridden per card */
}

/* ---------- 1. Page-to-page transitions (index <-> arsam-802) ---------- */
@view-transition { navigation: auto; }

nav{ view-transition-name: site-nav; }
.feature-logo-link img,
.hero > img{ view-transition-name: arsam-logo; }   /* logo morphs between pages */

::view-transition-old(root){ animation: fx-page-out .26s ease both; }
::view-transition-new(root){ animation: fx-page-in .5s var(--fx-ease) both; }
::view-transition-group(arsam-logo){ animation-duration: .6s; animation-timing-function: var(--fx-ease); }
::view-transition-group(site-nav){ animation-duration: .35s; }

@keyframes fx-page-out{ to{ opacity:0; transform:translateY(-6px) scale(.992); } }
@keyframes fx-page-in { from{ opacity:0; transform:translateY(10px) scale(1.004); } }

/* ---------- 2. Scroll progress ---------- */
#fx-progress{
  position:fixed; top:0; left:0; width:100%; height:2px; z-index:60;
  transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg,var(--violet),var(--cyan));
  box-shadow:0 0 12px rgba(155,124,249,.55);
  pointer-events:none;
}
html[dir="rtl"] #fx-progress{ transform-origin:100% 50%; }

/* ---------- 3. Living background: aurora + cursor glow ---------- */
.fx-aurora{ position:fixed; inset:0; z-index:0; overflow:hidden; pointer-events:none; }
.fx-aurora i{
  position:absolute; width:62vmax; height:62vmax; border-radius:50%;
  mix-blend-mode:screen; opacity:.55; will-change:transform;
}
.fx-aurora i:nth-child(1){
  left:-18vmax; top:-22vmax;
  background:radial-gradient(closest-side, rgba(155,124,249,.42), transparent 70%);
  animation:fx-drift-a 26s ease-in-out infinite alternate;
}
.fx-aurora i:nth-child(2){
  right:-24vmax; top:12vmax;
  background:radial-gradient(closest-side, rgba(65,224,214,.28), transparent 70%);
  animation:fx-drift-b 32s ease-in-out infinite alternate;
}
.fx-aurora i:nth-child(3){
  left:12vmax; bottom:-34vmax;
  background:radial-gradient(closest-side, rgba(76,141,246,.30), transparent 70%);
  animation:fx-drift-c 38s ease-in-out infinite alternate;
}
@keyframes fx-drift-a{ to{ transform:translate3d(14vmax,10vmax,0) scale(1.15); } }
@keyframes fx-drift-b{ to{ transform:translate3d(-16vmax,8vmax,0) scale(.9); } }
@keyframes fx-drift-c{ to{ transform:translate3d(10vmax,-12vmax,0) scale(1.1); } }

.fx-cursor{
  position:fixed; left:0; top:0; z-index:1; width:520px; height:520px; margin:-260px 0 0 -260px;
  border-radius:50%; pointer-events:none; opacity:0; will-change:transform;
  background:radial-gradient(closest-side, rgba(155,124,249,.16), rgba(65,224,214,.05) 55%, transparent 72%);
  transition:opacity .6s ease;
}
.fx-cursor.on{ opacity:1; }

/* ---------- 4. The hero moment: headline rises word by word ---------- */
html.js .hero h1{ visibility:hidden; animation:fx-unhide 0s linear 1.4s forwards; }  /* failsafe if JS fails */
html.js .hero h1.fx-words{ visibility:visible; animation:none; }
@keyframes fx-unhide{ to{ visibility:visible; } }

.fx-words .w{
  display:inline-block; overflow:hidden; vertical-align:bottom;
  padding:.06em .02em .16em; margin:-.06em -.02em -.16em;
}
.fx-words .w > span{
  display:inline-block; transform:translateY(112%);
  animation:fx-rise 1s var(--fx-ease) forwards;
  animation-delay:calc(var(--i) * 75ms + 160ms);
}
@keyframes fx-rise{ to{ transform:none; } }

/* hero supporting lines follow the headline, once */
html.js .hero .eyebrow,
html.js .hero p,
html.js .hero .actions,
html.js .hero > img{
  opacity:0; transform:translateY(14px);
  animation:fx-fade-up .9s var(--fx-ease) forwards;
}
html.js .hero > img{ animation-delay:.05s; }
html.js .hero .eyebrow{ animation-delay:.05s; }
html.js .hero p{ animation-delay:.75s; }
html.js .hero .actions{ animation-delay:.9s; }
@keyframes fx-fade-up{ to{ opacity:1; transform:none; } }

/* rotating word: smooth swap instead of a hard flicker */
#rot{ transition:opacity .18s ease, filter .18s ease, transform .18s ease; }
#rot.swap{ opacity:0; filter:blur(6px); transform:translateY(4px); }

/* ---------- 5. Navigation ---------- */
nav{ transition:background .35s ease, border-color .35s ease, box-shadow .35s ease; }
nav.scrolled{
  background:rgba(7,8,12,.86);
  border-bottom-color:rgba(255,255,255,.12);
  box-shadow:0 10px 30px -18px rgba(0,0,0,.8);
}
nav .links a{ position:relative; transition:color .25s ease; padding:4px 0; }
nav .links a::after{
  content:""; position:absolute; left:0; right:0; bottom:-2px; height:1px;
  background:linear-gradient(90deg,var(--violet),var(--cyan));
  transform:scaleX(0); transform-origin:left; transition:transform .35s var(--fx-ease);
}
nav .links a:hover::after,
nav .links a.active::after{ transform:scaleX(1); }
nav .links a.active{ color:var(--ink); }

/* ---------- 6. Buttons ---------- */
.btn, nav .cta{ position:relative; overflow:hidden; isolation:isolate; }
.btn::after, nav .cta::after{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:linear-gradient(105deg, transparent 30%, rgba(255,255,255,.28) 50%, transparent 70%);
  transform:translateX(-120%); transition:transform .7s var(--fx-ease);
}
.btn:hover::after, nav .cta:hover::after{ transform:translateX(120%); }
.btn.primary{ box-shadow:0 8px 28px -10px rgba(155,124,249,.7); transition:transform .2s ease, opacity .2s ease, box-shadow .3s ease; }
.btn.primary:hover{ box-shadow:0 12px 34px -8px rgba(155,124,249,.9); }
.btn:active, nav .cta:active{ transform:scale(.97); }

a:focus-visible, .btn:focus-visible{ outline:2px solid var(--cyan); outline-offset:3px; border-radius:8px; }

/* ---------- 7. Spotlight cards (ported from the 21st "Spotlight Card" idea) ----------
   A soft light + glowing border that follow the pointer, per card. */
[data-spot]{ position:relative; isolation:isolate; --mx:50%; --my:50%; }
[data-spot]::before,
[data-spot]::after{
  content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  opacity:0; transition:opacity .4s ease;
}
[data-spot]::before{            /* glowing border ring */
  padding:1px;
  background:radial-gradient(280px circle at var(--mx) var(--my), rgba(var(--spot-rgb),.95), rgba(var(--spot-rgb),.0) 70%);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor; mask-composite:exclude;
}
[data-spot]::after{             /* inner wash of light */
  z-index:-1;
  background:radial-gradient(420px circle at var(--mx) var(--my), rgba(var(--spot-rgb),.11), transparent 70%);
}
[data-spot]:hover::before, [data-spot]:hover::after{ opacity:1; }
[data-spot]{ transition:transform .45s var(--fx-ease), border-color .3s ease; }
@media (hover:hover) and (pointer:fine){
  .card[data-spot]:hover, .plate[data-spot]:hover{ transform:translateY(-3px); }
  .cat[data-spot]:hover{ transform:translateY(-2px); }
}

/* per-colour glow for the Persian page's categories */
.cat.c1{ --spot-rgb:155,124,249; }
.cat.c2{ --spot-rgb:80,220,140; }
.cat.c3{ --spot-rgb:76,141,246; }
.cat.c4{ --spot-rgb:246,111,176; }
.cat.c5{ --spot-rgb:245,197,66; }
.cat.c6{ --spot-rgb:65,224,214; }

/* ---------- 8. Logo tilt (index) ---------- */
.feature-logo-link{ perspective:800px; }
.feature-logo-link img{
  transition:transform .5s var(--fx-ease), filter .4s ease;
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
  will-change:transform;
  filter:drop-shadow(0 18px 40px rgba(155,124,249,.28));
}
.feature-logo-link:hover{ transform:none; }
.feature-logo-link:hover img{ filter:drop-shadow(0 24px 54px rgba(155,124,249,.5)); }
.feature-logo-link.tilting img{ transition:transform .08s linear, filter .4s ease; }

/* ---------- 9. "How we work": the list lights up as you read it ---------- */
html.js .step{ position:relative; }
html.js .step h3, html.js .step p, html.js .step .num{ transition:opacity .5s ease, color .5s ease; }
html.js .step:not(.is-active) h3,
html.js .step:not(.is-active) p{ opacity:.42; }
html.js .step:not(.is-active) .num{ opacity:.5; }
html.js .step.is-active .num{ color:var(--cyan); }
html.js .step::after{
  content:""; position:absolute; left:0; right:0; top:-1px; height:1px;
  background:linear-gradient(90deg,var(--violet),var(--cyan));
  transform:scaleX(0); transform-origin:left; transition:transform 1s var(--fx-ease);
}
html.js .step.is-active::after{ transform:scaleX(1); }

/* ---------- 10. Tech stack marquee (index) ---------- */
.marquee{
  margin-top:20px; overflow:hidden; position:relative;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
}
.marquee-track{ display:flex; width:max-content; animation:fx-marquee 34s linear infinite; }
.marquee:hover .marquee-track{ animation-play-state:paused; }
.marquee-set{ display:flex; gap:10px; padding-inline-end:10px; }
.marquee-set span{
  font-family:'JetBrains Mono',ui-monospace,monospace; font-size:.8rem; color:var(--ink);
  border:1px solid var(--panel-line); padding:6px 14px; border-radius:6px; white-space:nowrap;
  background:rgba(255,255,255,.03); transition:border-color .25s ease, color .25s ease;
}
.marquee-set span:hover{ border-color:var(--violet); color:#fff; }
@keyframes fx-marquee{ to{ transform:translateX(-50%); } }

/* ---------- 11. Persian page: icons draw themselves once ---------- */
html.js .cat .icon svg :is(path,circle,rect,line,polyline,ellipse){
  stroke-dasharray:1; stroke-dashoffset:1;
  transition:stroke-dashoffset 1.3s var(--fx-ease);
  transition-delay:calc(var(--d, 0) * 110ms + 150ms);
}
html.js .cat.is-drawn .icon svg :is(path,circle,rect,line,polyline,ellipse){ stroke-dashoffset:0; }
.cat .icon{ transition:background .4s ease, transform .5s var(--fx-ease); }
.cat:hover .icon{ background:rgba(255,255,255,.085); transform:rotate(-3deg) scale(1.04); }

/* ---------- 12. Accessibility & performance ---------- */
@media (hover:none), (pointer:coarse){
  .fx-cursor{ display:none; }
}
@media (max-width:640px){
  .fx-aurora i{ width:90vmax; height:90vmax; opacity:.45; }
  .marquee-track{ animation-duration:26s; }
}
@media (prefers-reduced-motion: reduce){
  ::view-transition-old(root), ::view-transition-new(root), ::view-transition-group(*){ animation:none !important; }
  .fx-aurora i, .marquee-track{ animation:none !important; }
  .fx-cursor{ display:none; }
  html.js .hero h1{ visibility:visible; animation:none; }
  .fx-words .w > span{ transform:none; animation:none; }
  html.js .hero .eyebrow, html.js .hero p, html.js .hero .actions, html.js .hero > img{ opacity:1; transform:none; animation:none; }
  html.js .cat .icon svg :is(path,circle,rect,line,polyline,ellipse){ stroke-dashoffset:0; transition:none; }
  html.js .step:not(.is-active) h3, html.js .step:not(.is-active) p, html.js .step:not(.is-active) .num{ opacity:1; }
  .btn::after, nav .cta::after{ display:none; }
  [data-spot]{ transition:none; }
}
