/* =========================================================================
   mohny.tech — motion layer
   Progressive enhancement ONLY. Every rule that hides content is gated on
   html.js (set by an inline script before paint) and unset by .rm
   (prefers-reduced-motion). No JS / reduced motion => everything visible.
   Animates transform + opacity only. Nothing here can cause layout shift.
   ========================================================================= */

:root{
  --e-out:cubic-bezier(.16,1,.3,1);      /* entering */
  --e-in:cubic-bezier(.7,0,.84,0);       /* exiting  */
  --d-fast:180ms; --d-mid:340ms;
  --z-grain:9000; --z-prog:9100; --z-cursor:9500; --z-curtain:9800;
}

/* full-bleed sections use 100vw; clip (not hidden) so position:sticky
   on lead-audit's score panel keeps working */
html,body{overflow-x:clip}

/* ---------- 1. grain ---------------------------------------------------- */
/* Pre-rendered PNG tile, no blend mode, no animation. An SVG feTurbulence
   filter under a full-viewport mix-blend-mode re-rasterises on every
   composite and pins the renderer — this costs nothing and looks the same. */
.grain{
  position:fixed; inset:0; z-index:var(--z-grain); pointer-events:none;
  opacity:.55; background-image:url(/assets/grain.png); background-size:140px 140px;
}

/* ---------- 2. scroll progress ------------------------------------------ */
.prog{
  position:fixed; top:0; left:0; height:2px; width:100%; z-index:var(--z-prog);
  transform:scaleX(0); transform-origin:0 50%; background:var(--ok);
  pointer-events:none; will-change:transform;
}

/* ---------- 3. custom cursor (fine pointers only) ----------------------- */
.cur,.cur-r{position:fixed;top:0;left:0;z-index:var(--z-cursor);pointer-events:none;border-radius:50%;opacity:0}
.cur{width:6px;height:6px;background:var(--ok);margin:-3px 0 0 -3px}
.cur-r{
  width:38px;height:38px;margin:-19px 0 0 -19px;border:1px solid var(--ok);
  transition:width var(--d-fast) var(--e-out),height var(--d-fast) var(--e-out),
             margin var(--d-fast) var(--e-out),opacity var(--d-fast) linear,
             background-color var(--d-fast) linear;
}
html.js:not(.rm) .cur.on,html.js:not(.rm) .cur-r.on{opacity:1}
.cur-r.grow{width:66px;height:66px;margin:-33px 0 0 -33px;background:color-mix(in srgb,var(--ok) 12%,transparent)}
@media (hover:none),(pointer:coarse){.cur,.cur-r{display:none}}

/* ---------- 4. page-transition curtain ---------------------------------- */
.curtain{
  position:fixed; inset:0; z-index:var(--z-curtain); background:var(--ground);
  transform:scaleY(0); transform-origin:50% 100%; pointer-events:none;
}
html.js:not(.rm) .curtain.out{transform:scaleY(1);transform-origin:50% 100%;transition:transform 520ms var(--e-in)}
html.js:not(.rm) .curtain.in{transform:scaleY(0);transform-origin:50% 0;transition:transform 620ms var(--e-out)}

/* ---------- 5. preloader ------------------------------------------------ */
.pre{
  position:fixed; inset:0; z-index:var(--z-curtain); background:var(--ground);
  display:grid; place-content:center; gap:18px; justify-items:center;
}
html:not(.js) .pre,html.rm .pre{display:none}
.pre-m{font-family:var(--mono);font-size:11px;letter-spacing:.28em;text-transform:uppercase;color:var(--ok)}
.pre-n{font-family:var(--mono);font-size:clamp(48px,12vw,110px);font-weight:600;color:var(--ink);line-height:1;font-variant-numeric:tabular-nums}
.pre-b{width:min(240px,54vw);height:1px;background:var(--hair);overflow:hidden}
.pre-b i{display:block;height:100%;width:100%;background:var(--ok);transform:scaleX(0);transform-origin:0 50%}
.pre.done{transform:translateY(-100%);transition:transform 760ms var(--e-in);pointer-events:none}

/* ---------- 6. hero ----------------------------------------------------- */
.hero{position:relative;margin-left:calc(50% - 50vw);width:100vw;padding:clamp(52px,10vh,110px) 0 clamp(28px,5vh,56px);overflow:hidden}
.hero-c{position:absolute;inset:0;width:100%;height:100%;opacity:.72}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .hero-c{opacity:.55}}
:root[data-theme="dark"] .hero-c{opacity:.55}
html.rm .hero-c{opacity:.28}
.hero-in{position:relative;max-width:760px;margin:0 auto;padding:0 22px}
.hero h1{
  font-size:clamp(42px,10.5vw,116px); line-height:.92; letter-spacing:-.045em;
  font-weight:700; margin:0; text-wrap:balance;
}
.hero .dek{max-width:52ch}

