/* Effects a site switches on in config.js (SITE.effects, a list of names). js/effects.js puts html.fx-<name> on the
   page and adds the layers; this file does the rest. Each one is a port from the effects toolbox (tools\effects\,
   the rules in tools\effects-catalogue.md): the source library and component are named on each block. Plain CSS,
   the site's own colours (the --dk-* tokens from desktop.css), no inline styles: the per element numbers (a sparkle's
   place, a tilt angle) arrive as custom properties set from the script. Every motion is off under
   prefers-reduced-motion: the layers that only move are hidden, the rest show their end state.

   The names:  sparkles   tiny stars twinkling over the hero photo            (Aceternity sparkles)
               beams      faint light curves drifting across the hero         (Aceternity background-beams)
               aurora     soft bands of the accent colours moving over the hero (Aceternity aurora-background)
               spotlight  a soft light follows the mouse over the hero         (Aceternity spotlight-new)
               tilt       the photo tiles tilt toward the mouse with a glare   (Aceternity 3d-card)
               glow       a light runs round the edge of the main buttons      (Aceternity moving-border)
               dots       a dot grid texture behind the steps band             (Aceternity grid-and-dot-backgrounds)
   A theme can tune a colour: --fx-sparkle, --fx-beam, --fx-aurora-2, --fx-glow (set them on :root in theme.css). */

/* ---- the hero layers (class fx-layer fxl-<name>): under the words, over the photo. The hero's own gradient (::after,
   z-index -1) paints over them too, so every layer fades out toward the bottom where the words sit. ---- */
.fx-layer{position:absolute;inset:0;z-index:-1;pointer-events:none;overflow:hidden}

/* sparkles: Aceternity sparkles (tsparticles in the source). Each <i> is one star; --x and --y in percent, --s its size in
   pixels, --d the twinkle length, --t its delay. */
.fxl-sparkles i{position:absolute;left:calc(var(--x,50) * 1%);top:calc(var(--y,50) * 1%);width:calc(var(--s,2) * 1px);height:calc(var(--s,2) * 1px);border-radius:50%;background:var(--fx-sparkle,#fff);box-shadow:0 0 calc(var(--s,2) * 3px) 1px var(--fx-sparkle,#fff);opacity:0;transform:scale(.3)}
@media (prefers-reduced-motion:no-preference){
  .fxl-sparkles i{animation:fx-twinkle var(--d,3s) ease-in-out var(--t,0s) infinite}
  @keyframes fx-twinkle{0%,100%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1)}}
}
@media (prefers-reduced-motion:reduce){.fxl-sparkles i{opacity:.55;transform:none}}

/* beams: Aceternity background-beams. The script writes one SVG: a faint web of the curves and fifty beams, each a short
   dash that runs its curve (stroke-dasharray on pathLength 1), fades in and out and repeats. Durations and delays vary
   by nth-child so no two move together. Same port as the landing hero. */
