/* 架构介绍页的客户端全景图（arch.js）。颜色沿用 site.css 的变量。 */

/* 这一篇没有导语和第一节的小标题：说明直接接在大标题下面。 */
.article-head {
  margin-bottom: 18px;
}

#overview {
  padding-top: 0;
}

.fig {
  --fig-bg: #08111e;
  --ok: #9fdcae;
  --violet: #d9b8f6;
  position: relative;
  margin: 26px 0 14px;
  border: 1px solid var(--line-strong);
  background:
    radial-gradient(120% 70% at 50% 0%, rgba(142, 198, 242, 0.07), transparent 65%),
    var(--fig-bg);
}

/* 左上、右下两个蓝图刻度角 */
.fig::before,
.fig::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border: 0 solid var(--accent);
  pointer-events: none;
}

.fig::before {
  top: -1px;
  left: -1px;
  border-top-width: 2px;
  border-left-width: 2px;
}

.fig::after {
  right: -1px;
  bottom: -1px;
  border-right-width: 2px;
  border-bottom-width: 2px;
}

/* ---- 标题栏：运行指示、编号、名字、播放/暂停、从头播放 ---- */

.fig-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px 8px 16px;
  border-bottom: 1px dashed var(--line);
  font: 12px/1.4 var(--mono);
}

.fig-live {
  flex: none;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--faint);
}

.fig.is-running .fig-live {
  background: var(--hot);
  animation: fig-live 1.6s ease-out infinite;
}

@keyframes fig-live {
  from { box-shadow: 0 0 0 0 rgba(242, 160, 103, 0.55); }
  to { box-shadow: 0 0 0 8px rgba(242, 160, 103, 0); }
}

.fig-id {
  color: var(--accent);
  letter-spacing: 0.12em;
}

.fig-name {
  flex: 1;
  min-width: 0;
  color: var(--muted);
  font-family: var(--sans);
  font-size: 13px;
}

.fig-btn {
  display: grid;
  flex: none;
  place-items: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.fig-btn:hover,
.fig-btn:focus-visible {
  border-color: var(--accent);
  background: rgba(142, 198, 242, 0.08);
  color: var(--accent-strong);
}

.fig-btn svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
}

.fig-btn .i-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
}

.fig-btn .i-play,
.fig.is-paused .fig-btn .i-pause {
  display: none;
}

.fig.is-paused .fig-btn .i-play {
  display: block;
}

/* ---- 图：窄屏上保持最小宽度、横向滑动 ---- */

.fig-stage {
  overflow-x: auto;
  padding: 12px;
}

.fig-svg {
  display: block;
  width: 100%;
  min-width: 720px;
  height: auto;
  overflow: visible;
}

.fig .fig-hint {
  display: none;
  margin: 10px 16px 0;
  color: var(--faint);
  font: 12px/1.4 var(--mono);
  text-align: center;
}

.fig-svg text {
  fill: var(--text);
  font-family: var(--sans);
  font-size: 13px;
}

.fig-svg .mono {
  font-family: var(--mono);
}

.zone {
  fill: rgba(142, 198, 242, 0.025);
  stroke: var(--line);
  stroke-dasharray: 6 6;
}

.fig-svg .zone-label {
  fill: var(--faint);
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  paint-order: stroke;
  stroke: var(--fig-bg);
  stroke-width: 8px;
  stroke-linejoin: round;
}

/* 连线上的虚线一直往前流，图停下时一起停 */
.wire {
  fill: none;
  stroke: rgba(142, 198, 242, 0.26);
  stroke-width: 1.2;
  stroke-dasharray: 3 5;
  animation: wire-flow 1.4s linear infinite;
}

.wire-load {
  stroke: rgba(217, 184, 246, 0.3);
}

@keyframes wire-flow {
  to { stroke-dashoffset: -16; }
}

.fig:not(.is-running) .wire {
  animation-play-state: paused;
}

/* ---- 包和它的各部分 ---- */

.pkg-box {
  fill: rgba(217, 184, 246, 0.04);
  stroke: rgba(217, 184, 246, 0.45);
  stroke-dasharray: 5 4;
}

.fig-svg .pkg-title {
  fill: var(--violet);
  font-size: 14px;
  font-weight: 600;
}

.fig-svg .pkg-note {
  fill: var(--faint);
  font-size: 11.5px;
}

.chip rect {
  fill: #0d1a2c;
  stroke: var(--line-strong);
  transition: fill 0.35s ease, stroke 0.35s ease;
}

.fig-svg .chip text {
  fill: var(--muted);
  font-size: 12.5px;
  transition: fill 0.35s ease;
}

.chip.is-loaded rect {
  fill: #141a2e;
  stroke: rgba(217, 184, 246, 0.55);
}

.fig-svg .chip.is-loaded text {
  fill: var(--violet);
}

.chip.is-active rect {
  fill: #23193a;
  stroke: var(--violet);
  stroke-width: 2;
  animation: chip-glow 1.2s ease-in-out infinite alternate;
}

.fig-svg .chip.is-active text {
  fill: #ffffff;
}

