/* SBL fx.css: styles for data-fx effects (see /_docs/INTERACTIONS.md). Owner: fx agent.
   Colours come only from core tokens. Every hidden-until-animated state is added by JS,
   so content is visible without JS and under reduced motion. */

@property --fx-r { syntax: '<percentage>'; inherits: false; initial-value: 0%; }

:root {
  --fx-dir: 1;
  --fx-ease: cubic-bezier(.16, 1, .3, 1);
  --fx-ease-io: cubic-bezier(.65, 0, .35, 1);
  --fx-spot-fill: color-mix(in srgb, var(--ink) 5%, transparent);
  --fx-spot-edge: color-mix(in srgb, var(--ink) 50%, transparent);
  --fx-sheen: color-mix(in srgb, var(--surface) 62%, transparent);
  --fx-mono: var(--photo-filter, grayscale(1));
  --fx-color: var(--photo-filter-on, none);
}
:root[dir="rtl"] { --fx-dir: -1; }
:root[data-theme="dark"] {
  --fx-spot-fill: color-mix(in srgb, var(--accent) 13%, transparent);
  --fx-spot-edge: var(--accent);
  --fx-sheen: color-mix(in srgb, var(--accent) 36%, transparent);
}

.fx-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* 1. spotlight */
.fx-spot { position: relative; isolation: isolate; }
.fx-spot__l {
  position: absolute; inset: 0; z-index: -1; border-radius: inherit; pointer-events: none;
  --mx: 50%; --my: 0%;
}
.fx-spot__l::before, .fx-spot__l::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; opacity: 0;
  transition: opacity .45s var(--fx-ease);
}
.fx-spot__l::before {
  background: radial-gradient(var(--fx-spot-r, 440px) circle at var(--mx) var(--my), var(--fx-spot-fill), transparent 70%);
}
.fx-spot__l::after {
  padding: 1px;
  background: radial-gradient(var(--fx-edge-r, 280px) circle at var(--mx) var(--my), var(--fx-spot-edge), transparent 72%);
  -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
}
.fx-spot:hover > .fx-spot__l::before, .fx-spot:focus-within > .fx-spot__l::before,
.fx-spot:hover > .fx-spot__l::after, .fx-spot:focus-within > .fx-spot__l::after,
.fx-spot-grid.is-lit .fx-spot__l::after { opacity: 1; }
.touch .fx-spot__l::after { opacity: .5; }

/* 2. tilt */
.fx-tilt { position: relative; transform-style: preserve-3d; }
.fx-tilt.is-tilt { will-change: transform; }
.fx-tilt__shine {
  position: absolute; inset: 0; border-radius: inherit; overflow: hidden; pointer-events: none; z-index: 2;
  opacity: 0; transition: opacity .5s var(--fx-ease); --sx: 0%; --sy: 0%;
}
.fx-tilt__shine::before {
  content: ""; position: absolute; inset: -50%;
  background: radial-gradient(closest-side, var(--fx-sheen), transparent);
  transform: translate3d(var(--sx), var(--sy), 0);
}
.fx-tilt.is-tilt > .fx-tilt__shine { opacity: .7; }

/* 4. colorize */
.fx-colorize { position: relative; isolation: isolate; }
.fx-colorize img { filter: var(--fx-mono); }
.fx-colorize__color {
  position: absolute; inset: 0; pointer-events: none;
  clip-path: circle(var(--fx-r) at var(--cx, 50%) var(--cy, 50%));
  transition: --fx-r 1.15s var(--fx-ease);
}
.fx-colorize__color > *, .fx-colorize__color img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fx-colorize .fx-colorize__color img { filter: var(--fx-color); }
.fx-colorize.is-hot .fx-colorize__color { --fx-r: 150%; transition-duration: 1.4s; }
.fx-colorize.is-color .fx-colorize__color,
.fx-colorize:focus-within .fx-colorize__color,
:focus-visible > .fx-colorize .fx-colorize__color { --fx-r: 150%; }
.reduced .fx-colorize__color { clip-path: none; opacity: 0; transition: opacity .4s; }
.reduced .fx-colorize.is-color .fx-colorize__color, .reduced .fx-colorize:hover .fx-colorize__color { opacity: 1; }