/* subpages carry longer titles, so they get a smaller display scale */
.hero--sub{padding:clamp(38px,7vh,76px) 0 clamp(22px,4vh,44px)}
.hero--sub h1{font-size:clamp(34px,6.6vw,72px);line-height:.98;letter-spacing:-.035em}


/* word reveal — the mask never changes layout height */
.sw{display:inline-block;overflow:hidden;vertical-align:top;padding-bottom:.08em;margin-bottom:-.08em}
.sw>i{display:inline-block;font-style:normal;will-change:transform}
html.js:not(.rm) .sw>i{transform:translateY(105%)}
html.js:not(.rm) .rv .sw>i{transform:translateY(0);transition:transform 900ms var(--e-out);transition-delay:var(--dl,0ms)}

/* ---------- 7. scroll reveal -------------------------------------------- */
html.js:not(.rm) [data-rv]{opacity:0;transform:translateY(22px);will-change:transform,opacity}
/* CSS-only failsafe: html.js is set by an inline script, so if motion.js 404s
   or throws before boot, nothing would ever add .rv and the content would stay
   invisible. This reveals it after 4s regardless of JS. */
html.js:not(.rm) [data-rv]{animation:rv-failsafe 1ms linear 4s forwards}
html.js:not(.rm) .sw>i{animation:sw-failsafe 1ms linear 4s forwards}
@keyframes rv-failsafe{to{opacity:1;transform:none}}
@keyframes sw-failsafe{to{transform:translateY(0)}}

html.js:not(.rm) [data-rv].rv{
  opacity:1;transform:none;
  transition:opacity 620ms var(--e-out),transform 720ms var(--e-out);
  transition-delay:var(--dl,0ms);
}

/* ---------- 8. resource cards ------------------------------------------- */
/* vector card icons — emoji render differently on every OS and read as clip-art */
html.js:not(.rm) .mag{transition:transform 420ms var(--e-out)}

/* ---------- 8b. numbered index (hub) ------------------------------------
   Replaces the small card grid. Full-bleed, wider than the reading column,
   big type rows — scans faster on a phone and gives far bigger tap targets. */
.idx{margin-left:calc(50% - 50vw);width:100vw;margin-top:8px}
.idx-in{max-width:1120px;margin:0 auto;padding:0 22px}
.idx-h{font-family:var(--mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-mute);padding:22px 0 12px;border-bottom:1px solid var(--hair);display:flex;
  justify-content:space-between}
.ix{
  display:grid;grid-template-columns:auto 1fr auto;column-gap:clamp(14px,2.6vw,34px);
  align-items:start;padding:clamp(20px,3vw,30px) 0;border-bottom:1px solid var(--hair);
  text-decoration:none;color:inherit;position:relative;isolation:isolate;
}
.ix::before{
  content:"";position:absolute;inset:0 -22px;z-index:-1;pointer-events:none;
  background:color-mix(in srgb,var(--ok) 7%,transparent);opacity:0;
}
html.js:not(.rm) .ix{transition:transform 420ms var(--e-out)}
html.js:not(.rm) .ix::before{transition:opacity 300ms linear}
html.js:not(.rm) .ix:hover,html.js:not(.rm) .ix:focus-visible{transform:translateX(10px)}
html.js:not(.rm) .ix:hover::before,html.js:not(.rm) .ix:focus-visible::before{opacity:1}
.ix .n{font-family:var(--mono);font-size:12px;letter-spacing:.12em;color:var(--ink-mute);
  padding-top:.45em;font-variant-numeric:tabular-nums}
.ix:hover .n,.ix:focus-visible .n{color:var(--ok)}
.ix h2{font-size:clamp(23px,4.6vw,46px);line-height:1.02;letter-spacing:-.032em;font-weight:600;
  display:flex;align-items:center;gap:.5em;flex-wrap:wrap}
.ix h2 svg{width:clamp(18px,2.4vw,26px);height:clamp(18px,2.4vw,26px);color:var(--ok);flex:none}
.ix .d{font-family:var(--serif);font-size:15.5px;line-height:1.55;color:var(--ink-2);
  margin-top:10px;max-width:58ch}
.ix .go{font-family:var(--mono);color:var(--ok);font-size:18px;padding-top:.3em;flex:none}
html.js:not(.rm) .ix .go{transition:transform 420ms var(--e-out)}
.ix:hover .go,.ix:focus-visible .go{transform:translate(6px,-6px)}
@media (max-width:560px){
  .ix{grid-template-columns:auto 1fr;row-gap:0}
  .ix .go{display:none}
}

