/* HyperCurio — motion (#960, Terry's "Motion Animatics v1", 8 Oct 2026).
 *
 * The principles page, as rules every board follows:
 *   Honest progress   driven by real events; determinate wherever the count is real.
 *   Time thresholds   under 150 ms nothing; 150 ms to 1 s a 2 px hairline; 1-10 s the stage; over 10 s
 *                     a narrative and an estimate; over 30 s "keep browsing".
 *   Never stuck       something changes every 4-6 s.
 *   One language      gold for active, teal for done, red only for warnings.
 *   Restraint         celebrations 2.5 s or less, skippable, flecks never confetti, played once.
 *   Accessibility     prefers-reduced-motion gets a fade or a colour change on every board; stage
 *                     changes are announced (hc-motion.js announce()).
 *   Tokens            micro 150 ms, standard 300 ms, reveal 600 ms; ease cubic-bezier(.2,.8,.2,1).
 * UI motion is CSS and the View Transitions API, as the tokens page says.
 */
:root {
  --hc-motion-micro: 150ms;
  --hc-motion-std: 300ms;
  --hc-motion-reveal: 600ms;
  --hc-motion-celebrate: 2500ms;
  --hc-ease: cubic-bezier(.2, .8, .2, 1);
  --hc-done: #3fbfb0;            /* teal: done */
}

/* ---------------------------------------------------------------- K: Never Blank
   Same-origin page changes cross-fade 180 ms with an 8 px slide; an item thumbnail grows into the
   item page's hero (the pages give both the same view-transition-name, see hc-motion.js). */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: hcVtOut 180ms var(--hc-ease) both; }
::view-transition-new(root) { animation: hcVtIn 180ms var(--hc-ease) both; }
@keyframes hcVtOut { to { opacity: 0; } }
@keyframes hcVtIn { from { opacity: 0; transform: translateX(calc(8px * var(--hc-vt-dir, 1))); } }
::view-transition-group(hc-hero) { animation-duration: 300ms; animation-timing-function: var(--hc-ease); }

/* The 2 px gold hairline under the bar, shown only when a page takes longer than 150 ms. */
.hc-hairline { position: fixed; left: 0; top: 0; height: 2px; width: 100%; z-index: 9999; pointer-events: none; overflow: hidden; opacity: 0; transition: opacity var(--hc-motion-micro) linear; }
.hc-hairline.on { opacity: 1; }
.hc-hairline i { position: absolute; top: 0; height: 100%; width: 30%; background: var(--hc-accent); animation: hcHair 1.1s var(--hc-ease) infinite; }
@keyframes hcHair { from { left: -30%; } to { left: 100%; } }