/* 5. split: masks get room for Arabic marks and Latin descenders. 6 kashida, 7 parallax: no CSS */
.fx-line-mask { padding-block: .12em; margin-block: -.12em; }
/* Arabic script: joined glyphs and Nastaliq swashes overhang the line box */
:is(:lang(ar), :lang(ur)) .fx-line-mask { padding-inline: .3em; margin-inline: -.3em; padding-block: .25em; margin-block: -.25em; }

/* 8. marquee */
.fx-marquee {
  display: flex; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, black 7%, black 93%, transparent);
  mask-image: linear-gradient(90deg, transparent, black 7%, black 93%, transparent);
}
.fx-marquee__rail { display: flex; flex: none; width: max-content; will-change: transform; }
.fx-marquee__track {
  display: flex; flex: none; align-items: center; margin: 0; list-style: none;
  gap: var(--fx-gap, 3rem); padding-inline: 0 var(--fx-gap, 3rem);
}
.reduced .fx-marquee { overflow-x: auto; -webkit-mask-image: none; mask-image: none; }

/* 9. drag rail */
.fx-drag {
  display: grid; grid-auto-flow: column; grid-auto-columns: var(--fx-card, min(78vw, 380px));
  gap: var(--fx-gap, 1rem); overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scrollbar-width: none; padding-block-end: 2px;
}
.fx-drag::-webkit-scrollbar { display: none; }
.fx-drag > * { scroll-snap-align: start; }
.fx-drag.is-gliding { scroll-snap-type: none; }
html:not(.touch) .fx-drag { cursor: grab; }
html:not(.touch) .fx-drag.is-grab { cursor: grabbing; user-select: none; }
.fx-drag.is-grab img { pointer-events: none; }
.fx-drag:focus-visible { outline: 2px solid var(--accent); outline-offset: 6px; }
.fx-drag__bar { height: 2px; margin-block-start: 1.25rem; background: var(--line); overflow: hidden; }
.fx-drag__bar span { display: block; height: 100%; background: var(--ink); transform-origin: 0 50%; transform: scaleX(0); }
[dir="rtl"] .fx-drag__bar span { transform-origin: 100% 50%; }
[data-theme="dark"] .fx-drag__bar span { background: var(--glow); }

/* 10. compare */
.fx-compare { position: relative; overflow: hidden; container-type: inline-size; --v: 50; user-select: none; }
.fx-compare > :first-child { display: block; width: 100%; }
.fx-compare__after {
  position: absolute; inset: 0; width: 100%; height: 100%;
  clip-path: inset(0 0 0 calc(var(--v) * 1%));
}
[dir="rtl"] .fx-compare__after { clip-path: inset(0 calc(var(--v) * 1%) 0 0); }
.fx-compare__after img, .fx-compare > :first-child img { display: block; width: 100%; height: 100%; object-fit: cover; }
.fx-compare__handle {
  position: absolute; inset-block: 0; inset-inline-start: 0; width: 2px; margin-inline-start: -1px; z-index: 2;
  background: var(--surface); pointer-events: none;
  translate: calc(var(--fx-dir) * var(--v) * 1cqi) 0;
}
.fx-compare__knob {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%; width: 46px; height: 46px;
  translate: calc(var(--fx-dir) * -50%) -50%; border-radius: 50%; direction: ltr;
  background: var(--btn-bg); box-shadow: var(--shadow-2);
}
.fx-compare__knob::before, .fx-compare__knob::after {
  content: ""; position: absolute; inset-block-start: 50%; width: 7px; height: 7px;
  border: solid var(--btn-ink); border-width: 0 0 1.5px 1.5px; translate: 0 -50%;
}
.fx-compare__knob::before { inset-inline-start: 13px; rotate: 45deg; }
.fx-compare__knob::after { inset-inline-end: 13px; rotate: -135deg; }
.fx-compare__range {
  position: absolute; inset: 0; z-index: 3; width: 100%; height: 100%; margin: 0;
  opacity: 0; cursor: ew-resize; -webkit-appearance: none; appearance: none; background: none; touch-action: pan-y;
}
.fx-compare__range::-webkit-slider-thumb { -webkit-appearance: none; width: 48px; height: 48px; }
.fx-compare__range::-moz-range-thumb { width: 48px; height: 48px; border: 0; }
.fx-compare__range:focus-visible + .fx-compare__handle .fx-compare__knob { outline: 2px solid var(--accent); outline-offset: 3px; }
.fx-compare__tag {
  position: absolute; inset-block-end: 12px; z-index: 2; padding: 4px 8px; border-radius: 2px;
  font: 500 11px/1.2 var(--f-mono, ui-monospace, monospace); letter-spacing: .06em; text-transform: uppercase;
  background: var(--surface); color: var(--ink); pointer-events: none;
}
.fx-compare__tag--before { inset-inline-start: 12px; }
.fx-compare__tag--after { inset-inline-end: 12px; }

