/* ============================================================
   NB.OS — FX layer (additive only)
   Techy entrance choreography, wireframe ghosts, HUD hover
   brackets, cursor spotlight, scanline. Loaded after style.css;
   activated by js/fx.js adding .fx-on to <body>.
   ============================================================ */

/* ---------- entrance: tiles start as blueprint ghosts ---------- */
body.fx-on .tile > *:not(.fx-wire):not(.fx-spot):not(.fx-corners) {
  transition: opacity .55s var(--ease-out), transform .55s var(--ease-out);
}

body.fx-on .tile.fx-pre {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
  backdrop-filter: none;
}
body.fx-on .tile.fx-pre > *:not(.fx-wire):not(.fx-spot):not(.fx-corners) {
  opacity: 0;
  transform: translateY(10px);
}
body.fx-on .tile {
  transition:
    background .5s var(--ease-out),
    border-color .5s var(--ease-out),
    box-shadow .5s var(--ease-out),
    transform .25s var(--ease-out);
}

/* the wireframe ghost itself */
.fx-wire {
  position: absolute;
  inset: 5px;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s var(--ease-out);
}
.fx-wire.show { opacity: 1; }
.fx-wire.hide { opacity: 0; transition: opacity .45s var(--ease-out); }

.fx-wire svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.fx-wire rect,
.fx-wire line {
  fill: none;
  stroke: color-mix(in srgb, var(--accent) 60%, transparent);
  stroke-width: 1;
  stroke-dasharray: 5 6;
}
.fx-wire line { stroke-dasharray: 3 7; opacity: .45; }

.fx-wire b {
  position: absolute;
  top: -3px;
  left: 10px;
  transform: translateY(-50%);
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: .12em;
  color: color-mix(in srgb, var(--accent) 85%, transparent);
  background: var(--bg);
  padding: 0 6px;
}

/* header / footer slide in */
body.fx-on .land-top,
body.fx-on .land-foot { transition: opacity .6s var(--ease-out), transform .6s var(--ease-out); }
body.fx-on .land-top.fx-pre { opacity: 0; transform: translateY(-10px); }
body.fx-on .land-foot.fx-pre { opacity: 0; transform: translateY(10px); }

/* ---------- HUD corner brackets on tile hover ---------- */
.fx-corners { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
.fx-corners i {
  position: absolute;
  width: 12px; height: 12px;
  border: 0 solid var(--accent);
  opacity: 0;
  transition: opacity .22s var(--ease-out), transform .22s var(--ease-out);
}
.fx-corners i:nth-child(1) { top: 7px; left: 7px; border-top-width: 1.5px; border-left-width: 1.5px; transform: translate(6px, 6px); }
.fx-corners i:nth-child(2) { top: 7px; right: 7px; border-top-width: 1.5px; border-right-width: 1.5px; transform: translate(-6px, 6px); }
.fx-corners i:nth-child(3) { bottom: 7px; left: 7px; border-bottom-width: 1.5px; border-left-width: 1.5px; transform: translate(6px, -6px); }
.fx-corners i:nth-child(4) { bottom: 7px; right: 7px; border-bottom-width: 1.5px; border-right-width: 1.5px; transform: translate(-6px, -6px); }
.tile:hover .fx-corners i { opacity: .9; transform: translate(0, 0); }

/* ---------- cursor spotlight inside tiles ---------- */
.fx-spot {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity .35s var(--ease-out);
  background: radial-gradient(
    280px circle at var(--fx-mx, 50%) var(--fx-my, 50%),
    color-mix(in srgb, var(--accent) 9%, transparent),
    transparent 70%
  );
}
.tile:hover .fx-spot { opacity: 1; }
/* keep spotlight under the OS-tile canvas glow but over plain tiles */
.t-os .fx-spot { z-index: 1; }

/* ---------- one-shot scanline sweep ---------- */
#fx-scan {
  position: fixed;
  left: 0; right: 0;
  top: -6px;
  height: 2px;
  z-index: 60;
  pointer-events: none;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  box-shadow: 0 0 18px var(--glow);
  animation: fx-scan 1.15s var(--ease-out) .15s both;
}
@keyframes fx-scan {
  from { transform: translateY(0); opacity: .9; }
  85%  { opacity: .9; }
  to   { transform: translateY(105vh); opacity: 0; }
}

/* ---------- footer cursor coordinate readout ---------- */
#fx-coord {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .12em;
  color: var(--faint);
  font-variant-numeric: tabular-nums;
}
#fx-coord b { color: var(--accent); font-weight: 500; }

/* ============================================================
   FX v2 — vibe-gated extras, driven by the Tweaks panel
   body[data-fx-vibe]: calm | techy | max
   --fx-motion: global speed multiplier
   ============================================================ */