/* ---------------------------------------------------------------- shared pieces */
/* Each section finishes with a gold hairline sweep across its top (I6), in place of a text note. */
.hc-sweep { position: relative; }
.hc-sweep::before { content: ''; position: absolute; left: 0; top: 0; height: 2px; width: 100%; background: var(--hc-accent); transform-origin: left; animation: hcSweep var(--hc-motion-reveal) var(--hc-ease) both, hcSweepFade 900ms 700ms ease forwards; border-radius: 2px; z-index: 2; }
@keyframes hcSweep { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes hcSweepFade { to { opacity: 0; } }
/* A status line that changes cross-fades (I, motion: 250 ms, each line at least 1.2 s). */
.hc-status-swap { transition: opacity 250ms var(--hc-ease); }
.hc-status-swap.out { opacity: 0; }
/* A new row slides in at the top with a teal flash (G6). */
.hc-arrive { animation: hcArrive var(--hc-motion-std) var(--hc-ease) both, hcFlash 1.2s var(--hc-motion-std) ease both; }
@keyframes hcArrive { from { opacity: 0; transform: translateY(-8px); } }
@keyframes hcFlash { from { box-shadow: 0 0 0 2px var(--hc-done); } to { box-shadow: 0 0 0 2px transparent; } }
/* A new card drops in from the top with a gold edge glow that fades over 2 s (H1). */
.hc-drop { animation: hcDrop 420ms var(--hc-ease) both, hcGlow 2s 420ms ease both; animation-delay: calc(var(--hc-i, 0) * 80ms), calc(var(--hc-i, 0) * 80ms + 420ms); }
@keyframes hcDrop { from { opacity: 0; transform: translateY(-14px); } }
@keyframes hcGlow { from { box-shadow: 0 0 0 2px var(--hc-accent); } to { box-shadow: 0 0 0 2px transparent; } }
/* A chip that bounces once (H1, the deal-quality chip). */
.hc-bounce { animation: hcBounce 600ms var(--hc-ease) 1; }
@keyframes hcBounce { 30% { transform: translateY(-4px); } 60% { transform: translateY(1px); } }
/* An old price strikes through and slides down into the new one (H2). */
.hc-pricedrop { display: inline-flex; flex-direction: column; line-height: 1.2; }
.hc-pricedrop s { color: var(--hc-text-muted); animation: hcStrike 700ms var(--hc-ease) both; font-weight: 400; font-size: .85em; }
.hc-pricedrop b { color: var(--hc-done); animation: hcIn 500ms 400ms var(--hc-ease) both; }
@keyframes hcStrike { from { opacity: 1; transform: translateY(-6px); } }
@keyframes hcIn { from { opacity: 0; transform: translateY(-6px); } }
/* Charts that grow from zero on their first fill (I4, J2). */
.hc-grow { transform-origin: left; animation: hcGrow var(--hc-motion-reveal) var(--hc-ease) both; animation-delay: calc(var(--hc-i, 0) * 60ms); }
.hc-grow-y { transform-origin: bottom; animation: hcGrowY var(--hc-motion-reveal) var(--hc-ease) both; animation-delay: calc(var(--hc-i, 0) * 60ms); }
@keyframes hcGrow { from { transform: scaleX(0); } }
@keyframes hcGrowY { from { transform: scaleY(0); } }
.hc-draw { stroke-dasharray: var(--hc-len, 2000); stroke-dashoffset: var(--hc-len, 2000); animation: hcDraw 800ms var(--hc-ease) forwards; }
@keyframes hcDraw { to { stroke-dashoffset: 0; } }
.hc-pop { animation: hcPop 300ms var(--hc-ease) both; animation-delay: calc(400ms + var(--hc-i, 0) * 90ms); transform-box: fill-box; transform-origin: center; }
@keyframes hcPop { from { opacity: 0; transform: scale(.2); } }

/* ---------------------------------------------------------------- G: Radar Sweep */
.hc-radar { position: relative; width: 168px; height: 168px; margin: var(--hc-3) auto; border-radius: 50%; }
.hc-radar svg { width: 100%; height: 100%; overflow: visible; }
.hc-radar .ring { fill: none; stroke: var(--hc-border); }
.hc-radar .arm { transform-origin: 84px 84px; animation: hcRadar 1.2s linear infinite; }
.hc-radar.slow .arm { animation-duration: 2.4s; opacity: .5; }
.hc-radar .mk { font-size: 9px; fill: var(--hc-text-muted); font-family: var(--hc-font-body); }
.hc-radar .blip { animation: hcBlip 250ms var(--hc-ease) both; }
@keyframes hcRadar { to { transform: rotate(360deg); } }
@keyframes hcBlip { from { r: 0; } }
.hc-radar-line { text-align: center; color: var(--hc-text-muted); font-size: 14px; }
.hc-finds { display: inline-block; margin: var(--hc-2) auto 0; padding: var(--hc-3) var(--hc-5); border: 1.5px solid var(--hc-accent); border-radius: var(--hc-radius-card); box-shadow: 6px -6px 0 -2px var(--hc-surface-1), 6px -6px 0 0 var(--hc-accent); animation: hcDrop 420ms var(--hc-ease) both; text-align: center; }
.hc-finds b { display: block; font-family: var(--hc-font-figure); font-size: calc(20px * var(--hc-scale-figure)); }

/* ---------------------------------------------------------------- L/M: The Last Piece, by category */
.hc-lastpiece { position: fixed; inset: 0; z-index: 90; display: flex; align-items: center; justify-content: center; background: rgba(4, 8, 18, .72); animation: hcIn 250ms ease both; cursor: pointer; }
.hc-lastpiece-card { text-align: center; padding: var(--hc-6) var(--hc-8); background: var(--hc-surface-1); border: 1px solid var(--hc-border); border-radius: var(--hc-radius-card); max-width: min(560px, 92vw); }
.hc-lastpiece-slots { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin: var(--hc-4) 0; }
.hc-lastpiece-slots i { width: 18px; height: 26px; border-radius: 3px; background: var(--hc-done); animation: hcIn 220ms var(--hc-ease) both; animation-delay: calc(var(--hc-i, 0) * 60ms); }
.hc-lastpiece--coin .hc-lastpiece-slots i { width: 22px; height: 22px; border-radius: 50%; }
.hc-lastpiece--card .hc-lastpiece-slots i { width: 18px; height: 25px; border-radius: 2px; }
.hc-lastpiece-slots i.last { background: var(--hc-accent); animation: hcLast 700ms var(--hc-ease) both; animation-delay: calc(var(--hc-i, 0) * 60ms + 200ms); }
@keyframes hcLast { 0% { opacity: 0; transform: translateY(-40px) scale(1.3); } 70% { transform: translateY(2px) scale(1); } }
.hc-lastpiece-banner { display: inline-block; margin-top: var(--hc-2); padding: 6px 16px; border-radius: 999px; background: var(--hc-accent); color: var(--hc-on-accent); font-weight: 700; letter-spacing: .08em; text-transform: uppercase; font-size: 13px; animation: hcIn 300ms 900ms var(--hc-ease) both; }
.hc-flecks { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.hc-flecks i { position: absolute; top: -10px; width: 4px; height: 4px; border-radius: 50%; background: var(--hc-accent); opacity: .8; animation: hcFleck 2.2s linear both; }
@keyframes hcFleck { to { transform: translateY(105vh); opacity: 0; } }

/* ---------------------------------------------------------------- N/O: Membership, Top-up */
.hc-meter { height: 10px; border-radius: 999px; background: var(--hc-surface-2); overflow: hidden; }
.hc-meter i { display: block; height: 100%; background: var(--hc-accent); border-radius: 999px; transform-origin: left; animation: hcGrow 900ms var(--hc-ease) both; }
.hc-flip { animation: hcFlip 700ms var(--hc-ease) both; transform-style: preserve-3d; }
@keyframes hcFlip { from { transform: perspective(800px) rotateY(-90deg); opacity: .2; } }

/* ---------------------------------------------------------------- the scanner (A, C, E, F) */
.hc-lens { position: absolute; width: 34%; aspect-ratio: 1; border: 2px solid var(--hc-accent); border-radius: 50%; box-shadow: 0 0 0 9999px rgba(4, 8, 18, .18); animation: hcLens 3.2s ease-in-out infinite; pointer-events: none; }
@keyframes hcLens { 0% { left: 6%; top: 8%; } 25% { left: 58%; top: 18%; } 50% { left: 40%; top: 56%; } 75% { left: 8%; top: 46%; } 100% { left: 6%; top: 8%; } }
.hc-lens-done { position: absolute; inset: 0; border: 2px solid var(--hc-accent); border-radius: var(--hc-radius-control); animation: hcIn 300ms var(--hc-ease) both; pointer-events: none; }
.hc-scanline { position: absolute; left: 0; right: 0; height: 2px; background: var(--hc-accent); box-shadow: 0 0 8px var(--hc-accent); animation: hcScan 1.8s ease-in-out infinite; pointer-events: none; }
@keyframes hcScan { 0% { top: 4%; } 50% { top: 94%; } 100% { top: 4%; } }
.hc-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--hc-2); }
.hc-pills span { padding: 3px 10px; border-radius: 999px; font-size: 12px; font-weight: 700; border: 1px solid var(--hc-border); color: var(--hc-text-muted); transition: all var(--hc-motion-std) var(--hc-ease); }
.hc-pills span.on { border-color: var(--hc-accent); color: var(--hc-accent); }
.hc-pills span.done { border-color: var(--hc-done); color: var(--hc-done); }
.hc-vault { animation: hcVault 700ms var(--hc-ease) both; }
@keyframes hcVault { 0% { transform: none; } 60% { transform: translateY(10px) scale(.92); opacity: .7; } 100% { transform: translateY(0) scale(1); opacity: 1; } }
.hc-conveyor { display: flex; gap: 6px; overflow: hidden; margin-top: var(--hc-3); mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent); }
.hc-conveyor img { width: 48px; height: 48px; object-fit: contain; background: var(--hc-surface-2); border-radius: 6px; border: 2px solid var(--hc-border); transition: border-color var(--hc-motion-std); flex: 0 0 auto; }
.hc-conveyor img.done { border-color: var(--hc-done); }
.hc-conveyor img.now { border-color: var(--hc-accent); }

/* ---------------------------------------------------------------- reduced motion: a fade or a colour change, never travel */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root), ::view-transition-group(hc-hero) { animation: none !important; }
  .hc-hairline i { animation: none; left: 0; width: 100%; opacity: .6; }
  .hc-sweep::before { animation: hcSweepFade 900ms ease forwards; transform: none; }
  .hc-arrive, .hc-drop, .hc-bounce, .hc-grow, .hc-grow-y, .hc-pop, .hc-vault, .hc-finds, .hc-flip, .hc-meter i,
  .hc-lastpiece-slots i, .hc-lastpiece-slots i.last, .hc-lastpiece-banner, .hc-pricedrop s, .hc-pricedrop b { animation: none !important; }
  .hc-drop, .hc-arrive { box-shadow: 0 0 0 2px var(--hc-accent); }
  .hc-draw { animation: none; stroke-dashoffset: 0; }
  .hc-radar .arm { animation: none; }
  .hc-lens, .hc-scanline { animation: none; display: none; }
  .hc-flecks { display: none; }
}
