/* Motion: restrained on the chrome, alive on the orange.

   The office furniture stays dead still — that is the joke. Everything that
   moves is either the ember or the plate behind glass. CSS only, so nothing is
   hidden behind a script and crawlers always get the finished page. */

/* ---------- futurist sigils: the one thing from the future ---------- */

.sigil { overflow: visible; }
.sigil .stroke { stroke: var(--ember-hot); fill: none; stroke-width: 1.5; }
.sigil .fill { fill: var(--ember-hot); }
.sigil .dim { opacity: 0.35; }

@media (prefers-reduced-motion: no-preference) {
  .sigil .spin { transform-origin: 50% 50%; animation: spin 14s linear infinite; }
  .sigil .spin-r { transform-origin: 50% 50%; animation: spin 9s linear infinite reverse; }
  .sigil .pulse { animation: sig-pulse 2.8s ease-in-out infinite; }
  .sigil .scan { animation: sig-scan 3.4s ease-in-out infinite; }
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes sig-pulse { 0%,100% { opacity: 0.28; } 50% { opacity: 1; } }
@keyframes sig-scan { 0%,100% { transform: translateY(-5px); } 50% { transform: translateY(5px); } }

.mark-glow { filter: drop-shadow(0 0 0 transparent); }
@media (prefers-reduced-motion: no-preference) {
  .brand img { animation: ember 5s ease-in-out infinite; }
}
@keyframes ember {
  0%,100% { filter: drop-shadow(0 0 0 rgba(254,89,0,0)); }
  50%     { filter: drop-shadow(0 0 5px rgba(254,89,0,0.7)); }
}

/* ---------- the plate, behind CRT glass ---------- */

.hero-plate::after {
  content: "";
  position: absolute; inset: 0;
  background:
    repeating-linear-gradient(to bottom, rgba(0,0,0,0.16) 0 1px, transparent 1px 3px),
    radial-gradient(120% 80% at 50% 40%, transparent 45%, rgba(8,7,6,0.55));
  pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
  .hero-plate img { animation: plate 40s ease-in-out infinite alternate; }
  .hero-plate::before {
    content: "";
    position: absolute; left: 0; right: 0; height: 25%;
    z-index: 2;
    background: linear-gradient(to bottom, transparent, rgba(255,140,60,0.08), transparent);
    animation: sweep 7s linear infinite;
    pointer-events: none;
  }
}
@keyframes plate { from { transform: scale(1.02); } to { transform: scale(1.1); } }
@keyframes sweep { from { top: -25%; } to { top: 100%; } }

/* ---------- terminal cursor ---------- */

.caret::after {
  content: "\2588";
  color: var(--ember);
  margin-left: 0.15em;
}
@media (prefers-reduced-motion: no-preference) {
  .caret::after { animation: blink 1.1s steps(1) infinite; }
}
@keyframes blink { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }

/* ---------- boot sequence: windows arrive in order ---------- */

@media (prefers-reduced-motion: no-preference) {
  .boot { animation: boot 0.34s steps(3) backwards; }
  .boot-1 { animation-delay: 0.02s; }
  .boot-2 { animation-delay: 0.12s; }
  .boot-3 { animation-delay: 0.22s; }
  .boot-4 { animation-delay: 0.32s; }
  .boot-5 { animation-delay: 0.42s; }
}
@keyframes boot {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* scroll-in, gated so unsupported browsers simply show the content */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal {
      animation: boot linear both;
      animation-timeline: view();
      animation-range: entry 4% cover 18%;
    }
  }
}

/* ---------- status ticker ---------- */

.tick { overflow: hidden; }
.tick-track {
  display: flex; gap: 2.5rem; width: max-content; white-space: nowrap;
}
@media (prefers-reduced-motion: no-preference) {
  .tick-track { animation: marquee 44s linear infinite; }
}
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* ---------- the portrait's two frames ----------

   1.5s a side. steps(1) so each frame is held and then cut, with no dissolve
   between them — a crossfade would blur the pixel edges at every midpoint and
   make a sharp drawing look like a smear. Frame B runs the same keyframes on a
   negative delay, which puts it exactly half a cycle out of phase.

   Outside `prefers-reduced-motion: no-preference` nothing animates: frame B
   stays at opacity 0 from styles.css and the portrait is simply the first pose.
   The global reduce block further down would flatten this anyway, but the gate
   is explicit here because an image that flashes twice a second is precisely
   what that setting exists to prevent. */

@media (prefers-reduced-motion: no-preference) {
  .plate .frame-a { animation: frames 3s steps(1) infinite; }
  .plate .frame-b { animation: frames 3s steps(1) infinite -1.5s; }
}
@keyframes frames {
  0%   { opacity: 1; }
  50%  { opacity: 0; }
  100% { opacity: 1; }
}
