/* css/fx.css: the connective tissue. Header, mobile menu, magnetic buttons,
   label decode and page atmosphere. Loaded right after styles.css.
   JS lives in js/fx.mjs. Everything decorative here is aria-hidden and pointer-events:none. */

/* ==========================================================================
   Header: transparent over the hero, a solid soot bar once scrolled,
   hides on scroll down (js adds .fx-hide) and returns on scroll up.
   ========================================================================== */
/* A taller bar than the old text wordmark needed, so the winged logo reads at a glance */
:root{--header-h:96px}
@media (max-width:900px){:root{--header-h:80px}}
.site-header{
  position:fixed;top:0;left:0;right:0;z-index:50;
  min-height:var(--header-h);padding:0 clamp(16px,4.5vw,64px);
  display:flex;align-items:center;justify-content:flex-start;gap:clamp(12px,2vw,28px);
  color:var(--text);
  background:linear-gradient(180deg,rgb(var(--brand-deep-rgb) / 0.72),rgb(var(--brand-deep-rgb) / 0.3) 62%,rgb(var(--brand-deep-rgb) / 0));
  border:0;box-shadow:none;
  transition:translate .65s var(--ease-out),box-shadow .45s ease;
}
/* The soot bar is a layer, so it can fade without repainting the header's contents. */
.site-header::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:var(--background);border-bottom:1px solid var(--line);
  opacity:0;transition:opacity .45s ease;
}
.site-header.is-scrolled{box-shadow:0 18px 40px -28px var(--brand-deep)}
.site-header.is-scrolled::before{opacity:1}
.site-header.fx-hide{translate:0 -100%;box-shadow:none}
/* A transform on the header would trap the fixed menu overlay inside it, so none while the menu is open. */
body.menu-open .site-header{translate:none;transition:none}

/* Reading-progress line: a red fuse with an ember tip. It sits just under the bar,
   so it stays visible at the top of the viewport while the header is tucked away. */
.site-header::after{
  content:"";position:absolute;left:0;right:0;bottom:-2px;height:2px;z-index:2;pointer-events:none;
  background:linear-gradient(90deg,var(--oxblood),var(--red) 62%,var(--ember));
  box-shadow:0 0 12px rgb(var(--brand-clay-rgb) / 0.4);
  transform-origin:left center;transform:scaleX(var(--scroll-progress,0));
  transition:opacity .3s ease;
}
body.menu-open .site-header::after{opacity:0}

/* Wordmark: the winged REINCAROCK logo (assets/reincarock-logo.webp, white on transparent) */
.wordmark{
  position:relative;z-index:1;order:0;margin-right:auto;
  display:inline-flex;align-items:center;padding-block:4px;line-height:0;
}
.wordmark-logo{display:block;width:auto;height:calc(var(--header-h) - 8px);max-width:none;transition:filter .35s ease,opacity .45s ease,translate .45s var(--ease-out)}
/* hidden while the hero's big logo is on screen (app.mjs toggles .hero-logo-in) */
.site-header.hero-logo-in .wordmark{pointer-events:none}
.site-header.hero-logo-in .wordmark-logo{opacity:0;translate:0 -8px}
.site-header.hero-logo-in .wordmark:focus-visible{pointer-events:auto}
.site-header.hero-logo-in .wordmark:focus-visible .wordmark-logo{opacity:1;translate:none}
.wordmark:hover .wordmark-logo,.wordmark:focus-visible .wordmark-logo{filter:drop-shadow(0 0 12px rgb(var(--brand-clay-rgb) / 0.45))}

/* Slot order: wordmark, nav (desktop); wordmark, menu toggle (mobile). */
.site-header nav{order:1}
.site-header>.menu-toggle{order:3}

