﻿/* ============================================================================
   fx.css —《基础会计》数字教材 · 4D 舱与全站动效层
   ---------------------------------------------------------------------------
   · 唯一色彩来源：本文件 :root 内的令牌（其余规则一律 var(...)，无硬编码色值）
   · 只做 transform / opacity / background-position / stroke-dashoffset，不改布局尺寸
   · prefers-reduced-motion: reduce 与 ?fx=off（body.fx-reduced）下全部关闭，内容完整可见
   · 禁止：模糊发光滤镜、表格行 hover 位移、持续脉冲装饰灯、不可暂停的自动播放
   ========================================================================== */

:root {
  /* 深底 4D 舱（与契约 3.1 一致） */
  --hq-bg: #0B1420;
  --fx-hq-2: #101C2C;
  --fx-hq-3: #142234;
  --hq-line: #243A55;
  --hq-ink: #EAF0F7;
  --hq-brand: #4EC5D4;
  /* fx 专用 */
  --fx-ink-2: #A9BACE;
  --fx-ink-3: #7387A0;
  --fx-brass: #D9A441;
  --fx-brass-soft: #F0E3C8;
  --fx-ledger: #37C08D;
  --fx-alarm: #E4593F;
  --fx-amber: #E0A64B;
  --fx-purple: #8E7CE0;
  --fx-paper: #F7F5F0;
  --fx-rule: #D9D3C6;
  /* 半透明层（rgba，不是硬编码 6 位色值） */
  --fx-holo-line: rgba(18, 58, 99, 0.05);
  --fx-scan-tint: rgba(154, 107, 31, 0.045);
  --fx-glow-tint: rgba(18, 58, 99, 0.05);
  --fx-sheen: rgba(78, 197, 212, 0.10);
  --fx-sheen-warm: rgba(217, 164, 65, 0.13);
  --fx-rule-soft: rgba(185, 177, 160, 0.30);
  --fx-mask-on: rgba(0, 0, 0, 1);
  --fx-mask-off: rgba(0, 0, 0, 0);
  --fx-shadow: 0 18px 44px -24px rgba(11, 20, 32, 0.6);
  --fx-mono: "JetBrains Mono", Consolas, "Cascadia Mono", "Courier New", monospace;
}

[hidden] { display: none !important; }

/* ---------------------------------------------------------------- 关键帧 */
@keyframes fx-in { from { opacity: 0; transform: translate3d(0, 18px, 0) scale(.994); } to { opacity: 1; transform: none; } }
@keyframes fx-in-left { from { opacity: 0; transform: translate3d(-20px, 0, 0); } to { opacity: 1; transform: none; } }
@keyframes fx-pop { 0% { transform: scale(1); } 40% { transform: scale(1.14); } 100% { transform: scale(1); } }
@keyframes fx-holo { 0% { background-position: 0 0, 0 0; } 100% { background-position: 112px 112px, 112px 0; } }
@keyframes fx-scan-y { 0% { transform: translateY(-14%); } 100% { transform: translateY(112%); } }
@keyframes fx-ledger-breathe { 0%, 100% { background-position: 0 0, 0 0; } 50% { background-position: 0 17px, 0 0; } }
@keyframes fx-blink { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }

