/* Academiq v4 instruments: sizing and state colours only. Tokens from tokens.css.
   Defaults use :where() so base.css / home.css / pages.css can override without specificity fights. */

[data-instrument]{pointer-events:none}
[data-instrument="sort"]{pointer-events:auto}
canvas[data-instrument],.ins-cv{display:block;width:100%;height:100%}
:where([data-instrument]:not(canvas):not(svg):not([data-instrument="states"]):not([data-instrument="method"])){position:relative}
[data-instrument]>.ins-cv{position:absolute;inset:0}

/* default boxes (fixed aspect so nothing shifts layout) */
:where([data-instrument="rule110"]){min-height:48px}
:where([data-instrument="tape"]){height:52px}
:where([data-instrument="sort"]){height:72px}
:where([data-instrument="life"]){aspect-ratio:1/1;max-width:280px}
:where([data-instrument="rotor"]){aspect-ratio:1/1}
:where([data-instrument="ita2"]){height:28px}
:where([data-instrument="bits"]){height:56px}
:where([data-instrument="bcdclock"]){height:28px;width:76px}
:where([data-instrument="grayscott"]){width:108px;height:108px;aspect-ratio:1/1;border-radius:var(--r-round,999px)}
:where([data-instrument="guilloche"]){position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
:where(svg.fsm){width:40px;height:20px;flex:none}

/* rotor sits behind/around a mentor photo */
:where([data-instrument="rotor"].rotor-ring){position:absolute;inset:0;width:100%;height:100%}

/* states: .stat children cycle */
:where([data-instrument="states"] .stat){transition:background var(--t2,240ms) var(--ease,ease),color var(--t2,240ms) var(--ease,ease)}
:where([data-instrument="states"] .stat.is-on){background:var(--violet);color:#fff}

/* cross-highlights written by instruments onto page elements */
:where(.course.is-hl){box-shadow:var(--seat,none),var(--lift,none)}
:where(.sweden-step.is-visited){box-shadow:inset 0 3px 0 var(--mint)}

/* method graph (SVG overlay on .sweden-steps) */
svg.mg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.mg-edge{fill:none;stroke:var(--rule);stroke-width:1.5;transition:stroke var(--t2,240ms)}
.mg-edge.on{stroke:var(--mint)}
.mg-back{stroke-dasharray:3 3}
.mg-node{fill:var(--s2);stroke:var(--ink-3);stroke-width:1.5;pointer-events:all;transition:fill var(--t1,120ms)}
.mg-node.on{fill:var(--mint);stroke:var(--mint)}
.mg-node.cur{stroke:var(--blue);stroke-width:3}
.mg-node.fail{fill:var(--err);stroke:var(--err);stroke-width:3}

/* fsm glyph */
.fsm .fs-n{fill:none;stroke:var(--ink-3);stroke-width:1.25}
.fsm .fs-n.on{fill:var(--mint);stroke:var(--mint)}
.fsm .fs-a{fill:none;stroke:var(--ink-3);stroke-width:1.25;stroke-linecap:square;stroke-dasharray:16;stroke-dashoffset:0}
.fsm.go .fs-a{animation:fsm-go var(--t3,480ms) var(--ease,ease)}
@keyframes fsm-go{from{stroke-dashoffset:16}to{stroke-dashoffset:0}}

/* cipher overlay: real text stays in the DOM, transparent while ciphertext overlays it */
[data-cipher]{position:relative}
.cph-on{color:transparent !important;-webkit-text-fill-color:transparent}
.cph{position:absolute;white-space:nowrap;pointer-events:none;margin:0;padding:0}

@media (prefers-reduced-motion:reduce){
  .fsm.go .fs-a{animation:none}
  .mg-edge,.mg-node,[data-instrument="states"] .stat{transition:none}
}
