/* =============================================================================
 * UPLATEGARAGE — uplategarage.com.au
 * The studio page. Deliberately NOT the product sites.
 *
 * The products live in the dark: uplategarage.com and currentdraw.app are both
 * near-black with a lit accent, because both are about working at night. This
 * page is the daylight, public, business face of the same company — so it runs
 * on paper rather than board, and the studio's amber appears only as a signal
 * (the mark, a rule, a status) instead of as the theme.
 *
 * The thread that ties all three together is JetBrains Mono: every label, tier
 * and number on every property is set in it. Same family, different register.
 *
 * Fonts are self-hosted — no third-party requests anywhere on this site.
 * ========================================================================== */

:root {
  color-scheme: light;

  --paper:   #FAFAF8;   /* near-white ground — deliberately not a warm cream */
  --paper-2: #F1F1EE;   /* raised panel                                     */
  --ink:     #0C0D0F;   /* near-black type                                  */
  --graphite:#3A3D42;   /* body prose                                       */
  /* #8A8F98 measured 3.11:1 on paper and 2.87:1 on the panel — a fail for the
     9.5-11px labels it carries. Darkened until it clears 4.5:1 on both. */
  --mute:    #696D74;   /* labels, tertiary — AA on paper and panel         */
  --rule:    rgba(12,13,15,.11);
  --rule-2:  rgba(12,13,15,.20);
  --amber:   #EAB308;   /* studio signal only — never a text colour on paper */
  --amber-ink:#7A5B04;  /* the amber, darkened until it passes on white      */

  /* The plot's night, and the three apps as the plot draws them: each lit on
     the night in its own colour, with an ink of the same hue for paper. */
  --night:       #0A0C10;
  --bubble:      #38BDF8;  --bubble-ink:  #0369A1;  /* Bubble Drift — its Abyss sky */
  --current:     #45E3B0;  --current-ink: #047857;  /* Current Draw — its 12V mint  */
  --uplate:      #EAB308;  --uplate-ink:  #A16207;  /* UpLate Garage — the amber    */

  --display: 'Bricolage Grotesque', system-ui, sans-serif;
  --body:    'Bricolage Grotesque', system-ui, sans-serif;
  --mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --w: 1140px;
  --gutter: 32px;
  --ease: cubic-bezier(.2,0,0,1);
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  background: var(--paper); color: var(--graphite);
  font-family: var(--body); font-size: 16px; line-height: 1.6;
  -webkit-font-smoothing: antialiased; overflow-x: hidden;
  /* Bricolage is variable with an optical-size axis that defaults to 96 —
     display grade. Left alone, body copy would be set with display letterforms.
     `auto` lets opsz track font-size, which is the whole point of the axis. */
  font-optical-sizing: auto;
}
::selection { background: var(--ink); color: var(--paper); }
a { color: inherit; text-decoration: none; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
img, canvas { display: block; max-width: 100%; }

.wrap { max-width: var(--w); margin: 0 auto; padding: 0 var(--gutter); }
@media (max-width: 640px) { :root { --gutter: 20px; } }

.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--paper);
  padding: 10px 16px; border-radius: 4px; z-index: 100;
}
.skip:focus { left: 12px; top: 12px; }

.lbl {
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--mute);
}

/* ── Header ─────────────────────────────────────────────────────────────── */
.head { border-bottom: 1px solid var(--rule); background: var(--paper); position: sticky; top: 0; z-index: 60; }
.bar { display: flex; align-items: center; justify-content: space-between; height: 70px; gap: 20px; }
.mark {
  display: flex; align-items: center; gap: 9px;
  font-family: var(--mono); font-weight: 500; font-size: 13px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--ink);
}
.nav { display: flex; gap: 28px; }
.nav a, .tlink {
  font-family: var(--mono); font-size: 11px; letter-spacing: .18em;
  text-transform: uppercase; color: var(--mute);
  transition: color .15s var(--ease);
}
.nav a:hover { color: var(--ink); }
.tlink { color: var(--ink); border-bottom: 1px solid var(--rule-2); padding-bottom: 3px; transition: border-color .15s var(--ease); }
.tlink:hover { border-color: var(--amber); }
@media (max-width: 720px) { .nav { display: none; } }

