/* Site-wide motion and micro-interactions. Loads on every public page after app.css; pairs with motion.js.
   Sources (cited per rule below): transitions.dev (skills/transitions-dev), Arc UI (uiarc.dev motion tokens),
   emil-design-eng (hover gating, exits faster than enters, never scale(0)), better-ui (press scale, explicit
   transition-property, image outlines), Amicro (expo-out cubic-bezier(.16,1,.3,1) reveals).
   Nothing here hides content unless html.js is present, and every hidden state has a JS or timer exit. */

:root {
  /* transitions.dev shared tokens (subset actually used) */
  --duration-stagger: 40ms;
  --duration-quick: 150ms;
  --duration-fast: 250ms;
  --duration-very-slow: 500ms;
  --ease-smooth-out: cubic-bezier(.22, 1, .36, 1);
  --ease-bounce: cubic-bezier(.34, 1.36, .64, 1);
  --distance-medium: 12px;
  --blur-small: 2px;
  --blur-medium: 3px;
}

/* Anchors land below the sticky top bar */
[id] { scroll-margin-top: 88px; }

/* ---------- Scroll reveals: transitions.dev 18 "texts reveal" (12px rise, 3px blur, 500ms) ----------
   app.js adds .is-in; this only refines the curve and adds the blur. End state is filter:none so sticky
   children (persona picker list) are not trapped in a filter containing block. */
.js [data-reveal] {
  filter: blur(var(--blur-medium));
  transform: translateY(var(--distance-medium));
  transition-property: opacity, transform, filter;
  transition-duration: var(--duration-very-slow);
  transition-timing-function: var(--ease-smooth-out);
}
.js [data-reveal].is-in { filter: none; transform: none; }

/* ---------- Top bar: hairline becomes a soft shadow once the page scrolls (motion.js sets .is-scrolled) ---------- */
.topbar { transition-property: box-shadow; transition-duration: var(--duration-fast); transition-timing-function: var(--ease-smooth-out); }
.topbar.is-scrolled { box-shadow: 0 1px 0 var(--border), 0 10px 30px -18px rgb(7 29 58 / .22); }

/* ---------- Nav: one hover pill that slides between links (transitions.dev 16 "tabs sliding") ---------- */
.nav-links { position: relative; }
.nav-links li { position: relative; z-index: 1; }
.nav-pill {
  position: absolute; z-index: 0; top: 50%; left: 0; height: 38px; width: var(--w, 0); margin-top: -19px;
  border-radius: var(--radius-control); background: color-mix(in oklab, currentColor 8%, transparent); pointer-events: none; opacity: 0;
  transform: translateX(var(--x, 0));
  transition: transform var(--duration-fast) var(--ease-smooth-out), width var(--duration-fast) var(--ease-smooth-out), opacity var(--duration-quick) ease-out;
}
.nav-pill.is-on { opacity: 1; }
.nav-pill.is-instant { transition: opacity var(--duration-quick) ease-out; }
@media (hover: hover) and (pointer: fine) { .nav-links.has-pill a:hover { background: transparent; } }
/* Active marker draws out from its centre on page load (transform-origin set, never scale(0)) */
.nav-links a[aria-current="page"]::after { transform-origin: 50% 50%; animation: m-mark 420ms var(--ease-smooth-out) 120ms backwards; }
@keyframes m-mark { from { transform: scaleX(.2); opacity: 0; } }

/* ---------- Links: underline fills left to right instead of a colour flip ---------- */
.text-link, .footer ul a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor), linear-gradient(var(--border-strong), var(--border-strong));
  background-position: 0 100%, 0 100%; background-repeat: no-repeat; background-size: 0% 1px, 100% 1px;
  padding-bottom: 2px; -webkit-box-decoration-break: clone; box-decoration-break: clone;
  transition-property: background-size, color; transition-duration: 300ms, var(--d-fast); transition-timing-function: var(--ease-smooth-out);
}
.footer ul a { background-image: linear-gradient(currentColor, currentColor); background-size: 0% 1px; }
@media (hover: hover) and (pointer: fine) {
  .text-link:hover, .footer ul a:hover { background-size: 100% 1px, 100% 1px; text-decoration: none; }
}
.text-link:focus-visible, .footer ul a:focus-visible { background-size: 100% 1px, 100% 1px; }

/* Trailing arrows on plain links nudge forward: transitions.dev 24 "learn more hover" (2px, 350ms) */
a:not(.btn) > i.ph-arrow-right, a:not(.btn) > i.ph-arrow-up-right { display: inline-block; transition-property: transform; transition-duration: 350ms; transition-timing-function: var(--ease-smooth-out); }
@media (hover: hover) and (pointer: fine) {
  a:not(.btn):hover > i.ph-arrow-right { transform: translateX(3px); }
  a:not(.btn):hover > i.ph-arrow-up-right { transform: translate(2px, -2px); }
  .btn:hover i.ph-arrow-up-right { transform: translate(2px, -2px); }
  .btn:hover i.ph-arrow-down { transform: translateY(2px); }
}

