/* 프로그래밍 언어론 13강 전용 스타일: 그림 속 글씨 크기, 코드 상자, 실행 표시, 실행 길, 나무 */

/* 그림 속 글씨는 12px 이상 */
.viz text.s,
.viz text.n,
.viz text.v-num { font-size: 12px; }
.viz text.v-num.big { font-size: 20px; }
.viz text.k { fill: var(--key); font-weight: 700; }
.viz text.v { fill: var(--value); font-weight: 700; }
.viz text.bad { font-weight: 700; }
.viz text.tag { font-size: 12px; font-weight: 700; fill: var(--muted); }
.viz text.fx { transition: opacity 0.3s ease, fill 0.3s ease; }
.viz text.dim { opacity: 0.35; }

/* 코드 글씨 */
.viz text.code {
  font-family: var(--mono);
  font-size: 12.5px;
  fill: var(--text);
}
.viz text.code.m { fill: var(--muted); }
.viz text.code.on { fill: var(--accent); }
.viz text.code.k { fill: var(--key); }
.viz text.code.bad { fill: var(--value); }
.viz text.code tspan { transition: fill 0.3s ease, fill-opacity 0.3s ease; }
.viz text.code tspan.on { fill: var(--accent); font-weight: 700; }
.viz text.code tspan.k { fill: var(--key); font-weight: 700; }
.viz text.code tspan.v,
.viz text.code tspan.bad { fill: var(--value); font-weight: 700; }
.viz text.code tspan.m { fill: var(--muted); }
.viz text.code tspan.hide { fill-opacity: 0; }

