/* UUAAPP Sci-Fi Layer — additive only, must be loaded AFTER style.css */
/* ==========================================================================
   全部 selector 均以 .sf- 為前綴，只新增、不改寫現有規則。
   深色專屬特效一律用 :root:not([data-theme="light"]) 隔離；
   light theme 下特效停用但版面仍可讀。
   效能：只動畫化 transform / opacity；支援 prefers-reduced-motion 停機。
   ========================================================================== */

/* ---------- 0. Layer defaults ---------- */
.sf-scanlines,
.sf-vignette,
.sf-scanbeam,
.sf-digital-rain{
  position:fixed;
  inset:0;
  pointer-events:none;
}

/* ---------- 1. Starfield parallax（配合現有 #starfield canvas） ---------- */
:root:not([data-theme="light"]) .sf-parallax{
  opacity:1 !important; /* 實際星點由 scifi.js 繪製；JS 停用時此 class 不會加上，保留原 canvas 效果 */
  will-change:transform;
}
@media (max-width:767px){
  .sf-parallax{transform:none !important}
}

/* ---------- 2. CRT 掃描線 + 暗角 + 巡掠掃描光 ---------- */
.sf-scanlines{
  z-index:9000;
  background:repeating-linear-gradient(
    to bottom,
    rgba(0,229,255,0.025) 0px,
    rgba(0,229,255,0.025) 1px,
    transparent 1px,
    transparent 3px
  );
}
.sf-vignette{
  z-index:9001;
  background:radial-gradient(ellipse at center,
    transparent 52%,
    rgba(2,4,10,0.34) 84%,
    rgba(2,4,10,0.62) 100%
  );
}
.sf-scanbeam{
  z-index:9001;
  height:160px;
  inset:auto 0;
  background:linear-gradient(to bottom,
    transparent,
    rgba(0,229,255,0.045) 46%,
    rgba(0,229,255,0.085) 50%,
    rgba(0,229,255,0.045) 54%,
    transparent
  );
  animation:sf-beam 13s linear infinite;
  will-change:transform;
}
@keyframes sf-beam{
  from{transform:translateY(-170px)}
  to{transform:translateY(100vh)}
}

/* ---------- 3. Glitch 故障字（RGB 分離 + 定時觸發） ---------- */
.sf-glitch{
  position:relative;
  display:inline-block;
}
.sf-glitch::before,
.sf-glitch::after{
  content:attr(data-text);
  position:absolute;
  left:0;
  top:0;
  width:100%;
  overflow:hidden;
  opacity:0;
  pointer-events:none;
  clip-path:inset(0 0 0 0);
}
.sf-glitch::before{color:var(--accent-primary)}
.sf-glitch::after{color:var(--accent-secondary)}
.sf-glitch:hover::before,
.sf-glitch.sf-glitch-on::before{
  opacity:0.8;
  animation:sf-glitch-a 0.55s steps(2,end) 1;
}
.sf-glitch:hover::after,
.sf-glitch.sf-glitch-on::after{
  opacity:0.65;
  animation:sf-glitch-b 0.55s steps(2,end) 1;
}
@keyframes sf-glitch-a{
  0%{transform:translate(-3px,-1px);clip-path:inset(6% 0 62% 0)}
  20%{transform:translate(3px,1px);clip-path:inset(48% 0 12% 0)}
  40%{transform:translate(-2px,0);clip-path:inset(20% 0 45% 0)}
  60%{transform:translate(2px,-1px);clip-path:inset(70% 0 4% 0)}
  80%{transform:translate(-1px,1px);clip-path:inset(30% 0 38% 0)}
  100%{transform:none;clip-path:inset(0 0 100% 0);opacity:0}
}
@keyframes sf-glitch-b{
  0%{transform:translate(3px,1px);clip-path:inset(58% 0 8% 0)}
  20%{transform:translate(-3px,-1px);clip-path:inset(12% 0 60% 0)}
  40%{transform:translate(2px,1px);clip-path:inset(40% 0 30% 0)}
  60%{transform:translate(-2px,0);clip-path:inset(4% 0 76% 0)}
  80%{transform:translate(1px,-1px);clip-path:inset(66% 0 16% 0)}
  100%{transform:none;clip-path:inset(100% 0 0 0);opacity:0}
}

/* ---------- 4. 霓虹光暈（青 + 紫雙色） ---------- */
.sf-neon{
  text-shadow:
    0 0 6px rgba(0,229,255,0.45),
    0 0 22px rgba(124,58,237,0.30);
  animation:sf-neon-breathe 4.5s ease-in-out infinite;
}
@keyframes sf-neon-breathe{
  0%,100%{text-shadow:0 0 6px rgba(0,229,255,0.45),0 0 22px rgba(124,58,237,0.30)}
  50%{text-shadow:0 0 11px rgba(0,229,255,0.70),0 0 36px rgba(124,58,237,0.48)}
}