/* ------------------------------------------------------- 环境层（阅读页） */
/* 账簿横线呼吸：画在正文容器自身的背景层上，文字永远压在它之上，不挡正文 */
body.fx-ready .dtb-main {
  background-image:
    repeating-linear-gradient(180deg, transparent 0 33px, var(--fx-rule-soft) 33px 34px),
    linear-gradient(180deg, var(--fx-holo-line), transparent 46%);
  background-size: 100% 34px, 100% 100%;
  background-repeat: repeat, no-repeat;
  animation: fx-ledger-breathe 16s ease-in-out infinite;
}
/* 扫描带：极低透明度 + multiply，绝不模糊文字 */
body.fx-ready .fx-scanbeam {
  position: fixed; left: 0; right: 0; top: 0; height: 38vh;
  z-index: 3; pointer-events: none; opacity: 1; mix-blend-mode: multiply;
  background: linear-gradient(180deg, var(--fx-mask-off), var(--fx-scan-tint) 48%, var(--fx-mask-off));
  animation: fx-scan-y 11s linear infinite;
}
body.fx-ready .fx-ledger-glow {
  position: fixed; inset: 0; z-index: 3; pointer-events: none; mix-blend-mode: multiply;
  background: radial-gradient(34rem 22rem at var(--fx-x, 50%) var(--fx-y, 22%), var(--fx-glow-tint), var(--fx-mask-off) 72%);
}
body.fx-ready .fx-holo {
  position: absolute; inset: 0; z-index: 0; pointer-events: none; opacity: .55;
  background-image:
    linear-gradient(90deg, var(--fx-holo-line) 1px, transparent 1px),
    linear-gradient(180deg, var(--fx-holo-line) 1px, transparent 1px);
  background-size: 112px 112px, 112px 112px;
  animation: fx-holo 46s linear infinite;
}
/* 全息网格：仅指针径向范围内可见（遮罩外完全透明），5% 淡线不影响任何对比度 */
body.fx-ready::before {
  content: ""; position: fixed; inset: -60px; z-index: 1; pointer-events: none; opacity: .85;
  background-image:
    linear-gradient(90deg, var(--fx-holo-line) 1px, transparent 1px),
    linear-gradient(180deg, var(--fx-holo-line) 1px, transparent 1px);
  background-size: 112px 112px, 112px 112px;
  animation: fx-holo 46s linear infinite;
  -webkit-mask-image: radial-gradient(circle at var(--fx-x, 50%) var(--fx-y, 22%), var(--fx-mask-on) 0, var(--fx-mask-off) 78%);
  mask-image: radial-gradient(circle at var(--fx-x, 50%) var(--fx-y, 22%), var(--fx-mask-on) 0, var(--fx-mask-off) 78%);
}

/* ------------------------------------------------------------ 入场错峰 */
/* 无 JS 时 .fx-in 不会出现，内容默认完全可见 */
body.fx-ready .fx-in { opacity: 0; transform: translate3d(0, 18px, 0); }
body.fx-ready .fx-in.is-visible { animation: fx-in .54s cubic-bezier(.2, .7, .2, 1) both; animation-delay: var(--fx-delay, 0ms); }
body.fx-ready .fx-in-left { opacity: 0; transform: translate3d(-20px, 0, 0); }
body.fx-ready .fx-in-left.is-visible { animation: fx-in-left .5s cubic-bezier(.2, .7, .2, 1) both; animation-delay: var(--fx-delay, 0ms); }

/* --------------------------------------------------- 卡片流光（不裁内容） */
body.fx-ready .metric,
body.fx-ready .entry,
body.fx-ready .stmt,
body.fx-ready .case,
body.fx-ready .quiz,
body.fx-ready .kmap-card,
body.fx-ready .term,
body.fx-ready .cover-card {
  background-image: linear-gradient(105deg, transparent 42%, var(--fx-sheen) 50%, transparent 58%);
  background-size: 260% 100%;
  background-repeat: no-repeat;
  background-position: 132% 0;
  transition: background-position .85s cubic-bezier(.2, .7, .2, 1), box-shadow .3s, border-color .2s;
}
body.fx-ready .metric:hover,
body.fx-ready .entry:hover,
body.fx-ready .stmt:hover,
body.fx-ready .case:hover,
body.fx-ready .kmap-card:hover,
body.fx-ready .term:hover { background-position: -42% 0; }
body.fx-ready .entry { background-image: linear-gradient(105deg, transparent 42%, var(--fx-sheen-warm) 50%, transparent 58%); }

/* ------------------------------------------------- 数字滚动（仅 metric） */
body.fx-ready .metric b.fx-count { font-variant-numeric: tabular-nums; }
body.fx-ready .metric b.fx-bump { animation: fx-pop .42s cubic-bezier(.2, .7, .2, 1); }

