/* Effects layer — grid atmosphere, border beams, isometric figures, stats band,
   scroll reveals. Loaded after landing.css. */

@property --beam-angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }

:root {
  --grid-dot: rgba(13, 13, 13, 0.14);
  --grid-line: rgba(13, 13, 13, 0.05);
  --beam-colors: #00aeef, #7c5cff, #ff4fa3, #ffb547, #00aeef;
  --fig-stroke: rgba(13, 13, 13, 0.32);
  --fig-stroke-strong: rgba(13, 13, 13, 0.7);
  --fig-fill: var(--bg);
  --fig-top: #ffffff;
  --duration-beam: 5s;
  --duration-reveal: 700ms;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --grid-dot: rgba(255, 255, 255, 0.13);
    --grid-line: rgba(255, 255, 255, 0.045);
    --fig-stroke: rgba(255, 255, 255, 0.22);
    --fig-stroke-strong: rgba(255, 255, 255, 0.78);
    --fig-top: #151517;
  }
}
:root[data-theme="dark"] {
  --grid-dot: rgba(255, 255, 255, 0.13);
  --grid-line: rgba(255, 255, 255, 0.045);
  --fig-stroke: rgba(255, 255, 255, 0.22);
  --fig-stroke-strong: rgba(255, 255, 255, 0.78);
  --fig-top: #151517;
}

/* ---------- Hero atmosphere ---------- */
.hero { position: relative; isolation: isolate; overflow: hidden; }
.hero::before, .cta::before { content: ""; position: absolute; inset: 0; z-index: -2; background-image: linear-gradient(var(--grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--grid-line) 1px, transparent 1px), radial-gradient(var(--grid-dot) 1px, transparent 1.4px); background-size: 72px 72px, 72px 72px, 18px 18px; background-position: center top; mask-image: radial-gradient(ellipse 70% 75% at 65% 30%, #000 20%, transparent 75%); }

/* Light beams travelling along the grid lines, slowly: 25px per second, at 50% opacity.
   Distances are fixed in px so the speed is the same on every screen; negative delays
   start each beam part-way along its path so they're visible from the first frame. */
.hero-beams { position: absolute; inset: 0; z-index: -1; pointer-events: none; }
.hero-beams i { position: absolute; height: 1px; width: 220px; background: linear-gradient(90deg, transparent, var(--accent), transparent); opacity: 0; filter: drop-shadow(0 0 6px var(--accent)); animation: beam-run 85.6s linear infinite; }   /* 2140px at 25px/s */
.hero-beams i:nth-child(1) { top: 144px; animation-delay: -16s; }
.hero-beams i:nth-child(2) { top: 360px; animation-delay: -46s; }
.hero-beams i:nth-child(3) { top: 504px; animation-delay: -30s; }
.hero-beams i:nth-child(4) { top: 0; left: 72%; width: 1px; height: 180px; background: linear-gradient(180deg, transparent, var(--accent), transparent); animation-name: beam-drop; animation-delay: -12s; animation-duration: 33.6s; }   /* 840px at 25px/s */
@keyframes beam-run { 0% { transform: translateX(-220px); opacity: 0; } 4%, 94% { opacity: 0.5; } 100% { transform: translateX(1920px); opacity: 0; } }
@keyframes beam-drop { 0% { transform: translateY(-200px); opacity: 0; } 8%, 92% { opacity: 0.5; } 100% { transform: translateY(640px); opacity: 0; } }

.hero h1 .shine { background: linear-gradient(100deg, var(--text) 30%, var(--accent-ink) 50%, var(--text) 70%); background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: shine 6s var(--ease-smooth-out) 1s infinite; }
@keyframes shine { 0% { background-position: 100% 0; } 40%, 100% { background-position: -50% 0; } }

/* ---------- Border beam ---------- */
.beam { position: relative; isolation: isolate; }
.beam::after { content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none; border-radius: inherit; padding: 1.5px; /* ring width, not spacing */ background: conic-gradient(from var(--beam-angle), transparent 0 62%, var(--beam-colors), transparent 100%); -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: beam-spin var(--duration-beam) linear infinite; }
.beam--hover::after { opacity: 0; transition: opacity var(--duration-slow); }
.beam--hover:hover::after, .beam--hover:focus-visible::after { opacity: 1; }
@keyframes beam-spin { to { --beam-angle: 360deg; } }

.card-stage--grid { background-image: radial-gradient(var(--grid-dot) 1px, transparent 1.4px), var(--stage-bg); background-size: 16px 16px, auto; }

/* ---------- Stats band ---------- */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); border-bottom: 1px solid var(--line); }
.stats > div { padding: 36px 24px 32px; border-left: 1px solid var(--line); }
.stats > div:first-child { border-left: 0; padding-left: 0; }
.stats dt { margin-top: 12px; }
.stats dd { margin: 0; font-size: var(--text-stat); font-weight: 600; letter-spacing: -0.05em; line-height: 1; font-variant-numeric: tabular-nums; }
.stats dd span { color: var(--accent); }
.stats > div { display: flex; flex-direction: column-reverse; justify-content: flex-end; }