/* ---------- 5. 雷達掃描（radar sweep） ---------- */
.sf-radar{
  position:relative;
  width:clamp(130px, 20vw, 190px);
  aspect-ratio:1/1;
  margin:0 auto;
  border-radius:50%;
  border:1px solid rgba(0,229,255,0.35);
  background:
    repeating-radial-gradient(circle at 50% 50%,
      transparent 0 22px,
      rgba(0,229,255,0.10) 22px 23px),
    radial-gradient(circle at 50% 50%, rgba(0,229,255,0.06), transparent 72%);
  box-shadow:0 0 26px rgba(0,229,255,0.10), inset 0 0 34px rgba(0,229,255,0.06);
}
.sf-radar::before{
  content:'';
  position:absolute;
  inset:0;
  border-radius:50%;
  background:
    linear-gradient(to right, transparent calc(50% - 0.5px), rgba(0,229,255,0.18) 50%, transparent calc(50% + 0.5px)),
    linear-gradient(to bottom, transparent calc(50% - 0.5px), rgba(0,229,255,0.18) 50%, transparent calc(50% + 0.5px));
}
.sf-radar-sweep{
  position:absolute;
  inset:0;
  border-radius:50%;
  background:conic-gradient(from 0deg,
    rgba(0,229,255,0.45),
    rgba(0,229,255,0.12) 32deg,
    transparent 85deg,
    transparent 360deg
  );
  animation:sf-radar-spin 4.2s linear infinite;
  will-change:transform;
}
@keyframes sf-radar-spin{to{transform:rotate(360deg)}}
.sf-radar-blip{
  position:absolute;
  width:7px;
  height:7px;
  border-radius:50%;
  background:var(--accent-primary);
  box-shadow:0 0 10px var(--accent-primary);
  animation:sf-blip 4.2s ease-out infinite;
  opacity:0;
}
.sf-radar-blip:nth-child(2){top:26%;left:66%;animation-delay:0.5s}
.sf-radar-blip:nth-child(3){top:64%;left:30%;animation-delay:1.8s}
.sf-radar-blip:nth-child(4){top:42%;left:52%;animation-delay:3s}
@keyframes sf-blip{
  0%{opacity:0;transform:scale(0.5)}
  10%{opacity:1;transform:scale(1.25)}
  55%{opacity:0.3}
  100%{opacity:0;transform:scale(1)}
}

/* ---------- 6. 數碼雨 canvas（透明度由 JS 控制，極低） ---------- */
.sf-digital-rain{
  z-index:0;
  opacity:0; /* JS 啟用時才會 setProperty 覆蓋 */
}

/* ---------- 7. Count-up（數字由 scifi.js 滾動；class 只提供光暈） ---------- */
.sf-counted{
  text-shadow:0 0 14px rgba(0,229,255,0.5);
}

/* ---------- 8. Scroll reveal ----------
   🔴 2026-09-21 hardening: this used to hide content (opacity:0) and wait for
   IntersectionObserver to reveal it. If IO never fired (headless capture,
   prerender, crawler, or any JS hiccup) the page rendered as blank boxes.
   It is now an ENTRANCE ANIMATION ONLY — CSS never hides the content, so a
   failed observer degrades to "no animation", never to "invisible content". */
@keyframes sf-rise{
  from{opacity:0;transform:translateY(26px)}
  to{opacity:1;transform:none}
}
.sf-revealed{
  animation:sf-rise 0.7s cubic-bezier(0.22,0.61,0.36,1) both;
}

/* ---------- 9. 卡片全息質感（邊框流光 + 3D tilt 錨點） ---------- */
.sf-holo{
  position:relative;
}
.sf-holo::before{
  content:'';
  position:absolute;
  inset:-1px;
  border-radius:inherit;
  padding:1px;
  background:conic-gradient(from var(--sf-angle,0deg),
    transparent 0 66deg,
    rgba(0,229,255,0.85) 88deg,
    rgba(124,58,237,0.85) 108deg,
    transparent 142deg 360deg
  );
  -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;
  opacity:0;
  transition:opacity 0.4s ease;
  pointer-events:none;
}
.sf-holo:hover::before{
  opacity:1;
  animation:sf-border-flow 3.2s linear infinite;
}
@keyframes sf-border-flow{
  to{--sf-angle:360deg}
}
@property --sf-angle{
  syntax:'<angle>';
  initial-value:0deg;
  inherits:false;
}
.sf-tilt{
  transform:perspective(900px)
    rotateX(var(--sf-rx,0deg))
    rotateY(var(--sf-ry,0deg))
    translateZ(0);
  will-change:transform;
}