/* -------------------------------------------- 4D 舱（canvas + HUD 上下排） */
.fx4d {
  position: relative;
  display: flex;
  flex-direction: column;
  margin: 26px 0;
  border: 1px solid var(--hq-line);
  border-radius: 14px;
  background: var(--hq-bg);
  box-shadow: var(--fx-shadow);
}
.fx4d-canvas {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  max-height: min(58vh, 560px);
  border-radius: 13px 13px 0 0;
  background: var(--hq-bg);
  cursor: grab;
  touch-action: none;
}
.fx4d-canvas:active { cursor: grabbing; }
.fx4d-canvas:focus-visible { outline: 2px solid var(--hq-brand); outline-offset: 2px; }
.fx4d-hud {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px 16px;
  color: var(--hq-ink);
  font-size: .8125rem;
  line-height: 1.65;
}
.fx4d-top { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; justify-content: space-between; }
.fx4d-title { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.fx4d-title b { font-size: 1.02rem; font-weight: 700; color: var(--hq-ink); letter-spacing: .01em; }
.fx4d-title span { font-size: .8125rem; color: var(--hq-brand); letter-spacing: .08em; }
.fx4d-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.fx4d-chip {
  display: flex; flex-direction: column; gap: 1px;
  min-width: 108px; padding: 6px 11px;
  border: 1px solid var(--hq-line); border-radius: 9px; background: var(--hq-bg-2, var(--fx-hq-2));
}
.fx4d-chip i { font-style: normal; font-family: var(--fx-mono); font-size: .9375rem; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--hq-ink); }
.fx4d-chip em { font-style: normal; font-size: .75rem; letter-spacing: .04em; color: var(--hq-ink-3, var(--fx-ink-3)); }
.fx4d-chip-day { min-width: 96px; border-color: var(--hq-brass, var(--fx-brass)); }
.fx4d-chip-day i { font-size: 1.125rem; color: var(--hq-brass, var(--fx-brass)); }
.fx4d-chip-day em { color: var(--hq-ink-2, var(--fx-ink-2)); }
.fx4d-asset i { color: var(--hq-brand); }
.fx4d-liab i { color: var(--fx-amber); }
.fx4d-equity i { color: var(--fx-purple); }
.fx4d-debit i { color: var(--hq-brand); }
.fx4d-credit i { color: var(--hq-brass, var(--fx-brass)); }
.fx4d-ok i { color: var(--hq-ledger, var(--fx-ledger)); }
.fx4d-warn i { color: var(--hq-alarm, var(--fx-alarm)); }
.fx4d-badge {
  align-self: center;
  padding: 5px 13px;
  border: 1px solid var(--hq-line);
  border-radius: 999px;
  font-size: .8125rem; font-weight: 700; letter-spacing: .04em;
  color: var(--hq-ink);
}
.fx4d-badge.ok { border-color: var(--hq-ledger, var(--fx-ledger)); color: var(--hq-ledger, var(--fx-ledger)); }
.fx4d-badge.pending { border-color: var(--fx-amber); color: var(--fx-amber); animation: fx-blink 2.2s ease-in-out infinite; }
.fx4d-badge.alarm { border-color: var(--hq-alarm, var(--fx-alarm)); color: var(--hq-alarm, var(--fx-alarm)); }
.fx4d-legend { display: flex; flex-wrap: wrap; gap: 5px 16px; font-size: .8125rem; color: var(--hq-ink-2, var(--fx-ink-2)); }
.fx4d-lg { display: inline-flex; align-items: center; gap: 6px; }
.fx4d-lg i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; }
.fx4d-foot { display: flex; flex-direction: column; gap: 10px; }
.fx4d-beat {
  display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: baseline;
  padding: 9px 13px; border-left: 3px solid var(--hq-brand); border-radius: 8px; background: var(--hq-bg-2, var(--fx-hq-2));
}
.fx4d-beat b { flex: 0 0 auto; font-size: .8125rem; font-weight: 700; letter-spacing: .04em; color: var(--hq-brand); }
.fx4d-beat span { font-size: .875rem; line-height: 1.7; color: var(--hq-ink); }
.fx4d-ctl { display: flex; flex-wrap: wrap; gap: 10px 16px; align-items: center; }
.fx4d-btn {
  font: inherit; font-size: .8125rem; color: var(--hq-ink);
  background: var(--hq-panel, var(--fx-hq-3)); border: 1px solid var(--hq-line); border-radius: 8px;
  padding: 6px 15px; cursor: pointer;
  transition: background-color .2s, border-color .2s, color .2s;
}
.fx4d-btn:hover { border-color: var(--hq-brand); color: var(--hq-brand); }
.fx4d-btn:focus-visible { outline: 2px solid var(--hq-brand); outline-offset: 2px; }
.fx4d-range { display: flex; align-items: center; gap: 8px; font-size: .8125rem; color: var(--hq-ink-2, var(--fx-ink-2)); }
.fx4d-range input[type="range"] { width: 148px; accent-color: var(--hq-brand); }
.fx4d-range-speed input[type="range"] { width: 104px; }
.fx4d-note { padding-top: 9px; border-top: 1px dashed var(--hq-line); font-size: .8125rem; line-height: 1.75; color: var(--hq-ink-2, var(--fx-ink-2)); }
.fx4d-static-note {
  margin: 0 16px 16px; padding: 10px 13px;
  border: 1px dashed var(--hq-line); border-radius: 8px;
  font-size: .8125rem; line-height: 1.75; color: var(--hq-ink-2, var(--fx-ink-2)); background: var(--hq-bg-2, var(--fx-hq-2));
}
.fx4d-fallback {
  margin: 0 0 22px; padding: 14px 16px;
  border: 1px dashed var(--hq-brass, var(--fx-brass)); border-radius: 12px;
  background: var(--hq-brass-soft, var(--fx-brass-soft)); color: var(--hq-bg);
  font-size: .875rem; line-height: 1.8;
}
.fx4d-fallback b { display: block; margin-bottom: 4px; font-size: .9375rem; }
.fx4d.is-static .fx4d-ctl { display: none; }
.fx4d.is-static .fx4d-canvas { cursor: default; }