/* Desktop nav */
.site-header nav{
  display:flex;align-items:center;gap:clamp(14px,2.1vw,34px);
  font-size:.8125rem;line-height:1.2;letter-spacing:.12em;text-transform:uppercase;font-weight:400;
}
.site-header nav>a:not(.button){
  position:relative;display:inline-flex;align-items:flex-start;padding-block:12px;
  color:var(--brand-blush);transition:color .3s ease;
}
.site-header nav>a:not(.button):hover,.site-header nav>a[aria-current]{color:var(--text)}
.nav-text{position:relative}
/* A dry-brush stroke that draws in from the left and wipes out to the right. */
.nav-text::after{
  content:"";position:absolute;left:-3px;right:-3px;bottom:-7px;height:6px;pointer-events:none;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 10' preserveAspectRatio='none'%3E%3Cpath d='M2 6.4C22 4.2 44 5.6 66 4.6S108 3 130 3.8s46 1.6 68-.6l-.6 3.4c-20 1.6-42 .8-64 .9S94 8.6 72 8.4 26 8.9 2.6 9.2z'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 10' preserveAspectRatio='none'%3E%3Cpath d='M2 6.4C22 4.2 44 5.6 66 4.6S108 3 130 3.8s46 1.6 68-.6l-.6 3.4c-20 1.6-42 .8-64 .9S94 8.6 72 8.4 26 8.9 2.6 9.2z'/%3E%3C/svg%3E") center/100% 100% no-repeat;
  transform:scaleX(0);transform-origin:right center;transition:transform .55s var(--ease-out);
}
.site-header nav>a:hover .nav-text::after,.site-header nav>a:focus-visible .nav-text::after{transform:scaleX(1);transform-origin:left center}
.site-header nav>a[aria-current] .nav-text::after{transform:scaleX(1);transform-origin:left center;background:var(--ember)}
.nav-meta{display:none}

/* "Book tickets": a yellow paper fill with a torn top edge rises through the red. */
.site-header .nav-ticket{
  position:relative;overflow:hidden;isolation:isolate;gap:.6em;
  min-height:42px;padding:10px 18px;margin-left:clamp(0px,.6vw,10px);
  font-size:.78rem;letter-spacing:.12em;background:var(--red);border:1px solid var(--red);color:var(--text);
  transition:color .35s ease,border-color .35s ease,box-shadow .4s ease,scale .2s ease;
}
.site-header .nav-ticket::before{
  content:"";position:absolute;inset:-9px -1px -1px;z-index:-1;pointer-events:none;background:var(--yellow);
  clip-path:polygon(0 7px,7% 3px,15% 8px,24% 2px,33% 7px,43% 1px,52% 6px,61% 2px,70% 8px,79% 3px,88% 7px,95% 2px,100% 6px,100% 100%,0 100%);
  transform:translateY(101%);transition:transform .55s var(--ease-out);
}
.site-header .nav-ticket:hover,.site-header .nav-ticket:focus-visible{background:var(--red);color:var(--black);border-color:var(--yellow);box-shadow:0 10px 30px -12px rgb(var(--brand-clay-rgb) / 0.7)}
.site-header .nav-ticket:hover::before,.site-header .nav-ticket:focus-visible::before{transform:none}
.nav-ticket-arrow{display:inline-block;font-family:var(--sans);line-height:1;transition:translate .45s var(--ease-spring)}
.site-header .nav-ticket:hover .nav-ticket-arrow{translate:2px -2px}

/* Menu toggle: "Menu +" morphs to "Close ×". Only the visible word is in the accessible name. */
.menu-toggle{
  display:none;position:relative;z-index:1;align-items:center;gap:10px;
  min-height:44px;padding:6px 2px 6px 10px;border:0;background:transparent;color:var(--text);cursor:pointer;
  font-family:var(--sans);font-size:.72rem;line-height:1;letter-spacing:.16em;text-transform:uppercase;
}
.menu-toggle-label{display:grid;overflow:hidden;padding-block:.2em}
.menu-toggle-label>span{grid-area:1/1;text-align:right;transition:translate .5s var(--ease-out),opacity .3s ease,visibility 0s linear 0s}
.menu-toggle-close,
.menu-toggle[aria-expanded="true"] .menu-toggle-open{translate:0 115%;opacity:0;visibility:hidden;transition:translate .5s var(--ease-out),opacity .3s ease,visibility 0s linear .5s}
.menu-toggle[aria-expanded="true"] .menu-toggle-open{translate:0 -115%}
.menu-toggle[aria-expanded="true"] .menu-toggle-close{translate:none;opacity:1;visibility:visible;transition:translate .5s var(--ease-out) .05s,opacity .3s ease .05s,visibility 0s linear 0s}
.menu-toggle-icon{
  position:relative;flex:none;width:32px;height:32px;border-radius:50%;
  border:1px solid rgb(var(--brand-sand-rgb) / 0.35);
  transition:rotate .6s var(--ease-spring),border-color .3s ease,background-color .3s ease;
}
.menu-toggle-icon::before,.menu-toggle-icon::after{
  content:"";position:absolute;left:50%;top:50%;width:12px;height:1.5px;margin:-.75px 0 0 -6px;border-radius:1px;background:currentColor;
}
.menu-toggle-icon::after{rotate:90deg}
.menu-toggle:hover .menu-toggle-icon{border-color:var(--ochre)}
.menu-toggle[aria-expanded="true"] .menu-toggle-icon{rotate:135deg;border-color:var(--ember);background:rgb(var(--brand-clay-rgb) / 0.12)}

