/* Headroom motion: one language for every page. Strong ease-out, transform + opacity only, quick on controls.
   ui/motion.js tags elements (data-load for the entrance, data-lens for the scroll focus) and adds .hr-motion to <html>;
   without JS nothing is hidden. The lens itself is computed in motion.js so it behaves the same in every browser. */
:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --dur-fast: 160ms; --dur: 260ms; --dur-reveal: 720ms;
}

/* hold the first paint until motion.js has tagged the page (a timeout in motion.js always releases it) */
.hr-motion:not(.hr-ready) body { opacity: 0; }

/* ---------- load: above-the-fold blocks rise in, small groups staggered ---------- */
@keyframes hr-in {
  from { opacity: 0; transform: translateY(var(--hr-dy, 14px)) scale(var(--hr-s, 1)); filter: blur(var(--hr-blur, 0px)); }
}
.hr-motion [data-load] { animation: hr-in var(--dur-reveal) var(--ease-out) both; animation-delay: calc(60ms + var(--i, 0) * 70ms); }
.hr-motion [data-load="soft"] { --hr-dy: 8px; --hr-s: 0.985; }
.hr-motion [data-load="text"] { --hr-blur: 4px; }
.hr-hold [data-load] { animation-play-state: paused; }

/* ---------- lens on the scroll timeline (Chrome, Edge, Safari 26) ----------
   motion.js measures each block once (and on resize) and writes its in range (--in-s..--in-e: rising up from the
   bottom edge) and out range (--out-s..--out-e: leaving under the top edge) in px of page scroll. The two animations
   below are scrubbed by the scroll position on the compositor, so they never lag the page. */