/* ── Hero ───────────────────────────────────────────────────────────────── */
.hero { padding: clamp(56px, 8vw, 96px) 0 0; }
.eyebrow {
  display: flex; align-items: center; gap: 12px; margin-bottom: 30px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--mute);
}
.eyebrow::before { content: ""; width: 26px; height: 1px; background: var(--amber); flex: none; }
h1 {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(52px, 10.4vw, 138px); line-height: .88;
  letter-spacing: -.032em; color: var(--ink);
  margin-bottom: 30px; text-wrap: balance;
}
.lede { font-size: clamp(17px, 1.6vw, 19px); line-height: 1.62; color: var(--graphite); max-width: 56ch; margin-bottom: 34px; }
.lede strong { color: var(--ink); font-weight: 600; }
.acts { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.btn {
  font-family: var(--mono); font-size: 11.5px; letter-spacing: .16em; text-transform: uppercase;
  background: var(--ink); color: var(--paper); padding: 14px 24px; border-radius: 2px;
  transition: opacity .15s var(--ease);
}
.btn:hover { opacity: .84; }

/* ── The signature: when the work happens ─────────────────────────────────
   The studio's real commit log drawn as one day. The canvas does the moving;
   everything readable around it is plain HTML in the page's own mono. */
.plot-wrap { margin-top: clamp(48px, 7vw, 84px); padding-bottom: clamp(48px, 7vw, 84px); }
.plot-head { display: flex; align-items: baseline; justify-content: space-between; gap: 6px 16px; flex-wrap: wrap; padding-bottom: 14px; }
.plot-meta { display: inline-flex; align-items: baseline; gap: 16px; }
.replay {
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--ink);
  background: none; border: 0; border-bottom: 1px solid var(--rule-2); border-radius: 0;
  padding: 0 0 2px; cursor: pointer; transition: border-color .15s var(--ease);
}
.replay:hover { border-color: var(--amber); }
.replay[hidden] { display: none; }