/* 11. lens */
.fx-lens-host { position: relative; overflow: hidden; cursor: crosshair; }
.fx-lens {
  position: absolute; direction: ltr; inset-block-start: 0; inset-inline-start: 0; z-index: 4;
  width: var(--fx-lens, 190px); aspect-ratio: 1; border-radius: 50%; overflow: hidden; pointer-events: none;
  background: var(--surface); box-shadow: 0 0 0 1px var(--line-2), var(--shadow-2);
  opacity: 0; transition: opacity .25s var(--fx-ease);
}
.fx-lens-host.is-lens .fx-lens { opacity: 1; }
.fx-lens img { position: absolute; inset-block-start: 0; inset-inline-start: 0; max-width: none; box-sizing: border-box; }

/* 12. scramble */
.fx-scramble { font-variant-numeric: tabular-nums; }

/* 13. reveal-grid */
.fx-rg--armed > * {
  opacity: 0; transform: translate3d(0, 36px, 0);
  transition: opacity .7s var(--fx-ease) var(--fx-d, 0s), transform 1.1s var(--fx-ease) var(--fx-d, 0s);
}
.fx-rg--armed.is-in > * { opacity: 1; transform: none; }

/* 14. stack-cards */
.fx-stack > * {
  position: sticky; transform-origin: 50% 0;
  top: calc(var(--fx-stack-top, 12vh) + var(--i, 0) * var(--fx-stack-step, 16px));
}
.fx-stack__shade { position: absolute; inset: 0; border-radius: inherit; background: var(--bg); opacity: 0; pointer-events: none; z-index: 5; }
@media (max-width: 640px) {
  .fx-stack > * { top: calc(var(--fx-stack-top-m, 9vh) + var(--i, 0) * 10px); }
}

/* 15. hover-preview */
.fx-hp [data-hp] { display: none; }
.touch .fx-hp [data-hp], .reduced .fx-hp [data-hp] {
  display: block; flex: none; width: var(--fx-hp-thumb, 92px); aspect-ratio: 4 / 3; overflow: hidden; border-radius: 2px;
}
.touch .fx-hp [data-hp] img, .reduced .fx-hp [data-hp] img { width: 100%; height: 100%; }
.touch .fx-hp img[data-hp], .reduced .fx-hp img[data-hp], .touch .fx-hp [data-hp] img, .reduced .fx-hp [data-hp] img {
  object-fit: cover; filter: var(--fx-mono); transition: filter .5s;
}
.fx-hp .is-current img[data-hp], .fx-hp .is-current [data-hp] img { filter: var(--fx-color); }
.fx-hp-float {
  position: fixed; direction: ltr; inset-block-start: 0; inset-inline-start: 0; z-index: 60;
  width: var(--fx-hp-w, min(26vw, 360px)); aspect-ratio: 4 / 3; overflow: hidden; border-radius: 3px;
  pointer-events: none; opacity: 0; box-shadow: var(--shadow-2); transition: opacity .3s var(--fx-ease);
}
.fx-hp-float.is-on { opacity: 1; }
.fx-hp-float__m {
  position: absolute; inset: 0; display: block; clip-path: inset(100% 0 0 0);
  transition: clip-path .7s var(--fx-ease);
}
.fx-hp-float__m.is-on { clip-path: inset(0); }
.fx-hp-float__m img, img.fx-hp-float__m { display: block; width: 100%; height: 100%; object-fit: cover; }