/* ==========================================================================
   Mobile menu (<=900px): a full-screen soot overlay that drops like a torn curtain.
   Scoped to html.js (set in <head> before first paint), so the closed state holds from the first
   frame; without JS the nav stays an ordinary wrapped row. Closing transitions only run once js
   has armed the header (.fx-menu-armed), so nothing replays on load or when resizing past 900px.
   ========================================================================== */
@media (max-width:900px){
  .site-header{padding-inline:clamp(16px,5vw,40px);gap:12px}
  .menu-toggle:not([hidden]){display:inline-flex}
  body.menu-open{overflow:hidden}

  html.js .site-header nav{
    position:fixed;inset:0;z-index:0;width:auto;max-height:none;
    display:flex;flex-direction:column;flex-wrap:nowrap;align-items:stretch;justify-content:flex-start;gap:0;
    padding:calc(var(--header-h) + clamp(14px,4.5svh,44px)) clamp(20px,7vw,56px) max(24px,env(safe-area-inset-bottom));
    overflow:hidden auto;overscroll-behavior:contain;scrollbar-width:none;
    font-size:1rem;letter-spacing:0;text-transform:none;
    visibility:hidden;
  }
  html.js .site-header nav::-webkit-scrollbar{display:none}
  /* Soot sheet with grain and a torn bottom edge; the edge sits off-screen once it has dropped. */
  html.js .site-header nav::before{
    content:"";position:fixed;inset:0 0 -12svh;z-index:-2;pointer-events:none;
    background:
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.1'/%3E%3C/svg%3E") 0 0/200px 200px,
      radial-gradient(70% 45% at 92% 4%,rgb(var(--brand-wine-rgb) / 0.55),transparent 70%),
      var(--soot);
    clip-path:polygon(0 0,100% 0,100% 97%,96% 98.5%,91% 97%,85% 99%,78% 97.5%,70% 99.5%,62% 98%,55% 99.3%,47% 97.4%,40% 99.6%,33% 98%,25% 99.4%,18% 97.6%,11% 99.2%,5% 97.8%,0 99%);
    transform:translateY(-101%);
  }
  /* Ember glow banked at the foot of the sheet. */
  html.js .site-header nav::after{
    content:"";position:fixed;left:-25%;right:-25%;bottom:-30svh;height:75svh;z-index:-1;pointer-events:none;
    background:radial-gradient(closest-side,rgb(var(--brand-clay-rgb) / 0.34),rgb(var(--brand-red-rgb) / 0.2) 52%,transparent);
    opacity:0;
  }
  html.js .site-header nav>*{opacity:0;translate:0 42px}

  /* Closing: items fade first, then the sheet lifts away. */
  .site-header.fx-menu-armed:has(.menu-toggle[aria-expanded="false"]) nav{transition:visibility 0s linear .75s}
  .site-header.fx-menu-armed:has(.menu-toggle[aria-expanded="false"]) nav::before{transition:transform .6s cubic-bezier(.76,0,.24,1) .14s}
  .site-header.fx-menu-armed:has(.menu-toggle[aria-expanded="false"]) nav::after{transition:opacity .3s ease}
  .site-header.fx-menu-armed:has(.menu-toggle[aria-expanded="false"]) nav>*{transition:opacity .2s ease,translate 0s linear .3s}

  /* Opening: the sheet drops, then items stagger in. */
  .site-header:has(.menu-toggle[aria-expanded="true"]) nav{visibility:visible}
  .site-header:has(.menu-toggle[aria-expanded="true"]) nav::before{transform:none;transition:transform .6s cubic-bezier(.76,0,.24,1)}
  .site-header:has(.menu-toggle[aria-expanded="true"]) nav::after{opacity:1;transition:opacity .9s ease .35s;animation:fx-embers 4.5s ease-in-out 1.2s infinite alternate}
  .site-header:has(.menu-toggle[aria-expanded="true"]) nav>*{
    opacity:1;translate:none;
    transition:opacity .5s ease calc(.26s + var(--i,0)*70ms),translate .9s var(--ease-out) calc(.26s + var(--i,0)*70ms);
  }
  .site-header nav>:nth-child(2){--i:1}
  .site-header nav>:nth-child(3){--i:2}
  .site-header nav>:nth-child(4){--i:3}
  .site-header nav>:nth-child(5){--i:4}
  .site-header nav>:nth-child(6){--i:5}

  html.js .site-header nav>a:not(.button){
    display:flex;align-items:flex-start;gap:clamp(12px,3.5vw,22px);padding:.2em 0 .12em;
    border-bottom:1px solid var(--line);
    font-family:var(--serif);font-size:clamp(2.2rem,min(12.5vw,8.6svh),5.2rem);line-height:1.02;letter-spacing:.005em;text-transform:uppercase;
    color:var(--text);
  }
  html.js .site-header nav>a:first-child{border-top:1px solid var(--line)}
  html.js .site-header .nav-text::after{bottom:-.02em;height:.14em}
  html.js .site-header nav>a[aria-current] .nav-text{text-shadow:0 0 28px rgb(var(--brand-clay-rgb) / 0.45)}
  html.js .site-header nav>.nav-ticket{margin:clamp(20px,4svh,36px) 0 0;width:100%;min-height:58px;font-size:.8rem}
  html.js .site-header .nav-meta{
    display:flex;flex-direction:column;gap:4px;margin-top:auto;padding-top:clamp(18px,4svh,40px);
    font-size:.66rem;line-height:1.5;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
    /* Fade in place so the bottom label never creates overflow while entering. */
    translate:none;
  }
}
@media (max-width:380px){
  .site-header{gap:8px}
  .wordmark-logo{height:calc(var(--header-h) - 14px)}
  .menu-toggle{gap:8px;padding-left:4px}
  .menu-toggle-icon{width:28px;height:28px}
}
@keyframes fx-embers{from{opacity:1;transform:scale(1)}to{opacity:.62;transform:scale(1.08) translateY(2%)}}