/* ---------- 8c. closing statement --------------------------------------- */
.say{margin-left:calc(50% - 50vw);width:100vw;padding:clamp(60px,11vh,130px) 0 clamp(40px,7vh,80px);
  border-top:1px solid var(--hair);margin-top:52px}
.say-in{max-width:1120px;margin:0 auto;padding:0 22px}

.say p{font-size:clamp(28px,6.2vw,68px);line-height:1.02;letter-spacing:-.04em;font-weight:700;
  max-width:16ch;text-wrap:balance}
.say p em{font-style:normal;color:var(--ok)}
.say p.say-lead{font-family:var(--serif);font-size:16px;font-weight:400;line-height:1.6;letter-spacing:0;color:var(--ink-2);max-width:56ch;margin:0 0 clamp(28px,5vh,52px)}
.say .go{display:inline-block;margin-top:clamp(24px,4vh,44px);font-family:var(--mono);
  font-size:14px;letter-spacing:.06em;color:var(--ok);text-decoration:none;
  border:1px solid var(--ok);padding:15px 26px;border-radius:2px;min-height:48px}
html.js:not(.rm) .say .go{transition:transform 420ms var(--e-out),background-color 300ms linear}
.say .go:hover,.say .go:focus-visible{background:color-mix(in srgb,var(--ok) 12%,transparent)}

/* ---------- 9. marquee -------------------------------------------------- */
.mq{
  margin-left:calc(50% - 50vw);width:100vw;overflow:hidden;
  border-top:1px solid var(--hair);border-bottom:1px solid var(--hair);
  padding:13px 0;margin-top:44px;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
}
.mq-t{display:flex;width:max-content}
.mq-t span{
  font-family:var(--mono);font-size:11.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink-mute);padding:0 26px;white-space:nowrap;
}
.mq-t span b{color:var(--ok);font-weight:600}
html.js:not(.rm) .mq-t{animation:mq 42s linear infinite}
html.js:not(.rm) .mq:hover .mq-t{animation-play-state:paused}
@keyframes mq{to{transform:translateX(-50%)}}

/* ---------- 10. section rule draw --------------------------------------- */
.rule{transform-origin:0 50%}
html.js:not(.rm) section .rule{transform:scaleX(0)}
html.js:not(.rm) section.rv .rule{transform:scaleX(1);transition:transform 820ms var(--e-out) 90ms}

/* ---------- 11. handle underline ---------------------------------------- */
.handle{position:relative;text-decoration:none;display:inline-block}
.handle::after{
  content:"";position:absolute;left:0;right:0;bottom:-3px;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:100% 50%;
}
html.js:not(.rm) .handle:hover::after,html.js:not(.rm) .handle:focus-visible::after{
  transform:scaleX(1);transform-origin:0 50%;transition:transform var(--d-mid) var(--e-out);
}
html:not(.js) .handle,html.rm .handle{text-decoration:underline}

/* ---------- 12. failsafes ----------------------------------------------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  .pre,.cur,.cur-r,.curtain{display:none!important}
  [data-rv],.sw>i{opacity:1!important;transform:none!important}
}
html.rm [data-rv],html.rm .sw>i,html.rm section .rule{opacity:1!important;transform:none!important}

/* ---------- MAXIMALISM ---------------------------------------------------
   Purple + clashing accents, after Memphis (Sottsass, 1981) and 90s rave /
   jungle flyer print, where purple against acid lime was the loudest pairing
   available in commercial printing. Every accent is used at once, on purpose.
   Slab colours are brand constants: identical in both themes, so the
   colour-on-colour ratios below never change. */
/* slab and tape derive from the accent tokens so they follow the palette.
   Text on them is --ground, and every accent was verified >=4.5:1 against
   --ground, so these pairings are contrast-safe by construction. */
:root{--slab:var(--ok);--slab-ink:var(--ground);--tape:var(--alt);--tape-ink:var(--ground)}

/* display type is loud again: heavy grotesk, tight, big */
.hero h1,.ix h2,.say p:not(.say-lead){font-family:var(--sans);font-weight:800}
.hero h1{font-size:clamp(46px,11vw,124px);line-height:.88;letter-spacing:-.05em}
.hero--sub h1{font-size:clamp(36px,7vw,82px);line-height:.92;letter-spacing:-.042em}
.ix h2{font-size:clamp(24px,4.4vw,46px);line-height:1;letter-spacing:-.035em}
.say p:not(.say-lead){font-size:clamp(30px,6.4vw,74px);line-height:.96;letter-spacing:-.045em;max-width:15ch}