.fxl-beams svg{position:absolute;inset:0;width:100%;height:100%;fill:none}
.fxl-beams path{vector-effect:non-scaling-stroke}
.fxl-beams .web{stroke:var(--fx-beam,var(--dk-paper,#fff));stroke-opacity:.07;stroke-width:.5}
.fxl-beams .beam{stroke:var(--fx-beam,var(--dk-paper,#fff));stroke-opacity:0;stroke-width:1.2;stroke-linecap:round;stroke-dasharray:.09 1;stroke-dashoffset:1}
@media (prefers-reduced-motion:no-preference){
  .fxl-beams .beam{animation:fx-beam 16s linear infinite}
  .fxl-beams .beam:nth-child(5n+2){animation-duration:13s;animation-delay:-4s}
  .fxl-beams .beam:nth-child(5n+3){animation-duration:21s;animation-delay:-11s}
  .fxl-beams .beam:nth-child(5n+4){animation-duration:17s;animation-delay:-2s}
  .fxl-beams .beam:nth-child(5n){animation-duration:24s;animation-delay:-15s}
  .fxl-beams .beam:nth-child(7n+1){animation-delay:-7s}
  .fxl-beams .beam:nth-child(7n+4){animation-delay:-19s}
  .fxl-beams .beam:nth-child(3n+1){animation-duration:19s}
  @keyframes fx-beam{0%{stroke-dashoffset:1;stroke-opacity:0}12%{stroke-opacity:.45}60%{stroke-opacity:.45}100%{stroke-dashoffset:-.09;stroke-opacity:0}}
}
@media (prefers-reduced-motion:reduce){.fxl-beams .beam{display:none}}

/* aurora: Aceternity aurora-background. Two repeating gradients of the accent and a second colour, blurred wide and kept
   faint so they tint the photo instead of covering it, drifting slowly. The photo stays the picture. */
.fxl-aurora{inset:-25%;filter:blur(38px);mix-blend-mode:screen;
  background:
    repeating-linear-gradient(100deg,color-mix(in srgb,var(--dk-accent,#fff) 30%,transparent) 8%,transparent 16%,color-mix(in srgb,var(--fx-aurora-2,#9ad7ff) 30%,transparent) 24%,transparent 32%,color-mix(in srgb,var(--dk-accent,#fff) 30%,transparent) 40%),
    repeating-linear-gradient(100deg,color-mix(in srgb,var(--fx-aurora-2,#9ad7ff) 30%,transparent) 5%,transparent 15%,color-mix(in srgb,var(--dk-accent,#fff) 30%,transparent) 25%,transparent 35%);
  background-size:260% 180%,300% 160%;background-position:50% 50%,30% 60%;
  mask-image:radial-gradient(ellipse at 50% 20%,#000 20%,transparent 75%);-webkit-mask-image:radial-gradient(ellipse at 50% 20%,#000 20%,transparent 75%)}
@media (prefers-reduced-motion:no-preference){
  .fxl-aurora{animation:fx-aurora 28s linear infinite alternate}
  @keyframes fx-aurora{from{background-position:50% 50%,30% 60%}to{background-position:150% 30%,130% 20%}}
}

/* spotlight: Aceternity spotlight-new. A soft radial light at the mouse (--mx, --my in percent, set by the script), shown
   while the mouse is over the hero. Mouse only: a phone never sees it. */
@property --fx-sp{syntax:"<number>";inherits:false;initial-value:0}
.fxl-spotlight{--fx-sp:0;transition:--fx-sp .5s;background:radial-gradient(560px circle at calc(var(--mx,50) * 1%) calc(var(--my,40) * 1%),color-mix(in srgb,var(--dk-paper,#fff) calc(16% * var(--fx-sp)),transparent),color-mix(in srgb,var(--dk-paper,#fff) calc(5% * var(--fx-sp)),transparent) 40%,transparent 70%)}
/* The light fades in through the registered --fx-sp. The layer classes are fxl-<name>, never fx-<name>: that is the
   switch on <html>, and a layer rule that matched <html> once blurred the whole page and once hid it (2026-11-02). */
@media (hover:hover) and (pointer:fine){.desk-hero:hover .fxl-spotlight{--fx-sp:1}}

/* tilt: Aceternity 3d-card. A tile turns toward the mouse (--rx, --ry in degrees from the script), lifts a little, and a
   glare (--gx, --gy in percent) follows the mouse across it. Mouse only, wide screens only: a phone keeps its carousel. */
@media (hover:hover) and (pointer:fine) and (min-width:1000px) and (prefers-reduced-motion:no-preference){
  html.fx-tilt .desk-tile{transform:perspective(1100px) rotateX(calc(var(--ry,0) * 1deg)) rotateY(calc(var(--rx,0) * 1deg)) scale(var(--tz,1));transition:transform .18s ease-out,box-shadow .3s;will-change:transform}
  html.fx-tilt .desk-tile.is-tilting{transition:transform .06s linear;box-shadow:0 24px 50px color-mix(in srgb,var(--dk-ink,#000) 45%,transparent);z-index:2}
  html.fx-tilt .desk-tile::before{content:"";position:absolute;inset:0;z-index:2;pointer-events:none;opacity:0;transition:opacity .35s;background:radial-gradient(circle at calc(var(--gx,50) * 1%) calc(var(--gy,50) * 1%),rgba(255,255,255,.28),rgba(255,255,255,.06) 35%,transparent 60%)}
  html.fx-tilt .desk-tile.is-tilting::before{opacity:1}
}

/* glow: Aceternity moving-border. The main buttons keep their colour in the padding box; the border box carries a conic
   gradient whose angle (--fx-a, a registered property) spins, so one bright point runs round the edge. The ghost button
   stays as it is. */
@property --fx-a{syntax:"<angle>";inherits:false;initial-value:0deg}
html.fx-glow .desk-hero-btn:not(.ghost){border:2px solid transparent;background:linear-gradient(var(--dk-accent),var(--dk-accent)) padding-box,conic-gradient(from var(--fx-a),transparent 0 58%,var(--fx-glow,#fff) 74%,transparent 88%) border-box}
html.fx-glow .desk-hero-btn:not(.ghost)::after{inset:2px}
@media (prefers-reduced-motion:no-preference){
  html.fx-glow .desk-hero-btn:not(.ghost){animation:fx-glow 3.2s linear infinite}
  @keyframes fx-glow{to{--fx-a:360deg}}
}

/* dots: Aceternity grid-and-dot-backgrounds. A dot grid in the band's own text colour, faded out toward the edges. */
html.fx-dots .desk-steps{background-image:radial-gradient(color-mix(in srgb,var(--on-accent,#fff) 24%,transparent) 1.2px,transparent 1.2px);background-size:24px 24px;background-position:12px 12px}