@property --flip { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --mid { syntax: "<number>"; inherits: true; initial-value: 0; }
:root { --lens-fade: 0.8; --lens-blur: 7px; --lens-rise: 26px; --lens-lift: 16px; --lens-tilt: 5deg; --lens-shrink: 0.02; --lens-ease: cubic-bezier(0.45, 0, 0.55, 1); }
body[data-lens-mode="strong"] { --lens-fade: 1; --lens-blur: 12px; --lens-rise: 46px; --lens-lift: 30px; --lens-tilt: 10deg; --lens-shrink: 0.035; }
/* movement and fade (compositor) are kept apart from the blur (main thread) so a slow blur frame never holds back
   the movement: the block itself always tracks the scroll exactly */
@keyframes hr-lens-in {
  from { opacity: calc(1 - var(--lens-fade));
    transform: perspective(1100px) translate3d(0, var(--lens-rise), 0) rotateX(var(--lens-tilt)) scale(calc(1 - var(--lens-shrink))); }
  to { opacity: 1; transform: perspective(1100px) translate3d(0, 0, 0) rotateX(0deg) scale(1); }
}
@keyframes hr-lens-out {
  from { opacity: 1; transform: perspective(1100px) translate3d(0, 0, 0) rotateX(0deg) scale(1); }
  to { opacity: calc(1 - var(--lens-fade));
    transform: perspective(1100px) translate3d(0, calc(var(--lens-lift) * -1), 0) rotateX(calc(var(--lens-tilt) * -1)) scale(calc(1 - var(--lens-shrink))); }
}
@keyframes hr-fade-in { from { opacity: calc(1 - var(--lens-fade)); } to { opacity: 1; } }
@keyframes hr-fade-out { from { opacity: 1; } to { opacity: calc(1 - var(--lens-fade)); } }
@keyframes hr-focus-in { from { filter: blur(calc(var(--lens-blur) * 0.85)); } to { filter: blur(0px); } }
@keyframes hr-focus-out { from { filter: blur(0px); } to { filter: blur(var(--lens-blur)); } }
.hr-sdt.hr-lens [data-lens]:not([data-load]) {
  animation: hr-lens-in var(--lens-ease) both, hr-lens-out var(--lens-ease) forwards,
    hr-focus-in var(--lens-ease) both, hr-focus-out ease-in forwards;
  animation-timeline: scroll(root), scroll(root), scroll(root), scroll(root);
  animation-range: var(--in-s, -2px) var(--in-e, -1px), var(--out-s, 999999px) var(--out-e, 1000000px),
    var(--in-s, -2px) var(--in-e, -1px), var(--out-s, 999999px) var(--out-e, 1000000px); }
/* the landing hero print turns over its own stretch of scroll (--flip-s..--flip-e) */
@keyframes hr-flip { from { --flip: 0; } to { --flip: 1; } }
@keyframes hr-mid { 0% { --mid: 0; } 25% { --mid: 0.71; } 50% { --mid: 1; } 75% { --mid: 0.71; } 100% { --mid: 0; } }
.hr-sdt.hr-lens .lenti[data-lens]:not([data-load]) {
  animation: hr-lens-in var(--lens-ease) both, hr-lens-out var(--lens-ease) forwards,
    hr-focus-in var(--lens-ease) both, hr-focus-out ease-in forwards, hr-flip var(--lens-ease) both, hr-mid linear both;
  animation-timeline: scroll(root), scroll(root), scroll(root), scroll(root), scroll(root), scroll(root);
  animation-range: var(--in-s, -2px) var(--in-e, -1px), var(--out-s, 999999px) var(--out-e, 1000000px),
    var(--in-s, -2px) var(--in-e, -1px), var(--out-s, 999999px) var(--out-e, 1000000px),
    var(--flip-s, 0px) var(--flip-e, 300px), var(--flip-s, 0px) var(--flip-e, 300px); }
/* backdrop lights drift at their own rates as the page scrolls (--hr-max: the page's scroll length) */
@keyframes hr-drift { to { transform: translate3d(var(--dx, 0px), calc(var(--hr-max, 2000px) * var(--rate, -0.1)), 0); } }
.hr-sdt .hr-backdrop i { animation: hr-drift linear both; animation-timeline: scroll(root); }
.hr-backdrop i:nth-child(1) { --rate: -0.06; --dx: 18px; }
.hr-backdrop i:nth-child(2) { --rate: -0.14; --dx: -26px; }
.hr-backdrop i:nth-child(3) { --rate: -0.1; --dx: 14px; }

/* ---------- lens: scroll focus ----------
   motion.js writes opacity, blur and a small tilt on every [data-lens] block from its distance to the viewport edges.
   Nothing here hides content: without JS (or with reduced motion) every block simply stays sharp. */
.hr-lens [data-lens] { backface-visibility: hidden; }
.hr-lens .hr-blurred { will-change: transform, opacity, filter; }
/* a tilted full-width block can poke a few px past the window: clip at the page wrappers (clip on body would pass to
   the window as hidden, which can still be scrolled), without making them scroll containers, so sticky still works */
.hr-lens main, .hr-lens .main, .hr-lens body > .foot { overflow-x: clip; }
.hr-lens body { overflow-x: clip; }   /* backstop for anything outside those wrappers (the sticky headers) */
/* a button that is itself a lens block keeps its colour feedback but drops the transform transition, so it tracks the scroll */
.hr-lens [data-lens].hr-btn { transition-property: background-color, border-color, color, box-shadow; }

/* one-shot effects started when their block comes into view  */
.hr-motion [data-trigger] td .bar i { transform: scaleX(0); transform-origin: right center;
  transition: transform 900ms var(--ease-out); transition-delay: calc(200ms + var(--r, 0) * 70ms); }
.hr-motion [data-trigger].is-in td .bar i { transform: none; }
[data-trigger] tbody tr:nth-child(2) { --r: 1; } [data-trigger] tbody tr:nth-child(3) { --r: 2; }
[data-trigger] tbody tr:nth-child(4) { --r: 3; } [data-trigger] tbody tr:nth-child(5) { --r: 4; }

/* ---------- scroll progress: a 2px line that tracks the page ---------- */
.hr-progress { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 50; background: var(--primary);
  transform-origin: 0 50%; transform: scaleX(var(--hr-p, 0)); pointer-events: none; }
@keyframes hr-grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
.hr-sdt .hr-progress { animation: hr-grow linear both; animation-timeline: scroll(root); }

/* landing: the nav gains its edge once the page moves */
@keyframes hr-nav-edge { from { box-shadow: 0 0 0 rgba(30, 27, 58, 0); } to { box-shadow: 0 6px 24px rgba(30, 27, 58, 0.07); } }
.hr-sdt .nav { animation: hr-nav-edge linear both; animation-timeline: scroll(root); animation-range: 0 140px; }
.nav.hr-scrolled { box-shadow: 0 6px 24px rgba(30, 27, 58, 0.07); }

/* ---------- state changes inside the dashboards ---------- */
.moment:not(.hidden) { animation: hr-in 420ms var(--ease-out) both; --hr-dy: -6px; }
.phase, .c-pill, .kpi, .tile { transition: background-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out); }
.tpanel.sub { transition: background-color 400ms var(--ease-out); }