/* 코드 상자와 줄 강조 */
.v-code { fill: #0a0c10; stroke: var(--line); }
.v-codeblock { transition: opacity 0.3s ease; }
.v-codeblock.dim { opacity: 0.4; }
.v-codeblock.hide { opacity: 0; }
.v-hl { fill: var(--accent); opacity: 0.2; }
.v-hl.bad { fill: var(--value); opacity: 0.24; }
.v-hl.k { fill: var(--key); opacity: 0.22; }
.v-hl.hide { opacity: 0; }

/* 칩: 틀림(붉은 테두리), 청록 */
.v-chip.bad rect { fill: none; stroke: var(--value); stroke-width: 1.5; }
.v-chip.bad text { fill: var(--value); }
.v-chip.k rect { fill: none; stroke: var(--key); stroke-width: 1.5; }
.v-chip.k text { fill: var(--key); }
.v-chip.kk rect { fill: var(--key); }
.v-chip.kk text { fill: var(--on-accent); }

/* 메모리 칸, 표의 칸 */
.v-cellbox {
  fill: var(--surface-2);
  stroke: transparent;
  stroke-width: 1.5;
  transition: stroke 0.25s ease, fill 0.3s ease, opacity 0.3s ease;
}
.v-cellbox.k { stroke: var(--key); }
.v-cellbox.on { stroke: var(--accent); fill: color-mix(in srgb, var(--accent) 20%, var(--surface)); }
.v-cellbox.bad { stroke: var(--value); fill: color-mix(in srgb, var(--value) 20%, var(--surface)); }
.v-cellbox.dim { opacity: 0.4; }

/* 체크와 가위표 */
.v-mark {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity 0.3s ease;
}
.v-mark.bad { stroke: var(--value); }
.v-mark.hide { opacity: 0; }

/* 틀, 상자 */
.v-frame { transition: stroke 0.3s ease, opacity 0.3s ease; }
.v-frame.bad { stroke: var(--value); }
.v-frame.k { stroke: var(--key); }
.v-frame.soft { fill: none; stroke-dasharray: 3 3; }
.v-box rect { transition: stroke 0.3s ease; }
.v-box.fx { transition: opacity 0.3s ease; }
.v-step { transition: opacity 0.3s ease; }
.v-step.dim { opacity: 0.4; }
.v-step.bad .bg { stroke: var(--value); }

/* 곧은 점선 (V.path 는 길이를 1로 맞추므로 점선은 따로 그린다) */
.v-rule { fill: none; stroke: var(--line); stroke-width: 1.2; }
.v-rule.dot { stroke: var(--muted); stroke-dasharray: 3 4; }
.v-rule.on { stroke: var(--accent); }

/* 선과 화살표의 색 바꾸기 */
.v-line.fx { transition: opacity 0.3s ease, stroke 0.3s ease, stroke-width 0.3s ease; }
.v-line.hide, .v-vector.hide { opacity: 0; }
.v-line.soft { stroke: var(--line); }
.v-vector { transition: opacity 0.3s ease; }
.v-vector line, .v-vector path { transition: stroke 0.3s ease; }
.v-vector.k line, .v-vector.k path { stroke: var(--key); }
.v-vector.bad line, .v-vector.bad path { stroke: var(--value); }
.v-vector.dim { opacity: 0.35; }

.v-line.docline { stroke: #4b5263; }
.v-bar.badsoft { fill: color-mix(in srgb, var(--value) 32%, var(--surface-2)); }
.v-dot.k { fill: var(--key); }
.v-dot.bad { fill: var(--value); }
.v-dot.m { fill: var(--muted); }
.v-bar { transition: opacity 0.3s ease; }
.v-bar.dim { opacity: 0.3; }
.v-tri { fill: var(--accent); }
.v-tri.bad { fill: var(--value); }
.v-grid rect.hide { opacity: 0; }

.fx.off { opacity: 0.18; }
.nb { white-space: nowrap; }

@media (prefers-reduced-motion: reduce) {
  .viz * { transition: none !important; }
}

/* --- 4강에서 더한 것 --- */

/* 코드 상자 안에서 스코프를 칠하는 띠 */
.v-band { fill: var(--accent); opacity: 0.2; stroke: none; }
.v-band.k { fill: var(--key); opacity: 0.3; }
.v-band.bad { fill: var(--value); opacity: 0.26; }
.v-band.hide { opacity: 0; }
.v-band.dim { opacity: 0.07; }

/* 시간 띠: 실행 전(노랑)과 실행 중(청록) */
.v-seg { fill: var(--surface-2); transition: opacity 0.3s ease, fill 0.3s ease; }
.v-seg.pre { fill: color-mix(in srgb, var(--accent) 42%, var(--surface-2)); }
.v-seg.run { fill: color-mix(in srgb, var(--key) 42%, var(--surface-2)); }
.v-seg.on { fill: var(--accent); }
.v-seg.k { fill: var(--key); }
.v-seg.bad { fill: var(--value); }
.v-seg.soft { fill: color-mix(in srgb, var(--key) 55%, var(--surface-2)); }
.v-seg.hide { opacity: 0; }
.v-seg.dim { opacity: 0.3; }

/* 시간 띠 위의 점 */
.v-pin { fill: var(--muted); stroke: var(--bg); stroke-width: 2; transition: opacity 0.3s ease, fill 0.3s ease; }
.v-pin.on { fill: var(--accent); }
.v-pin.k { fill: var(--key); }
.v-pin.bad { fill: var(--value); }
.v-pin.hide { opacity: 0; }

/* 메모리 칸: 돌려준 칸(점선), 청록으로 채운 칸 */
.v-cellbox.ghost { fill: none; stroke: var(--muted); stroke-dasharray: 3 3; }
.v-cellbox.kk { stroke: var(--key); fill: color-mix(in srgb, var(--key) 20%, var(--surface)); }
.v-cellbox.hide { opacity: 0; }
.v-cell2 { transition: opacity 0.3s ease; }
.v-cell2.hide { opacity: 0; }
.v-cell2.dim { opacity: 0.35; }

/* 틀: 청록, 흐림 */
.v-frame.fx { transition: stroke 0.3s ease, opacity 0.3s ease; }
.v-frame.dim { opacity: 0.4; }
.v-frame.hide { opacity: 0; }
.v-frame.dash { stroke-dasharray: 4 3; }

/* 쐐기 (효율과 유연성) */
.v-wedge { fill: var(--accent); opacity: 0.85; }
.v-wedge.k { fill: var(--key); }

/* 글자 색 바꾸기 */
.viz text.fx.off { opacity: 0.25; }
.viz text.code tspan.dim { fill-opacity: 0.35; }
.viz text.code.b { font-weight: 700; }
.viz text.v-num.k { fill: var(--key); }
.viz text.v-num.mid { font-size: 15px; }
.v-chip.bb rect { fill: var(--value); }
.v-chip.bb text { fill: var(--on-accent); }
.v-step.k .bg { stroke: var(--key); }
.v-step.k circle { fill: var(--key); }
.v-step.k text.n { fill: var(--on-accent); }
.v-vector.fx { transition: opacity 0.3s ease; }
.v-vector.on line, .v-vector.on path { stroke: var(--accent); }
.v-line.k.thick, .v-line.on.thick { stroke-width: 3; }
g.fx.hide { opacity: 0; }
g.fx.dim { opacity: 0.35; }

/* --- 13강에서 더한 것 --- */

/* 실행 표시: 코드 왼쪽 여백의 세모 */
.v-run {
  fill: var(--accent);
  transition: transform 0.45s cubic-bezier(0.3, 0.7, 0.3, 1), opacity 0.3s ease, fill 0.3s ease;
}
.v-run.bad { fill: var(--value); }
.v-run.k { fill: var(--key); }
.v-run.hide { opacity: 0; }

/* 코드 줄: 글자 색 바꾸기, 흐리게, 자리 옮기기 */
.viz text.code.fx { transition: opacity 0.3s ease, fill 0.3s ease, transform 0.6s cubic-bezier(0.3, 0.7, 0.3, 1); }
.viz text.code.dim { opacity: 0.32; }
.viz text.code.hide { opacity: 0; }
.viz text.hide { opacity: 0; }
.viz text.k.fx, .viz text.on.fx, .viz text.bad.fx { transition: opacity 0.3s ease, fill 0.3s ease; }
.viz text.sm { font-size: 12px; }

/* 날아가는 딱지 */
.v-tok { transition: opacity 0.3s ease; }
.v-tok.hide { opacity: 0; }
.v-chip.badfill rect { fill: var(--value); }
.v-chip.badfill text { fill: var(--on-accent); }
.v-chip.ghost rect { fill: none; stroke: var(--muted); stroke-dasharray: 3 3; stroke-width: 1.2; }
.v-chip.ghost text { fill: var(--muted); }
.v-chip.fx { transition: opacity 0.3s ease; }

/* 글이 든 칸 */
.v-slotg { transition: opacity 0.3s ease; }
.v-slotg.dim { opacity: 0.35; }
.v-slotg.hide { opacity: 0; }
.v-cellbox.kline { stroke: var(--key); stroke-dasharray: 4 3; fill: none; }

/* 실행 길 */
.v-lane { fill: none; stroke: var(--line); stroke-width: 2.5; stroke-linecap: round; transition: opacity 0.3s ease; }
.v-lane.on { stroke: var(--accent); }
.v-lane.bad { stroke: var(--value); }
.v-lane.k { stroke: var(--key); }
.v-lanedot { fill: var(--bg); stroke: var(--line); stroke-width: 2; transition: fill 0.3s ease, stroke 0.3s ease; }
.v-lanedot.lit.on { fill: var(--accent); stroke: var(--accent); }
.v-lanedot.lit.bad { fill: var(--value); stroke: var(--value); }
.v-lanedot.lit.k { fill: var(--key); stroke: var(--key); }
.v-lanedot.skip.lit { fill: var(--bg); }

/* 나무의 가지 */
.v-rule.branch { stroke: var(--muted); stroke-width: 1.2; }
.v-rule.fx { transition: opacity 0.3s ease, stroke 0.3s ease; }
.v-rule.hide { opacity: 0; }
.v-rule.bad { stroke: var(--value); }
.v-rule.k { stroke: var(--key); }
.v-rule.thick { stroke-width: 2.2; }
.v-rule.dash { stroke-dasharray: 4 4; stroke: var(--muted); }
.v-rule.dash.on { stroke: var(--accent); }
.v-rule.dash.bad { stroke: var(--value); }
.v-rule.dash.k { stroke: var(--key); }

/* 상자와 틀의 색 */
.v-box.k rect { stroke: var(--key); }
.v-box.bad rect { stroke: var(--value); }
.v-box.dim { opacity: 0.35; }
.v-box.hide { opacity: 0; }
.v-frame.kk { stroke: var(--key); fill: color-mix(in srgb, var(--key) 14%, var(--surface)); }
.v-frame.onfill { stroke: var(--accent); fill: color-mix(in srgb, var(--accent) 14%, var(--surface)); }
.v-frame.badfill { stroke: var(--value); fill: color-mix(in srgb, var(--value) 14%, var(--surface)); }
.v-frame.ghost { fill: none; stroke: var(--muted); stroke-dasharray: 4 3; opacity: 0.6; }
.v-mark.k { stroke: var(--key); }
.v-mark.fx { transition: opacity 0.3s ease; }
.v-dot.fx { transition: opacity 0.3s ease, fill 0.3s ease; }
.v-dot.hide { opacity: 0; }
.v-step.bad circle { fill: var(--value); }
.v-step.bad text.n { fill: var(--on-accent); }

/* GUI 그림: 단추, 체크 칸 */
.v-btn { fill: var(--surface-2); stroke: var(--muted); stroke-width: 1.5; transition: fill 0.2s ease, stroke 0.2s ease; }
.v-btn.on { fill: var(--accent); stroke: var(--accent); }
.v-btn.k { stroke: var(--key); }
.v-radio { fill: var(--bg); stroke: var(--muted); stroke-width: 1.5; }
.v-radio-dot { fill: var(--accent); transition: opacity 0.2s ease; }
.v-radio-dot.hide { opacity: 0; }

/* 휘어 가는 화살표 */
.v-bend { transition: opacity 0.3s ease; }
.v-bend .ln { fill: none; stroke: var(--muted); stroke-width: 1.6; stroke-linecap: round; }
.v-bend .hd { fill: var(--muted); }
.v-bend.bad .ln { stroke: var(--value); }
.v-bend.bad .hd { fill: var(--value); }
.v-bend.on .ln { stroke: var(--accent); }
.v-bend.on .hd { fill: var(--accent); }
.v-bend.k .ln { stroke: var(--key); }
.v-bend.k .hd { fill: var(--key); }
.v-bend.dash .ln { stroke-dasharray: 4 4; }
.v-bend.hide { opacity: 0; }
.v-radio.on { stroke: var(--accent); }
