/* Post-export CSS overrides (added manually — NOT part of the CD export).
   Injected on every page by apply-patches.py. Re-export overwrites the bundle,
   so this file is re-applied by the patch script. */

/* --- Menu: full-screen backdrop + un-clipped panel ---------------------------
   The menu's blur backdrop and panel are authored with position:absolute, so the
   backdrop only covers its container (not the viewport) and the panel gets clipped
   by the hero's overflow:hidden. position:fixed makes the backdrop fill the whole
   screen and lets the panel escape the clipping container.
   NOTE: inline styles serialize WITH a space after the colon, so selectors must
   match "prop: value" (with space), not "prop:value". */
[style*="backdrop-filter: blur(7px)"] { position: fixed !important; }
[style*="width: 470px"][style*="z-index: 6"] { position: fixed !important; }
[style*="left: 12px"][style*="z-index: 6"] { position: fixed !important; }

/* --- Kill the film-grain over the menu ---------------------------------------
   The page's grain overlays (mix-blend, pointer-events:none) paint over the menu
   and add noise to the cream panel, the button and the previews. While the menu
   is open (a blur backdrop is present) hide the grain — the page behind is blurred,
   so its grain isn't missed. */
body:has([style*="backdrop-filter: blur(7px)"]) [style*="Noise.png"],
body:has([style*="backdrop-filter: blur(7px)"]) [style*="Dither.png"] { display: none !important; }


/* --- Responsive: CD ships BOTH #page (desktop 1440) and #page-m (mobile 390)
   with no media query, so both render side-by-side and the mobile column leaves a
   stray band on the right. Add the missing toggle + center the fixed-width page. */
#page-m { display: none !important; }
#page { margin-left: auto !important; margin-right: auto !important; }
@media (max-width: 900px) {
  #page   { display: none !important; }
  #page-m { display: block !important; margin-left: auto !important; margin-right: auto !important; }
}

/* --- Hero intro: heading first, then the CTA ---------------------------------
   Pure-CSS so it plays when the real element renders (survives dc's placeholder→
   real swap, no flash). Heading rises in, the "Email me" button follows.
   Button is matched by its inline width (unique to the hero CTA). */
@keyframes heroIn { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
#page h1 { animation: heroIn .8s cubic-bezier(.2,.7,.2,1) .15s both; }
[style*="width: 665px"] { animation: heroIn .8s cubic-bezier(.2,.7,.2,1) .85s both; }
@media (prefers-reduced-motion: reduce) {
  #page h1, [style*="width: 665px"] { animation: none; }
}

/* --- Entrance reveals (paired with reveal.js) --------------------------------
   Quiet fade + rise for section headings and cards as they scroll in.
   reveal.js only adds .rv to below-the-fold elements, so there is no flash. */
.rv { opacity: 0; transform: translateY(24px); will-change: opacity, transform; }
.rv.rv-in {
  opacity: 1; transform: none;
  transition: opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1);
}
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1 !important; transform: none !important; }
}
