/* ============================================================================
   shenfa.css — "Shenfa and the Goal of Wushu" article view
   Three animated figures + the article chrome that articles.css does not carry.

   Self-contained by design: the figure primitives (.a-fade, .a-rise, .a-pop,
   .a-draw) share their NAMES with sanjie.css but are declared here under
   `.sf-fig`, so this file does not depend on sanjie.css being loaded, on the
   order of the two <link>s, or on sanjie.css continuing to exist.
   All motion is gated on prefers-reduced-motion. Themes with the site.
   ============================================================================ */

/* The accent lives in articles.css with every other article's. It must not be
   repeated here at ID weight: that would outrank the dark-mode remap and leave
   the light green sitting on the dark ground. */

/* figure-local palette — falls back to global --color-* outside .oa-artview */
.sf-fig {
  --fg-ink:  var(--ink,  var(--color-text));
  --fg-soft: var(--ink3, var(--color-text-2));
  --fg-mut:  var(--mut,  var(--color-muted));
  --fg-rule: var(--bd,   var(--color-border));
  --fg-card: var(--surf2, #faf7f1);
  --fg-acc:  var(--acc,  var(--color-accent));
  --fg-accd: var(--accd, #8fc9a3);
  --fg-sage-d:#587a52;
  --fg-night:#5a6a7f;
  --fg-grey2:#b9b0a1;
  /* Motion contract — personality: Premium. One easing for everything on
     screen, three durations, no overshoot anywhere in this article. */
  --fg-e:  cubic-bezier(.4,0,.2,1);
  --fg-e2: cubic-bezier(.2,.7,.2,1);
  --sf-quick: 160ms;
  --sf-std:   320ms;
  --sf-slow:  560ms;
}
:root[data-theme="dark"] .sf-fig {
  --fg-card:#26221e; --fg-sage-d:#a6c39c; --fg-night:#93a7c1; --fg-grey2:#5b544c;
}

/* ---- figure container + reveal ---- */
.sf-fig {
  margin: 34px 0 30px; text-align: center;
  opacity: 0; transform: translateY(16px);
  transition: opacity .7s var(--fg-e), transform .7s var(--fg-e);
}
.sf-fig.in { opacity: 1; transform: none; }
.sf-fig svg { width: 100%; max-width: 600px; height: auto; display: block; margin: 0 auto; overflow: visible; }
.sf-fig figcaption {
  font-family: 'Inter', system-ui, sans-serif; font-size: 12.5px; line-height: 1.55;
  color: var(--fg-mut); text-align: left; margin: 14px auto 0; max-width: 540px;
}
.sf-fig figcaption .fnum {
  font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  font-size: 10.5px; color: var(--fg-acc); margin-right: .5em;
}
.sf-fig figcaption .hanzi { font-family: 'Noto Serif TC', serif; }
.sf-fig text { font-family: 'Inter', system-ui, sans-serif; fill: var(--fg-soft); }
.sf-fig text.zh { font-family: 'Noto Serif TC', serif; }
.sf-fig .t-sm  { font-size: 11px; fill: var(--fg-mut); }
.sf-fig .t-tiny{ font-size: 9.5px; fill: var(--fg-mut); }
.sf-fig .t-hd  { font-size: 12.5px; font-weight: 700; letter-spacing: .12em; fill: var(--fg-night); }

/* ---- animation primitives (play when .sf-fig gets .in) ---- */
.sf-fig .a-fade { opacity: 0; transition: opacity .6s var(--fg-e); transition-delay: var(--d,0s); }
.sf-fig.in .a-fade { opacity: 1; }

.sf-fig .a-rise { opacity: 0; transform: translateY(12px); transition: opacity .6s var(--fg-e), transform .6s var(--fg-e); transition-delay: var(--d,0s); }
.sf-fig.in .a-rise { opacity: 1; transform: none; }

.sf-fig .a-pop { opacity: 0; transform: scale(.4); transform-box: fill-box; transform-origin: center; transition: opacity .4s var(--fg-e), transform .5s cubic-bezier(.34,1.56,.64,1); transition-delay: var(--d,0s); }
.sf-fig.in .a-pop { opacity: 1; transform: scale(1); }

.sf-fig .a-draw { stroke-dasharray: var(--len,1); stroke-dashoffset: var(--len,1); transition: stroke-dashoffset 1.15s var(--fg-e2); transition-delay: var(--d,0s); }
.sf-fig.in .a-draw { stroke-dashoffset: 0; }

@media (prefers-reduced-motion: reduce) {
  .sf-fig,
  .sf-fig .a-fade, .sf-fig .a-rise, .sf-fig .a-pop, .sf-fig .a-draw {
    opacity: 1 !important; transform: none !important; stroke-dashoffset: 0 !important; transition: none !important;
  }
}

/* ============================================================================
   The three instruments
   Shared shell first, then each one. Everything interactive keeps a visible
   focus ring: these are the only controls inside the reading column.
   ============================================================================ */
.sf-inst .sf-holder { position: relative; }
.sf-inst svg { max-width: 640px; }
/* the threshold chart carries its legend outside the plot, so it is drawn on a
   wider canvas and needs the extra room to scale into */
.sf-inst#sff-thresh svg { max-width: 700px; }
.sf-inst :focus-visible { outline: 2px solid var(--acc); outline-offset: 3px; border-radius: 3px; }

/* readout panels (secondary layer) */
.sf-panel {
  max-width: 560px; margin: 14px auto 0; padding: 12px 15px;
  background: var(--surf2); border: 1px solid var(--bd); border-left: 3px solid var(--acc);
  border-radius: 9px; text-align: left;
  font-family: 'Inter', system-ui, sans-serif;
}
.sf-panel.swap { animation: sf-swap var(--sf-std) var(--fg-e); }
@keyframes sf-swap { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.sf-panel-head { display: flex; align-items: baseline; gap: .6em; }
.sf-panel-han { font-family: 'Noto Serif TC', serif; font-size: 1.32rem; color: var(--acc); line-height: 1.2; }
.sf-panel-rom { font-size: 12px; color: var(--mut); font-style: italic; }
.sf-panel-gloss { font-size: 13px; color: var(--ink3); margin-top: 2px; font-weight: 600; }
.sf-panel-body { font-size: 12.5px; line-height: 1.6; color: var(--mut); margin: .5em 0 0; }

/* ---- 1 · the Twelve Forms range ---- */
.sf-node { cursor: pointer; }
.sf-node .sf-node-ring { opacity: 0; transform-box: fill-box; transform-origin: center; transform: scale(.7);
  transition: opacity var(--sf-quick) var(--fg-e), transform var(--sf-quick) var(--fg-e); }
.sf-node .sf-node-dot { transform-box: fill-box; transform-origin: center;
  transition: transform var(--sf-quick) var(--fg-e), fill var(--sf-quick) var(--fg-e); }
.sf-node .sf-node-lbl { fill: var(--fg-mut); transition: fill var(--sf-quick) var(--fg-e), font-weight var(--sf-quick); }
.sf-node:hover .sf-node-dot { transform: scale(1.28); }
.sf-node:hover .sf-node-lbl { fill: var(--fg-soft); }
.sf-node.is-on .sf-node-ring { opacity: 1; transform: scale(1); }
.sf-node.is-on .sf-node-dot { transform: scale(1.35); }
.sf-node.is-on .sf-node-lbl { fill: var(--fg-acc); font-weight: 700; }
/* ambient: the selected node keeps the faintest pulse, on screen only */
.sf-fig.amb .sf-node.is-on .sf-node-ring { animation: sf-breathe 3.2s var(--fg-e) infinite; }
@keyframes sf-breathe { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .5; transform: scale(1.14); } }

/* ---- 2 · the threshold scrub ---- */
.sf-hit { cursor: ew-resize; }
.sf-scrub { cursor: ew-resize; }
.sf-scrub line, .sf-scrub circle { transition: transform var(--sf-quick) var(--fg-e); }
.sf-scrub circle:last-of-type { transition: r var(--sf-quick) var(--fg-e); }
.sf-inst svg.is-drag .sf-scrub circle:last-of-type { r: 8; }
.sf-panel--read { max-width: 470px; }
.sf-phase { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; font-weight: 700; color: var(--acc); margin-bottom: .7em; }
.sf-row { display: grid; grid-template-columns: 1fr 96px 62px; align-items: center; gap: 10px; margin: 5px 0; }
.sf-row-lbl { font-size: 12px; color: var(--ink3); }
.sf-row-track { height: 5px; border-radius: 3px; background: var(--bd); overflow: hidden; }
.sf-row-fill { display: block; height: 100%; width: 100%; transform-origin: left center; transform: scaleX(0);
  transition: transform var(--sf-std) var(--fg-e); }
.sf-row-val { font-size: 11.5px; color: var(--mut); text-align: right; font-variant-numeric: tabular-nums; }

/* ---- 3 · the chain, drawn through a body ---- */
.sf-chainfig .sf-holder { max-width: 640px; margin: 0 auto; }
.sf-stage { position: relative; }
.sf-body { width: 100%; max-width: 640px; height: auto; display: block; margin: 0 auto; }
/* the body's own greys: the chain reads in --fg-link, everything that is not
   the chain (front leg, guard arm, head) recedes to --fg-quiet */
.sf-fig { --fg-link: var(--ink3, #4b4540); --fg-quiet: var(--fg-grey2); }
:root[data-theme="dark"] .sf-fig { --fg-link: var(--ink3, #cbc3b6); }

.sf-ctl { max-width: 560px; margin: 12px auto 0; font-family: 'Inter', system-ui, sans-serif; text-align: left; }
.sf-ctl-row { display: flex; align-items: center; gap: 12px; margin: 8px 0; flex-wrap: wrap; }
.sf-ctl-lbl { font-size: 11px; text-transform: uppercase; letter-spacing: .1em; font-weight: 700; color: var(--mut); min-width: 52px; }
.sf-ctl-end { font-size: 11px; color: var(--mut); }

.sf-seg { display: inline-flex; border: 1px solid var(--bd); border-radius: 7px; overflow: hidden; }
.sf-seg button {
  font: inherit; font-size: 12px; padding: 5px 13px; border: 0; cursor: pointer;
  background: var(--surf2); color: var(--ink3);
  transition: background var(--sf-quick) var(--fg-e), color var(--sf-quick) var(--fg-e);
}
.sf-seg button + button { border-left: 1px solid var(--bd); }
.sf-seg button:hover { background: var(--bd); }
.sf-seg button.is-on { background: var(--acc); color: #fff; }
.sf-seg button:active { transform: translateY(1px); transition: transform 130ms var(--fg-e); }

.sf-range { flex: 1 1 170px; min-width: 130px; accent-color: var(--acc); cursor: pointer; }
.sf-range:disabled { cursor: not-allowed; opacity: .4; }
.sf-ctl.is-frozen .sf-ctl-end { opacity: .4; }

.sf-fire {
  font: inherit; font-size: 12px; font-weight: 600; padding: 6px 16px; cursor: pointer;
  border: 1px solid var(--acc); border-radius: 7px; background: transparent; color: var(--acc);
  transition: background var(--sf-quick) var(--fg-e), color var(--sf-quick) var(--fg-e);
}
.sf-fire:hover { background: var(--acc); color: #fff; }
.sf-fire:active { transform: translateY(1px); transition: transform 130ms var(--fg-e); }

.sf-out { font-size: 12px; color: var(--ink3); flex: 1 1 240px; }
.sf-out-l.swap { display: inline-block; animation: sf-swap var(--sf-std) var(--fg-e); }
.sf-pulse { width: 100%; max-width: 560px; height: auto; display: block; margin: 2px auto 10px; overflow: visible; }
.sf-pulse text { font-family: 'Inter', system-ui, sans-serif; fill: var(--fg-mut); }
.sf-pulse .t-tiny { font-size: 9px; }
.sf-pulse path { transition: d var(--sf-std) var(--fg-e); }

@media (prefers-reduced-motion: reduce) {
  .sf-panel.swap, .sf-out-v.swap, .sf-stage.is-booting::after,
  .sf-fig.amb .sf-node.is-on .sf-node-ring { animation: none !important; }
  .sf-node .sf-node-ring, .sf-node .sf-node-dot, .sf-node .sf-node-lbl,
  .sf-row-fill, .sf-seg button, .sf-fire, .sf-scrub line, .sf-scrub circle { transition: none !important; }
}

@media (max-width: 640px) {
  .sf-row { grid-template-columns: 1fr 70px 54px; gap: 8px; }
  .sf-ctl-row { gap: 8px; }
}

/* ============================================================================
   Article chrome specific to views/shenfa.html
   (the companion oa-* classes come from articles.css; these are the extras)
   ============================================================================ */
#view-shenfa sup.oa-fn { font-size: .62em; line-height: 0; vertical-align: super; }
#view-shenfa sup.oa-fn a { color: var(--acc); text-decoration: none; font-weight: 700; }

#view-shenfa .oa-h3 { font-family: 'Spectral', Georgia, serif; font-weight: 700; font-size: 1.16rem; color: var(--ink); margin: 2.1em 0 .45em; line-height: 1.3; }
#view-shenfa .oa-lede-p { font-size: 1.1em; color: var(--ink3); }

#view-shenfa .oa-epi { margin: 1.5em 0; padding: .2em 0 .2em 1.1em; border-left: 2px solid var(--acc); font-family: 'Spectral', serif; font-style: italic; color: var(--ink3); font-size: 1.02rem; }
#view-shenfa .oa-epi .small { font-size: .86em; color: var(--mut); }
#view-shenfa .oa-epi cite { display: block; font-style: normal; font-size: .8rem; color: var(--mut); margin-top: .5em; }
#view-shenfa .oa-epi cite::before { content: "— "; }
#view-shenfa .oa-epi .hanzi { font-family: 'Noto Serif TC', serif; font-style: normal; }

#view-shenfa .oa-thesis { margin: 1.7em 0; padding: 1.05em 1.35em; background: var(--surf2); border: 1px solid var(--bd); border-left: 3px solid var(--acc); border-radius: 9px; }
#view-shenfa .oa-thesis-lbl { display: block; font-family: 'Inter', sans-serif; text-transform: uppercase; letter-spacing: .1em; font-size: .68rem; font-weight: 700; color: var(--acc); margin-bottom: .45em; }
#view-shenfa .oa-thesis p { margin: 0; font-size: .98rem; }

#view-shenfa .oa-tablewrap { overflow-x: auto; margin: 1.5em 0; -webkit-overflow-scrolling: touch; }
#view-shenfa .oa-table { border-collapse: collapse; width: 100%; min-width: 540px; font-family: 'Inter', sans-serif; font-size: .82rem; line-height: 1.45; }
#view-shenfa .oa-table th, #view-shenfa .oa-table td { border: 1px solid var(--bd); padding: .55em .7em; vertical-align: top; text-align: left; }
#view-shenfa .oa-table th { background: var(--surf2); color: var(--acc); font-weight: 700; }
#view-shenfa .oa-table td:first-child { font-family: 'Noto Serif TC', serif; font-size: 1.05rem; white-space: nowrap; color: var(--acc); }
#view-shenfa .oa-table td:nth-child(2) { font-style: italic; white-space: nowrap; }
#view-shenfa .hanzi { font-family: 'Noto Serif TC', serif; }

#view-shenfa .oa-sources .oa-h2 { font-size: 1.4rem; }
#view-shenfa .oa-srcs { columns: 2; column-gap: 2.2em; list-style: none; padding: 0; margin: .4em 0 0; font-family: 'Inter', sans-serif; font-size: .8rem; line-height: 1.52; color: var(--ink3); }
#view-shenfa .oa-srcs li { margin: 0 0 .85em; break-inside: avoid; -webkit-column-break-inside: avoid; }
#view-shenfa .oa-srcs li .n { color: var(--acc); font-weight: 700; margin-right: .3em; }
#view-shenfa .oa-srcs em { font-style: italic; }

#view-shenfa .oa-summary-lbl { font-family: 'Inter', sans-serif; text-transform: uppercase; letter-spacing: .12em; font-size: .68rem; font-weight: 700; color: var(--acc); margin-bottom: .5em; }

@media (max-width: 640px) {
  #view-shenfa .oa-srcs { columns: 1; }
  #view-shenfa .oa-table td:first-child,
  #view-shenfa .oa-table td:nth-child(2) { white-space: normal; }
}