/* ==========================================================================
   Buttons: magnetic pull is written by js as the `translate` property,
   so it composes with any transform a section applies.
   ========================================================================== */
.button.fx-magnetic{transition:background-color .3s ease,border-color .3s ease,color .3s ease,box-shadow .4s ease,scale .25s var(--ease-spring)}

/* ==========================================================================
   Label decode: scrambled letters resolve into the label.
   The final character always holds the width; the glyph floats over it.
   ========================================================================== */
.fx-dw{white-space:nowrap}
.fx-dc{position:relative}
.fx-dc__g{
  position:absolute;left:50%;top:50%;translate:-50% -52%;pointer-events:none;
  font-size:1em;line-height:1;letter-spacing:0;font-style:normal;
  color:currentColor;opacity:.72;
}
.fx-dc:not(.is-set):not(.is-static) .fx-dc__f{opacity:0}
.fx-dc.is-set .fx-dc__g{opacity:0}
.fx-dc.is-set .fx-dc__f{animation:fx-dc-flash .7s ease-out both}
@keyframes fx-dc-flash{from{color:var(--ember);text-shadow:0 0 10px rgb(var(--brand-clay-rgb) / 0.8)}to{}}

/* ==========================================================================
   Atmosphere: edge vignette (static) and drifting ash (js canvas).
   ========================================================================== */
.fx-vignette{
  position:fixed;inset:0;z-index:45;pointer-events:none;
  background:radial-gradient(135% 105% at 50% 42%,transparent 58%,rgb(var(--brand-deep-rgb) / 0.26) 84%,rgb(var(--brand-deep-rgb) / 0.5) 100%);
}
.fx-ash{position:fixed;inset:0;width:100%;height:100%;z-index:40;pointer-events:none}

/* ==========================================================================
   Reduced motion: no ash, the header never hides.
   (styles.css already stops every animation and transition.)
   ========================================================================== */
:root[data-motion="reduce"] .fx-ash{display:none}
:root[data-motion="reduce"] .site-header.fx-hide{translate:none}
@media (prefers-reduced-motion:reduce){
  .fx-ash{display:none}
  .site-header.fx-hide{translate:none}
}