:root { --fx-motion: 1; }

/* rotating border beam on the NB.OS tile */
@property --fx-a { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
body.fx-on:not([data-fx-vibe="calm"]) .t-os::after {
  content: '';
  position: absolute;
  inset: -1px;
  border-radius: var(--r-tile);
  padding: 1px;
  z-index: 5;
  pointer-events: none;
  background: conic-gradient(from var(--fx-a),
    transparent 0turn 0.58turn,
    color-mix(in srgb, var(--accent) 85%, transparent) 0.76turn,
    transparent 0.94turn);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask-composite: exclude;
  animation: fx-beam calc(5.5s / var(--fx-motion)) linear infinite;
}
body[data-fx-vibe="max"] .t-os::after { animation-duration: calc(3s / var(--fx-motion)); }
@keyframes fx-beam { to { --fx-a: 360deg; } }

/* occasional RGB-split glitch on the hero name */
body.fx-on:not([data-fx-vibe="calm"]) .t-hero h1 {
  animation: fx-glitch calc(9s / var(--fx-motion)) steps(1) infinite;
}
body[data-fx-vibe="max"] .t-hero h1 { animation-duration: calc(4s / var(--fx-motion)); }
@keyframes fx-glitch {
  0%, 92.9%, 96.1%, 100% { text-shadow: none; transform: none; }
  93% { text-shadow: 2px 0 var(--accent), -2px 0 var(--accent-2); transform: translateX(-1.5px) skewX(-1.5deg); }
  94.2% { text-shadow: -3px 0 var(--accent), 3px 0 var(--accent-2); transform: translateX(1.5px); }
  95.4% { text-shadow: 1.5px 0 var(--accent-2), -1.5px 0 var(--accent); transform: skewX(1deg); }
}

/* radar ping around the login avatar */
body.fx-on:not([data-fx-vibe="calm"]) .login-avatar {
  animation: fx-ping calc(2.8s / var(--fx-motion)) var(--ease-out) infinite;
}
@keyframes fx-ping {
  0% {
    box-shadow: 0 0 48px var(--glow),
      0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent),
      0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent);
  }
  100% {
    box-shadow: 0 0 48px var(--glow),
      0 0 0 3px color-mix(in srgb, var(--accent) 35%, transparent),
      0 0 0 28px transparent;
  }
}

/* film grain overlay */
#fx-grain {
  position: fixed;
  inset: -120px;
  z-index: 80;
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  animation: fx-grain calc(0.7s / var(--fx-motion)) steps(2) infinite;
}
body[data-fx-vibe="calm"] #fx-grain { display: none; }
body[data-fx-vibe="max"] #fx-grain { opacity: 0.085; }
@keyframes fx-grain {
  50% { transform: translate(34px, -22px); }
}

/* theme swatches pop in */
body.fx-on .theme-swatches .swatch {
  animation: fx-pop 0.4s var(--ease-out) both;
  animation-delay: calc(0.75s + var(--i, 0) * 50ms);
}
@keyframes fx-pop { from { opacity: 0; transform: scale(0.4); } }

/* blueprint overlay mode — persistent wireframes */
.fx-wire.stay { opacity: 0.85; transition: none; }
body.fx-blueprint .tile { border-style: dashed; }

/* ============================================================
   FX v3 — interactive resume (tabs · timeline · live log)
   ============================================================ */
.app-resume-shell { display: flex; flex-direction: column; min-height: 100%; }

.res-tabs {
  display: flex;
  gap: 4px;
  padding: 10px 14px 0;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 3;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: blur(6px);
}
.res-tabs button {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: .04em;
  color: var(--muted);
  padding: 8px 14px;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
}
.res-tabs button:hover { color: var(--text); }
.res-tabs button.active { color: var(--accent); background: var(--surface-2); border-color: var(--line); }