/* ---------- 10. 打字機效果（CSS 純實作，JS 有進階版 .sf-typing-js） ---------- */
.sf-typing{
  display:inline-block;
  overflow:hidden;
  white-space:nowrap;
  font-family:var(--font-mono);
  border-right:2px solid var(--accent-warm);
  width:0;
  animation:
    sf-type 2.4s steps(var(--sf-chars,42),end) 0.25s both,
    sf-caret 0.85s step-end infinite;
}
/* JS-driven variant (scifi.js [data-sf-type]): caret only, width follows text */
.sf-typing-js{
  display:inline-block;
  font-family:var(--font-mono);
  border-right:2px solid var(--accent-warm);
  animation:sf-caret 0.85s step-end infinite;
}
@keyframes sf-type{
  from{width:0}
  to{width:var(--sf-w,100%)}
}
@keyframes sf-caret{
  50%{border-color:transparent}
}

/* ---------- 機密印章（懸疑感，非 emoji） ---------- */
.sf-stamp{
  display:inline-block;
  font-family:var(--font-mono);
  font-size:0.7rem;
  font-weight:600;
  letter-spacing:0.18em;
  text-transform:uppercase;
  color:var(--accent-warm);
  border:1px solid rgba(245,158,11,0.5);
  border-radius:4px;
  padding:2px 10px;
  transform:rotate(-3deg);
  box-shadow:0 0 12px rgba(245,158,11,0.18);
}
.sf-stamp-danger{
  color:var(--accent-danger);
  border-color:rgba(239,68,68,0.5);
  box-shadow:0 0 12px rgba(239,68,68,0.18);
}

/* ---------- 刪節號遮條（redaction bar，呼應 64/71 刪節） ---------- */
.sf-redacted{
  display:inline-block;
  width:5.5ch;
  height:0.95em;
  vertical-align:-0.12em;
  background:currentColor;
  opacity:0.75;
  border-radius:1px;
  margin:0 2px;
}

/* ---------- 終端機視窗外框 ---------- */
.sf-terminal{
  position:relative;
  font-family:var(--font-mono);
  background:rgba(2,6,14,0.72);
  border:1px solid rgba(0,229,255,0.22);
  border-radius:var(--radius);
  padding:1rem 1.2rem;
  color:var(--text-secondary);
  overflow:hidden;
}
.sf-terminal::after{
  content:'';
  position:absolute;
  left:0;
  right:0;
  top:-40%;
  height:40%;
  background:linear-gradient(to bottom, transparent, rgba(0,229,255,0.05), transparent);
  animation:sf-term-scan 5.5s linear infinite;
  pointer-events:none;
}
@keyframes sf-term-scan{
  from{transform:translateY(0)}
  to{transform:translateY(350%)}
}
.sf-cursor{
  display:inline-block;
  width:9px;
  height:1em;
  vertical-align:-0.12em;
  background:var(--accent-primary);
  box-shadow:0 0 8px rgba(0,229,255,0.7);
  animation:sf-caret 1s step-end infinite;
}

/* ---------- 暗色專屬效果：light theme 一併停用 ---------- */
@media all{
  [data-theme="light"] .sf-scanlines,
  [data-theme="light"] .sf-vignette,
  [data-theme="light"] .sf-scanbeam,
  [data-theme="light"] .sf-digital-rain{display:none}

  [data-theme="light"] .sf-neon,
  [data-theme="light"] .sf-counted{text-shadow:none}

  [data-theme="light"] .sf-glitch::before,
  [data-theme="light"] .sf-glitch::after{display:none}

  [data-theme="light"] .sf-holo::before{filter:saturate(0.4);opacity:0}

  [data-theme="light"] .sf-stamp,
  [data-theme="light"] .sf-stamp-danger{box-shadow:none}

  [data-theme="light"] .sf-terminal{background:rgba(240,248,255,0.8)}
  [data-theme="light"] .sf-terminal::after{display:none}
}

/* ---------- prefers-reduced-motion：全部動畫停機 ---------- */
@media (prefers-reduced-motion: reduce){
  .sf-scanbeam,
  .sf-radar-sweep,
  .sf-radar-blip,
  .sf-neon,
  .sf-typing,
  .sf-typing-js,
  .sf-glitch::before,
  .sf-glitch::after,
  .sf-holo:hover::before,
  .sf-terminal::after,
  .sf-cursor{
    animation:none !important;
  }
  .sf-vignette{display:none}
  .sf-reveal{
    opacity:1 !important;
    transform:none !important;
    transition:none !important;
  }
  .sf-typing,
  .sf-typing-js{
    width:auto !important;
    white-space:normal;
    border-right:none;
  }
  .sf-scanbeam{display:none}
}

