/* =========================================================================
   Wicked Pines — page styles
   -------------------------------------------------------------------------
   Loaded AFTER /assets/pw/stage.css, so it can do two things:

     1. Re-point the site's shared custom properties to a cold-pine palette.
        The utility strip, the footer and the motion button all read those
        variables, so they turn silver here without any of their rules
        being touched or duplicated.

     2. Own the stage and the hero, which are this page's alone.

   Everything is prefixed `wp-`. The shared `pw-` classes keep working.
   ========================================================================= */

/* ------------------------------------------------------------- palette */

.wp-page {
  /* Overrides of the shared vars. These cascade to .pw-strip, .pw-footer
     and .pw-motion, which is the whole point of doing it here. */
  --pw-void: #04070a;
  --pw-void-2: #0a1210;
  --pw-bone: #eef3f0;
  --pw-bone-dim: #9fb2b6;
  --pw-bone-faint: #62767b;
  /* The accent trio lives in stage.css under .pw-accent-frost, which this
     page's <body> carries — one definition, shared with the other themed
     pages, instead of a private copy that drifts. */

  /* Page-local. */
  --wp-pine: #0a1410;
  --wp-pine-2: #12211a;
  --wp-moon: #cfe2ea;
  --wp-frost: #a8cfd6;
  --wp-sage: #7fb59b;
  --wp-measure: 62rem;

  background: var(--pw-void) !important;
  color: var(--pw-bone);
  min-height: 100vh;
  min-height: 100dvh;
}

/* --------------------------------------------------------------- stage */

/* Behind ordinary content, exactly like the shared stage: z-index -1 means
   no sibling needs lifting, and the fixed utility strip keeps winning. */
.wp-stage {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--pw-void);
  overflow: hidden;
}

/* The forest plate. Full-bleed, and scaled slightly so the parallax
   translate has headroom and never exposes an edge. It moves LESS than
   the fog in front of it — that difference is the depth. */
.wp-plate {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 60%;
  filter: saturate(0.82) contrast(1.08) brightness(0.74);
  transform: translate3d(calc(var(--wp-par-x, 0) * -0.9%), calc(var(--wp-par-y, 0) * -0.6%), 0)
             scale(1.06);
  will-change: transform;
}

/* Faded out by script when the clip has not arrived, so the shader's
   procedural treeline shows instead of a black box or a broken-media icon.

   Opacity rather than display:none deliberately. Hiding the element can stall
   a load that is still in flight, which turned a slow clip into a permanently
   missing one. This way it keeps downloading behind the drawn forest and
   fades in when it is ready. */
.wp-plate--waiting { opacity: 0; }

/* The fog. Sits over the plate and veils it. Sized in CSS pixels; the
   drawing buffer underneath is smaller (data-wp-quality) because fog has
   no hard edges to lose. */
.wp-fog {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}

/* Corner fall-off, so the frame reads as a clearing rather than a photo.
   Kept in CSS rather than the shader — free, and easier to tune. */
.wp-vignette {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    /* Reading scrim. The hero sits bottom-left, so the frame is weighted
       that way — which doubles as depth: the near corner is in shadow and
       the eye travels right, into the trees. Without it, body copy over a
       bright patch of the clip is a coin toss. */
    linear-gradient(to right, rgba(2, 6, 8, 0.74) 0%, rgba(2, 6, 8, 0.40) 32%, transparent 62%),
    linear-gradient(to top, rgba(2, 6, 8, 0.62) 0%, transparent 46%),
    radial-gradient(120% 85% at 50% 42%, transparent 38%, rgba(2, 5, 7, 0.62) 100%),
    linear-gradient(to bottom, rgba(2, 5, 7, 0.55) 0%, transparent 22%, transparent 100%);
}

/* ---------------------------------------------------------------- hero */

.wp-frame {
  position: relative;
  z-index: 1;
  /* --pw-chrome-h, not --pw-strip-h: the chrome is two fixed bands now, the
     utility strip and the breadcrumb row under it. Offsetting by the strip
     alone puts the hero a breadcrumb-height too low. */
  min-height: calc(100vh - var(--pw-chrome-h));
  min-height: calc(100dvh - var(--pw-chrome-h));
  display: flex;
  align-items: flex-end;
  padding: clamp(2rem, 7vh, 6rem) clamp(1.1rem, 5vw, 4rem) clamp(2rem, 8vh, 5rem);
}

.wp-hero {
  width: 100%;
  max-width: var(--wp-measure);
}