/* --- timeline view --- */
.res-tl {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 24px 24px 24px 48px;
}
.res-tl::before {
  content: '';
  position: absolute;
  left: 27px;
  top: 34px;
  bottom: 34px;
  width: 2px;
  background: linear-gradient(var(--accent), transparent);
  opacity: .35;
}
.tl-item {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  text-align: left;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface-2);
  cursor: pointer;
  transition: border-color .2s var(--ease-out), transform .2s var(--ease-out);
}
.tl-item:hover { border-color: var(--line-strong); transform: translateX(3px); }
.tl-dot {
  position: absolute;
  left: -26px;
  top: 19px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid var(--accent);
  background: var(--surface);
}
.tl-item.live .tl-dot {
  background: var(--accent);
  box-shadow: 0 0 12px var(--glow);
  animation: pulse 2.4s ease-in-out infinite;
}
.tl-head strong { font-size: 15px; }
.tl-head em { font-style: normal; color: var(--muted); margin-left: 6px; }
.tl-meta {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--faint);
  text-transform: uppercase;
  letter-spacing: .08em;
}
.tl-meta b { color: var(--accent); font-weight: 500; }
.tl-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .35s var(--ease-out); }
.tl-body ul {
  overflow: hidden;
  min-height: 0;
  margin: 0;
  padding-left: 18px;
  color: var(--muted);
  font-size: 13.5px;
}
.tl-body ul li { margin: 6px 0; }
.tl-item.open .tl-body { grid-template-rows: 1fr; }
.tl-item.open .tl-body ul { margin-top: 6px; }
.tl-more {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--accent);
  letter-spacing: .1em;
  text-transform: uppercase;
  margin-top: 2px;
}
.res-tl.play .tl-item { animation: fx-tl-in .5s var(--ease-out) both; animation-delay: var(--d, 0ms); }
@keyframes fx-tl-in { from { opacity: 0; transform: translateX(-14px); } }

/* --- log view --- */
.res-log {
  padding: 20px 24px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  line-height: 1.85;
  cursor: pointer;
  white-space: pre-wrap;
  word-break: break-word;
}
.res-log.done { cursor: default; }
.res-log .ll-cmd { color: var(--accent); }
.res-log .ll-info { color: var(--muted); }
.res-log .ll-edu { color: var(--text); }
.res-log .ll-cert { color: #3ddc97; }
.res-log .ll-out { color: var(--text); }
.log-cursor::after { content: '▮'; color: var(--accent); animation: caret 1.1s steps(1) infinite; }

/* --- classic doc view: scroll-staggered reveal + livelier chips --- */
body.fx-on .app-resume .fx-rv {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .5s var(--ease-out), transform .5s var(--ease-out);
}
body.fx-on .app-resume .fx-rv.seen { opacity: 1; transform: none; }
.app-resume .skill-chips span {
  transition: transform .18s var(--ease-out), border-color .18s, color .18s;
}
.app-resume .skill-chips span:hover {
  transform: translateY(-2px);
  color: var(--accent);
  border-color: var(--accent);
}

/* ============================================================
   FX v4 — Hall of Fame alive · Travel flags · Desktop icons
   ============================================================ */

/* ---------- NB.SYS: Component Hall of Fame ---------- */
body.fx-on .rc-hall-grid { perspective: 1000px; }
body.fx-on .rc-hcard {
  position: relative;
  overflow: hidden;
  transform-style: preserve-3d;
  animation: fx-hcard-in .55s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 85ms);
}
.rc-hall-grid .rc-hcard:nth-child(1) { --i: 0; }
.rc-hall-grid .rc-hcard:nth-child(2) { --i: 1; }
.rc-hall-grid .rc-hcard:nth-child(3) { --i: 2; }
.rc-hall-grid .rc-hcard:nth-child(4) { --i: 3; }
.rc-hall-grid .rc-hcard:nth-child(5) { --i: 4; }
.rc-hall-grid .rc-hcard:nth-child(6) { --i: 5; }
@keyframes fx-hcard-in {
  from { opacity: 0; transform: translateY(18px) rotateX(14deg); }
}

/* keep the components in colour so the grid never looks empty */
body.fx-on .rc-hcard svg { filter: grayscale(.35) brightness(.95); }
body.fx-on .rc-hcard:hover svg,
body.fx-on .rc-hcard:focus-visible svg { filter: none; }

/* rank badge in the corner */
body.fx-on .rc-hcard::before {
  position: absolute; top: 9px; left: 11px;
  font-family: var(--font-mono); font-size: 9.5px; letter-spacing: .12em;
  color: var(--ln); opacity: .45;
}
.rc-hall-grid .rc-hcard:nth-child(1)::before { content: '#01'; }
.rc-hall-grid .rc-hcard:nth-child(2)::before { content: '#02'; }
.rc-hall-grid .rc-hcard:nth-child(3)::before { content: '#03'; }
.rc-hall-grid .rc-hcard:nth-child(4)::before { content: '#04'; }
.rc-hall-grid .rc-hcard:nth-child(5)::before { content: '#05'; }
.rc-hall-grid .rc-hcard:nth-child(6)::before { content: '#06'; }

/* diagonal shine sweep on hover */
body.fx-on .rc-hcard::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 42%, rgba(255,255,255,.09) 50%, transparent 58%);
  transform: translateX(-130%);
}
body.fx-on .rc-hcard:hover::after { animation: fx-shine .85s var(--ease-out); }
@keyframes fx-shine { to { transform: translateX(130%); } }

/* moving parts — always turning, faster on hover */
body.fx-on .fx-blades { animation: fx-spin 4.5s linear infinite; }
body.fx-on .rc-hcard:hover .fx-blades { animation-duration: .85s; }
@keyframes fx-spin { to { transform: rotate(360deg); } }