/* 16. cursor follower (native cursor stays visible) */
.fx-cursor { position: fixed; inset: 0; z-index: 9999; direction: ltr; pointer-events: none; opacity: 0; transition: opacity .3s; }
.fx-cursor.is-on { opacity: 1; }
.fx-cursor__dot, .fx-cursor__ring { position: absolute; inset-block-start: 0; inset-inline-start: 0; }
.fx-cursor__dot {
  width: 6px; height: 6px; margin-block-start: -3px; margin-inline-start: -3px; border-radius: 50%;
  background: var(--accent);
}
.fx-cursor__ring::before {
  content: ""; position: absolute; width: 36px; height: 36px; inset-block-start: -18px; inset-inline-start: -18px;
  border-radius: 50%; border: 1px solid color-mix(in srgb, var(--ink) 35%, transparent);
  transition: scale .45s var(--fx-ease), background-color .3s, border-color .3s;
}
[data-theme="dark"] .fx-cursor__ring::before { border-color: color-mix(in srgb, var(--glow) 55%, transparent); }
.fx-cursor.is-link .fx-cursor__ring::before { scale: 1.5; }
.fx-cursor.is-label .fx-cursor__ring::before { scale: 2.4; background: var(--accent); border-color: transparent; }
.fx-cursor.is-text { opacity: 0; }
.fx-cursor__label {
  position: absolute; translate: -50% -50%; white-space: nowrap; opacity: 0; transition: opacity .25s;
  font: 600 10px/1 var(--f-mono, ui-monospace, monospace); letter-spacing: .08em; text-transform: uppercase; color: var(--bg);
}
.fx-cursor.is-label .fx-cursor__label { opacity: 1; }

/* 17. sweep: a light band crosses glass in reading direction */
.fx-sweep { position: relative; overflow: hidden; isolation: isolate; }
.fx-sweep__band {
  position: absolute; inset-block: -20%; inset-inline-start: 0; width: 45%; z-index: 2; pointer-events: none;
  background: linear-gradient(100deg, transparent 20%, var(--fx-sheen) 48%, transparent 76%);
  transform: translateX(calc(var(--fx-dir) * -130%)) skewX(-14deg);
}
.fx-sweep.is-sweep .fx-sweep__band { animation: fx-sweep 1.6s var(--fx-ease-io) .15s both; }
@media (hover: hover) {
  .fx-sweep:hover .fx-sweep__band { animation: fx-sweep-b 1.3s var(--fx-ease-io) both; }
}
.fx-sweep:focus-within .fx-sweep__band { animation: fx-sweep-b 1.3s var(--fx-ease-io) both; }
@keyframes fx-sweep { to { transform: translateX(calc(var(--fx-dir) * 330%)) skewX(-14deg); } }
@keyframes fx-sweep-b {
  from { transform: translateX(calc(var(--fx-dir) * -130%)) skewX(-14deg); }
  to { transform: translateX(calc(var(--fx-dir) * 330%)) skewX(-14deg); }
}

/* 18. draw (CSS fallback when DrawSVGPlugin is absent) */
.fx-draw--css [pathLength] {
  stroke-dasharray: 1; stroke-dashoffset: 1;
  transition: stroke-dashoffset 1.6s var(--fx-ease-io) var(--fx-d, 0s);
}
.fx-draw--css.is-in [pathLength] { stroke-dashoffset: 0; }

/* 19. trail */
[data-fx~="trail"] [data-trail] { display: none; }
.fx-trail { position: relative; overflow: hidden; }
.fx-trail [data-trail].fx-trail__img {
  display: block; position: absolute; direction: ltr; inset-block-start: 0; inset-inline-start: 0; z-index: 1;
  width: var(--fx-trail-w, clamp(140px, 15vw, 230px)); aspect-ratio: 3 / 4; object-fit: cover;
  pointer-events: none; opacity: 0; transform: translate(-50%, -50%);
}
.fx-trail__img.is-on.is-a { animation: fx-trail-a 1.2s var(--fx-ease) forwards; }
.fx-trail__img.is-on:not(.is-a) { animation: fx-trail-b 1.2s var(--fx-ease) forwards; }
@keyframes fx-trail-a {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.55); }
  25% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -38%) scale(.94); }
}
@keyframes fx-trail-b {
  0% { opacity: 1; transform: translate(-50%, -50%) scale(.55); }
  25% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -38%) scale(.94); }
}

/* 20. expand */
.fx-expand > .is-open { grid-column: 1 / -1; }
[data-expand-more][hidden] { display: none; }
