/* Motion art directions. html[data-fx] picks one; html[data-slow] plays everything 3x slower.
   Five directions, one shared rule: nothing flashes, every move is under ~2 s, and the work is the anchor. */

@property --sweep { syntax: "<angle>"; inherits: true; initial-value: 0deg; }
@property --rl { syntax: "<length>"; inherits: true; initial-value: 0px; }
@property --hole { syntax: "<length>"; inherits: false; initial-value: 0px; }
@property --rl2 { syntax: "<length>"; inherits: false; initial-value: 6px; }

:root { --fx-speed: 1; --fx-ease: cubic-bezier(0.65, 0, 0.35, 1); --fx-out: cubic-bezier(0.16, 1, 0.3, 1); }
:root[data-slow] { --fx-speed: 3; }

/* ---------- page transitions (tile -> sheet, sheet -> sheet) ---------- */
@view-transition { navigation: auto; }
::view-transition-group(*) { animation-duration: calc(560ms * var(--fx-speed)); animation-timing-function: var(--fx-out); }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: calc(380ms * var(--fx-speed)); }

/* acquisition: the new page opens as a widening ring from where you clicked */
:root[data-fx="acquisition"]::view-transition-old(root) { animation: none; }
:root[data-fx="acquisition"]::view-transition-new(root) { animation: vt-ring calc(760ms * var(--fx-speed)) var(--fx-ease) both; }
@keyframes vt-ring {
  from { clip-path: circle(0 at var(--vx, 50%) var(--vy, 50%)); }
  to { clip-path: circle(150% at var(--vx, 50%) var(--vy, 50%)); }
}

/* boot: blast doors part from a center seam */
:root[data-page="boot"]::view-transition-old(root), :root[data-page="both"]::view-transition-old(root) { animation: none; }
:root[data-page="boot"]::view-transition-new(root) { animation: vt-shutter calc(620ms * var(--fx-speed)) var(--fx-ease) both; }
@keyframes vt-shutter { from { clip-path: inset(50% 0 50% 0); } to { clip-path: inset(0 0 0 0); } }

/* optics: push through the lens, then rack focus on the new page */
:root[data-fx="optics"]::view-transition-old(root) { animation: vt-push calc(520ms * var(--fx-speed)) var(--fx-ease) both; }
:root[data-fx="optics"]::view-transition-new(root) { animation: vt-focus calc(640ms * var(--fx-speed)) var(--fx-out) calc(120ms * var(--fx-speed)) both; }
@keyframes vt-push { to { transform: scale(1.05); filter: blur(10px); opacity: 0; } }
@keyframes vt-focus { from { transform: scale(0.97); filter: blur(12px); opacity: 0; } }