/* buildings: fade to grey when they lose power, the status dot pops when it changes */
.bmark { transition: box-shadow 400ms var(--ease-out); }
.bmark::before { transition: opacity 600ms var(--ease-out); }
.bmark i { transition: background-color var(--dur) var(--ease-out); }
@keyframes hr-pop { 0% { transform: scale(1); } 40% { transform: scale(1.6); } 100% { transform: scale(1); } }
.bmark.pop i { animation: hr-pop 520ms var(--ease-out); }
@keyframes hr-flash { from { background-color: rgba(255, 255, 255, 0.24); } to { background-color: rgba(255, 255, 255, 0); } }
.tcell.flash { animation: hr-flash 1400ms var(--ease-out) both; animation-delay: var(--since, 0ms); }

/* tooltip: scales in from its anchor instead of popping */
.tip { transition: opacity 120ms var(--ease-out), transform 120ms var(--ease-out); transform-origin: 0 0; }
.tip.hidden { display: block !important; opacity: 0; transform: scale(0.96); visibility: hidden; transition: opacity 100ms ease, transform 100ms ease, visibility 0s 100ms; }

/* ---------- controls: quick, physical feedback ---------- */
.btn, .hr-btn, .side-btn, select, button { transition: background-color var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out),
  color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out); }
.btn:active, .hr-btn:active, .side-btn:active, button:active { transform: scale(0.97); }
.panel, .cmp, .stepcol, .ladder li { transition: border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out); }
.panel:hover, .cmp:hover { border-color: color-mix(in srgb, var(--primary) 22%, var(--glass-line)); }
.ladder li:hover { background-color: var(--blush-soft); }

@media (prefers-reduced-motion: reduce) {
  /* reduced motion: no movement, blur or tilt, no pinned hero; blocks still fade gently with the scroll */
  :root, body[data-lens-mode="strong"] { --lens-fade: 0.6; --lens-blur: 0px; --lens-rise: 0px; --lens-lift: 0px; --lens-tilt: 0deg; --lens-shrink: 0; }
  .hr-motion [data-load] { --hr-dy: 0px; --hr-s: 1; --hr-blur: 0px; animation-duration: 400ms; }
  /* fade only: an identity 3D transform still gives each block its own layer, and Chromium then drops part of the
     frosted header over a block scrolling under it */
  .hr-sdt.hr-lens [data-lens]:not([data-load]), .hr-sdt.hr-lens .lenti[data-lens]:not([data-load]) {
    animation: hr-fade-in linear both, hr-fade-out linear forwards; animation-timeline: scroll(root), scroll(root);
    animation-range: var(--in-s, -2px) var(--in-e, -1px), var(--out-s, 999999px) var(--out-e, 1000000px); }
  .hr-sdt .hr-backdrop i { animation: none; }
  .moment:not(.hidden), .hr-sdt .nav { animation: none !important; }
  .hr-motion [data-trigger] td .bar i { transform: none; transition: none; }
  .hr-progress { display: none; }
  .bmark.pop i, .tcell.flash { animation: none; }
  .btn:active, .hr-btn:active, .side-btn:active, button:active { transform: none; }
}