/* ---------- Figures (process) ---------- */
.figs { display: grid; grid-template-columns: repeat(3, 1fr); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.fig { display: flex; flex-direction: column; padding: 28px 32px 40px; border-left: 1px solid var(--line); }
.fig:first-child { border-left: 0; }
.fig .label { font-size: var(--fs-12); letter-spacing: 0.08em; }
.fig-stage { display: grid; place-items: center; height: 300px; margin: 8px 0 28px; }
.fig-art { display: block; width: 100%; max-width: 280px; height: 260px; overflow: visible; }
.fig h3 { font-size: var(--fs-16); font-weight: 500; letter-spacing: -0.01em; }
.fig p { margin-top: 8px; color: var(--muted); max-width: 30ch; }

.fig-art polygon, .fig-art polyline { stroke: var(--fig-stroke); stroke-width: 1; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.fig-art polyline { fill: none; }
.fig-art .f-side { fill: var(--fig-fill); }
.fig-art .f-dim { fill: color-mix(in srgb, var(--fig-fill) 92%, var(--text)); }
.fig-art .f-top { fill: var(--fig-top); stroke: var(--fig-stroke-strong); }
.fig-art .f-line { fill: none; stroke: var(--fig-stroke-strong); }
.fig-art .f-glyph { stroke: var(--fig-stroke-strong); stroke-width: 1.5; }
.fig-art .f-text, .fig-art .f-trace, .fig-art .f-cell { stroke: var(--fig-stroke); }
.fig-art .f-text { stroke-width: 2.5; }
.fig-art .f-accent { stroke: var(--accent); }
.fig-art .f-dot { fill: var(--accent); stroke: none; }
.fig-art .f-ray { stroke: var(--fig-stroke); stroke-dasharray: 2 4; animation: ray-march 1.2s linear infinite; }
.fig-art .f-signal { stroke: var(--accent); stroke-width: 2; stroke-dasharray: 18 260; animation: signal-run 2.4s linear infinite; filter: drop-shadow(0 0 3px var(--accent)); }
.fig-art .f-focus { animation: focus-pulse 2.4s ease-in-out infinite; }

/* Fig 0.1 — keys go down in a typing rhythm, their caps light up */
.f-key.is-pressed { animation: key-press 2.8s var(--ease-smooth-out) var(--k) infinite; }
.f-key.is-pressed .f-top { animation: key-light 2.8s linear var(--k) infinite; }
@keyframes key-press { 0%, 12%, 100% { transform: none; } 4% { transform: translateY(5px); } }
@keyframes key-light { 0%, 16%, 100% { stroke: var(--fig-stroke-strong); } 3% { stroke: var(--accent); } }

/* Fig 0.2 — messages arrive in order, then the thread resets */
.f-msg { animation: msg-in 7s var(--ease-smooth-out) calc(var(--i) * 0.7s) infinite backwards; }
.f-typing { animation: typing-dot 1.2s ease-in-out calc(var(--t) * 0.18s) infinite; }
@keyframes msg-in { 0% { opacity: 0; transform: translateY(10px); } 7%, 84% { opacity: 1; transform: none; } 94%, 100% { opacity: 0; transform: none; } }
@keyframes typing-dot { 0%, 60%, 100% { opacity: 0.25; } 30% { opacity: 1; } }

/* Fig 0.3 — the magnified die hovers, a signal runs across it */
.f-lens { animation: lens-float 4s ease-in-out infinite alternate; }
@keyframes lens-float { to { transform: translateY(-8px); } }
@keyframes ray-march { to { stroke-dashoffset: -6; } }
@keyframes signal-run { from { stroke-dashoffset: 278; } to { stroke-dashoffset: 0; } }
@keyframes focus-pulse { 50% { opacity: 0.35; } }

/* Only animate figures while they are on screen */
.js .fig:not(.is-in) * { animation-play-state: paused; }

/* ---------- Scroll reveal (only when JS is present) ---------- */
.js .reveal { opacity: 0; translate: 0 18px; transition: opacity var(--duration-reveal) var(--ease-smooth-out), translate var(--duration-reveal) var(--ease-smooth-out), transform var(--duration-fast) var(--ease-smooth-out), box-shadow var(--duration-fast); transition-delay: calc(var(--d, 0) * 80ms), calc(var(--d, 0) * 80ms), 0s, 0s; }
.js .reveal.is-in { opacity: 1; translate: none; }

/* ---------- Responsive ---------- */
@media (max-width: 960px) {
  .figs { grid-template-columns: 1fr; }
  .fig { border-left: 0; border-top: 1px solid var(--line); padding-inline: 0; }
  .fig:first-child { border-top: 0; }
  .fig-stage { height: 240px; }
  .fig-art { height: 210px; }
  .stats { grid-template-columns: 1fr 1fr; }
  .stats > div:nth-child(3) { border-left: 0; padding-left: 0; }
  .stats > div:nth-child(n + 3) { border-top: 1px solid var(--line); }
}

@media (prefers-reduced-motion: reduce) {
  .hero-beams { display: none; }
  .js .reveal { opacity: 1; translate: none; }
  .beam::after { background: conic-gradient(from 200deg, transparent 0 62%, var(--beam-colors), transparent 100%); }
}