/* raster: the new page arrives as an interlaced feed */
:root[data-page="raster"]::view-transition-old(root) { animation: none; }
:root[data-page="raster"]::view-transition-new(root) {
  mask-image: repeating-linear-gradient(to bottom, #000 0 var(--rl), transparent var(--rl) 6px);
  animation: vt-raster calc(640ms * var(--fx-speed)) var(--fx-ease) both;
}
@keyframes vt-raster { from { --rl: 0px; } to { --rl: 6px; } }

/* both: the shutter opens from the seam, and what shows through it is an interlaced feed thickening to whole */
:root[data-page="both"]::view-transition-new(root) {
  mask-image: repeating-linear-gradient(to bottom, #000 0 var(--rl), transparent var(--rl) 6px);
  animation: vt-shutter calc(560ms * var(--fx-speed)) var(--fx-ease) both, vt-raster calc(820ms * var(--fx-speed)) var(--fx-ease) both;
}

/* ---------- the work resolving inside a figure ---------- */
.fig .fxbox { position: absolute; pointer-events: none; opacity: 0; overflow: hidden; }
.fig.instant .fxbox { display: none; }
:root:not([data-fx="drafting"]) .fig .scan, :root[data-work] .fig .scan { display: none; }

/* acquisition: a radar sweep paints the work in, trailing a faint wedge */
:root[data-fx="acquisition"] .fig .media { clip-path: none; mask-image: conic-gradient(from 0deg, #000 var(--sweep), transparent var(--sweep)); }
:root[data-fx="acquisition"] .fig.resolved { animation: fx-sweep calc(1300ms * var(--fx-speed)) linear forwards; }
:root[data-fx="acquisition"] .fig.resolved .media { transition: none; }
:root[data-fx="acquisition"] .fig.resolved .fxbox {
  opacity: 1;
  background: conic-gradient(from calc(var(--sweep) - 40deg), transparent 0deg, color-mix(in srgb, var(--signal) 26%, transparent) 40deg, transparent 40.5deg);
  animation: fx-fade calc(300ms * var(--fx-speed)) ease calc(1300ms * var(--fx-speed)) forwards;
}
@keyframes fx-sweep { from { --sweep: 0deg; } to { --sweep: 360deg; } }
@keyframes fx-fade { to { opacity: 0; } }

/* boot: the work arrives as packets, cell by cell (cells are made in kit.js) */
:root[data-work="boot"] .fig .media { clip-path: none; opacity: 0; }
:root[data-work="boot"] .fig.resolved .media { opacity: 1; transition: none; }
:root[data-work="boot"] .fig.resolved .fxbox, :root[data-work="both"] .fig.resolved .fxbox { opacity: 1; display: grid; }
.fxbox .cell { background: var(--ground); }
.fxbox .cell.hot { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--signal) 70%, transparent); background: color-mix(in srgb, var(--ground) 82%, var(--signal)); }

/* both: packets land as scanlined cells, and the work arrives in grayscale before its color settles */
:root[data-work="both"] .fig .media { clip-path: none; opacity: 0; filter: grayscale(1) contrast(1.15); }
:root[data-work="both"] .fig.resolved .media { opacity: 1; filter: none; transition: filter calc(800ms * var(--fx-speed)) ease calc(900ms * var(--fx-speed)); }
:root[data-work="both"] .fxbox .cell { background: var(--ground); }
:root[data-work="both"] .fxbox .cell.hot {
  background: repeating-linear-gradient(to bottom, color-mix(in srgb, var(--signal) 34%, transparent) 0 1px, var(--ground) 1px 4px);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--signal) 55%, transparent);
}

/* optics: reticle corners close on the work while it racks into focus */
:root[data-fx="optics"] .fig .media { clip-path: none; opacity: 0; filter: blur(16px) brightness(0.55); transform: scale(1.04); }
:root[data-fx="optics"] .fig.resolved .media {
  opacity: 1; filter: none; transform: none;
  transition: opacity calc(300ms * var(--fx-speed)) ease, filter calc(900ms * var(--fx-speed)) var(--fx-out) calc(150ms * var(--fx-speed)), transform calc(1000ms * var(--fx-speed)) var(--fx-out);
}
:root[data-fx="optics"] .fig .fxbox {
  --c: var(--signal);
  background:
    linear-gradient(var(--c), var(--c)) top left / 18px 1.5px no-repeat, linear-gradient(var(--c), var(--c)) top left / 1.5px 12px no-repeat,
    linear-gradient(var(--c), var(--c)) top right / 18px 1.5px no-repeat, linear-gradient(var(--c), var(--c)) top right / 1.5px 12px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom left / 18px 1.5px no-repeat, linear-gradient(var(--c), var(--c)) bottom left / 1.5px 12px no-repeat,
    linear-gradient(var(--c), var(--c)) bottom right / 18px 1.5px no-repeat, linear-gradient(var(--c), var(--c)) bottom right / 1.5px 12px no-repeat;
}
:root[data-fx="optics"] .fig.resolved .fxbox { animation: fx-reticle calc(1200ms * var(--fx-speed)) var(--fx-out) forwards; }
@keyframes fx-reticle {
  0% { opacity: 0; transform: scale(1.14); }
  20% { opacity: 1; }
  60% { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(1); }
}