/* ---------- Focus: the gold ring settles in instead of snapping (Arc focus, 150ms) ---------- */
:focus-visible { animation: m-focus 160ms var(--ease-smooth-out); }
@keyframes m-focus { from { outline-offset: 5px; outline-color: rgb(242 183 5 / 0); } }

/* ---------- Press feedback on list-style links (better-ui scale on press, kept tiny for rows) ---------- */
.routes a, .drawer a.d-link, .h-ways a { transition-property: background-color, transform; }
.routes a:active, .drawer a.d-link:active { transform: scale(.99); }

/* ---------- Drawer: items follow the panel in with a short stagger; leave together, faster ---------- */
.drawer > * { opacity: 0; transform: translateX(14px); transition: opacity 120ms ease-out, transform 120ms ease-out; }
.drawer.is-open > * { opacity: 1; transform: none; transition: opacity 260ms var(--ease-smooth-out), transform 340ms var(--ease-smooth-out); transition-delay: calc(60ms + var(--i, 0) * 30ms); }
.drawer > :nth-child(2) { --i: 1; } .drawer > :nth-child(3) { --i: 2; } .drawer > :nth-child(4) { --i: 3; }
.drawer > :nth-child(5) { --i: 4; } .drawer > :nth-child(6) { --i: 5; } .drawer > :nth-child(7) { --i: 6; }
.drawer > :nth-child(8) { --i: 7; } .drawer > :nth-child(9) { --i: 8; } .drawer > :nth-child(n+10) { --i: 9; }

/* ---------- Toasts: transitions.dev 22 (16px, .97 scale, 2px blur; open 350ms, close faster) ---------- */
.toast { animation: m-toast-in 350ms var(--ease-smooth-out) both; }
.toast.is-leaving { animation: m-toast-out 170ms ease-in both; }
@keyframes m-toast-in { from { opacity: 0; transform: translateY(16px) scale(.97); filter: blur(var(--blur-small)); } }
@keyframes m-toast-out { to { opacity: 0; transform: translateY(6px) scale(.98); } }

/* ---------- Images: fade in once decoded (motion.js adds .m-fade only to images still loading) ---------- */
.js img.m-fade { opacity: 0; transition: opacity 400ms ease-out; }
.js img.m-fade.is-loaded { opacity: 1; }

/* ---------- Photo cards: slow zoom inside the frame on hover ---------- */
a .photo img, a.card img { transition-property: scale; transition-duration: 700ms; transition-timing-function: var(--ease-standard); }
@media (hover: hover) and (pointer: fine) { a:hover .photo img, a.card:hover img { scale: 1.03; } }

/* ---------- Figures: transitions.dev 02 "number pop-in" (each digit re-enters, 70ms stagger, 2px blur) ---------- */
.m-digit { display: inline-block; }
.is-counting .m-digit { animation: m-digit 500ms var(--ease-bounce) backwards; animation-delay: calc(var(--d, 0) * 70ms); }
@keyframes m-digit { from { opacity: 0; transform: translateY(8px); filter: blur(var(--blur-small)); } }

/* ---------- Accordion (.faq): transitions.dev 21, height via ::details-content where supported ---------- */
.faq details[open] .answer { animation: m-acc 250ms var(--ease-smooth-out); }
@keyframes m-acc { from { opacity: 0; transform: translateY(-4px); } }
@supports (interpolate-size: allow-keywords) {
  .faq details { interpolate-size: allow-keywords; }
  .faq details::details-content { block-size: 0; overflow: clip; transition: block-size 250ms var(--ease-smooth-out), content-visibility 250ms allow-discrete; }
  .faq details[open]::details-content { block-size: auto; }
}

/* ---------- Persona picker: selected tab's gold marker grows from its centre ---------- */
.picker-tab[aria-selected="true"]::before { transform-origin: 50% 50%; animation: m-bar 250ms var(--ease-smooth-out); }
@keyframes m-bar { from { transform: scaleY(.3); opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { filter: none; transform: none; }
  .nav-pill, .drawer > *, .js img.m-fade { transition: none !important; }
  .js img.m-fade { opacity: 1; }
  .drawer > * { opacity: 1; transform: none; }
  :focus-visible, .toast, .toast.is-leaving, .is-counting .m-digit, .nav-links a[aria-current="page"]::after { animation: none !important; }
}