/* --------------------------------------------------------------- 封面 */
.cover-fx, .cover-fx-wrap { position: relative; }
.cover-canvas {
  display: block; width: 100%;
  aspect-ratio: 16 / 9; max-height: min(62vh, 600px);
  border-radius: 14px; background: var(--hq-bg);
}
.cover-canvas.is-static { cursor: default; }
.cover-fx-note {
  margin-top: 10px; font-size: .8125rem; line-height: 1.7; color: var(--hq-ink-2, var(--fx-ink-2));
}

/* ------------------------------------------------------------ 指针视差 */
/* 位移量由 JS 计算并夹紧在 ≤6px；此处只声明合成层提示 */
body.fx-ready [data-parallax] { will-change: transform; }

/* --------------------------------------------------- 低动效 / 打印 关闭 */
@media (prefers-reduced-motion: reduce) {
  body.fx-ready::before,
  body.fx-ready .fx-scanbeam,
  body.fx-ready .fx-ledger-glow,
  body.fx-ready .fx-holo { display: none !important; }
  body.fx-ready .dtb-main { animation: none !important; background-image: none; }
  body.fx-ready .fx-in,
  body.fx-ready .fx-in-left { opacity: 1 !important; transform: none !important; animation: none !important; }
  body.fx-ready .metric,
  body.fx-ready .entry,
  body.fx-ready .stmt,
  body.fx-ready .case,
  body.fx-ready .quiz,
  body.fx-ready .kmap-card,
  body.fx-ready .term,
  body.fx-ready .cover-card { transition: none !important; background-position: 132% 0 !important; }
  body.fx-ready .fx4d-badge.pending { animation: none !important; }
  body.fx-ready .metric b.fx-bump { animation: none !important; }
  [data-parallax] { transform: none !important; }
}
body.fx-reduced::before,
body.fx-reduced .fx-scanbeam,
body.fx-reduced .fx-ledger-glow,
body.fx-reduced .fx-holo { display: none !important; }
body.fx-reduced .dtb-main { animation: none !important; background-image: none; }
body.fx-reduced .fx-in,
body.fx-reduced .fx-in-left { opacity: 1 !important; transform: none !important; animation: none !important; }
body.fx-reduced .fx4d-badge.pending { animation: none !important; }
body.fx-reduced [data-parallax] { transform: none !important; }

@media print {
  body.fx-ready::before,
  .fx-scanbeam,
  .fx-ledger-glow,
  .fx-holo { display: none !important; }
  .fx-in, .fx-in-left { opacity: 1 !important; transform: none !important; animation: none !important; }
  .fx4d-ctl { display: none !important; }
  .fx4d { break-inside: avoid; }
}

@media (max-width: 640px) {
  .fx4d-canvas { aspect-ratio: 4 / 3; max-height: none; }
  .fx4d-chip { min-width: 88px; padding: 5px 9px; }
  .fx4d-chip i { font-size: .875rem; }
  .fx4d-range input[type="range"] { width: 108px; }
  .fx4d-hud { padding: 12px 12px 14px; }
  .fx4d-static-note { margin: 0 12px 14px; }
}