.wp-eyebrow {
  font-family: var(--pw-mono);
  font-size: 0.66rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--pw-bone-faint);
  margin-bottom: clamp(0.9rem, 2.5vh, 1.6rem);
}

.wp-title {
  margin: 0;
  font-family: var(--pw-display);
  font-weight: 900;
  font-size: clamp(2.6rem, 11vw, 7.5rem);
  line-height: 0.92;
  letter-spacing: 0.02em;
  color: var(--pw-bone);
  /* A cold halo, as if the letters were catching the same moon the fog is.
     Two shadows: a tight one for legibility over a moving background, a
     wide one for the glow. */
  text-shadow:
    0 0 1px rgba(4, 7, 10, 0.9),
    0 0.06em 0.5em rgba(4, 10, 12, 0.75),
    0 0 1.4em rgba(168, 207, 214, 0.14);
}

.wp-lede {
  margin: clamp(1rem, 3vh, 1.8rem) 0 0;
  max-width: 38ch;
  font-family: var(--pw-body);
  font-size: clamp(0.98rem, 1.6vw, 1.16rem);
  line-height: 1.55;
  color: var(--pw-bone-dim);
  text-shadow: 0 1px 6px rgba(2, 6, 8, 0.85);
}

/* -------------------------------------------------------------- roster */

.wp-roster {
  list-style: none;
  margin: clamp(1.8rem, 5vh, 3rem) 0 0;
  padding: 0;
  border-top: 1px solid var(--pw-rule);
  max-width: 46rem;
}

.wp-roster__row { border-bottom: 1px solid var(--pw-rule); }

.wp-roster__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: baseline;
  gap: 0.4rem 1rem;
  padding: 0.85rem 0.2rem;
  text-decoration: none;
  color: var(--pw-bone);
  transition: background-color 160ms ease, padding-left 160ms ease;
}

.wp-roster__link:hover,
.wp-roster__link:focus-visible {
  background: rgba(168, 207, 214, 0.06);
  padding-left: 0.7rem;
}

.wp-roster__index {
  font-family: var(--pw-mono);
  font-size: 0.7rem;
  color: var(--pw-bone-faint);
  letter-spacing: 0.12em;
}

.wp-roster__title {
  font-family: var(--pw-body);
  font-weight: 500;
  font-size: clamp(1rem, 2vw, 1.2rem);
  letter-spacing: 0.01em;
}

/* The blurb rides under the title, in the same column. */
.wp-roster__blurb {
  grid-column: 2;
  font-family: var(--pw-body);
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--pw-bone-faint);
}

.wp-roster__status {
  font-family: var(--pw-mono);
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--pw-brass-dim);
  color: var(--pw-bone-dim);
  white-space: nowrap;
}

.wp-roster__status--live    { color: var(--wp-sage);  border-color: rgba(127, 181, 155, 0.5); }
.wp-roster__status--soon    { color: var(--wp-frost); border-color: rgba(168, 207, 214, 0.45); }
.wp-roster__status--planned { color: var(--pw-bone-faint); }

/* ------------------------------------------------------------- contact */

.wp-contact {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1rem;
  align-items: baseline;
  margin-top: clamp(1.6rem, 5vh, 2.6rem);
  font-family: var(--pw-mono);
  font-size: 0.7rem;
  letter-spacing: 0.12em;
}

.wp-contact__label { color: var(--pw-bone-faint); text-transform: uppercase; }
.wp-contact__value { color: var(--pw-bone-dim); text-decoration: none; }
.wp-contact__value:hover,
.wp-contact__value:focus-visible { color: var(--wp-frost); }

/* ---------------------------------------------------------- the tuner */

/* Only ever rendered when the URL carries ?tune. It is a build tool that
   happens to live in the page: drag sliders until the fog is right, hit
   Copy, paste the attributes onto <div class="wp-stage"> and delete the
   query string. Nothing about it ships to a normal visitor. */
.wp-tuner {
  position: fixed;
  right: clamp(0.6rem, 2vw, 1.2rem);
  /* Clear of the jay switch, which sits in the same corner. */
  bottom: 3.6rem;
  z-index: 80;
  width: min(17rem, calc(100vw - 1.6rem));
  padding: 0.85rem 0.9rem 0.7rem;
  background: rgba(6, 12, 14, 0.86);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border: 1px solid var(--pw-rule);
  font-family: var(--pw-mono);
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  color: var(--pw-bone-dim);
}

