/* Blokks teaser. No external assets, libraries or fonts at runtime. */
:root {
  color-scheme: dark;
  --editor-canvas: #131219;
  --editor-selection: #355200;
  --editor-selection-strong: #b8ef63;
  --edge-stroke: #56535f;
  --motion-press: 90ms;
  --motion-fast: 120ms;
  --motion-default: 210ms;
  --motion-slow: 300ms;
  --ease-spatial: cubic-bezier(.16,1,.3,1);
  --ease-effects: cubic-bezier(.2,.8,.2,1);
  --ease-exit: cubic-bezier(.55,0,1,.45);
  /* Explicit choreography exception: motion-wire-waiting.html. */
  --wire-period: 2.4s;
}
* { box-sizing: border-box; }
html, body { margin: 0; width: 100%; height: 100%; background: #0c0c0e; }
body { overflow: hidden; overscroll-behavior: none; }
.teaser { position: relative; width: 100%; height: 100%; height: 100svh; overflow: hidden;
  animation: content-enter var(--motion-default) var(--ease-effects) both; }
.scene { display: block; width: 100%; height: 100%; isolation: isolate; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
@keyframes content-enter { from { opacity: 0; } to { opacity: 1; } }

/* Exact DS wire/wait specimen values (source snapshot in docs/motion-parity.md).
   Each path is normalized to 230 logical units, matching the specimen's
   M0,35 H230 geometry. This preserves its 10/220 dash and -210 destination
   on the curved wires of different lengths. Stroke widths are NOT normalized. */
.wire-base { fill: none; stroke: var(--edge-stroke); stroke-width: 2.5; }
.wire-tracer {
  fill: none; stroke: var(--editor-selection-strong); stroke-width: 3;
  stroke-linecap: round; stroke-dasharray: 10 220;
  animation: travel 2.4s linear infinite;
  animation-delay: var(--phase, 0ms);
}
@keyframes travel {
  0% { stroke-dashoffset: 0; opacity: .9; }
  45% { stroke-dashoffset: -210; opacity: .9; }
  52%, 100% { stroke-dashoffset: -210; opacity: 0; }
}

/* Teaser-only breathing requested by the user. Same phase relationship as
   the DS waiting specimen; restrained scale is an intentional spatial layer.
   Scaling about the fixed port keeps each wire connected, without JS frames. */
.node-breath {
  transform-box: view-box;
  animation: node-breathe var(--wire-period) ease-in-out infinite;
  animation-delay: var(--phase, 0ms);
}
@keyframes node-breathe {
  0%, 45% { transform: scale(1); }
  52%, 68% { transform: scale(1.025); }
  86%, 100% { transform: scale(1); }
}
.node-halo {
  fill: none; stroke: var(--editor-selection-strong); stroke-linejoin: round;
  stroke-width: 0; opacity: 0;
  animation: node-halo var(--wire-period) ease-in-out infinite;
  animation-delay: var(--phase, 0ms);
}
@keyframes node-halo {
  0%, 45% { stroke-width: 0; opacity: 0; }
  52%, 68% { stroke-width: 12; opacity: .12; }
  86%, 100% { stroke-width: 0; opacity: 0; }
}
.node-icon, .letterform, .node-port { shape-rendering: geometricPrecision; }
/* The initial still is fully visible even with scripting disabled. */
html:not([data-ready]) .loop,
html[data-paused="true"] .loop { animation-play-state: paused !important; }
.motion-toggle {
  position: fixed; z-index: 10; right: max(18px, env(safe-area-inset-right));
  bottom: max(18px, env(safe-area-inset-bottom)); display: grid; place-items: center;
  width: 44px; height: 44px; padding: 0; border-radius: 50%; cursor: pointer;
  border: 1px solid #8a879666; background: #131219e8; color: #f5f4f4;
  opacity: .72; transition: opacity var(--motion-fast) var(--ease-effects),
    background var(--motion-fast) var(--ease-effects), transform var(--motion-press) var(--ease-spatial);
}
.motion-toggle:hover { opacity: 1; background: #292831; }
.motion-toggle:focus-visible { outline: 2px solid var(--editor-selection-strong); outline-offset: 4px; opacity: 1; }
.motion-toggle:active:not(:disabled) { transform: scale(.95); }
.motion-toggle:disabled { cursor: default; opacity: .4; }
.motion-toggle svg { width: 18px; height: 18px; }
.motion-toggle .play-icon { display: none; }
html[data-paused="true"] .motion-toggle .pause-icon { display: none; }
html[data-paused="true"] .motion-toggle .play-icon { display: block; }
html[data-capture="true"] .motion-toggle { display: none; }
@media (prefers-reduced-motion: reduce) {
  .loop, .teaser { animation: none !important; }
  .node-breath { transform: none !important; }
  .wire-tracer, .node-halo { opacity: 0 !important; }
  .motion-toggle { transition: none !important; }
}
/* JS mirrors the media query so a preference change also controls API state. */
html[data-reduced-motion="true"] .loop { animation: none !important; }
html[data-reduced-motion="true"] .node-breath { transform: none !important; }
html[data-reduced-motion="true"] .wire-tracer,
html[data-reduced-motion="true"] .node-halo { opacity: 0 !important; }