#shift { width: 100%; height: 340px; touch-action: pan-y; }
@media (max-width: 900px) { #shift { height: 300px; } }
@media (max-width: 560px) { #shift { height: 270px; } }
/* Before the script runs, or if it never does: the day it would draw. */
html:not([data-plot]) #shift {
  background: linear-gradient(90deg, var(--paper) 0 42%, var(--night) 55% 91%, var(--paper));
}
.axis {
  display: flex; justify-content: space-between; padding-top: 9px;
  border-top: 1px solid var(--rule);
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em; color: var(--mute);
}

.plot-foot {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 20px 48px;
  align-items: start; padding-top: 24px;
}
@media (max-width: 760px) { .plot-foot { grid-template-columns: minmax(0, 1fr); } }

/* The feed: the last commit to land, typed out. Heights are reserved so the
   page never jumps as entries change length. */
.feed { min-width: 0; }
.feed-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; min-height: 16px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute);
}
.feed-app { font-weight: 500; }
.feed-app[data-app="0"] { color: var(--bubble-ink); }
.feed-app[data-app="1"] { color: var(--current-ink); }
.feed-app[data-app="2"] { color: var(--uplate-ink); }
.feed-sha, .feed-file { text-transform: none; letter-spacing: .04em; }
.feed-line {
  margin-top: 8px; min-height: 20px;
  font-family: var(--mono); font-size: 13.5px; line-height: 20px; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
/* Real code, shown as typed: no ligatures turning >= into ≥. */
.feed-code { font: inherit; font-variant-ligatures: none; font-feature-settings: "calt" 0, "liga" 0; }
.feed-caret {
  display: inline-block; width: .6em; height: 15px; margin-left: 2px; vertical-align: -2px;
  background: var(--ink); opacity: .75; animation: caret 1.05s steps(1) infinite;
}
.feed.typing .feed-caret { animation: none; opacity: .9; }
@keyframes caret { 50% { opacity: 0; } }
.feed-msg { margin-top: 6px; min-height: 22px; font-size: 14.5px; line-height: 22px; color: var(--graphite); }
@media (max-width: 560px) {
  .feed-line { font-size: 12.5px; }
  .feed-msg { min-height: 44px; }
}

.key {
  display: flex; flex-direction: column; align-items: flex-end; gap: 9px; padding-top: 1px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase; color: var(--mute);
}
.key-row { list-style: none; display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px 16px; }
.key-row li { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.key-note { letter-spacing: .1em; text-align: right; }
@media (max-width: 760px) {
  .key { align-items: flex-start; }
  .key-row { justify-content: flex-start; }
  .key-note { text-align: left; }
}
.sw { width: 9px; height: 9px; border-radius: 2px; flex: none; box-shadow: inset 0 0 0 1px rgba(12,13,15,.14); }
.sw[data-app="0"] { background: var(--bubble); }
.sw[data-app="1"] { background: var(--current); }
.sw[data-app="2"] { background: var(--uplate); }
.sw-wk { background: var(--ink); }
.sw-we { background: rgba(12,13,15,.3); box-shadow: none; }
.on-touch { display: none; }
@media (hover: none) { .on-hover { display: none; } .on-touch { display: inline; } }
html:not([data-plot]) .key-note span { display: none; }   /* nothing to replay without the script */

.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* ── Sections ───────────────────────────────────────────────────────────── */
.band { padding: clamp(64px, 9vw, 104px) 0; border-top: 1px solid var(--rule); }
.band-head { display: flex; align-items: baseline; justify-content: space-between; gap: 18px; flex-wrap: wrap; margin-bottom: 40px; }
h2 {
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(30px, 4.2vw, 48px); line-height: 1; letter-spacing: -.03em;
  color: var(--ink); text-wrap: balance;
}

/* ── The apps: each title in its product's own face ─────────────────────── */
.row {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 28px; align-items: start;
  padding: 30px 0; border-top: 1px solid var(--rule);
  transition: border-color .2s var(--ease);
}
.row:first-of-type { border-top-color: var(--rule-2); }
.row:hover { border-top-color: var(--rule-2); }
.row-top { display: flex; align-items: center; gap: 13px; flex-wrap: wrap; margin-bottom: 7px; }
.chip { width: 11px; height: 11px; border-radius: 2px; flex: none; }
/* Set here, not inline: the CSP (style-src 'self') drops style attributes. */
.chip[data-brand="bubble"]  { background: #050A0F; }
.chip[data-brand="current"] { background: #45E3B0; }
.chip[data-brand="uplate"]  { background: #EAB308; }
.pname { font-size: clamp(26px, 3.2vw, 36px); line-height: 1; color: var(--ink); }
.pname[data-brand="bubble"]  { font-family: 'Space Grotesk', sans-serif; font-weight: 700; letter-spacing: -.022em; }
.pname[data-brand="current"] { font-family: 'Sora', sans-serif; font-weight: 600; letter-spacing: -.012em; }
.pname[data-brand="uplate"]  { font-family: 'Saira Condensed', sans-serif; font-weight: 800; text-transform: uppercase; letter-spacing: .012em; }

/* Status is its own system, kept clear of the brand colours so the two are
   never confused: filled = shipped, outlined = not yet. */
.st { font-family: var(--mono); font-size: 9.5px; letter-spacing: .16em; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; white-space: nowrap; }
.st.live   { background: var(--ink); color: var(--paper); }
.st.review { border: 1px solid var(--amber); background: rgba(234,179,8,.10); color: var(--amber-ink); }
.st.dev    { border: 1px solid var(--rule-2); color: var(--mute); }

.meta { font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute); margin-bottom: 10px; }
.desc { font-size: 15.5px; line-height: 1.65; color: var(--graphite); max-width: 62ch; }
.go { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; color: var(--mute); white-space: nowrap; align-self: center; transition: color .15s var(--ease); }
a.row:hover .go { color: var(--ink); }
@media (max-width: 640px) { .row { grid-template-columns: 1fr; } .go { align-self: start; } }

/* ── Studio + the record ────────────────────────────────────────────────── */
.split { display: grid; grid-template-columns: 1.15fr .85fr; gap: 56px; align-items: start; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; gap: 40px; } }
.prose { display: flex; flex-direction: column; gap: 16px; font-size: 16.5px; line-height: 1.72; }
.prose strong { color: var(--ink); font-weight: 600; }

/* The record, as the builder's card. After-hours stock — the plot's night —
   with a holographic foil that slides against the light, a glare that follows
   the pointer, and the details typed on. Every effect is a layer over or under
   real text: with the script off, or motion reduced, it is simply a card. */
@property --ang { syntax: '<angle>'; inherits: true; initial-value: 0deg; }
.record { perspective: 1100px; }
.card {
  --mx: 26%; --my: 16%; --hx: 30%; --hy: 40%; --rx: 0deg; --ry: 0deg; --ang: 0deg;
  --card-ink: #EEF0F4; --card-mute: #8E97A4; --glare: .13;
  position: relative; isolation: isolate;
  display: flex; flex-direction: column; gap: 18px;
  max-width: 460px; aspect-ratio: 1.6 / 1;
  padding: 22px 26px 36px; border-radius: 16px;
  color: var(--card-ink);
  background:
    repeating-radial-gradient(circle at 112% 128%, rgba(255,255,255,.028) 0 1px, transparent 1px 6px),
    linear-gradient(150deg, #181B22 0%, #0B0D11 52%, #10131A 100%);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.07), inset 0 0 0 1px rgba(255,255,255,.05),
    0 2px 4px rgba(12,13,15,.10), 0 18px 36px -18px rgba(12,13,15,.5), 0 44px 70px -44px rgba(12,13,15,.45);
  transform: rotateX(var(--rx)) rotateY(var(--ry));
  transition: transform .8s var(--ease);
}
.card.is-live { transition: transform .15s ease-out; }

/* The foil: a band of spectral colour on the stock, under the type. */
.card::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; border-radius: inherit;
  background: linear-gradient(115deg, transparent 18%,
    hsl(192 95% 66%) 27%, hsl(158 85% 62%) 34%, hsl(52 95% 64%) 41%,
    hsl(332 90% 70%) 48%, hsl(262 90% 72%) 55%, transparent 68%);
  background-size: 260% 260%;
  background-position: var(--hx) var(--hy);
  mix-blend-mode: screen; opacity: .15;
  animation: foil-drift 16s ease-in-out infinite alternate;
  transition: opacity .6s var(--ease);
}
.card.is-live::before { animation: none; opacity: .24; transition: background-position .2s linear, opacity .4s var(--ease); }
.card.glint::before { opacity: .3; }
@keyframes foil-drift { from { background-position: 8% 30%; } to { background-position: 92% 70%; } }

/* The light: gloss where the pointer is, over everything like laminate. */
.card::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; border-radius: inherit;
  background: radial-gradient(farthest-corner circle at var(--mx) var(--my),
    rgba(255,255,255,var(--glare)) 0%, rgba(255,255,255,.035) 30%, transparent 58%);
  mix-blend-mode: screen;
}
.card.is-live { --glare: .2; }

.card-top { display: flex; align-items: center; justify-content: space-between; }
.card-mark { fill: var(--amber); flex: none; }
/* A hologram seal: the studio mark embossed into a disc of foil that turns
   slowly on its own and follows the pointer when there is one. */
.seal {
  position: relative; width: 30px; height: 30px; border-radius: 50%; flex: none; opacity: .9;
  background: conic-gradient(from var(--ang), #FF9FD6, #A8D8FF, #9FFFD0, #FFF0A0, #FFB8A0, #D9A8FF, #FF9FD6);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.4), inset 0 0 8px rgba(255,255,255,.35), 0 0 14px rgba(168,216,255,.18);
  animation: seal-turn 18s linear infinite;
}
.seal svg { position: absolute; inset: 8px; fill: rgba(11,13,17,.5); stroke: rgba(255,255,255,.4); stroke-width: 3; }
.card.is-live .seal { animation: none; }
@keyframes seal-turn { to { --ang: 360deg; } }

.card .rrow { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.card .k { font-family: var(--mono); font-size: 9.5px; letter-spacing: .2em; text-transform: uppercase; color: var(--card-mute); }
.card .v { position: relative; font-family: var(--mono); font-size: 13.5px; line-height: 1.3; color: var(--card-ink); white-space: nowrap; }
.card .r-name .v { font-size: 21px; font-weight: 500; letter-spacing: .16em; }
.card-pair { display: flex; flex-wrap: wrap; gap: 16px 34px; }
@media (max-width: 480px) { .card { gap: 16px; padding: 20px 20px 34px; } .card .r-name .v { font-size: 19px; } }
.card .v a { color: inherit; border-bottom: 1px solid var(--amber); transition: color .15s var(--ease), border-color .5s var(--ease); }
.card .v a:hover { color: var(--amber); }
.card a:focus-visible { outline-color: var(--amber); }

/* Security microprint along the foot of the card. */
.card-strip {
  position: absolute; left: 26px; right: 26px; bottom: 15px; height: 9px; overflow: hidden; border-radius: 2px;
  background: linear-gradient(90deg, #FF9FD6, #A8D8FF, #9FFFD0, #FFF0A0, #FFB8A0, #D9A8FF, #FF9FD6);
  background-size: 300% 100%; background-position: var(--hx) 50%; opacity: .55;
  animation: strip-drift 16s ease-in-out infinite alternate;
}
.card.is-live .card-strip { animation: none; transition: background-position .2s linear; }
@keyframes strip-drift { from { background-position: 0% 50%; } to { background-position: 100% 50%; } }
.card-strip span {
  display: block; font-family: var(--mono); font-size: 6px; line-height: 9px; letter-spacing: .3em;
  text-transform: uppercase; white-space: nowrap; color: rgba(11,13,17,.75);
}
@media (max-width: 480px) { .card-strip { left: 20px; right: 20px; } }

/* The typewriter. The real text is there all along — hidden, never missing —
   and the typing is drawn over it, so screen readers, copy-paste and the
   mailto link never meet the effect. */
.card.tw-armed .k { opacity: 0; transition: opacity .25s var(--ease); }
.card.tw-armed .rrow.tw-on .k { opacity: 1; }
.card.tw-armed .v, .card.tw-armed .v a { color: transparent; border-bottom-color: transparent; }
.tw { position: absolute; left: 0; top: 0; color: var(--card-ink); white-space: pre; pointer-events: none; }
.tw-noise { color: var(--amber); }
.tw-caret {
  display: inline-block; width: .6em; height: 1.05em; margin-left: 1px; vertical-align: -.14em;
  background: var(--amber);
}
.tw-caret.idle { animation: caret 1.05s steps(1) infinite; }

@media (forced-colors: active) { .card::before, .card::after, .card-strip, .seal { display: none; } }

/* ── 404 ────────────────────────────────────────────────────────────────────
   A 404 is short by nature — centre it rather than letting it hang off the top
   of a tall viewport. Lives here, not in a <style> block: the CSP drops those. */
.lost {
  min-height: 62vh; display: flex; flex-direction: column; justify-content: center;
  padding-bottom: clamp(40px, 6vw, 72px);
}
.lost > .wrap { width: 100%; }
.lost .code { margin-bottom: 18px; }
.lost h1 { font-size: clamp(40px, 7vw, 88px); margin-bottom: 22px; }
.lost .lede { margin-bottom: 32px; }
.lost .acts { gap: 20px; }

/* The egg (egg.js). Hidden until the script arms it, so a page without the
   script still shows the plain way home. */
.if-egg { display: none; }
html[data-egg] .if-egg { display: revert; }
html[data-egg] .no-egg { display: none; }
.egg-stage { position: relative; height: 240px; }
@media (max-width: 560px) { .egg-stage { height: 210px; } }
#egg { width: 100%; height: 100%; border-radius: 4px; }
.egg-hit {
  position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0; border-radius: 4px;
  background: none; cursor: pointer; touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
/* A game surface: a quiet frame when it has focus, not a heavy ring. */
.egg-hit:focus-visible { outline: 2px solid rgba(12,13,15,.18); outline-offset: 2px; }
.is-night .egg-hit:focus-visible { outline-color: var(--amber); }
/* The prize: once the egg breaks, the home button lives at the top of the
   stage, clear of the chick's jumps. */
.egg-home {
  position: absolute; z-index: 2; top: 16px; left: 50%; translate: -50% 0;
  transition: opacity .15s var(--ease), background-color .4s var(--ease), color .4s var(--ease);
}
.egg-home[hidden] { display: none; }
@media (max-width: 560px) { .egg-home { top: 10px; left: auto; right: 10px; translate: none; } }
.is-night .egg-home { background: var(--paper); color: var(--ink); }
.is-night .egg-home:focus-visible { outline-color: var(--amber); }
.egg-over {
  position: absolute; left: 50%; top: 50%; translate: -50% -50%; pointer-events: none; white-space: nowrap;
  font-family: var(--mono); font-size: 12px; letter-spacing: .42em; text-transform: uppercase; color: var(--ink);
}
.egg-over[hidden] { display: none; }
.is-night .egg-over { color: #E6E8EC; }
.egg-foot { display: flex; justify-content: space-between; gap: 16px; padding-top: 12px; }
.egg-score { color: var(--ink); letter-spacing: .16em; white-space: pre; }

/* ── Footer ─────────────────────────────────────────────────────────────── */
.foot { border-top: 1px solid var(--rule); padding: 36px 0 56px; }
.foot-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 28px; flex-wrap: wrap; }
.fine { font-family: var(--mono); font-size: 10.5px; letter-spacing: .06em; color: var(--mute); line-height: 1.9; }
.foot-links { display: flex; gap: 20px; flex-wrap: wrap; }
.foot-links a { font-family: var(--mono); font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--mute); transition: color .15s var(--ease); }
.foot-links a:hover { color: var(--ink); }

/* ── Motion ─────────────────────────────────────────────────────────────────
   Armed only once motion.js sets [data-motion] on <html>. With JS off, or the
   file blocked, none of this matches and the page renders complete. */
[data-motion="on"] [data-rise] {
  opacity: 0; transform: translateY(14px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
[data-motion="on"] [data-rise][data-shown] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  [data-motion="on"] [data-rise] { opacity: 1; transform: none; }
}