.wp-tuner h2 {
  margin: 0 0 0.6rem;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--wp-frost);
}

.wp-tuner label { display: block; margin-bottom: 0.55rem; }
.wp-tuner label span { display: flex; justify-content: space-between; margin-bottom: 0.2rem; }
.wp-tuner input[type="range"] { width: 100%; accent-color: var(--wp-frost); }

.wp-tuner button {
  width: 100%;
  margin-top: 0.3rem;
  padding: 0.4rem;
  font: inherit;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--wp-frost);
  background: transparent;
  border: 1px solid var(--pw-brass-dim);
  cursor: pointer;
}

.wp-tuner button:hover { background: var(--wp-frost); color: var(--pw-void); }
.wp-tuner code { display: block; margin-top: 0.5rem; color: var(--pw-bone-faint); word-break: break-all; line-height: 1.5; }

/* ------------------------------------------------------------ fallback */

/* If WebGL is missing entirely, pines.js adds this class and the fog
   becomes two slowly-sliding CSS gradients. Not the same thing, but the
   page still reads as a foggy forest instead of a bare video. */
.wp-nogl .wp-fog { display: none; }

.wp-nogl .wp-stage::after,
.wp-nogl .wp-stage::before {
  content: "";
  position: absolute;
  left: -30%;
  right: -30%;
  height: 70%;
  pointer-events: none;
  background: radial-gradient(60% 100% at 30% 60%, rgba(190, 215, 222, 0.16), transparent 70%),
              radial-gradient(50% 100% at 75% 40%, rgba(150, 180, 190, 0.13), transparent 70%);
  filter: blur(22px);
}

.wp-nogl .wp-stage::before { bottom: -6%; animation: wp-drift 68s linear infinite; }
.wp-nogl .wp-stage::after  { bottom: 22%; opacity: 0.6; animation: wp-drift 104s linear infinite reverse; }

@keyframes wp-drift {
  from { transform: translate3d(-8%, 0, 0); }
  to   { transform: translate3d(8%, 0, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .wp-plate { transform: scale(1.06); }
  .wp-nogl .wp-stage::before,
  .wp-nogl .wp-stage::after { animation: none; }
}

/* ------------------------------------------------------------- narrow */

/* On a phone the text spans the full width, so a left-weighted scrim
   protects nothing. Swap it for a bottom-up one. */
@media (max-width: 48rem) {
  .wp-vignette {
    background:
      linear-gradient(to top, rgba(2, 6, 8, 0.86) 0%, rgba(2, 6, 8, 0.52) 34%, transparent 68%),
      radial-gradient(130% 80% at 50% 30%, transparent 40%, rgba(2, 5, 7, 0.6) 100%),
      linear-gradient(to bottom, rgba(2, 5, 7, 0.55) 0%, transparent 24%);
  }
}

@media (max-width: 34rem) {
  .wp-roster__link { grid-template-columns: auto 1fr; }
  .wp-roster__status { grid-column: 2; justify-self: start; margin-top: 0.3rem; }
}

/* -------------------------------------------------------------- tuner switch */

/* The panel used to require ?tune in the URL, which hid the most enjoyable
   thing on the page from everyone who did not already know about it. It is
   closed by default and it stays out of the way, but it is findable: a small
   switch that sits at 50% until you approach it. */

.wp-tuner-toggle {
  position: fixed;
  right: clamp(0.6rem, 2vw, 1.2rem);
  /* Above the jay switch, below the panel it opens. */
  bottom: 3.6rem;
  z-index: 81;
  padding: 0.36rem 0.62rem;
  font-family: var(--pw-mono);
  font-size: 0.58rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--pw-bone-faint);
  background: rgba(6, 12, 14, 0.72);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid var(--pw-rule);
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}

.wp-tuner-toggle:hover,
.wp-tuner-toggle:focus-visible,
.wp-tuner-toggle.is-open {
  opacity: 1;
  color: var(--wp-frost);
  border-color: var(--wp-frost);
}

.wp-tuner-toggle:focus-visible {
  outline: 2px solid var(--wp-frost);
  outline-offset: 2px;
}

/* Clears the switch instead of covering it. Overrides the bottom set on
   .wp-tuner above — same specificity, later in the file. */
.wp-tuner { bottom: 6.4rem; }
.wp-tuner[hidden] { display: none; }

@media (prefers-reduced-motion: reduce) {
  .wp-tuner-toggle { transition: none; }
}