@keyframes chip-glow {
  to { fill: #2e2148; }
}

/* ---- 节点 ---- */

.node rect {
  fill: #0d1a2c;
  stroke: var(--line-strong);
  stroke-width: 1;
  transition: fill 0.35s ease, stroke 0.35s ease;
}

.fig-svg .node-title {
  font-size: 14px;
  font-weight: 600;
  transition: fill 0.35s ease;
}

.fig-svg .node-sub {
  fill: var(--muted);
  font-size: 11.5px;
}

.fig-svg .call {
  fill: var(--accent);
  font-family: var(--mono);
  font-size: 11.5px;
}

.fig-svg .engine-frame {
  fill: var(--accent);
  font-size: 12px;
}

.node-ext rect {
  stroke-dasharray: 5 4;
}

.node.is-lit rect {
  fill: #10253d;
  stroke: var(--accent);
}

.node.is-lit .node-title {
  fill: var(--accent-strong);
}

.node.is-pulse rect {
  animation: node-pulse 0.7s ease-out;
}

@keyframes node-pulse {
  from {
    fill: #1b3a5c;
    stroke: #ffffff;
    stroke-width: 4;
  }
}

/* 引擎里的单位：规则载入后出现，执行指令后移动 */
.units path {
  fill: var(--ok);
  opacity: 0;
  transition: opacity 0.4s ease, transform 1.1s cubic-bezier(0.45, 0, 0.2, 1);
}

.units.is-shown path {
  opacity: 1;
}

.units.is-moved path {
  transform: translateX(28px);
}

/* ---- 渲染里的两条刻度：逻辑帧和画面帧 ---- */

.fig-svg .lane-label {
  fill: var(--faint);
  font-size: 11.5px;
  transition: fill 0.35s ease;
}

.lane {
  stroke: var(--line-strong);
}

.tick-logic {
  stroke: var(--hot);
  stroke-width: 3;
}

.tick-display {
  stroke: var(--accent);
  stroke-width: 1.6;
}

.tick-logic.is-fresh,
.tick-display.is-fresh {
  stroke: #ffffff;
}

.now {
  stroke: var(--accent-strong);
  stroke-dasharray: 3 3;
}

.fig-svg .node-render.is-focus .lane-label {
  fill: var(--text);
}

.node-render.is-focus .tick-display {
  stroke-width: 2.4;
}

/* ---- 数据包 ---- */

.pkt-core {
  fill: var(--accent-strong);
}

.pkt-halo {
  fill: var(--accent);
  opacity: 0.22;
}

.fig-svg .pkt text {
  fill: var(--accent-strong);
  font-family: var(--mono);
  font-size: 11px;
  paint-order: stroke;
  stroke: var(--fig-bg);
  stroke-width: 5px;
  stroke-linejoin: round;
}

.pkt.load .pkt-core,
.pkt.load .pkt-halo,
.fig-svg .pkt.load text {
  fill: var(--violet);
}

.pkt.ok .pkt-core,
.pkt.ok .pkt-halo,
.fig-svg .pkt.ok text {
  fill: var(--ok);
}

.pkt.warm .pkt-core,
.pkt.warm .pkt-halo,
.fig-svg .pkt.warm text {
  fill: var(--hot);
}

.pkt.fd .pkt-core,
.fig-svg .pkt.fd text {
  fill: #ffffff;
}

.pkt.fd .pkt-halo {
  fill: var(--accent-strong);
  opacity: 0.3;
}

.ripple {
  fill: none;
  stroke: var(--accent-strong);
  stroke-width: 2;
}

/* ---- 步骤按钮和说明 ---- */

.fig-steps-rows {
  display: grid;
  gap: 6px;
}

.fig-steps-row {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr);
  align-items: center;
  padding: 0 12px 0 16px;
}

.fig-steps-row .grp {
  color: var(--faint);
  font: 12px/1.3 var(--mono);
}

.fig .fig-steps {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.fig .fig-steps li {
  display: flex;
  color: inherit;
  font-size: inherit;
}

.fig-steps button {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 8px;
  width: 100%;
  padding: 8px 10px 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--muted);
  font: 13px/1.35 var(--sans);
  text-align: left;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.fig-steps button:hover {
  border-color: var(--line-strong);
  color: var(--text);
}

.fig-steps .n {
  flex: none;
  color: var(--faint);
  font-family: var(--mono);
  font-size: 11px;
}

.fig-steps .bar {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 2px;
  background: var(--accent);
  transform: scaleX(var(--p, 0));
  transform-origin: left;
}

.fig-steps button.is-done {
  color: #b5c6d8;
}

.fig-steps button.is-done .bar {
  background: rgba(142, 198, 242, 0.35);
}

.fig-steps button.is-current {
  border-color: var(--accent);
  background: rgba(142, 198, 242, 0.08);
  color: var(--text);
}

.fig-steps button.is-current .n {
  color: var(--accent);
}

/* 所有说明叠在同一格里，高度取最长的一条，切换时不跳版 */
.fig-captions {
  display: grid;
  padding: 14px 16px 16px;
}

.article .fig-captions p {
  grid-area: 1 / 1;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s 0.35s;
}

.article .fig-captions p.is-current {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
}

/* ---- 各部分的规则 ---- */

.vm-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
  margin: 18px 0;
}

.vm-card {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-top: 2px solid var(--accent);
  background: var(--panel-solid);
}

.vm-card.vm-page {
  border-top-color: var(--hot);
}

.vm-card.vm-proxy {
  border-top-color: var(--violet, #d9b8f6);
}

.vm-card.vm-render {
  border-top-color: #9fdcae;
}

.article .vm-card h3 {
  margin: 0 0 8px;
  font-size: 16px;
}

.article .vm-card p {
  font-size: 14.5px;
}

/* ---- 窄屏 ---- */

@media (max-width: 760px) {
  .fig .fig-hint {
    display: block;
  }

  .vm-cards {
    grid-template-columns: minmax(0, 1fr);
  }

  .fig-steps-row {
    grid-template-columns: minmax(0, 1fr);
    gap: 4px;
    padding: 0 12px;
  }

  .fig .fig-steps {
    grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  }
}

@media (prefers-reduced-motion: reduce) {
  .fig *,
  .fig *::before,
  .fig *::after {
    animation: none !important;
    transition: none !important;
  }
}
