*, *::before, *::after { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  /* The home page steps between posts on a horizontal swipe (home.js), and a
     rightward swipe is also the browser's own back-navigation gesture. This
     asks the browser to keep the gesture on the page. It is not enough on its
     own - home.js also cancels the touchmove once a swipe is clearly
     horizontal, which is what actually stops it - but it costs nothing and it
     covers the case where a scroll container appears here later. */
  overscroll-behavior-x: contain;
}

body {
  font-family: var(--font-body);
  color: var(--on-art);
  background: var(--violet-900);
  overflow: hidden;                 /* the page is a fixed scene */
  -webkit-font-smoothing: antialiased;
}

body.is-scrollable { overflow: auto; }

/* ---------------- scrollbars ----------------
   Every scrolling box on the site, in one place: a 10px track with a 6px
   thumb inset 2px a side, both fully rounded. Measured off the scrollbar the
   owner drew over a screenshot of the announcement popup - see the tokens.

   The colours are read from --scroll-thumb / --scroll-track, so a home post
   that sets its own carries them into its popup (panelVars writes both on
   .feature and on each slide's [data-feature-popup]) while everything else
   keeps the site pair.
   ::-webkit-scrollbar inherits custom properties from the box it belongs to,
   which is what makes that work without a second set of selectors.

   WHY BOTH SPELLINGS, AND WHY THEY ARE NOT IN THE SAME BLOCK: Chrome ignores
   ::-webkit-scrollbar entirely on any element where the standard
   `scrollbar-width`/`scrollbar-color` are set to something other than their
   initial value. Declaring both together would therefore throw away the width
   and the radius. So the webkit rules are the ones Chrome and Safari get, and
   the standard properties are quarantined behind a query only a browser
   without the pseudo-element - Firefox - answers. Do not merge them. */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track {
  background: var(--scroll-track, #daaeb9);
  border-radius: 5px;
}
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb, #c1617a);
  border-radius: 5px;
  /* The inset is a transparent border with the paint clipped to the content
     box - a thumb cannot be given a margin, so this is how it is narrowed to
     6px without narrowing the track with it. */
  border: 2px solid transparent;
  background-clip: content-box;
}
*::-webkit-scrollbar-thumb:hover { filter: brightness(1.08); }
*::-webkit-scrollbar-corner { background: var(--scroll-track, #daaeb9); }
/* No arrow buttons: the pair in the default Windows scrollbar is what the
   owner asked to be rid of. Declaring them zero-height removes them. */
*::-webkit-scrollbar-button { display: none; width: 0; height: 0; }

@supports not selector(::-webkit-scrollbar) {
  * {
    scrollbar-width: thin;
    scrollbar-color: var(--scroll-thumb, #c1617a) var(--scroll-track, #daaeb9);
  }
}

/* ---------------- stage / background art ---------------- */

.stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}

.stage__art {
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-position: center center;
  background-size: cover;
}

/* The mockup shows the illustration untinted - no overlay here on purpose. */

/* ---------------- navigation ---------------- */

.nav {
  position: fixed;
  top: clamp(6px, 2.3vh, 26px);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: clamp(8px, 3.9vw, 75px);
  z-index: 40;
}

.nav__link {
  display: block;
  border-radius: var(--radius-sm);
  outline: none;
  transition: transform 220ms cubic-bezier(.2, .9, .3, 1.2),
              filter 220ms ease;
}

.nav__link img {
  display: block;
  width: clamp(96px, 9.4vw, 200px);
  height: auto;
  filter: drop-shadow(0 4px 14px rgba(43, 15, 46, .45));
}

.nav__link:hover   { transform: translateY(-2px) scale(1.035); }
.nav__link:active  { transform: translateY(0) scale(.985); }
.nav__link:focus-visible {
  box-shadow: 0 0 0 3px var(--petal-200), 0 0 0 7px rgba(139, 47, 147, .6);
}

/* Active-page indicator: the current page's button is darkened by exactly
   20%. Reusable - Home and Shop get it by setting .is-current too. */
.nav__link.is-current img { filter: brightness(0.8) drop-shadow(0 4px 14px rgba(43, 15, 46, .45)); }
.nav__link.is-current:hover { transform: none; cursor: default; }

/* ---------------- footer ---------------- */

.footer {
  /* Owner's request, 2026-08-25: white, replacing the near-black the mockups
     draw. An outline was added with it and REMOVED on 2026-08-26 - at any
     weight that read as an outline, the strokes of neighbouring letters met
     and the line looked like a dark slab rather than like letters, which on a
     phone was worse than the problem it solved. Plain white it is. Do not
     reintroduce a stroke without looking at it on a 375px screen first. */
  position: fixed;
  left: 50%;
  bottom: clamp(5px, 0.85vh, 12px);
  transform: translateX(-50%);
  text-align: center;
  font-size: clamp(10px, 0.82vw, 16px);
  line-height: 1.55;
  color: #fff;
  z-index: 40;
  pointer-events: none;
  white-space: nowrap;
}

/* Both lines are white; the credit keeps its own class because the mobile
   rules and the mockup notes still refer to it. */
.footer__credit { color: #fff; }

/* ---------------- streaming platform button ----------------
   Shared: the release popup on /music and the home panel both use it, so it
   cannot live in popup.css. Size and fill are overridden per page. */

.platform {
  display: grid;
  place-items: center;
  width: 62px; height: 62px;
  border-radius: var(--radius-pill);
  background: linear-gradient(180deg, #b45cf0, #9333d8);
  border: 1px solid rgba(255, 255, 255, .25);
  color: #fff;
  box-shadow: 0 2px 6px rgba(43, 15, 46, .35), 0 8px 20px rgba(70, 24, 74, .35);
  transition: transform 200ms cubic-bezier(.2, .9, .3, 1.25),
              box-shadow 200ms ease, filter 200ms ease;
}
.platform svg { width: 28px; height: 28px; fill: currentColor; }
.platform:hover {
  transform: translateY(-3px) scale(1.06);
  filter: brightness(1.08);
  box-shadow: 0 4px 10px rgba(43, 15, 46, .4), 0 14px 30px rgba(70, 24, 74, .45);
}
.platform:active { transform: translateY(0) scale(.96); }
.platform:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--petal-200); }

/* ---------------- generic controls ---------------- */

.btn {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 500;
  color: var(--cream);
  background: linear-gradient(180deg, var(--violet-500), var(--violet-600));
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  padding: 10px var(--sp-5);
  cursor: pointer;
  box-shadow: var(--shadow-cover);
  transition: transform 180ms cubic-bezier(.2, .9, .3, 1.2),
              box-shadow 180ms ease, background-color 180ms ease;
}
.btn:hover  { transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(.99); }
.btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--petal-200), var(--shadow-cover);
}
.btn--ghost {
  background: rgba(255, 255, 255, .10);
  border-color: rgba(255, 255, 255, .35);
}
.btn--danger { background: linear-gradient(180deg, #c2416b, #96274c); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ---------------- mobile navigation ---------------- */

.navtoggle {
  display: none;
  position: fixed;
  top: clamp(18px, 3.8vh, 34px);
  left: clamp(16px, 6vw, 30px);
  z-index: 60;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.navtoggle__box {
  display: grid;
  align-content: center;
  gap: 5px;
  width: 40px;
  height: 34px;
  padding: 6px 5px;
  border: 2px solid rgba(70, 24, 74, .62);
  border-radius: 3px;
  background: rgba(255, 255, 255, .06);
  transition: background-color 200ms ease, border-color 200ms ease;
}

.navtoggle__bar {
  display: block;
  height: 2px;
  border-radius: 2px;
  background: rgba(70, 24, 74, .78);
  transform-origin: center;
  transition: transform 260ms cubic-bezier(.2, .9, .3, 1.2), opacity 160ms ease;
}

.navtoggle:hover .navtoggle__box { background: rgba(255, 255, 255, .18); }
.navtoggle:focus-visible { outline: none; }
.navtoggle:focus-visible .navtoggle__box {
  border-color: var(--petal-200);
  box-shadow: 0 0 0 3px rgba(244, 205, 236, .45);
}

/* hamburger -> X */
body.nav-open .navtoggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
body.nav-open .navtoggle__bar:nth-child(2) { opacity: 0; transform: scaleX(.4); }
body.nav-open .navtoggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 760px) {
  /* ---- how the background art is framed on a phone ----
     The illustrations are 2.194:1. A portrait `cover` crop takes the middle
     and throws away whatever the mobile mockup was actually composed around -
     the doorway on Home, the girl at the bed on Music. Each offset below was
     fitted by searching for the one that best matches that page's mobile
     mockup across every pixel outside the page's own panel, so these are
     measurements rather than taste. Re-fit the same way if the art changes.

       home   7.68%   (mean abs channel difference 3.7/255)
       music 14.64%   (5.9/255, and more than double that 6px either side)

     Shop has no offset yet - the page is not built. */
  body[data-page="home"]  .stage__art { background-position: 7.68% center; }
  body[data-page="music"] .stage__art { background-position: 14.64% center; }
  body[data-page="shop"]  .stage__art { background-position: 9.52% center; }

  .navtoggle { display: block; }

  .nav {
    top: clamp(62px, 11vh, 96px);
    left: clamp(16px, 6vw, 30px);
    transform: none;
    flex-direction: column;
    gap: clamp(10px, 2.4vh, 22px);
    padding: clamp(14px, 4vw, 22px);
    border-radius: var(--radius-sm);
    background: rgba(233, 197, 240, .30);
    backdrop-filter: blur(4px);
    /* closed state - animated, not display:none, so it can transition */
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px) scale(.98);
    transform-origin: top left;
    transition: opacity 220ms ease, transform 260ms cubic-bezier(.2, .9, .3, 1.15),
                visibility 0s linear 260ms;
  }

  body.nav-open .nav {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }

  .nav__link img { width: clamp(120px, 36vw, 190px); }

  /* The white halo that used to sit under the near-black text went with it.
     White type is legible on all three mobile crops as it is; if a future
     page's art is pale behind the footer, put a soft DARK halo back here
     rather than reaching for an outline again. */
  .footer {
    font-size: clamp(11px, 3.2vw, 15px);
  }
}