/* hero gets a colour field behind the signal canvas */
.hero{background:
  radial-gradient(60% 80% at 12% 8%, color-mix(in srgb,var(--ok) 26%,transparent), transparent 70%),
  radial-gradient(50% 70% at 92% 22%, color-mix(in srgb,var(--bad) 20%,transparent), transparent 70%),
  radial-gradient(70% 60% at 60% 100%, color-mix(in srgb,var(--alt) 14%,transparent), transparent 70%);}

/* marquee = acid tape */
.mq{background:var(--tape);border-top:3px solid var(--ink);border-bottom:3px solid var(--ink);
    -webkit-mask-image:none;mask-image:none}
.mq-t span{color:var(--tape-ink);font-weight:700}
.mq-t span b{color:var(--tape-ink);font-weight:800}

/* index rows: chunky, colour-cycled, brutalist offset on hover */
.ix{border-bottom:2px solid var(--ink);padding-left:clamp(10px,1.6vw,20px)}
.ix::before{background:var(--rowc,var(--ok));opacity:0}
/* .idx-h occupies child 1, so rows start at child 2 — rotated so row 01 leads
   with the primary purple, then magenta, then lime */
.ix:nth-child(3n+2){--rowc:var(--ok)}
.ix:nth-child(3n+3){--rowc:var(--bad)}
.ix:nth-child(3n+1){--rowc:var(--alt)}
.ix .n{color:var(--rowc,var(--ok));font-weight:700;font-size:13px}
.ix h2 svg{color:var(--rowc,var(--ok))}
.ix .go{color:var(--rowc,var(--ok));font-weight:700}
html.js:not(.rm) .ix:hover,html.js:not(.rm) .ix:focus-visible{
  transform:translateX(12px);box-shadow:-12px 0 0 0 var(--rowc,var(--ok))}
html.js:not(.rm) .ix:hover::before,html.js:not(.rm) .ix:focus-visible::before{opacity:.14}
.idx-h{border-bottom:3px solid var(--ink);font-weight:700}

/* closing block = purple slab */
.say{background:var(--slab);color:var(--slab-ink);border-top:0}
.say p,.say p.say-lead{color:var(--slab-ink)}
/* invert the slab pair rather than introduce a third colour: --slab-ink is
   --ground, and every accent is verified >=4.5:1 against --ground, so this
   chip is contrast-safe in any palette. Using --tape here gave 1.35:1. */
.say p em{font-style:normal;background:var(--slab-ink);color:var(--slab);padding:0 .14em}
.say .go{color:var(--slab-ink);border:2px solid var(--slab-ink);font-weight:700}
html.js:not(.rm) .say .go{transition:background-color 200ms linear,transform 420ms var(--e-out)}
.say .go:hover,.say .go:focus-visible{background:var(--tape);border-color:var(--tape);color:var(--tape-ink)}

/* ---------- OFFICIAL BRAND LOCKUP ---------------------------------------
   Assets copied unaltered from the House of Mohny brand system
   (public/brand/svg, generated by `npm run brand`, guarded by
   tests/brand-guards.spec.ts). The official signal colour is red #D5202A,
   which would clash with this site's purple, so the sanctioned MONO variants
   are used instead: mono-paper on the dark theme, mono-ink on the light one.
   Neither file is recoloured. Aspect ratio is 11.22:1 — height drives width. */
.hom{display:inline-flex;align-items:center;gap:12px;text-decoration:none;
  padding:13px 0;margin:-13px 0}  /* 19px mark, 45px tap target, zero layout cost */
.hom-lockup{height:19px;width:calc(19px * 11.2176);display:block;
  background-color:currentColor;
  -webkit-mask:url(/assets/brand/lockup-horizontal-mono-ink.svg) no-repeat center/contain;
          mask:url(/assets/brand/lockup-horizontal-mono-ink.svg) no-repeat center/contain}
.hom{color:var(--ink)}
html.js:not(.rm) .hom-lockup{transition:opacity 220ms linear}
.hom:hover .hom-lockup,.hom:focus-visible .hom-lockup{opacity:.62}
.hom-out{font-family:var(--mono);font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ok);white-space:nowrap}
@media (max-width:620px){.hom-lockup{height:15px;width:calc(15px * 11.2176)}.hom-out{display:none}}

/* the header row holds the lockup on the left and the section label on the right */
header.top{align-items:center}
.brand{font-family:var(--mono);font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--ok);font-weight:700;text-decoration:none}
.fl{color:inherit;text-decoration:underline;text-underline-offset:2px}
.fl:hover,.fl:focus-visible{color:var(--ok)}