/* ===== Batch index + per-batch headline (added 2026-09-21) ===== */
.sf-idx-sub{max-width:760px;margin:-0.4rem auto 1.4rem;text-align:center;font-size:.88rem;line-height:1.75;color:#a3b4c4}
.sf-batch-index{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:1rem;margin:0 0 2.6rem}
.sf-idx-card{position:relative;display:block;overflow:hidden;text-decoration:none;border-radius:14px;padding:1.1rem 1.2rem 1.25rem;
  background:linear-gradient(160deg,rgba(0,229,255,.08),rgba(124,58,237,.07));
  border:1px solid rgba(0,229,255,.22);transition:transform .25s,border-color .25s,box-shadow .25s}
.sf-idx-card:hover,.sf-idx-card:focus-visible{transform:translateY(-4px);border-color:rgba(0,229,255,.62);box-shadow:0 0 26px rgba(0,229,255,.26)}
.sf-idx-card.is-newest{border-color:rgba(124,58,237,.55);box-shadow:0 0 22px rgba(124,58,237,.22)}
.sf-idx-card::after{content:"";position:absolute;left:0;right:0;height:36%;pointer-events:none;
  background:linear-gradient(180deg,transparent,rgba(0,229,255,.07),transparent);animation:sf-idx-scan 8s linear infinite}
@keyframes sf-idx-scan{0%{transform:translateY(-120%)}100%{transform:translateY(320%)}}
.sf-idx-num{position:absolute;right:.75rem;top:.35rem;font-size:3.6rem;font-weight:800;line-height:1;letter-spacing:-.05em;
  color:rgba(0,229,255,.11);font-variant-numeric:tabular-nums}
.sf-idx-meta{font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--text-muted,#5a6a7a)}
.sf-idx-count{display:inline-block;margin-left:.55rem;padding:1px 9px;border-radius:10px;font-size:.68rem;letter-spacing:0;
  background:rgba(0,229,255,.14);border:1px solid rgba(0,229,255,.32);color:var(--accent-primary,#00e5ff)}
.sf-idx-head{margin:.4rem 0 .5rem;font-size:1.02rem;font-weight:700;line-height:1.45;color:var(--text-primary,#e8edf2)}
.sf-idx-desc{font-size:.88rem;line-height:1.74;color:#a3b4c4}
.sf-batch-headline{margin:.15rem 0 .55rem;font-size:1.06rem;font-weight:700;line-height:1.5;
  background:linear-gradient(90deg,var(--accent-primary,#00e5ff),var(--accent-secondary,#7c3aed));
  -webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;color:transparent}
.sf-batch-tldr{margin:0 0 1rem;padding:.1rem 0 .1rem .85rem;border-left:2px solid rgba(0,229,255,.42);
  font-size:.92rem;line-height:1.78;color:#a8b9c9}
[data-theme="light"] .sf-idx-num{color:rgba(10,90,120,.16)}
[data-theme="light"] .sf-idx-card::after{display:none}
[data-theme="light"] .sf-batch-headline{background:none;-webkit-text-fill-color:currentColor;color:#0a6b7a}
@media (prefers-reduced-motion:reduce){.sf-idx-card{transition:none}.sf-idx-card:hover{transform:none}.sf-idx-card::after{animation:none;display:none}}
@media (max-width:560px){.sf-idx-num{font-size:2.6rem}}

/* ===== 2026-09-21 mobile + reduced-motion corrections =====================
   1) Reduced motion must NOT delete the radar. The sweep is the only genuinely
      motion-sick element; the rings + blips identify the site's look, so keep
      them visible as static marks instead of `display:none`.
   2) Phones were losing the signature visual entirely (radar too faint/small,
      no starfield canvas below 768px — fixed in scifi.js).            */
@media (prefers-reduced-motion: reduce){
  .sf-radar-blip{display:block !important;animation:none !important;opacity:.9}
  .sf-radar-sweep{display:none}
}
@media (max-width: 768px){
  .sf-radar{width:150px;border-color:rgba(0,229,255,.5);
    box-shadow:0 0 22px rgba(0,229,255,.18), inset 0 0 26px rgba(0,229,255,.08)}
  .sf-radar-sweep{opacity:.85}
  .sf-terminal{letter-spacing:normal !important;overflow-wrap:anywhere}
  .sf-terminal [style*="letter-spacing"]{letter-spacing:.12em !important}
  .sf-idx-card{padding:1rem 1rem 1.15rem}
  .sf-idx-num{font-size:2.9rem}
}
/* never let the sci-fi layer introduce horizontal scroll */
.sf-terminal,.sf-idx-card,.sf-batch-tldr,.sf-idx-desc,#sf-build{max-width:100%;overflow-wrap:anywhere}