body.fx-on .fx-stick {
  transform-box: fill-box;
  animation: fx-ram 1.5s steps(1) infinite;
  animation-delay: calc(var(--i, 0) * -.3s);
}
@keyframes fx-ram { 0%, 100% { opacity: .95; } 50% { opacity: .28; } }

body.fx-on .fx-led {
  transform-box: fill-box; transform-origin: center;
  animation: fx-led 1.7s ease-in-out infinite;
}
@keyframes fx-led {
  0%, 100% { opacity: 1; }
  50% { opacity: .3; transform: scale(.82); }
}

body.fx-on .fx-core {
  transform-box: fill-box; transform-origin: center;
  animation: fx-core 2.6s ease-in-out infinite;
}
@keyframes fx-core { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }

/* ---------- Travel: country flags ---------- */
.tv-list li .fl { display: inline-flex; align-items: center; justify-content: center; min-width: 22px; }
.tv-flag {
  width: 24px; height: 17px;
  object-fit: cover;
  border-radius: 3px;
  border: 1px solid var(--line);
  box-shadow: 0 1px 5px rgba(0,0,0,.5);
}
body.fx-on .tv-list li {
  animation: fx-tvli .45s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 48ms);
}
@keyframes fx-tvli { from { opacity: 0; transform: translateX(16px); } }
body.fx-on .tv-flag { animation: fx-flag .55s var(--ease-out) both; animation-delay: inherit; transform-origin: left center; }
@keyframes fx-flag { from { opacity: 0; transform: rotateY(85deg); } }
body.fx-on .tv-list li:hover .tv-flag { transform: scale(1.12); transition: transform .18s var(--ease-out); }

/* ---------- OS desktop: living icons ---------- */
body.fx-on #desktop.on .desk-icons .dicon {
  animation: fx-dicon-in .5s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 55ms);
}
.desk-icons .dicon:nth-child(1) { --i: 0; }
.desk-icons .dicon:nth-child(2) { --i: 1; }
.desk-icons .dicon:nth-child(3) { --i: 2; }
.desk-icons .dicon:nth-child(4) { --i: 3; }
.desk-icons .dicon:nth-child(5) { --i: 4; }
.desk-icons .dicon:nth-child(6) { --i: 5; }
.desk-icons .dicon:nth-child(7) { --i: 6; }
.desk-icons .dicon:nth-child(8) { --i: 7; }
.desk-icons .dicon:nth-child(9) { --i: 8; }
.desk-icons .dicon:nth-child(10) { --i: 9; }
.desk-icons .dicon:nth-child(11) { --i: 10; }
.desk-icons .dicon:nth-child(12) { --i: 11; }
@keyframes fx-dicon-in { from { opacity: 0; transform: translateY(16px) scale(.9); } }

/* gentle idle float on the icon tiles */
body.fx-on .desk-icons .dicon .ig {
  animation: fx-float 6.5s ease-in-out infinite;
  animation-delay: calc(var(--i, 0) * -.6s);
  transition: box-shadow .25s var(--ease-out), border-color .25s;
  border: 1px solid transparent;
}
@keyframes fx-float { 50% { transform: translateY(-5px); } }
body.fx-on .desk-icons .dicon:hover .ig {
  box-shadow: 0 12px 30px rgba(0,0,0,.5), 0 0 22px var(--glow);
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}
body.fx-on .desk-icons .dicon .ig svg { transition: transform .25s var(--ease-out); }
body.fx-on .desk-icons .dicon:hover .ig svg { transform: scale(1.14) rotate(-5deg); }

/* ---------- reduced motion: everything stays static ---------- */
@media (prefers-reduced-motion: reduce) {
  #fx-scan { display: none; }
  #fx-grain { display: none; }
  body.fx-on .t-os::after,
  body.fx-on .t-hero h1,
  body.fx-on .login-avatar,
  body.fx-on .theme-swatches .swatch,
  body.fx-on .rc-hcard,
  body.fx-on .fx-blades,
  body.fx-on .fx-stick,
  body.fx-on .fx-led,
  body.fx-on .fx-core,
  body.fx-on .tv-list li,
  body.fx-on .tv-flag,
  body.fx-on #desktop.on .desk-icons .dicon,
  body.fx-on .desk-icons .dicon .ig { animation: none; }
  .fx-wire:not(.stay) { display: none; }
  body.fx-on .tile.fx-pre,
  body.fx-on .land-top.fx-pre,
  body.fx-on .land-foot.fx-pre { opacity: 1; transform: none; }
  body.fx-on .tile.fx-pre > * { opacity: 1 !important; transform: none !important; }
}