/* raster: interlaced lines thicken until the feed is whole, color arriving last */
:root[data-work="raster"] .fig .media { clip-path: none; mask-image: repeating-linear-gradient(to bottom, #000 0 var(--rl), transparent var(--rl) 6px); filter: grayscale(1) contrast(1.15); }
:root[data-work="raster"] .fig.resolved { animation: fx-raster calc(900ms * var(--fx-speed)) var(--fx-ease) forwards; }
:root[data-work="raster"] .fig.resolved .media { filter: none; transition: filter calc(700ms * var(--fx-speed)) ease calc(700ms * var(--fx-speed)); }
@keyframes fx-raster { from { --rl: 0px; } to { --rl: 6px; } }

/* shown at rest (arriving by morph, reduced motion): no masks, nothing pending */
.fig.instant .media { mask-image: none !important; filter: none !important; opacity: 1 !important; transform: none !important; animation: none !important; }
.fig.instant { animation: none !important; }

/* ---------- loaders ---------- */
.loader { position: fixed; inset: 0; z-index: 90; background: var(--ground); color: var(--bone); pointer-events: none; }
.loader .mono { font-family: var(--mono); font-size: 12px; letter-spacing: 0.04em; color: var(--dim); }
.loader .center { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); display: grid; justify-items: center; gap: 18px; }
.loader .bigmark { width: 96px; height: 62px; }
.loader .bigmark path { fill: none; stroke: var(--bone); stroke-width: 1.6; }
.loader .line { position: absolute; background: var(--line-strong); }
.loader .ring { position: absolute; left: 50%; top: 50%; border: 1px solid var(--line-strong); border-radius: 50%; transform: translate(-50%, -50%); }
.loader .contact { position: absolute; width: 7px; height: 7px; border: 1px solid var(--bone); margin: -3.5px 0 0 -3.5px; }
.loader .contact.full { background: var(--bone); }
.loader .wedge { position: absolute; left: 50%; top: 50%; border-radius: 50%; translate: -50% -50%;
  background: conic-gradient(from 0deg, transparent 0deg, transparent 300deg, color-mix(in srgb, var(--signal) 22%, transparent) 359deg, transparent 360deg); }
.loader.boot { background: transparent; }
.loader.boot .half { position: absolute; left: 0; right: 0; height: 50.2%; background: var(--ground); }
.loader.boot .half.top { top: 0; }
.loader.boot .half.bottom { bottom: 0; }
.loader.boot .seam { position: absolute; left: 0; right: 0; top: 50%; height: 1px; background: var(--signal); opacity: 0; }
.loader.boot .log { position: absolute; left: clamp(20px, 6vw, 96px); bottom: clamp(28px, 12vh, 140px); display: grid; gap: 7px; min-width: min(460px, 80vw); }
.loader.boot .log .row { display: grid; grid-template-columns: auto 1fr auto auto; gap: 10px; align-items: baseline; opacity: 0; }
.loader.boot .log .row .lead { border-bottom: 1px dotted var(--faint); transform: translateY(-3px); }
.loader.boot .log .row .val { color: var(--bone); }
.loader.boot .log .row .ok { color: var(--signal); }
.loader.boot .bar { display: grid; grid-auto-flow: column; gap: 3px; margin-top: 10px; }
.loader.boot .bar i { height: 6px; background: var(--line); }
.loader.boot .bar i.on { background: var(--signal); }
.loader.boot .head { position: absolute; left: clamp(20px, 6vw, 96px); top: 28px; display: flex; gap: 14px; align-items: center; }
.loader .corner { position: absolute; width: 26px; height: 16px; border-color: var(--bone); border-style: solid; border-width: 0; }
.loader .corner.tl { border-top-width: 1.5px; border-left-width: 1.5px; }
.loader .corner.tr { border-top-width: 1.5px; border-right-width: 1.5px; }
.loader .corner.bl { border-bottom-width: 1.5px; border-left-width: 1.5px; }
.loader .corner.br { border-bottom-width: 1.5px; border-right-width: 1.5px; }
.loader.optics { background: color-mix(in srgb, var(--ground) 88%, transparent); backdrop-filter: blur(14px); }
.loader.raster { mask-image: repeating-linear-gradient(to bottom, #000 0 var(--rl2), transparent var(--rl2) 6px); }
.loader.acquisition { mask-image: radial-gradient(circle at 50% 50%, transparent var(--hole), #000 calc(var(--hole) + 1px)); }

/* both: the boot check, then the page arrives as an interlaced feed */
.loader.boot.feed { background: var(--ground); mask-image: repeating-linear-gradient(to bottom, #000 0 var(--rl2), transparent var(--rl2) 6px); }
.loader.boot.feed .half, .loader.boot.feed .seam { display: none; }
