/* =====================================================================
   FX — production motion layer (baked from FX Lab, 2026-09)
   Gated behind html[data-fx-*] attributes set by fx.js.
   Inspirations: nicoborja.com (type tokens, glass, gradient titles,
   constellation), portfolio-zxc.com (loader, gate frame, scene label),
   carre.studio (Lenis, marquee, char slide-up, line reveal, typed text).
   ===================================================================== */

:root {
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --track-block: -.045em;
  --track-caps: .14em;
  --lh-block: .9;
}

/* ---------- 1. LOADER (portfolio-zxc) ---------- */
html[data-fx-loader="1"] body.fx-loading { overflow: hidden; }
.fx-loader {
  position: fixed; inset: 0; z-index: 9000; background: #0B0B0E; color: #fafafa;
  display: flex; align-items: center; justify-content: center;
  transition: opacity .6s var(--ease), visibility .6s;
}
.fx-loader.hidden { opacity: 0; visibility: hidden; pointer-events: none; }
.fx-loader-inner { display: flex; flex-direction: column; align-items: center; gap: 1rem; }
.fx-loader-label { font-family: var(--mono); font-size: .9rem; letter-spacing: .12em; text-transform: uppercase; color: rgba(250,250,250,.85); }
.fx-loader-label span span { animation: fxDot 1.4s ease-in-out infinite; }
.fx-loader-label span span:nth-child(2) { animation-delay: .2s; }
.fx-loader-label span span:nth-child(3) { animation-delay: .4s; }
@keyframes fxDot { 0%,80%,100% { opacity: .2; } 40% { opacity: 1; } }
.fx-loader-track { width: 220px; height: 3px; background: rgba(250,250,250,.15); border-radius: 2px; overflow: hidden; }
.fx-loader-fill { height: 100%; width: 0; background: linear-gradient(90deg, #2563EB, #60a5fa); transition: width .25s; }
.fx-loader-pct { font-family: var(--mono); font-size: .78rem; color: rgba(250,250,250,.5); font-variant-numeric: tabular-nums; }

/* ---------- 2. ENTER GATE (portfolio-zxc) ---------- */
.fx-gate {
  position: fixed; inset: 0; z-index: 8990; background: #0B0B0E; color: #fafafa; overflow: hidden;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .7s var(--ease), visibility .7s;
}
.fx-gate.visible { opacity: 1; visibility: visible; pointer-events: auto; }
.fx-gate-grid {
  position: absolute; inset: 0;
  background-image: linear-gradient(rgba(250,250,250,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(250,250,250,.06) 1px, transparent 1px);
  background-size: 40px 40px;
}
.fx-gate-frame { position: absolute; inset: clamp(20px, 2.4vw, 42px); border: 1px solid rgba(250,250,250,.85); }
.fx-gate-wash {
  position: absolute; left: 50%; top: 50%; width: 70vw; height: 70vw; max-width: 900px; max-height: 900px;
  transform: translate(-50%, -50%); border-radius: 50%; filter: blur(90px); opacity: .5;
  background: radial-gradient(circle, #2563EB 0%, #1e40af 40%, transparent 70%);
  animation: fxBreathe 6s ease-in-out infinite;
}
@keyframes fxBreathe { 0%,100% { transform: translate(-50%,-50%) scale(1); } 50% { transform: translate(-50%,-50%) scale(1.06); } }
.fx-gate-meta { position: absolute; font-family: var(--mono); font-size: .78rem; letter-spacing: .1em; text-transform: uppercase; color: rgba(250,250,250,.75); top: calc(clamp(20px,2.4vw,42px) + 2.4rem); }
.fx-gate-meta.l { left: calc(clamp(20px,2.4vw,42px) + 2.4rem); }
.fx-gate-meta.c { left: 50%; transform: translateX(-50%); }
.fx-gate-meta.r { right: calc(clamp(20px,2.4vw,42px) + 2.4rem); }
.fx-gate-title {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; width: 90vw;
  font-family: "Archivo", sans-serif; font-weight: 800; text-transform: uppercase;
  letter-spacing: var(--track-block); line-height: var(--lh-block);
  font-size: clamp(2.6rem, 10vw, 8rem);
}
.fx-gate-title small { display: block; font-family: var(--mono); font-weight: 400; text-transform: uppercase; letter-spacing: var(--track-caps); font-size: clamp(.7rem, 1.3vw, .95rem); color: rgba(250,250,250,.6); margin-top: 1.2rem; }
.fx-gate-btn {
  position: absolute; top: 50%; transform: translateY(-50%);
  font-family: "Archivo", sans-serif; font-weight: 600; font-size: clamp(.9rem, 1.3vw, 1.1rem); letter-spacing: .14em; text-transform: uppercase;
  color: #fafafa; background: none; border: none; padding: 1rem; cursor: pointer; transition: color .25s;
}
.fx-gate-btn:hover { color: #93c5fd; }
.fx-gate-btn.l { left: clamp(60px, 14vw, 260px); }
.fx-gate-btn.r { right: clamp(60px, 14vw, 260px); }
.fx-gate-foot { position: absolute; bottom: calc(clamp(20px,2.4vw,42px) + 1.4rem); left: 50%; transform: translateX(-50%); font-family: var(--mono); font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; color: rgba(250,250,250,.4); white-space: nowrap; }
@media (max-width: 700px) {
  .fx-gate-btn { top: auto; bottom: calc(clamp(20px,2.4vw,42px) + 4.5rem); transform: none; }
  .fx-gate-btn.l { left: calc(clamp(20px,2.4vw,42px) + 1rem); }
  .fx-gate-btn.r { right: calc(clamp(20px,2.4vw,42px) + 1rem); }
  .fx-gate-meta.c { display: none; }
}

/* ---------- 3. LENIS smooth scroll (carre.studio) ---------- */
html[data-fx-lenis="1"] { scroll-behavior: auto; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }

/* ---------- 4. HERO CHAR SLIDE-UP (carre.studio) ---------- */
html[data-fx-chars="1"] .hero-title { opacity: 1 !important; transform: none !important; transition: none !important; }
.fx-word { display: inline-block; overflow: hidden; vertical-align: top; padding-bottom: .06em; margin-bottom: -.06em; }
.fx-char { display: inline-block; transform: translateY(110%); will-change: transform; }
.fx-char.in { animation: fxCharUp .8s var(--ease) forwards; }
@keyframes fxCharUp { to { transform: translateY(0); } }

/* ---------- 5. LINE REVEAL on scroll (carre.studio line-mask) ---------- */
html[data-fx-linereveal="1"] .about-body p {
  --p: 0;
  color: transparent;
  background-image: linear-gradient(90deg, var(--text) 0 calc(var(--p) * 100%), color-mix(in srgb, var(--text) 22%, transparent) calc(var(--p) * 100%) 100%);
  -webkit-background-clip: text; background-clip: text;
  transition: --p .05s linear;
}
html[data-fx-linereveal="1"] .about-body p strong { color: inherit; -webkit-text-fill-color: inherit; }

/* ---------- 6. SKILLS MARQUEE (carre.studio) ---------- */
.fx-marquee {
  position: relative; overflow: hidden; padding: 1.6rem 0;
  border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}
.fx-marquee-track { display: flex; width: max-content; will-change: transform; }
.fx-marquee-panel { display: flex; align-items: center; gap: 2.4rem; padding-right: 2.4rem; white-space: nowrap; }
.fx-marquee-panel span {
  font-family: "Archivo", sans-serif; font-weight: 800; text-transform: uppercase;
  font-size: clamp(1.4rem, 3.2vw, 2.4rem); letter-spacing: var(--track-block); line-height: 1; color: var(--text);
}
.fx-marquee-panel span.mono { font-family: var(--mono); font-weight: 400; font-size: .8rem; letter-spacing: var(--track-caps); color: var(--accent); }
.fx-marquee-panel svg { width: 34px; height: 34px; color: var(--accent); opacity: .7; }
.fx-marquee.dark { background: var(--dark-bg); border-color: var(--dark-border); }
.fx-marquee.dark .fx-marquee-panel span { color: var(--dark-text); }

/* ---------- 7. GLASS CARDS (nicoborja) ---------- */
html[data-fx-glass="1"] .skill-card,
html[data-fx-glass="1"] .build-card,
html[data-fx-glass="1"] .project-card,
html[data-fx-glass="1"] .edu-card {
  background: color-mix(in srgb, var(--surface) 62%, transparent);
  backdrop-filter: blur(14px) saturate(1.3); -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border-color: color-mix(in srgb, var(--text) 12%, transparent);
  box-shadow: 0 14px 40px rgba(0,0,0,.08), inset 0 1px 0 color-mix(in srgb, #fff 45%, transparent);
}
html[data-fx-glass="1"][data-theme="dark"] .skill-card,
html[data-fx-glass="1"][data-theme="dark"] .build-card,
html[data-fx-glass="1"][data-theme="dark"] .project-card,
html[data-fx-glass="1"][data-theme="dark"] .edu-card {
  background: rgba(255,255,255,.04);
  box-shadow: 0 14px 40px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.14);
}
html[data-fx-glass="1"] .section-alt { background: var(--surface-alt); background-image: radial-gradient(60% 50% at 20% 0%, var(--accent-soft), transparent 60%), radial-gradient(50% 40% at 90% 100%, var(--accent-soft), transparent 60%); }
html[data-fx-glass="1"] .section:not(.section-alt):not(.hero):not(.section-contact) { background-image: radial-gradient(40% 40% at 85% 10%, var(--accent-soft), transparent 65%); }

/* ---------- 8. GRADIENT TITLES per category (nicoborja) ---------- */
html[data-fx-gradtitle="1"] .project-card h3 {
  -webkit-background-clip: text; background-clip: text; color: transparent;
  background-image: linear-gradient(120deg, var(--text) 0%, var(--text) 45%, var(--gt, var(--accent)) 100%);
  letter-spacing: -.025em;
}
html[data-fx-gradtitle="1"] .project-card[data-category="security"]   { --gt: #3b82f6; }
html[data-fx-gradtitle="1"] .project-card[data-category="automation"] { --gt: #60a5fa; }
html[data-fx-gradtitle="1"] .project-card[data-category="apps"]       { --gt: #a1a1aa; }
html[data-fx-gradtitle="1"] .project-card[data-category="web"]        { --gt: #93c5fd; }
html[data-fx-gradtitle="1"] .project-card[data-category="data"]       { --gt: #2563eb; }
html[data-fx-gradtitle="1"] .project-card[data-category="ai"]         { --gt: #818cf8; }
html[data-fx-gradtitle="1"] .project-card[data-category="telephony"]  { --gt: #22d3ee; }
html[data-fx-gradtitle="1"] .section-title,
html[data-fx-gradtitle="1"] .contact-title {
  -webkit-background-clip: text; background-clip: text; color: transparent;
  background-image: linear-gradient(120deg, currentColor 0%, currentColor 55%, var(--accent) 100%);
}
html[data-fx-gradtitle="1"] .section-title { color: var(--text); }
html[data-fx-gradtitle="1"] .contact-title { color: var(--dark-text); background-image: linear-gradient(120deg, #fafafa 0%, #fafafa 50%, #60a5fa 100%); }

/* ---------- 9. CUSTOM CURSOR (carre.studio) ---------- */
html[data-fx-cursor="1"] { cursor: none; }
html[data-fx-cursor="1"] a, html[data-fx-cursor="1"] button, html[data-fx-cursor="1"] label { cursor: none; }
.fx-cursor {
  position: fixed; left: 0; top: 0; z-index: 9500; pointer-events: none;
  width: 12px; height: 12px; border-radius: 50%; background: #fff; mix-blend-mode: exclusion;
  transform: translate(-50%, -50%); transition: width .25s var(--ease), height .25s var(--ease), opacity .25s;
  will-change: transform;
}
.fx-cursor-ring {
  position: fixed; left: 0; top: 0; z-index: 9499; pointer-events: none;
  width: 36px; height: 36px; border-radius: 50%; border: 1.5px solid #fff; mix-blend-mode: exclusion;
  transform: translate(-50%, -50%); opacity: .7; transition: width .3s var(--ease), height .3s var(--ease), opacity .3s;
}
.fx-cursor.hover { width: 44px; height: 44px; }
.fx-cursor-ring.hover { width: 60px; height: 60px; opacity: .3; }
@media (pointer: coarse) { .fx-cursor, .fx-cursor-ring { display: none; } html[data-fx-cursor="1"], html[data-fx-cursor="1"] a { cursor: auto; } }

/* ---------- 10. TYPED CTA (carre.studio) ---------- */
.fx-typed-caret { display: inline-block; width: .55ch; height: 1em; background: currentColor; vertical-align: -.1em; margin-left: 2px; animation: fxCaret .8s step-end infinite; }
@keyframes fxCaret { 50% { opacity: 0; } }

/* ---------- 11. CONSTELLATION canvas in hero (nicoborja) ---------- */
.fx-constellation { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; pointer-events: none; opacity: .85; }
html[data-fx-constellation="1"] .hero-grid { opacity: .45; }

/* ---------- 12. TYPE TOKENS: big-block headlines (nicoborja Origin system) ---------- */
html[data-fx-typeblock="1"] .hero-title { text-transform: uppercase; letter-spacing: var(--track-block); line-height: var(--lh-block); font-weight: 800; }
html[data-fx-typeblock="1"] .section-title { text-transform: uppercase; letter-spacing: var(--track-block); line-height: .95; font-weight: 800; }
html[data-fx-typeblock="1"] .section-kicker,
html[data-fx-typeblock="1"] .eyebrow { font-family: var(--mono); font-weight: 400; letter-spacing: var(--track-caps); }
html[data-fx-typeblock="1"] .section-kicker::before,
html[data-fx-typeblock="1"] .eyebrow::before { content: "// "; opacity: .6; }
html[data-fx-typeblock="1"] .stat-label,
html[data-fx-typeblock="1"] .tag,
html[data-fx-typeblock="1"] .contact-label,
html[data-fx-typeblock="1"] .filter { font-family: var(--mono); letter-spacing: .08em; }
html[data-fx-typeblock="1"] .hero-role { font-family: var(--mono); font-weight: 400; text-transform: uppercase; letter-spacing: .06em; font-size: clamp(.9rem, 1.6vw, 1.15rem); color: var(--dark-text-muted); }
html[data-fx-typeblock="1"] .hero-role .arrow { color: var(--dark-accent); }

/* ---------- 13. SCENE LABEL on project visuals (portfolio-zxc) ---------- */
html[data-fx-scenelabel="1"] .project-visual { justify-items: start; align-items: end; padding: 0 1rem .9rem 1.1rem; }
html[data-fx-scenelabel="1"] .project-visual svg { position: absolute; right: 1rem; top: 1rem; width: 40px; height: 40px; opacity: .8; }
.fx-scene-label { position: relative; z-index: 1; display: flex; gap: .7rem; align-items: stretch; }
.fx-scene-label i { width: 2px; background: rgba(255,255,255,.75); border-radius: 1px; box-shadow: 0 1px 4px rgba(0,0,0,.5); }
.fx-scene-label span { display: flex; flex-direction: column; gap: .15rem; font-family: var(--mono); font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.85); text-shadow: 0 1px 4px rgba(0,0,0,.5); }
.fx-scene-label span b { font-family: "Archivo", sans-serif; font-weight: 700; font-size: .95rem; letter-spacing: -.01em; text-transform: none; }

/* ---------- reduced motion kills everything animated ---------- */
@media (prefers-reduced-motion: reduce) {
  .fx-char { transform: none !important; animation: none !important; }
  .fx-gate-wash, .fx-loader-label span span, .fx-typed-caret { animation: none !important; }
  .fx-constellation, .fx-cursor, .fx-cursor-ring { display: none !important; }
  html[data-fx-cursor="1"], html[data-fx-cursor="1"] a { cursor: auto !important; }
}
