/* ==========================================================================
   TSUKI CITY: storefront theme
   Plain CSS on purpose: no Tailwind build step, nothing to purge, and the
   file can be edited straight from SellAuth's code editor.

   1. Tokens            6. Navbar            11. Trust
   2. Base              7. Hero              12. FAQ
   3. Sky               8. Section chrome    13. Footer
   4. Cut-corner frame  9. Catalog           14. Prose / misc
   5. Buttons          10. Product page      15. Motion preferences
   ========================================================================== */

/* 1. Tokens
   ========================================================================== */
:root {
  /* night: sampled down from the darkest part of the brand artwork */
  --sky-0: #02040a;
  --sky-1: #050915;
  --sky-2: #0a1124;
  --sky-3: #111c3a;

  /* moonlight: the wordmark gradient, top to bottom */
  --ice: #a5e1f6;
  --glow: #84b4f8;
  --corn: #5e7dd4;
  --deep: #4861a6;
  /* channels, so glows can take any alpha. master.njk overrides --glow-rgb
     from the merchant's accent colour setting. */
  --glow-rgb: 132, 180, 248;
  --ice-rgb: 165, 225, 246;

  --text: #eef4ff;
  --text-dim: #a7b8d9;    /* 9.8:1 on --sky-1 */
  --text-faint: #7486ad;  /* 5.3:1 on --sky-1, still AA for body copy */

  --line: rgba(var(--glow-rgb), 0.14);
  --line-strong: rgba(var(--glow-rgb), 0.32);
  --surface: rgba(9, 15, 33, 0.82);
  --surface-raised: rgba(14, 23, 48, 0.9);

  --font-display: "Oxanium", "Eurostile", "Bank Gothic", system-ui, sans-serif;
  --font-body: "Geist", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Built-in CSS easings are too soft to feel intentional. */
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  /* sine: for things that breathe (twinkle, moon glow). The punchier curve
     above would make a loop read as a blink rather than a pulse. */
  --ease-breathe: cubic-bezier(0.45, 0, 0.55, 1);

  --wrap: 1200px;
  --gutter: clamp(20px, 5vw, 40px);
  --nav-h: 68px;
  --section-y: clamp(72px, 11vw, 136px);
}

/* 2. Base
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--sky-0);
  color-scheme: dark;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  font: 400 16px/1.65 var(--font-body);
  color: var(--text-dim);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

main {
  flex: 1;
}

img,
svg {
  display: block;
  max-width: 100%;
}

h1,
h2,
h3,
h4 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--text);
  text-wrap: balance;
}

p {
  margin: 0;
  text-wrap: pretty;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

/* :where() keeps this at zero specificity, so any component class can still
   set its own margin without fighting the reset. */
:where(ul[role="list"], ol[role="list"]) {
  list-style: none;
  margin: 0;
  padding: 0;
}

::selection {
  background: rgba(var(--glow-rgb), 0.35);
  color: #fff;
}

/* One focus treatment everywhere. :focus-visible keeps it off mouse clicks. */
:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
  border-radius: 2px;
}

.wrap {
  width: 100%;
  max-width: calc(var(--wrap) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 100;
  padding: 10px 16px;
  font: 600 13px/1 var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sky-0);
  background: var(--ice);
  transform: translateY(-200%);
}

.skip-link:focus {
  transform: none;
}

.icon {
  width: 1em;
  height: 1em;
  flex: none;
  fill: currentColor;
}

/* 3. Sky
   The fixed sky behind every page (snippets/sky.njk, generated together with
   its textures by tools/build-sky.py). Back to front: a faint Milky Way band,
   a dense layer of faint stars, a sparse layer of brighter stars carrying the
   twinkling ones. The moon and clouds belong to the hero and scroll away
   with it. Everything that moves animates transform/opacity only, so it
   stays on the compositor and never triggers layout or paint.
   ========================================================================== */
.sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(120% 70% at 50% -12%, rgba(44, 76, 160, 0.34), transparent 62%),
    radial-gradient(55% 45% at 88% 8%, rgba(34, 56, 124, 0.2), transparent 70%),
    radial-gradient(60% 50% at 6% 38%, rgba(24, 40, 96, 0.16), transparent 70%),
    linear-gradient(180deg, #060b1c 0%, #03060f 46%, var(--sky-0) 100%);
}

/* Each layer is taller than the screen by the distance it drifts on scroll
   (see "scroll" below), so its bottom edge never shows. The star tiles are
   vector: crisp on any screen, and their sizes (1500 / 1100px) differ, so
   the combined pattern does not visibly repeat. */
.sky__band,
.sky__far,
.sky__near {
  position: absolute;
  inset: 0;
  will-change: transform;
}

.sky__band {
  bottom: -140px;
  background: var(--milky-way) center / cover no-repeat;
  /* a hint, never a feature: it must not compete with text */
  opacity: 0.32;
}

.sky__far {
  bottom: -200px;
  background: var(--stars-far) 0 0 / 1500px 1500px repeat;
}

.sky__near {
  bottom: -520px;
  background: var(--stars-near) 340px 180px / 1100px 1100px repeat;
}

/* Twinkling stars. Real twinkling (scintillation) is quick and irregular,
   not a slow even pulse, so each star follows one of three uneven flicker
   patterns with its own duration and a negative delay (from sky.njk): no two
   are in step. Tiny and low-contrast, so nowhere near flashing thresholds. */
.tw {
  position: absolute;
  left: var(--x);
  top: var(--y);
  width: var(--s, 2px);
  height: var(--s, 2px);
  margin: calc(var(--s, 2px) / -2) 0 0 calc(var(--s, 2px) / -2);
  border-radius: 50%;
  background: #f4f7ff;
  box-shadow: 0 0 calc(var(--s, 2px) * 2.5) rgba(var(--ice-rgb), 0.4);
  opacity: 0.6;
  animation: scint-a var(--d, 4s) linear var(--dl, 0s) infinite;
}

.tw--b { animation-name: scint-b; }
.tw--c { animation-name: scint-c; }
.tw--blue { background: #d4e3ff; }
.tw--warm { background: #ffe6c8; box-shadow: 0 0 calc(var(--s, 2px) * 2.5) rgba(255, 214, 170, 0.35); }

/* a few bright ones get a faint cross-shaped glint, which pulses with them */
.tw--glint::before,
.tw--glint::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: calc(var(--s, 2px) * 7);
  height: 1px;
  margin: -0.5px 0 0 calc(var(--s, 2px) * -3.5);
  background: linear-gradient(90deg, transparent, rgba(236, 244, 255, 0.7), transparent);
}

.tw--glint::after {
  transform: rotate(90deg);
}

@keyframes scint-a {
  0%   { opacity: 0.55; transform: scale(0.9); }
  9%   { opacity: 0.95; transform: scale(1.06); }
  16%  { opacity: 0.5;  transform: scale(0.92); }
  27%  { opacity: 0.8;  transform: scale(1); }
  38%  { opacity: 0.42; transform: scale(0.88); }
  51%  { opacity: 1;    transform: scale(1.1); }
  58%  { opacity: 0.62; transform: scale(0.95); }
  73%  { opacity: 0.88; transform: scale(1.02); }
  84%  { opacity: 0.45; transform: scale(0.9); }
  100% { opacity: 0.55; transform: scale(0.9); }
}

@keyframes scint-b {
  0%   { opacity: 0.7;  transform: scale(0.95); }
  12%  { opacity: 0.4;  transform: scale(0.86); }
  19%  { opacity: 0.9;  transform: scale(1.04); }
  33%  { opacity: 0.6;  transform: scale(0.94); }
  41%  { opacity: 0.98; transform: scale(1.08); }
  47%  { opacity: 0.5;  transform: scale(0.9); }
  64%  { opacity: 0.75; transform: scale(0.98); }
  77%  { opacity: 0.38; transform: scale(0.86); }
  91%  { opacity: 0.85; transform: scale(1.03); }
  100% { opacity: 0.7;  transform: scale(0.95); }
}

@keyframes scint-c {
  0%   { opacity: 0.5;  transform: scale(0.9); }
  14%  { opacity: 0.65; transform: scale(0.95); }
  22%  { opacity: 0.35; transform: scale(0.85); }
  36%  { opacity: 0.92; transform: scale(1.07); }
  44%  { opacity: 0.55; transform: scale(0.92); }
  61%  { opacity: 0.7;  transform: scale(0.97); }
  68%  { opacity: 1;    transform: scale(1.1); }
  79%  { opacity: 0.48; transform: scale(0.9); }
  90%  { opacity: 0.72; transform: scale(0.98); }
  100% { opacity: 0.5;  transform: scale(0.9); }
}

/* --- hero sky: moon + clouds ------------------------------------------- */
.hero__sky {
  position: absolute;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  /* fade out at the bottom so the hero melts into the fixed starfield */
  -webkit-mask-image: linear-gradient(#000 62%, transparent 96%);
  mask-image: linear-gradient(#000 62%, transparent 96%);
}

.moon {
  position: absolute;
  top: var(--moon-top);
  /* The bowl of the wordmark's crescent is centred at 58% of the logo's
     width (measured from the artwork), not 50%. Nudging the moon by that 8%
     is what makes the crescent look like it is holding it. */
  left: calc(50% + var(--logo-w) * 0.08);
  width: var(--moon);
  height: var(--moon);
  margin-left: calc(var(--moon) / -2);
}

/* A rendered lunar texture (tools/build-sky.py): real maria layout, craters
   that only show relief toward the terminator, earthshine on the dark limb.
   The disc is opaque, so it hides the stars behind it like the real thing. */
.moon__disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--moon-img) center / 100% 100% no-repeat;
  opacity: 0.94;
  /* thin atmospheric bloom hugging the limb. Static, so it is rasterised once. */
  filter: drop-shadow(0 0 14px rgba(var(--glow-rgb), 0.45));
}

/* Defocused copy for the moonset (see "scroll" below). Blurred once when it
   is first drawn; after that only its opacity changes, which is free. */
.moon__disc--soft {
  filter: blur(9px);
  opacity: 0;
}

/* The glow is two pre-blurred gradients whose opacity and scale breathe.
   Animating box-shadow or filter here would repaint a huge area every frame;
   this costs nothing. Different periods (7s / 11s) mean the combined pulse
   only repeats every 77s, so it never feels mechanical. */
.moon__halo {
  position: absolute;
  top: 50%;
  left: 50%;
  border-radius: 50%;
  will-change: transform, opacity;
}

.moon__halo--inner {
  width: 300%;
  height: 300%;
  margin: -150% 0 0 -150%;
  background: radial-gradient(closest-side, rgba(var(--glow-rgb), 0.36), rgba(var(--glow-rgb), 0.12) 46%, transparent 72%);
  animation: moon-pulse 7s var(--ease-breathe) infinite alternate;
}

.moon__halo--outer {
  width: 640%;
  height: 640%;
  margin: -320% 0 0 -320%;
  background: radial-gradient(closest-side, rgba(var(--glow-rgb), 0.16), rgba(var(--glow-rgb), 0.05) 50%, transparent 74%);
  animation: moon-pulse 11s var(--ease-breathe) -3s infinite alternate;
}

@keyframes moon-pulse {
  from { opacity: 0.55; transform: scale(0.94); }
  to   { opacity: 1;    transform: scale(1.05); }
}

/* Clouds: a strip slides left by exactly one tile, then loops. The texture
   tiles seamlessly (see tools/build-assets.py) so the reset is invisible.
   Constant motion, so the easing is linear.

   Strip width is tile + 100vw: the least that still covers the viewport at
   the end of the travel. That keeps the GPU layer small and, because width no
   longer depends on tile >= viewport, lets the tile size be capped so a 4K
   screen does not allocate an 11,000px-wide texture. */
.cloud {
  --tile: clamp(1200px, 100vw, 2100px);
  position: absolute;
  left: 0;
  width: calc(var(--tile) + 100vw);
  height: calc(var(--tile) / 3.2);
  background-repeat: repeat-x;
  background-size: var(--tile) 100%;
  will-change: transform;
  animation: drift var(--speed) linear var(--offset, 0s) infinite;
}

/* far: small, slow, faint. near: large, quicker, denser. That ratio is what
   reads as depth. */
.cloud--far {
  --tile: clamp(860px, 72vw, 1500px);
  --speed: 280s;
  --offset: -90s;
  top: 2%;
  opacity: 0.5;
  background-image: var(--cloud-b);
}

.cloud--mid {
  --tile: clamp(1240px, 104vw, 2100px);
  --speed: 190s;
  --offset: -40s;
  top: 12%;
  opacity: 0.72;
  background-image: var(--cloud-a);
}

.cloud--near {
  --tile: clamp(1750px, 150vw, 2600px);
  --speed: 120s;
  --offset: -75s;
  top: 34%;
  opacity: 0.5;
  background-image: var(--cloud-b);
}

/* Moonlit copies. The same mid/near layers again (same keyframes, duration
   and offset, so they stay locked to the originals), brightened, and masked
   to a radius around the moon. Net effect: a cloud lights up as it drifts
   past the moon and fades back to shadow as it leaves, which is the single
   biggest cue that the moon is actually lighting the scene. */
.clouds-lit {
  --mx: calc(50% + var(--logo-w) * 0.08);
  --my: calc(var(--moon-top) + var(--moon) / 2);
  position: absolute;
  inset: 0;
  -webkit-mask-image: radial-gradient(circle at var(--mx) var(--my), #000 0, rgba(0, 0, 0, 0.6) calc(var(--moon) * 0.85), transparent calc(var(--moon) * 2.3));
  mask-image: radial-gradient(circle at var(--mx) var(--my), #000 0, rgba(0, 0, 0, 0.6) calc(var(--moon) * 0.85), transparent calc(var(--moon) * 2.3));
}

.clouds-lit .cloud {
  opacity: 0.9;
  filter: brightness(1.75) saturate(1.15);
}

@keyframes drift {
  to { transform: translate3d(calc(var(--tile) * -1), 0, 0); }
}

/* A shooting star, roughly three times a minute. It is only on screen for
   ~4% of the cycle; the rest of the keyframe holds it invisible. */
.shooting-star {
  position: absolute;
  top: 13%;
  left: 72%;
  width: 130px;
  height: 1px;
  border-radius: 1px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.95), rgba(var(--ice-rgb), 0.4) 30%, transparent);
  opacity: 0;
  transform: rotate(-32deg);
  animation: shoot 21s linear 5s infinite;
}

@keyframes shoot {
  0%, 95.5% { opacity: 0; transform: translate3d(0, 0, 0) rotate(-32deg) scaleX(0.4); }
  96%       { opacity: 0.9; animation-timing-function: var(--ease-out); }
  100%      { opacity: 0; transform: translate3d(-380px, 238px, 0) rotate(-32deg) scaleX(1); }
}

/* JS adds this when the hero leaves the viewport: no point compositing
   clouds nobody can see. */
.hero__sky.is-paused * {
  animation-play-state: paused;
}

/* --- scroll: moonset and sky depth ------------------------------------------
   Scroll-driven CSS animations (animation-timeline: scroll()): they run on
   the compositor, need no JavaScript, and track the scrollbar exactly.
   Browsers without support keep the static sky, i.e. how it looked before.

   Moonset: over the first 85% of a screen height of scrolling, the moon sinks
   a little slower than the page, so it slips down behind the wordmark. It
   defocuses (a crossfade to the pre-blurred copy, never an animated blur),
   shrinks slightly, dims, and its light on the clouds fades with it.

   Sky depth: the three sky layers drift up by 2%, 3% and 8% of the scroll, so
   the sky reads as far away instead of as dust on the screen. */
@supports (animation-timeline: scroll()) {
  .moon,
  .moon__disc,
  .moon__disc--soft,
  .clouds-lit {
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: scroll(root block);
    animation-range: 0px 85vh;
  }

  .moon { animation-name: moonset; }
  .moon__disc { animation-name: moon-sharp-out; }
  .moon__disc--soft { animation-name: moon-soft-in; }
  .clouds-lit { animation-name: moonlight-out; }

  .sky__band,
  .sky__far,
  .sky__near {
    animation: sky-drift linear both;
    animation-timeline: scroll(root block);
    animation-range: 0px 6000px;
  }

  .sky__band { --drift: -120px; }
  .sky__far  { --drift: -180px; }
  .sky__near { --drift: -480px; }

  /* reduced motion: the moon still defocuses and dims, but nothing travels */
  @media (prefers-reduced-motion: reduce) {
    .moon { animation-name: moon-dim; }

    .sky__band,
    .sky__far,
    .sky__near {
      animation: none;
    }
  }
}

@keyframes moonset {
  to { transform: translate3d(0, calc(var(--logo-w) * 0.3), 0) scale(0.93); opacity: 0.4; }
}

@keyframes moon-dim {
  to { opacity: 0.4; }
}

@keyframes moon-sharp-out {
  to { opacity: 0; }
}

@keyframes moon-soft-in {
  0%   { opacity: 0; }
  60%  { opacity: 0.85; }
  100% { opacity: 0.7; }
}

@keyframes moonlight-out {
  to { opacity: 0; }
}

@keyframes sky-drift {
  to { transform: translate3d(0, var(--drift, 0px), 0); }
}

/* 4. Cut-corner frame
   The wordmark's letters are sliced on a forward-leaning diagonal. Cards,
   buttons and tiles borrow that: top-left and bottom-right corners are
   chamfered on the same "/" angle.

   clip-path also clips borders and shadows, so the frame is built in layers:
     .frame            unclipped. Owns the glow (::before) so it can spill out.
     .frame__edge      clipped. Its background *is* the border.
     .frame__edge::after  clipped, inset by the border width. The fill.
   The inner cut is shortened by 0.586 x border-width (2 - sqrt 2) so the
   diagonal edge comes out the same thickness as the straight ones.
   ========================================================================== */
.frame {
  --cut: 14px;
  --bw: 1px;
  --fill: var(--surface);
  --edge: var(--line);
  position: relative;
  isolation: isolate;
}

.frame__edge,
.frame__edge::before,
.frame__edge::after {
  position: absolute;
  inset: 0;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.frame__edge {
  z-index: -1;
  background: var(--edge);
}

/* the lit border, faded in on hover/active */
.frame__edge::before {
  content: "";
  background: linear-gradient(135deg, var(--ice), var(--corn) 55%, rgba(var(--glow-rgb), 0.35));
  opacity: 0;
  transition: opacity 220ms ease;
}

.frame__edge::after {
  --cut-in: calc(var(--cut) - var(--bw) * 0.586);
  content: "";
  inset: var(--bw);
  background: var(--fill);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

/* Outer glow. Pre-blurred and static; hover only changes its opacity. */
.frame--glow::before {
  content: "";
  position: absolute;
  inset: 6px;
  z-index: -2;
  background: rgba(var(--glow-rgb), 0.6);
  filter: blur(20px);
  opacity: 0;
  transition: opacity 260ms ease;
  pointer-events: none;
}

/* 5. Buttons
   ========================================================================== */
.btn {
  --cut: 11px;
  --bw: 1.5px;
  --fill: rgba(5, 10, 24, 0.92);
  --edge: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.7em;
  min-height: 52px;
  padding: 0 30px;
  font: 600 14px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--ice);
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform 160ms var(--ease-out), color 200ms ease;
}

/* resting glow: the "glowing outline" */
.btn::before {
  content: "";
  position: absolute;
  inset: 4px 10px;
  z-index: -2;
  background: rgba(var(--glow-rgb), 0.7);
  filter: blur(18px);
  opacity: 0.38;
  transition: opacity 240ms ease;
  pointer-events: none;
}

/* hover fill: the dark face fades away and the gradient "border" layer,
   which was underneath all along, becomes the fill */
.btn .frame__edge::after {
  transition: opacity 220ms ease;
}

.btn .icon {
  transition: transform 220ms var(--ease-out);
}

.btn:active {
  transform: scale(0.97);
}

.btn--ghost {
  --edge: var(--line-strong);
  --fill: rgba(5, 10, 24, 0.6);
  color: var(--text-dim);
}

.btn--ghost::before {
  opacity: 0;
}

.btn--block {
  display: flex;
  width: 100%;
}

.btn--sm {
  --cut: 9px;
  min-height: 42px;
  padding: 0 20px;
  font-size: 12px;
}

.btn[aria-disabled="true"] {
  pointer-events: none;
  color: var(--text-faint);
  --edge: var(--line);
}

.btn[aria-disabled="true"]::before {
  opacity: 0;
}

/* Hover is gated: touch devices fire :hover on tap and then leave it stuck. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover {
    color: #041024;
  }

  .btn:hover::before {
    opacity: 0.85;
  }

  .btn:hover .frame__edge::after {
    opacity: 0;
  }

  .btn:hover .icon--arrow {
    transform: translateX(4px);
  }

  .btn--ghost:hover {
    color: var(--text);
  }

  .btn--ghost:hover::before {
    opacity: 0.3;
  }

  .btn--ghost:hover .frame__edge::after {
    opacity: 1;
  }

  .btn--ghost:hover .frame__edge::before {
    opacity: 1;
  }
}

/* Inline text link with a wipe-in underline. clip-path keeps it on the GPU
   and lets it enter from the left and leave to the right. */
.link {
  position: relative;
  color: var(--glow);
  transition: color 200ms ease;
}

.link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -3px;
  height: 1px;
  background: currentColor;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 260ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .link:hover {
    color: var(--ice);
  }

  .link:hover::after {
    clip-path: inset(0);
  }
}

/* 6. Navbar
   ========================================================================== */
.nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 50;
  height: var(--nav-h);
}

/* The backdrop is its own layer so scrolling only has to fade one opacity
   rather than transition background + backdrop-filter + border together. */
.nav::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(3, 6, 15, 0.74);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--line);
  opacity: 0;
  transition: opacity 260ms ease;
}

.nav.is-scrolled::before,
.nav.is-open::before {
  opacity: 1;
}

.nav__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 32px;
  height: 100%;
}

.nav__brand {
  display: block;
  flex: none;
  margin-left: -6px;
}

.nav__brand img {
  height: 38px;
  width: auto;
}

.nav__links {
  display: none;
  align-items: center;
  gap: 30px;
  margin-left: auto;
}

.nav__link {
  position: relative;
  padding: 8px 0;
  font: 600 12.5px/1 var(--font-display);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color 200ms ease;
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: linear-gradient(90deg, var(--ice), var(--corn));
  clip-path: inset(0 100% 0 0);
  transition: clip-path 260ms var(--ease-out);
}

.nav__link[aria-current="page"] {
  color: var(--text);
}

.nav__link[aria-current="page"]::after {
  clip-path: inset(0);
}

@media (hover: hover) and (pointer: fine) {
  .nav__link:hover {
    color: var(--text);
  }

  .nav__link:hover::after {
    clip-path: inset(0);
  }
}

.nav__actions {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-left: auto;
}

.nav__icon-btn {
  position: relative;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  font-size: 19px;
  color: var(--text-dim);
  transition: color 200ms ease, transform 160ms var(--ease-out);
}

.nav__icon-btn:active {
  transform: scale(0.94);
}

@media (hover: hover) and (pointer: fine) {
  .nav__icon-btn:hover {
    color: var(--ice);
  }
}

.nav__badge {
  position: absolute;
  top: 4px;
  right: 2px;
  display: grid;
  place-items: center;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  font: 700 10px/1 var(--font-display);
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow));
  border-radius: 999px;
  box-shadow: 0 0 10px rgba(var(--glow-rgb), 0.7);
}

.nav__icon-btn[aria-current="page"] {
  color: var(--ice);
}

/* the starter's currency / language pickers, sized to sit in the navbar */
.nav__select {
  display: none;
}

@media (min-width: 860px) {
  .nav__select { display: block; }
}

.nav__toggle-bars {
  position: relative;
  width: 20px;
  height: 12px;
}

.nav__toggle-bars::before,
.nav__toggle-bars::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1.5px;
  background: currentColor;
  transition: transform 240ms var(--ease-out);
}

.nav__toggle-bars::before { top: 0; }
.nav__toggle-bars::after  { bottom: 0; }

.nav.is-open .nav__toggle-bars::before { transform: translateY(5.25px) rotate(45deg); }
.nav.is-open .nav__toggle-bars::after  { transform: translateY(-5.25px) rotate(-45deg); }

/* Mobile sheet. visibility (not display) so it can transition, and so its
   links drop out of the tab order while closed. Exit is quicker than enter. */
.nav__sheet {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  padding: 8px var(--gutter) 28px;
  background: rgba(3, 6, 15, 0.96);
  border-bottom: 1px solid var(--line);
  visibility: hidden;
  opacity: 0;
  transform: translateY(-8px);
  transition: opacity 160ms ease, transform 160ms ease, visibility 0s 160ms;
}

.nav.is-open .nav__sheet {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition: opacity 240ms var(--ease-out), transform 240ms var(--ease-out), visibility 0s;
}

.nav__sheet a {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px 0;
  font: 600 15px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text);
  border-bottom: 1px solid var(--line);
}

.nav__sheet .icon {
  font-size: 13px;
  color: var(--glow);
}

@media (min-width: 860px) {
  .nav__links { display: flex; }
  .nav__toggle,
  .nav__sheet { display: none; }

  /* the links take over the auto margin; the actions just follow them */
  .nav__actions { margin-left: 0; }

  /* With cart and account switched off the only child is the (hidden) menu
     toggle. Drop the empty box so its flex gap does not push the links in. */
  .nav__actions:not(:has(a)) { display: none; }
}

/* 7. Hero
   ========================================================================== */
.hero {
  /* Both sizes also respond to viewport HEIGHT, so the full hero (through the
     CTA) still fits above the fold on a 768px-tall laptop. */
  --logo-w: min(560px, 82vw, 62vh);
  --moon: clamp(170px, min(22vw, 30vh), 290px);
  --moon-top: calc(var(--nav-h) + 8px);
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: min(100svh, 960px);
  /* Places the logo so the moon's lower edge dips ~22% into it: level with
     the crescent's horn, just above its bowl. (Logo height = 0.503 x width.) */
  padding: calc(var(--moon-top) + var(--moon) - var(--logo-w) * 0.11) 0 96px;
  text-align: center;
}

.hero__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.hero__title {
  margin: 0;
}

.hero__logo {
  width: var(--logo-w);
  height: auto;
}

.hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 8px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.34em;
  text-indent: 0.34em; /* optically re-centre tracked text */
  text-transform: uppercase;
  color: var(--glow);
}

.hero__eyebrow::before,
.hero__eyebrow::after {
  content: "";
  width: 36px;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--glow-rgb), 0.7));
}

.hero__eyebrow::after {
  transform: scaleX(-1);
}

.hero__tagline {
  max-width: 24em;
  text-wrap: balance;
  margin-top: 22px;
  font-size: clamp(17px, 2.1vw, 21px);
  line-height: 1.5;
  color: var(--text);
}

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 14px;
  margin-top: 36px;
}

/* stacked, the two CTAs share one width instead of each hugging its label */
@media (max-width: 520px) {
  .hero__cta {
    flex-direction: column;
    align-items: stretch;
    width: min(100%, 320px);
  }
}

.hero__points {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px 28px;
  margin-top: 44px;
  font: 500 12.5px/1 var(--font-display);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.hero__points li {
  display: inline-flex;
  align-items: center;
  gap: 9px;
}

.hero__points .icon {
  font-size: 12px;
  color: var(--glow);
}

/* Entrance. Seen once per visit, so it can afford to be a little slower and
   softer than UI motion. The blur hides the fade's double-image. */
@keyframes hero-in {
  from { opacity: 0; transform: translateY(14px); filter: blur(6px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}

.js .hero__inner > * {
  animation: hero-in 900ms var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms + 120ms);
}

.hero__scroll {
  position: absolute;
  left: 50%;
  bottom: 28px;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-left: -22px;
  color: var(--text-faint);
  transition: color 200ms ease;
}

.hero__scroll span {
  width: 1px;
  height: 34px;
  background: linear-gradient(180deg, currentColor, transparent);
  transform-origin: top;
  animation: scroll-hint 2.6s var(--ease-in-out) infinite;
}

@keyframes scroll-hint {
  0%        { transform: scaleY(0.2); opacity: 0; }
  35%       { opacity: 1; }
  100%      { transform: scaleY(1); opacity: 0; }
}

@media (hover: hover) and (pointer: fine) {
  .hero__scroll:hover { color: var(--ice); }
}

/* 8. Section chrome
   ========================================================================== */
.section {
  position: relative;
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: calc(var(--section-y) * 0.6);
}

.section-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 640px;
  margin: 0 auto clamp(40px, 6vw, 64px);
  text-align: center;
}

.section-head--left {
  align-items: flex-start;
  margin-inline: 0;
  text-align: left;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 18px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--glow);
}

.eyebrow .icon {
  font-size: 13px;
}

.section-head h2 {
  font-size: clamp(30px, 4.6vw, 52px);
}

/* *word* in a heading setting becomes <span class="mk"> via the markup filter */
.mk {
  background: linear-gradient(180deg, var(--ice), var(--glow) 55%, var(--corn));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.section-head p {
  margin-top: 18px;
  font-size: 17px;
}

.section-cta {
  display: flex;
  justify-content: center;
  margin-top: 48px;
}

.section-note {
  margin-top: 34px;
  text-align: center;
}

/* Crescent divider */
.moon-divider {
  display: flex;
  align-items: center;
  gap: 22px;
  color: var(--glow);
}

.moon-divider::before,
.moon-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(var(--glow-rgb), 0.38));
}

.moon-divider::after {
  transform: scaleX(-1);
}

.moon-divider .icon {
  font-size: 18px;
  filter: drop-shadow(0 0 8px rgba(var(--glow-rgb), 0.8));
}

/* Scroll reveal. Hidden state only exists once JS has confirmed it can undo
   it, so content is never stranded invisible. */
.js.motion-ok .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 700ms var(--ease-out), transform 700ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * 60ms);
}

.js.motion-ok .reveal.is-in {
  opacity: 1;
  transform: none;
}

/* 9. Catalog
   ========================================================================== */
.chips {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-bottom: 40px;
}

.chip {
  padding: 10px 18px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(8, 13, 30, 0.6);
  transition: color 200ms ease, border-color 200ms ease, background-color 200ms ease, transform 160ms var(--ease-out);
}

.chip:active {
  transform: scale(0.97);
}

.chip[aria-current="page"] {
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow));
  border-color: transparent;
}

@media (hover: hover) and (pointer: fine) {
  .chip:not([aria-current="page"]):hover {
    color: var(--text);
    border-color: var(--line-strong);
  }
}

.card-grid {
  display: grid;
  gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 264px), 1fr));
}

/* A short catalog should not hug the left edge of a mostly empty grid.
   The template sets the class from the number of cards it renders:
     1 card   .card-grid--solo  one centred column; a wide spotlight from 760px
     2-3      .card-grid--few   auto-fit (empty tracks collapse) inside a width
                           cap of --n cards, centred
     4+       plain .card-grid  auto-fill keeps every card the same size, even
                           on a part-filled last row
   (A max track size on the base rule would do it in one line, but auto-fit
   counts columns from the MAX size when it is definite, which drops a full
   catalog from 4 columns to 3.) */
.card-grid--few {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 264px), 1fr));
  max-width: calc(var(--n, 3) * 360px + (var(--n, 3) - 1) * 22px);
  margin-inline: auto;
}

.card-grid--solo {
  grid-template-columns: minmax(0, 940px);
  justify-content: center;
}

@media (min-width: 760px) {
  .card-grid--solo .card {
    --cut: 24px;
    flex-direction: row;
  }

  .card-grid--solo .card__media {
    flex: 0 0 56%;
    margin: 1px 0 1px 1px;
  }

  /* fade toward the details panel rather than toward the bottom */
  .card-grid--solo .card__media::after {
    background: linear-gradient(90deg, transparent 58%, rgba(5, 9, 21, 0.7));
  }

  .card-grid--solo .card__body {
    justify-content: center;
    padding: clamp(24px, 3.4vw, 40px);
  }

  .card-grid--solo .card__title {
    font-size: clamp(24px, 2.6vw, 32px);
  }

  .card-grid--solo .card__desc {
    margin-top: 12px;
  }

  .card-grid--solo .card__foot {
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--line);
  }

  .card-grid--solo .price__value {
    font-size: 30px;
  }
}

.card {
  --cut: 18px;
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform 260ms var(--ease-out);
}

.card__media {
  position: relative;
  margin: 1px 1px 0;
  aspect-ratio: 16 / 10;
  overflow: hidden;
  background: var(--sky-2);
  /* matches the frame's top-left cut so the thumbnail follows the chamfer */
  clip-path: polygon(calc(var(--cut) - 0.6px) 0, 100% 0, 100% 100%, 0 100%, 0 calc(var(--cut) - 0.6px));
}

.card__media {
  aspect-ratio: var(--product-card-image-aspect-ratio, 16 / 10);
}

.card__media--group {
  aspect-ratio: var(--group-card-image-aspect-ratio, 16 / 10);
}

.card__media img {
  width: 100%;
  height: 100%;
  object-fit: var(--product-image-fit, cover);
  transition: transform 600ms var(--ease-out);
}

/* keeps a bright thumbnail from fighting the dark card under it */
.card__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 55%, rgba(5, 9, 21, 0.75));
  pointer-events: none;
}

/* Branded stand-in for products without an image */
.card__placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font-size: 54px;
  color: rgba(var(--glow-rgb), 0.5);
  background:
    radial-gradient(80% 90% at 50% 120%, rgba(var(--glow-rgb), 0.28), transparent 70%),
    linear-gradient(160deg, #0e1a3a, #060b1b);
}

.card__placeholder .icon {
  filter: drop-shadow(0 0 18px rgba(var(--glow-rgb), 0.6));
}

.card__badges {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
}

.card__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  font: 600 10.5px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ice);
  background: rgba(3, 6, 15, 0.78);
  border: 1px solid var(--badge, var(--line-strong));
  border-radius: 999px;
}

.card__badge--out {
  color: var(--text-faint);
  border-color: var(--line);
}

.card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 20px 22px 22px;
}

.card__title {
  font-size: 19px;
  letter-spacing: 0.04em;
}

/* The title link stretches over the whole card: one tab stop, one big target,
   and the accessible name is just the product name. */
.card__title a::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}

/* a group card's control is a <button> (it opens a dialog, it does not navigate) */
.card__title button {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  text-align: left;
  color: inherit;
}

.card__title button::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
}

.card__title a:focus-visible,
.card__title button:focus-visible {
  outline: none;
}

.card:has(.card__title :focus-visible) {
  outline: 2px solid var(--ice);
  outline-offset: 4px;
}

.card__desc {
  display: -webkit-box;
  margin-top: 8px;
  overflow: hidden;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--text-faint);
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.card__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 12px;
  margin-top: auto;
  padding-top: 22px;
}

.price {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.price__label {
  font: 500 10.5px/1 var(--font-display);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.price__value {
  font: 700 22px/1 var(--font-display);
  letter-spacing: 0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.price__was {
  margin-left: 8px;
  font-size: 0.62em;
  font-weight: 500;
  color: var(--text-faint);
}

.card__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding-bottom: 2px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--glow);
  transition: color 200ms ease;
}

.card__cta .icon {
  transition: transform 260ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .card:hover {
    transform: translateY(-4px);
  }

  .card:hover::before {
    opacity: 0.34;
  }

  .card:hover .frame__edge::before {
    opacity: 1;
  }

  .card:hover .card__media img {
    transform: scale(1.04);
  }

  .card:hover .card__cta {
    color: var(--ice);
  }

  .card:hover .card__cta .icon {
    transform: translateX(4px);
  }
}

.empty {
  padding: 56px 24px;
  text-align: center;
  color: var(--text-faint);
}

.empty .icon {
  margin: 0 auto 18px;
  font-size: 34px;
  color: rgba(var(--glow-rgb), 0.55);
}

.pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  margin-top: 48px;
}

.pagination a,
.pagination span {
  display: grid;
  place-items: center;
  min-width: 44px;
  height: 44px;
  padding: 0 12px;
  font: 600 13px/1 var(--font-display);
  letter-spacing: 0.06em;
  color: var(--text-dim);
  border: 1px solid var(--line);
  transition: color 200ms ease, border-color 200ms ease;
}

.pagination [aria-current="page"] {
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow));
  border-color: transparent;
}

.pagination span[aria-disabled="true"] {
  opacity: 0.35;
}

@media (hover: hover) and (pointer: fine) {
  .pagination a:hover {
    color: var(--ice);
    border-color: var(--line-strong);
  }
}

/* 10. Product page
   ========================================================================== */
.page-top {
  padding-top: calc(var(--nav-h) + clamp(28px, 5vw, 56px));
}

.page-head {
  margin-top: 28px;
}

/* a section that opens a page already has .page-top clearing the navbar */
.page-top > .section:first-child {
  padding-top: clamp(24px, 4vw, 48px);
}

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  font: 500 12px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.crumbs a {
  transition: color 200ms ease;
}

.crumbs [aria-current="page"] {
  color: var(--text-dim);
}

.crumbs li + li::before {
  content: "/";
  margin-right: 10px;
  color: rgba(var(--glow-rgb), 0.4);
}

@media (hover: hover) and (pointer: fine) {
  .crumbs a:hover { color: var(--ice); }
}

.info-block {
  margin-top: 48px;
}

.info-block__title {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 20px;
  font-size: 15px;
  letter-spacing: 0.2em;
  color: var(--text-dim);
}

.info-block__title .icon {
  font-size: 14px;
  color: var(--glow);
}

.assurances {
  display: grid;
  gap: 12px;
  margin-top: 24px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: 14px;
}

.assurances li {
  display: flex;
  align-items: center;
  gap: 12px;
}

.assurances .icon {
  font-size: 13px;
  color: var(--glow);
}

/* 10b. Product page (components/product-page.njk)
   Tsuki layout around SellAuth's own form. The form's markup is the
   starter's, so it is styled from the outside, anchored ONLY on attributes
   its logic depends on (label[for=variant|quantity], x-on:click="addToCart",
   type="submit", @click="changeQuantity(...)"), which cannot change without
   breaking checkout itself. Every form rule is prefixed `.pp .pp-form` so it
   outranks the starter's Tailwind hover variants (0,3,0).
   ========================================================================== */
.pp {
  padding-bottom: 24px;
}

.pp__grid {
  display: grid;
  gap: 28px;
  margin-top: 24px;
  grid-template-areas: "head" "media" "buy" "info";
}

@media (min-width: 960px) {
  .pp__grid {
    grid-template-columns: minmax(0, 1fr) 420px;
    grid-template-rows: auto auto 1fr;
    grid-template-areas:
      "head  buy"
      "media buy"
      "info  buy";
    column-gap: 48px;
  }
}

/* Sticky only when the screen is tall enough to show the whole box: a sticky
   box taller than the viewport hides its own Buy button. */
@media (min-width: 960px) and (min-height: 880px) {
  .pp__buy {
    position: sticky;
    top: calc(var(--nav-h) + 20px);
    align-self: start;
  }
}

.pp__head {
  grid-area: head;
  min-width: 0;
}

.pp__head .eyebrow {
  margin-bottom: 14px;
}

.pp__head .eyebrow a {
  transition: color 200ms ease;
}

.pp__title {
  font-size: clamp(30px, 4.6vw, 52px);
  overflow-wrap: anywhere;
}

.pp__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 18px;
}

.pp__status,
.pp__badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 7px 13px;
  font: 600 11.5px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
}

/* merchant-chosen colours tint the pill instead of flooding it */
.pp__status {
  color: var(--status);
  border-color: color-mix(in srgb, var(--status) 45%, transparent);
  background: color-mix(in srgb, var(--status) 9%, transparent);
}

.pp__badge {
  color: var(--ice);
  border-color: var(--badge, var(--line-strong));
  background: rgba(3, 6, 15, 0.6);
}

.pp__status-dot {
  position: relative;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--status);
}

/* the starter's .pulsating ring (keyframes live in built.css) */
.pp__status-dot .pulsating {
  background: var(--status);
}

/* --- gallery: a 1px line drawn by the outer clip, the image by the inner one */
.pp__media {
  --cut: 26px;
  grid-area: media;
  position: relative;
  min-width: 0;
  padding: 1px;
  background: var(--line-strong);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.pp__media > * {
  --cut-in: calc(var(--cut) - 0.6px);
  background: var(--sky-2);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

.pp__media img {
  display: block;
  width: 100%;
  aspect-ratio: var(--product-page-image-aspect-ratio, 16 / 9);
  object-fit: var(--product-image-fit, cover);
}

.pp .splide__arrow {
  width: 40px;
  height: 40px;
  background: rgba(3, 6, 15, 0.72);
  border: 1px solid var(--line-strong);
  opacity: 1;
  transition: border-color 200ms ease, transform 160ms var(--ease-out);
}

.pp .splide__arrow svg {
  width: 14px;
  height: 14px;
  fill: var(--ice);
}

.pp .splide__arrow:active {
  transform: translateY(-50%) scale(0.94);
}

@media (hover: hover) and (pointer: fine) {
  .pp__head .eyebrow a:hover {
    color: var(--ice);
  }

  .pp .splide__arrow:hover:not(:disabled) {
    border-color: var(--ice);
    opacity: 1;
  }
}

/* --- buy box --------------------------------------------------------------- */
.pp__buy {
  grid-area: buy;
  min-width: 0;
}

.pp__box {
  --cut: 22px;
  --fill: var(--surface-raised);
  padding: clamp(20px, 2.6vw, 28px);
}

.pp__price {
  padding-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

.pp__total {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.pp__total-value {
  font: 800 clamp(34px, 4vw, 42px)/1 var(--font-display);
  letter-spacing: 0.01em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.pp__was {
  font: 500 17px/1 var(--font-display);
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}

.pp__save {
  padding: 6px 10px;
  font: 700 11px/1 var(--font-display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow));
  border-radius: 999px;
}

.pp__each {
  margin-top: 8px;
  font-size: 14px;
  color: var(--text-faint);
}

.pp__stock {
  margin-top: 14px;
  font-size: 14px;
}

.pp__stock-row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--text-dim);
}

.pp__stock-row .icon {
  font-size: 14px;
  color: var(--glow);
}

.pp__stock-row--out {
  color: #ffadb9;
}

.pp__live {
  display: grid;
  gap: 10px;
  margin: 22px 0 0;
  padding: 18px 0 0;
  list-style: none;
  font-size: 13.5px;
  color: var(--text-faint);
  border-top: 1px solid var(--line);
}

.pp__live li {
  display: flex;
  align-items: center;
  gap: 10px;
}

.pp__live .icon {
  font-size: 13px;
  color: var(--glow);
}

.pp__live strong,
.pp__live b {
  color: var(--text-dim);
}

.pp__live-dot {
  position: relative;
  flex: none;
  width: 8px;
  height: 8px;
  margin: 0 3px;
  border-radius: 50%;
  background: #6ee7b7;
}

.pp__live-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: inherit;
  animation: live-ping 2.4s var(--ease-out) infinite;
}

@keyframes live-ping {
  from { opacity: 0.7; transform: scale(1); }
  to   { opacity: 0;   transform: scale(2.6); }
}

/* --- SellAuth's form, restyled ---------------------------------------------- */
.pp .pp-form {
  /* the Altcha captcha is a web component themed through these */
  --altcha-color-base: rgba(5, 10, 24, 0.8);
  --altcha-color-border: var(--line-strong);
  --altcha-color-border-focus: var(--ice);
  --altcha-color-text: var(--text);
  --altcha-border-radius: 3px;
  --altcha-max-width: 100%;
}

.pp .pp-form form > div {
  padding: 22px 0 0;
  background: none;
  border: 0;
}

.pp .pp-form .border-b,
.pp .pp-form .border-white\/5 {
  border-color: var(--line);
}

.pp .pp-form .rounded-lg,
.pp .pp-form .rounded {
  border-radius: 3px;
}

.pp .pp-form .bg-white\/\[0\.025\] {
  background-color: rgba(var(--glow-rgb), 0.045);
}

.pp .pp-form label.block {
  margin-bottom: 12px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
}

/* variants: the same cut-corner radio tiles as the rest of the design */
.pp .pp-form label[for="variant"] + div {
  gap: 10px;
}

.pp .pp-form label[for="variant"] + div > button {
  --cut: 10px;
  position: relative;
  isolation: isolate;
  gap: 14px;
  padding: 14px 16px;
  text-align: left;
  border: 0;
  border-radius: 0;
  background: none;
  transition: transform 160ms var(--ease-out);
}

.pp .pp-form label[for="variant"] + div > button::before,
.pp .pp-form label[for="variant"] + div > button::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
}

.pp .pp-form label[for="variant"] + div > button::before {
  inset: 0;
  background: var(--line);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  transition: background-color 200ms ease;
}

.pp .pp-form label[for="variant"] + div > button::after {
  --cut-in: calc(var(--cut) - 0.6px);
  inset: 1px;
  background: rgba(5, 10, 24, 0.86);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
  transition: background-color 200ms ease;
}

/* selected: the starter marks it with the !border-accent-500 class */
.pp .pp-form label[for="variant"] + div > button[class~="!border-accent-500"]::before {
  background: linear-gradient(135deg, var(--ice), var(--corn) 55%, rgba(var(--glow-rgb), 0.35));
}

.pp .pp-form label[for="variant"] + div > button[class~="!border-accent-500"]::after {
  background: rgba(15, 25, 54, 0.94);
}

.pp .pp-form label[for="variant"] + div > button:active:not(:disabled) {
  transform: scale(0.985);
}

.pp .pp-form label[for="variant"] + div > button:disabled {
  cursor: not-allowed;
  opacity: 0.45;
}

/* name line gets the radio dot */
.pp .pp-form label[for="variant"] + div > button .flex-1 > p:first-child {
  position: relative;
  padding-left: 30px;
  font: 600 14px/1.25 var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text);
}

.pp .pp-form label[for="variant"] + div > button .flex-1 > p:first-child::before,
.pp .pp-form label[for="variant"] + div > button .flex-1 > p:first-child::after {
  content: "";
  position: absolute;
  top: 50%;
  border-radius: 50%;
}

.pp .pp-form label[for="variant"] + div > button .flex-1 > p:first-child::before {
  left: 0;
  width: 18px;
  height: 18px;
  margin-top: -9px;
  border: 1.5px solid var(--line-strong);
  transition: border-color 200ms ease;
}

.pp .pp-form label[for="variant"] + div > button .flex-1 > p:first-child::after {
  left: 4.5px;
  width: 9px;
  height: 9px;
  margin-top: -4.5px;
  background: var(--ice);
  box-shadow: 0 0 10px rgba(var(--ice-rgb), 0.9);
  opacity: 0;
  transform: scale(0.5);
  transition: opacity 180ms ease, transform 220ms var(--ease-out);
}

.pp .pp-form label[for="variant"] + div > button[class~="!border-accent-500"] .flex-1 > p:first-child::before {
  border-color: var(--ice);
}

.pp .pp-form label[for="variant"] + div > button[class~="!border-accent-500"] .flex-1 > p:first-child::after {
  opacity: 1;
  transform: none;
}

/* description and stock lines sit under the name, past the dot */
.pp .pp-form label[for="variant"] + div > button .flex-1 > p:not(:first-child) {
  padding-left: 30px;
  font-size: 12.5px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--text-faint);
}

/* price column */
.pp .pp-form label[for="variant"] + div > button > div:last-child {
  padding: 0;
  text-align: right;
  font: 700 16px/1 var(--font-display);
  color: var(--text);
  background: none;
  font-variant-numeric: tabular-nums;
}

.pp .pp-form label[for="variant"] + div > button > div:last-child .line-through {
  display: block;
  margin-top: 5px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-faint);
}

/* dropdown variant picker (Choices.js), if the merchant switches to it */
.pp .choices__inner {
  min-height: 48px;
  padding: 10px 14px;
  background: rgba(5, 10, 24, 0.8);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
}

.pp .choices__list--dropdown,
.pp .choices__list[aria-expanded] {
  background: var(--sky-2);
  border-color: var(--line-strong);
}

.pp .choices__list--dropdown .choices__item--selectable.is-highlighted {
  background: rgba(var(--glow-rgb), 0.14);
}

/* quantity stepper */
.pp .pp-form label[for="quantity"] + div {
  max-width: 220px;
  border: 1px solid var(--line-strong);
  border-radius: 0;
}

.pp .pp-form label[for="quantity"] + div:focus-within {
  outline: 2px solid var(--ice);
  outline-offset: 2px;
  box-shadow: none;
}

.pp .pp-form label[for="quantity"] + div > button {
  flex: none;
  width: 44px;
  height: 44px;
  color: var(--text-dim);
  background: none;
  transition: color 200ms ease, background-color 200ms ease;
}

.pp .pp-form label[for="quantity"] + div > input {
  flex: 1;
  width: auto;
  min-width: 0;
  height: 44px;
  font: 600 15px/1 var(--font-display);
  text-align: center;
  color: var(--text);
  background: none;
  border-inline: 1px solid var(--line);
}

.pp .pp-form label[for="quantity"] + div > button:active:not(:disabled) {
  background: rgba(var(--glow-rgb), 0.16);
}

/* action buttons: Buy now is the primary, Add to cart the secondary */
.pp .pp-form div:has(> button[type="submit"]) {
  gap: 12px;
  margin-top: 22px;
}

.pp .pp-form button[type="submit"],
.pp .pp-form [x-on\:click="addToCart"],
.pp .pp-form [x-on\:click="subscribeNow"],
.pp .pp-form [x-on\:click="openInstantBalance"] {
  --cut: 11px;
  position: relative;
  isolation: isolate;
  min-height: 52px;
  padding: 0 16px;
  gap: 12px;
  /* two buttons share ~370px in the desktop box: tighter tracking and
     nowrap keep "Add to cart" on one line */
  font: 600 13px/1 var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  border: 0;
  border-radius: 0;
  background: none;
  transition: transform 160ms var(--ease-out), color 200ms ease;
}

.pp .pp-form button[type="submit"]::before,
.pp .pp-form button[type="submit"]::after,
.pp .pp-form [x-on\:click="addToCart"]::before,
.pp .pp-form [x-on\:click="addToCart"]::after,
.pp .pp-form [x-on\:click="subscribeNow"]::before,
.pp .pp-form [x-on\:click="subscribeNow"]::after,
.pp .pp-form [x-on\:click="openInstantBalance"]::before,
.pp .pp-form [x-on\:click="openInstantBalance"]::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
  transition: background-color 200ms ease, opacity 200ms ease;
}

.pp .pp-form button[type="submit"]::before,
.pp .pp-form [x-on\:click="addToCart"]::before,
.pp .pp-form [x-on\:click="subscribeNow"]::before,
.pp .pp-form [x-on\:click="openInstantBalance"]::before {
  inset: 0;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.pp .pp-form button[type="submit"]::after,
.pp .pp-form [x-on\:click="addToCart"]::after,
.pp .pp-form [x-on\:click="subscribeNow"]::after,
.pp .pp-form [x-on\:click="openInstantBalance"]::after {
  --cut-in: calc(var(--cut) - 0.9px);
  inset: 1.5px;
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

/* primary: solid moonlight gradient, dark text, soft static glow */
.pp .pp-form button[type="submit"] {
  color: #041024;
  filter: drop-shadow(0 0 14px rgba(var(--glow-rgb), 0.4));
}

.pp .pp-form button[type="submit"]::before {
  background: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
}

/* hover brightens through an overlay's opacity, never an animated filter */
.pp .pp-form button[type="submit"]::after {
  background: #fff;
  opacity: 0;
}

/* secondary: outlined */
.pp .pp-form [x-on\:click="addToCart"],
.pp .pp-form [x-on\:click="subscribeNow"],
.pp .pp-form [x-on\:click="openInstantBalance"] {
  color: var(--ice);
}

.pp .pp-form [x-on\:click="addToCart"]::before,
.pp .pp-form [x-on\:click="subscribeNow"]::before,
.pp .pp-form [x-on\:click="openInstantBalance"]::before {
  background: var(--line-strong);
}

.pp .pp-form [x-on\:click="addToCart"]::after,
.pp .pp-form [x-on\:click="subscribeNow"]::after,
.pp .pp-form [x-on\:click="openInstantBalance"]::after {
  background: rgba(5, 10, 24, 0.92);
}

.pp .pp-form button[type="submit"]:active:not(:disabled),
.pp .pp-form [x-on\:click="addToCart"]:active:not(:disabled),
.pp .pp-form [x-on\:click="subscribeNow"]:active:not(:disabled),
.pp .pp-form [x-on\:click="openInstantBalance"]:active:not(:disabled) {
  transform: scale(0.97);
}

.pp .pp-form button:disabled {
  cursor: not-allowed;
}

.pp .pp-form button[type="submit"]:disabled {
  filter: none;
}

/* the starter's error message */
.pp .pp-form .bg-red-500 {
  color: #ffd9df;
  background: rgba(255, 86, 112, 0.12);
  border: 1px solid rgba(255, 120, 140, 0.45);
  border-radius: 3px;
}

.pp .pp-form .text-red-500 {
  color: #ff9fae;
}

@media (hover: hover) and (pointer: fine) {
  .pp .pp-form label[for="variant"] + div > button:not(:disabled):not([class~="!border-accent-500"]):hover::before {
    background: var(--line-strong);
  }

  .pp .pp-form label[for="quantity"] + div > button:hover:not(:disabled) {
    color: var(--ice);
    background: rgba(var(--glow-rgb), 0.08);
  }

  .pp .pp-form button[type="submit"]:hover:not(:disabled) {
    background: none;
  }

  .pp .pp-form button[type="submit"]:hover:not(:disabled)::after {
    opacity: 0.16;
  }

  .pp .pp-form [x-on\:click="addToCart"]:hover:not(:disabled),
  .pp .pp-form [x-on\:click="subscribeNow"]:hover:not(:disabled),
  .pp .pp-form [x-on\:click="openInstantBalance"]:hover:not(:disabled) {
    color: var(--text);
    background: none;
  }

  .pp .pp-form [x-on\:click="addToCart"]:hover:not(:disabled)::before,
  .pp .pp-form [x-on\:click="subscribeNow"]:hover:not(:disabled)::before,
  .pp .pp-form [x-on\:click="openInstantBalance"]:hover:not(:disabled)::before {
    background: var(--glow);
  }
}

.pp .assurances {
  margin-top: 22px;
}

/* --- description, reviews, upsells --------------------------------------- */
.pp__info {
  grid-area: info;
  min-width: 0;
}

.pp__about.info-block {
  margin-top: 0;
}

.pp .editor {
  max-width: 72ch;
}

.pp__tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 22px;
}

.pp__tabs .chip[aria-selected="true"] {
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow));
  border-color: transparent;
}

.pp__upsells {
  padding-bottom: 0;
}

/* 10c. Cart (templates/cart.njk around the starter's cart-page.njk)
   SellAuth's cart markup, restyled from outside. Anchors are the bindings
   its logic needs (x-data="cartPage", @click="removeItem(index)",
   @click="changeQuantity(...)", x-text="cartItem...") plus the pinned
   starter's layout classes, all scoped under `.cartx` so nothing leaks.
   ========================================================================== */
.cartx {
  --altcha-color-base: rgba(5, 10, 24, 0.8);
  --altcha-color-border: var(--line-strong);
  --altcha-color-border-focus: var(--ice);
  --altcha-color-text: var(--text);
  --altcha-border-radius: 3px;
  --altcha-max-width: 100%;
}

.cartx .page-head {
  margin-bottom: 28px;
}

.cartx .section-head {
  margin-bottom: 0;
}

.cartx .rounded-lg,
.cartx .rounded {
  border-radius: 3px;
}

.cartx .bg-card {
  background-color: var(--surface);
}

.cartx .border-white\/5,
.cartx .border-b,
.cartx .border-t {
  border-color: var(--line);
}

/* two columns: items | order summary */
.cartx [x-data="cartPage"] > div {
  padding: 0;
}

.cartx [x-data="cartPage"] > div > div {
  gap: 24px;
  margin-bottom: 0;
}

@media (min-width: 1024px) {
  .cartx [x-data="cartPage"] > div > div {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 380px;
    gap: 40px;
    align-items: start;
  }

  .cartx [x-data="cartPage"] > div > div > div {
    width: auto;
  }

  .cartx .lg\:w-1\/4 {
    position: sticky;
    top: calc(var(--nav-h) + 20px);
  }
}

/* --- item rows: cut-corner tiles ------------------------------------------ */
.cartx .md\:gap-4.lg\:gap-5 {
  gap: 12px;
}

.cartx .md\:gap-4.lg\:gap-5 > div {
  --cut: 14px;
  position: relative;
  isolation: isolate;
  gap: 14px;
  padding: 12px;
  border: 0;
  border-radius: 0;
  background: none;
}

.cartx .md\:gap-4.lg\:gap-5 > div::before,
.cartx .md\:gap-4.lg\:gap-5 > div::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
}

.cartx .md\:gap-4.lg\:gap-5 > div::before {
  inset: 0;
  background: var(--line);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.cartx .md\:gap-4.lg\:gap-5 > div::after {
  --cut-in: calc(var(--cut) - 0.6px);
  inset: 1px;
  background: var(--surface);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

@media (min-width: 640px) {
  .cartx .md\:gap-4.lg\:gap-5 > div {
    align-items: center;
    padding: 12px 20px 12px 12px;
  }
}

.cartx .md\:gap-4.lg\:gap-5 > div img {
  border-radius: 2px;
}

/* product name and variant */
.cartx .md\:gap-4.lg\:gap-5 > div a[\:href] {
  font: 700 16px/1.2 var(--font-display);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text);
  text-decoration: none;
  transition: color 200ms ease;
}

.cartx [x-text="cartItem.variant.name"] {
  margin-top: 6px;
  font-size: 14px;
  color: var(--text-dim);
}

/* quantity stepper, same as the product page */
.cartx div:has(> button[\@click^="changeQuantity"]) {
  max-width: 132px;
  border: 1px solid var(--line-strong);
  border-radius: 0;
}

.cartx div:has(> button[\@click^="changeQuantity"]):focus-within {
  outline: 2px solid var(--ice);
  outline-offset: 2px;
  box-shadow: none;
}

.cartx button[\@click^="changeQuantity"] {
  width: 40px;
  height: 40px;
  color: var(--text-dim);
  background: none;
  transition: color 200ms ease, background-color 200ms ease;
}

.cartx button[\@click^="changeQuantity"]:active:not(:disabled) {
  background: rgba(var(--glow-rgb), 0.16);
}

.cartx div:has(> button[\@click^="changeQuantity"]) > input {
  flex: 1;
  width: auto;
  min-width: 0;
  font: 600 15px/1 var(--font-display);
  color: var(--text);
  background: none;
  border-inline: 1px solid var(--line);
}

/* line price */
.cartx [x-text^="appCurrency.format(getItemSinglePrice"] {
  font: 700 18px/1 var(--font-display);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* remove: a quiet icon with a full-size hit area */
.cartx button[\@click="removeItem(index)"] {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin: -6px -8px -6px 0;
  color: var(--text-faint);
  border-radius: 50%;
  transition: color 200ms ease, background-color 200ms ease, transform 160ms var(--ease-out);
}

.cartx button[\@click="removeItem(index)"]:active {
  transform: scale(0.92);
}

@media (min-width: 640px) {
  .cartx button.sm\:hidden[\@click="removeItem(index)"] {
    display: none;
  }
}

@media (max-width: 639px) {
  .cartx button.hidden.sm\:block[\@click="removeItem(index)"] {
    display: none;
  }
}

/* --- order summary ---------------------------------------------------------- */
.cartx .lg\:w-1\/4 > .flex > div:first-child {
  --cut: 20px;
  position: relative;
  isolation: isolate;
  padding: clamp(20px, 2.6vw, 28px);
  border: 0;
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 18px 40px rgba(0, 0, 0, 0.35));
}

.cartx .lg\:w-1\/4 > .flex > div:first-child::before,
.cartx .lg\:w-1\/4 > .flex > div:first-child::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
}

.cartx .lg\:w-1\/4 > .flex > div:first-child::before {
  inset: 0;
  background: linear-gradient(160deg, rgba(var(--ice-rgb), 0.55), rgba(var(--glow-rgb), 0.18) 40%, var(--line) 70%);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.cartx .lg\:w-1\/4 > .flex > div:first-child::after {
  --cut-in: calc(var(--cut) - 0.6px);
  inset: 1px;
  background: var(--surface-raised);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

.cartx form label.block {
  margin-bottom: 14px;
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.cartx form .mb-4.pb-2 {
  padding-bottom: 16px;
}

.cartx form .mb-4.pb-2 .text-sm {
  font-size: 14px;
}

.cartx [x-text="appCurrency.format(cartSubtotalPrice, cartCurrency)"],
.cartx [x-text="appCurrency.format(cartTotalPrice, cartCurrency)"] {
  font: 700 24px/1 var(--font-display);
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* checkout: the same primary button as Buy now */
.cartx [x-data="cartPage"] form button[type="submit"] {
  --cut: 11px;
  position: relative;
  isolation: isolate;
  min-height: 52px;
  margin-top: 20px;
  padding: 0 20px;
  gap: 12px;
  font: 600 13.5px/1 var(--font-display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: #041024;
  border: 0;
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 0 14px rgba(var(--glow-rgb), 0.4));
  transition: transform 160ms var(--ease-out);
}

.cartx [x-data="cartPage"] form button[type="submit"]::before,
.cartx [x-data="cartPage"] form button[type="submit"]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.cartx [x-data="cartPage"] form button[type="submit"]::before {
  background: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
}

.cartx [x-data="cartPage"] form button[type="submit"]::after {
  background: #fff;
  opacity: 0;
  transition: opacity 200ms ease;
}

.cartx [x-data="cartPage"] form button[type="submit"]:active:not(:disabled) {
  transform: scale(0.97);
}

.cartx [x-data="cartPage"] form button[type="submit"]:disabled {
  filter: none;
}

.cartx .bg-red-500 {
  color: #ffd9df;
  background: rgba(255, 86, 112, 0.12);
  border: 1px solid rgba(255, 120, 140, 0.45);
}

@media (hover: hover) and (pointer: fine) {
  .cartx .md\:gap-4.lg\:gap-5 > div a[\:href]:hover {
    color: var(--ice);
    text-decoration: none;
  }

  .cartx button[\@click^="changeQuantity"]:hover:not(:disabled) {
    color: var(--ice);
    background: rgba(var(--glow-rgb), 0.08);
  }

  .cartx button[\@click="removeItem(index)"]:hover {
    color: #ffadb9;
    background: rgba(255, 120, 140, 0.1);
  }

  .cartx [x-data="cartPage"] form button[type="submit"]:hover:not(:disabled) {
    background: none;
  }

  .cartx [x-data="cartPage"] form button[type="submit"]:hover:not(:disabled)::after {
    opacity: 0.16;
  }
}

/* --- empty cart --------------------------------------------------------------- */
/* Hide SellAuth's bare "empty" box and the inactive order panel; the Tsuki
   empty state (in cart.njk) takes their place. Notices stay visible. */
.cartx.is-empty .lg\:w-1\/4,
.cartx.is-empty [x-data="cartPage"] div.bg-card:has(> p.text-center:only-child) {
  display: none;
}

.cartx.is-empty [x-data="cartPage"] > div > div {
  display: block;
}

.cartx__empty {
  --cut: 22px;
  --fill: var(--surface);
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 560px;
  margin: 8px auto 0;
  padding: clamp(36px, 6vw, 56px) 28px;
  text-align: center;
}

.cartx__empty-moon {
  margin-bottom: 18px;
  font-size: 40px;
  color: var(--glow);
  filter: drop-shadow(0 0 16px rgba(var(--glow-rgb), 0.7));
}

.cartx__empty h2 {
  font-size: clamp(22px, 3vw, 28px);
}

.cartx__empty p {
  max-width: 30em;
  margin: 12px 0 26px;
}

/* 10d. Login pop-up (starter's snippets/customer-login-modal.njk)
   Wrapped in `.loginx` by master.njk and styled from outside. Anchors: the
   dialog role and the appCustomer.* handlers its logic runs on. All four
   steps (email, password, 6-digit code, 2FA) share these rules.
   ========================================================================== */
.loginx {
  --panel: #0b1430;
  --altcha-color-base: rgba(5, 10, 24, 0.8);
  --altcha-color-border: var(--line-strong);
  --altcha-color-border-focus: var(--ice);
  --altcha-color-text: var(--text);
  --altcha-border-radius: 3px;
  --altcha-max-width: 100%;
}

.loginx .bg-black\/75 {
  background: rgba(1, 3, 8, 0.78);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

/* The starter closes with ease-in over 200ms, which feels sluggish at the
   exact moment the user is done. Enter stays soft, exit gets quick. */
.loginx .duration-300 { transition-duration: 240ms; }
.loginx .duration-200 { transition-duration: 160ms; }
.loginx .ease-out { transition-timing-function: var(--ease-out); }
.loginx .ease-in { transition-timing-function: ease; }

/* the panel: a solid cut-corner card with the lit edge */
.loginx [role="dialog"] .max-w-lg {
  --cut: 22px;
  position: relative;
  isolation: isolate;
  max-width: 440px;
  padding: clamp(24px, 4vw, 34px);
  overflow: visible;
  border: 0;
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 24px 60px rgba(0, 0, 0, 0.55));
}

.loginx [role="dialog"] .max-w-lg::before,
.loginx [role="dialog"] .max-w-lg::after {
  content: "";
  position: absolute;
  z-index: -1;
  pointer-events: none;
}

.loginx [role="dialog"] .max-w-lg::before {
  inset: 0;
  background: linear-gradient(160deg, rgba(var(--ice-rgb), 0.6), rgba(var(--glow-rgb), 0.2) 40%, var(--line) 70%);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.loginx [role="dialog"] .max-w-lg::after {
  --cut-in: calc(var(--cut) - 0.6px);
  inset: 1px;
  background: var(--panel);
  clip-path: polygon(var(--cut-in) 0, 100% 0, 100% calc(100% - var(--cut-in)), calc(100% - var(--cut-in)) 100%, 0 100%, 0 var(--cut-in));
}

.loginx [role="dialog"] h3 {
  font: 700 24px/1.1 var(--font-display);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
}

.loginx button[\@click="appCustomer.modalClose()"] {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin: -8px -10px 0 0;
  border-radius: 50%;
  transition: background-color 200ms ease;
}

.loginx button[\@click="appCustomer.modalClose()"] svg {
  width: 22px;
  height: 22px;
  color: var(--text-faint);
  transition: color 200ms ease;
}

.loginx label.block {
  font: 600 12px/1 var(--font-display);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.loginx small.block {
  margin-top: 8px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--text-faint);
}

/* fields */
.loginx input[type="email"],
.loginx input[type="password"],
.loginx input[x-model="appCustomer.modalTfaCode"] {
  height: 48px;
  padding: 0 16px;
  font: 400 16px/1 var(--font-body);   /* 16px: iOS does not zoom the page on focus */
  color: var(--text);
  background: rgba(3, 6, 15, 0.7);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  transition: border-color 200ms ease;
}

.loginx input::placeholder {
  color: var(--text-faint);
}

/* the six code boxes */
.loginx input[maxlength="1"] {
  width: 48px;
  height: 56px;
  font: 700 22px/1 var(--font-display);
  color: var(--text);
  background: rgba(3, 6, 15, 0.7);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  transition: border-color 200ms ease;
}

.loginx .flex.gap-2.mt-2 {
  justify-content: space-between;
  gap: 8px;
}

.loginx input:focus {
  border-color: var(--ice);
  outline: 2px solid rgba(var(--ice-rgb), 0.35);
  outline-offset: 1px;
  box-shadow: none;
}

/* Continue: the primary button */
.loginx button[type="submit"] {
  --cut: 11px;
  position: relative;
  isolation: isolate;
  min-height: 50px;
  margin-top: 18px;
  gap: 12px;
  font: 600 13.5px/1 var(--font-display);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #041024;
  border: 0;
  border-radius: 0;
  background: none;
  filter: drop-shadow(0 0 14px rgba(var(--glow-rgb), 0.4));
  transition: transform 160ms var(--ease-out);
}

.loginx button[type="submit"]::before,
.loginx button[type="submit"]::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
}

.loginx button[type="submit"]::before {
  background: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
}

.loginx button[type="submit"]::after {
  background: #fff;
  opacity: 0;
  transition: opacity 200ms ease;
}

.loginx button[type="submit"]:active:not(:disabled) {
  transform: scale(0.97);
}

/* "Use a password instead" / "Use an email code" */
.loginx button[\@click="appCustomer.modalUsePasswordLogin()"],
.loginx button[\@click="appCustomer.modalUseOtpLogin()"] {
  margin-top: 16px;
  font-size: 14px;
  color: var(--glow);
  text-decoration: underline;
  text-decoration-color: rgba(var(--glow-rgb), 0.4);
  text-underline-offset: 3px;
  transition: color 200ms ease, text-decoration-color 200ms ease;
}

/* "or" divider: the label's background must match the panel it masks */
.loginx .border-t.border-white\/5 {
  border-color: var(--line);
}

.loginx span.bg-background {
  padding: 0 12px;
  font: 600 11px/1 var(--font-display);
  letter-spacing: 0.24em;
  color: var(--text-faint);
  background: var(--panel);
}

/* Continue with Discord */
.loginx button[\@click="appCustomer.loginWithDiscord()"] {
  min-height: 48px;
  gap: 10px;
  font: 600 13px/1 var(--font-display);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  background: rgba(88, 101, 242, 0.12);
  border: 1px solid rgba(88, 101, 242, 0.55);
  border-radius: 3px;
  transition: background-color 200ms ease, border-color 200ms ease, transform 160ms var(--ease-out);
}

.loginx button[\@click="appCustomer.loginWithDiscord()"] svg {
  width: 18px;
  height: 18px;
  color: #aab3ff;
}

.loginx button[\@click="appCustomer.loginWithDiscord()"]:active:not(:disabled) {
  transform: scale(0.97);
}

.loginx .text-red-500 {
  color: #ff9fae;
}

@media (hover: hover) and (pointer: fine) {
  .loginx button[\@click="appCustomer.modalClose()"]:hover {
    background: rgba(var(--glow-rgb), 0.1);
  }

  .loginx button[\@click="appCustomer.modalClose()"]:hover svg {
    color: var(--ice);
  }

  .loginx button[type="submit"]:hover:not(:disabled) {
    background: none;
  }

  .loginx button[type="submit"]:hover:not(:disabled)::after {
    opacity: 0.16;
  }

  .loginx button[\@click="appCustomer.modalUsePasswordLogin()"]:hover,
  .loginx button[\@click="appCustomer.modalUseOtpLogin()"]:hover {
    color: var(--ice);
    text-decoration-color: currentColor;
  }

  .loginx button[\@click="appCustomer.loginWithDiscord()"]:hover:not(:disabled) {
    background: rgba(88, 101, 242, 0.24);
    border-color: rgba(120, 132, 255, 0.85);
  }
}

/* 11. Trust
   ========================================================================== */
.stats {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(2, 1fr);
}

@media (min-width: 860px) {
  .stats {
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
  }
}

.stats {
  margin: 0;
  padding: 0;
  list-style: none;
}

.stat {
  --cut: 14px;
  display: flex;
  flex-direction: column;
  padding: 26px 18px;
  text-align: center;
}

.stat__value small {
  font-size: 0.5em;
  letter-spacing: 0.06em;
}

.stat__value {
  font: 800 clamp(30px, 4.4vw, 46px)/1 var(--font-display);
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #fff 10%, var(--ice) 50%, var(--corn));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.stat__label {
  margin-top: 12px;
  font: 500 11.5px/1.3 var(--font-display);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.features {
  display: grid;
  gap: 32px;
  margin-top: clamp(48px, 7vw, 80px);
}

@media (min-width: 760px) {
  .features {
    grid-template-columns: repeat(3, 1fr);
    gap: 40px;
  }
}

.feature__icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 20px;
  font-size: 20px;
  color: var(--ice);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(var(--glow-rgb), 0.22), transparent 70%);
}

.feature h3 {
  font-size: 18px;
  letter-spacing: 0.08em;
}

.feature p {
  margin-top: 10px;
  font-size: 15.5px;
}

.reviews {
  display: grid;
  gap: 18px;
  margin-top: clamp(48px, 7vw, 80px);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
}

.reviews--flush {
  margin-top: 0;
}

.rating-summary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px 16px;
  margin: -16px 0 44px;
  font-size: 15px;
}

.rating-summary strong {
  font: 700 18px/1 var(--font-display);
  color: var(--text);
}

.review {
  --cut: 14px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  height: 100%;
  padding: 24px;
}

.review__text {
  flex: 1;
  font-size: 15.5px;
  color: var(--text);
}

.review__image {
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border: 1px solid var(--line);
}

.review__reply {
  padding-left: 14px;
  font-size: 14px;
  color: var(--text-faint);
  border-left: 1px solid var(--line-strong);
}

.review__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
  color: var(--text-faint);
}

/* Ratings in moons, not stars. */
.moons {
  display: inline-flex;
  gap: 4px;
  font-size: 15px;
  color: rgba(var(--glow-rgb), 0.22);
}

.moons .is-lit {
  color: var(--ice);
  filter: drop-shadow(0 0 5px rgba(var(--ice-rgb), 0.65));
}

.discord {
  --cut: 22px;
  --fill: linear-gradient(120deg, rgba(20, 32, 72, 0.92), rgba(8, 13, 30, 0.92));
  display: grid;
  gap: 24px;
  align-items: center;
  margin-top: clamp(48px, 7vw, 80px);
  padding: clamp(28px, 4vw, 44px);
}

@media (min-width: 760px) {
  .discord {
    grid-template-columns: 1fr auto;
  }
}

.discord h3 {
  font-size: clamp(24px, 3vw, 32px);
}

.discord p {
  max-width: 34em;
  margin-top: 10px;
}

/* 12. FAQ
   ========================================================================== */
.faq {
  max-width: 820px;
  margin-inline: auto;
}

.faq__item {
  position: relative;
  border-bottom: 1px solid var(--line);
}

.faq__item:first-child {
  border-top: 1px solid var(--line);
}

/* accent bar */
.faq__item::before {
  content: "";
  position: absolute;
  left: 0;
  top: -1px;
  bottom: -1px;
  width: 2px;
  background: linear-gradient(180deg, var(--ice), var(--corn));
  box-shadow: 0 0 14px rgba(var(--glow-rgb), 0.9);
  opacity: 0;
  transition: opacity 260ms ease;
}

.faq__item.is-open::before {
  opacity: 1;
}

.faq__q {
  margin: 0;
  font: inherit;
  letter-spacing: 0;
  text-transform: none;
}

.faq__trigger {
  display: flex;
  align-items: center;
  gap: 16px;
  width: 100%;
  padding: 22px 8px 22px 20px;
  font: 600 17px/1.35 var(--font-display);
  letter-spacing: 0.03em;
  text-align: left;
  color: var(--text);
  transition: color 200ms ease;
}

.faq__trigger > .icon {
  font-size: 13px;
  color: var(--text-faint);
  transition: color 240ms ease;
}

.faq__item.is-open .faq__trigger {
  color: var(--ice);
}

.faq__item.is-open .faq__trigger > .icon {
  color: var(--ice);
}

.faq__trigger span:first-of-type {
  flex: 1;
}

/* plus that collapses to a minus */
.faq__sign {
  position: relative;
  flex: none;
  width: 14px;
  height: 14px;
  color: var(--glow);
}

.faq__sign::before,
.faq__sign::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1.5px;
  margin-top: -0.75px;
  background: currentColor;
  transition: transform 300ms var(--ease-out);
}

.faq__sign::after {
  transform: rotate(90deg);
}

.faq__item.is-open .faq__sign::after {
  transform: rotate(0deg);
}

/* Height is animated with the grid 0fr -> 1fr trick: no JS measuring, and it
   stays correct if the answer reflows. Without JS every panel is simply open. */
.js .faq__panel {
  display: grid;
  grid-template-rows: 0fr;
  visibility: hidden;
  transition: grid-template-rows 200ms ease, visibility 0s 200ms;
}

.js .faq__item.is-open .faq__panel {
  grid-template-rows: 1fr;
  visibility: visible;
  transition: grid-template-rows 320ms var(--ease-out), visibility 0s;
}

.faq__panel-inner {
  min-height: 0;
  overflow: hidden;
}

.faq__answer {
  padding: 0 44px 26px 49px;
  font-size: 16px;
}

.js .faq__answer {
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 160ms ease, transform 160ms ease;
}

.js .faq__item.is-open .faq__answer {
  opacity: 1;
  transform: none;
  transition: opacity 320ms ease 60ms, transform 320ms var(--ease-out) 60ms;
}

@media (hover: hover) and (pointer: fine) {
  .faq__trigger:hover {
    color: var(--ice);
  }
}

/* 13. Footer
   ========================================================================== */
.footer {
  margin-top: var(--section-y);
  padding-bottom: 40px;
}

.footer__grid {
  display: grid;
  gap: 40px;
  padding-block: clamp(48px, 7vw, 72px);
}

@media (min-width: 760px) {
  .footer__grid {
    grid-template-columns: 1.5fr repeat(3, 1fr);
    gap: 48px;
  }
}

.footer__brand img {
  width: 170px;
  height: auto;
  margin-left: -8px;
}

.footer__brand p {
  max-width: 26em;
  margin-top: 16px;
  font-size: 15px;
}

.footer h2 {
  margin-bottom: 18px;
  font-size: 12px;
  letter-spacing: 0.24em;
  color: var(--text-faint);
}

.footer__list {
  display: grid;
  gap: 4px;
}

.footer__list a {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 36px;
  font-size: 15px;
  color: var(--text-dim);
  transition: color 200ms ease;
}

.footer__list .icon--social {
  font-size: 16px;
}

.footer__list .icon {
  font-size: 11px;
  color: rgba(var(--glow-rgb), 0.5);
  transition: color 200ms ease, transform 260ms var(--ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .footer__list a:hover {
    color: var(--ice);
  }

  .footer__list a:hover .icon {
    color: var(--ice);
    transform: rotate(-18deg);
  }
}

.footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 12px;
  padding-top: 28px;
  font-size: 13.5px;
  color: var(--text-faint);
  border-top: 1px solid var(--line);
}

/* 14. Prose / misc
   ========================================================================== */
.page-title {
  font-size: clamp(34px, 5.4vw, 60px);
}

.prose {
  max-width: 760px;
  font-size: 16.5px;
}

.prose > * + * {
  margin-top: 1.1em;
}

.prose h1,
.prose h2,
.prose h3,
.prose h4 {
  margin-top: 1.9em;
  font-size: 20px;
  letter-spacing: 0.08em;
}

.prose h1:first-child,
.prose h2:first-child,
.prose h3:first-child {
  margin-top: 0;
}

.prose a {
  color: var(--glow);
  text-decoration: underline;
  text-decoration-color: rgba(var(--glow-rgb), 0.4);
  text-underline-offset: 3px;
  transition: color 200ms ease, text-decoration-color 200ms ease;
}

.prose strong {
  font-weight: 600;
  color: var(--text);
}

.prose ul,
.prose ol {
  padding-left: 1.3em;
}

.prose li + li {
  margin-top: 0.4em;
}

.prose li::marker {
  color: var(--glow);
}

.prose img {
  height: auto;
  border: 1px solid var(--line);
}

.prose code {
  padding: 2px 6px;
  font-size: 0.9em;
  color: var(--ice);
  background: rgba(var(--glow-rgb), 0.1);
}

@media (hover: hover) and (pointer: fine) {
  .prose a:hover {
    color: var(--ice);
    text-decoration-color: currentColor;
  }
}

.maintenance {
  display: grid;
  place-items: center;
  min-height: 100dvh;
  padding: 40px var(--gutter);
  text-align: center;
}

.maintenance .eyebrow {
  justify-content: center;
}

.maintenance__text {
  margin-top: 16px;
  font-size: 17px;
}

.maintenance img {
  width: min(420px, 78vw);
  margin: 0 auto 28px;
}

/* Group dialog. Centred, so it scales from its centre (it is not anchored to
   a trigger). Enter 260ms, exit 160ms: slow in, fast out. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: grid;
  place-items: start center;
  padding: clamp(16px, 6vh, 72px) var(--gutter);
  overflow-y: auto;
}

.modal__scrim {
  position: fixed;
  inset: 0;
  background: rgba(1, 3, 8, 0.78);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.modal__panel {
  --cut: 22px;
  --fill: rgba(7, 12, 28, 0.97);
  width: min(100%, 1180px);
  padding: clamp(20px, 3vw, 36px);
}

.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
}

.modal__head h3 {
  font-size: clamp(22px, 3vw, 30px);
}

.modal__x {
  position: relative;
  width: 18px;
  height: 18px;
}

.modal__x::before,
.modal__x::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 0;
  width: 100%;
  height: 1.5px;
  background: currentColor;
  transform: rotate(45deg);
}

.modal__x::after {
  transform: rotate(-45deg);
}

/* Alpine x-transition hooks (see snippets/group-modals.njk) */
.modal-t {
  transition: opacity 260ms var(--ease-out), transform 260ms var(--ease-out);
}

.modal-t--out {
  transition-duration: 160ms;
  transition-timing-function: ease;
}

.modal-t.is-from {
  opacity: 0;
}

.modal__panel.modal-t.is-from {
  transform: translateY(10px) scale(0.97);
}

/* `.starter`: pages still rendered by SellAuth's own markup (cart, product
   form, customer area, blog, status). The --cl-* tokens in master.njk already
   give them the palette; this just pulls their shapes and type toward Tsuki.
   Deliberately shallow: it restyles, it never hides or moves anything, so the
   starter's functionality cannot be broken from here. */
.starter {
  padding-bottom: 24px;
  font-family: var(--font-body);
  color: var(--text-dim);
}

.starter h1,
.starter h2,
.starter h3 {
  font-family: var(--font-display);
  letter-spacing: 0.04em;
}

.starter .rounded-lg,
.starter .rounded-md,
.starter .rounded {
  border-radius: 3px;
}

.starter .bg-card {
  background-color: var(--surface);
}

.starter .border-white\/5 {
  border-color: var(--line);
}

.starter a:not([class]) {
  color: var(--glow);
}

.starter button,
.starter [type="submit"] {
  font-family: var(--font-display);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.starter input,
.starter select,
.starter textarea {
  font-family: var(--font-body);
  letter-spacing: 0;
  text-transform: none;
}

.starter :focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 2px;
}

/* Customer area (and the other starter pages): the shared building blocks.
   Panels, sidebar, stat labels and numbers, tables, buttons, fields. All
   scoped to .starter, which master.njk puts on every page that still uses
   SellAuth's own markup, so none of this reaches Tsuki pages. */
.starter > .container {
  max-width: none;
  padding: 0;
}

.starter > .container > .relative {
  padding-inline: 0;
}

/* panels: a faint moonlit top edge */
.starter .bg-card.border {
  background-color: var(--surface);
  border-color: var(--line);
  box-shadow: inset 0 1px 0 rgba(var(--ice-rgb), 0.07);
}

/* a panel's own title is a quiet label, so the value under it leads */
.starter .bg-card > h3 {
  font: 600 11.5px/1.3 var(--font-display);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.starter .text-2xl.font-semibold {
  font: 700 clamp(22px, 2.4vw, 28px)/1.15 var(--font-display);
  letter-spacing: 0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* sidebar navigation */
.starter .lg\:flex-1 > .bg-card h3 {
  font-size: 17px;
  letter-spacing: 0.08em;
}

.starter .lg\:flex-1 ul {
  gap: 2px;
}

.starter .lg\:flex-1 ul > li > a,
.starter .lg\:flex-1 ul > li > button {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 40px;
  padding: 0 0 0 14px;
  font: 600 12.5px/1 var(--font-display);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-dim);
  transition: color 200ms ease;
}

.starter .lg\:flex-1 ul > li > a.text-accent-500 {
  color: var(--ice);
}

/* the current page gets the glowing bar used for open FAQ answers */
.starter .lg\:flex-1 ul > li > a.text-accent-500::before {
  content: "";
  position: absolute;
  top: 9px;
  bottom: 9px;
  left: 0;
  width: 2px;
  background: linear-gradient(180deg, var(--ice), var(--corn));
  box-shadow: 0 0 12px rgba(var(--glow-rgb), 0.9);
}

.starter .lg\:flex-1 ul > li > button[\@click="appCustomer.logout()"] {
  color: var(--text-faint);
}

/* tables */
.starter table {
  border-collapse: collapse;
}

.starter thead {
  background: rgba(var(--glow-rgb), 0.05);
}

.starter th {
  font: 600 11px/1.2 var(--font-display);
  letter-spacing: 0.18em;
  color: var(--text-faint);
}

.starter tbody tr {
  border-color: var(--line);
  transition: background-color 200ms ease;
}

.starter td a.text-accent-500 {
  font-family: var(--font-display);
  letter-spacing: 0.04em;
}

/* primary buttons and button-links: the moonlight gradient */
.starter button.bg-accent-500,
.starter a.bg-accent-500 {
  position: relative;
  isolation: isolate;
  color: #041024;
  background: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
  border-color: transparent;
  border-radius: 3px;
  box-shadow: 0 0 16px rgba(var(--glow-rgb), 0.28);
  transition: transform 160ms var(--ease-out);
}

.starter button.bg-accent-500::after,
.starter a.bg-accent-500::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: #fff;
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}

.starter button.bg-accent-500:active:not(:disabled),
.starter a.bg-accent-500:active {
  transform: scale(0.97);
}

/* fields */
.starter input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.starter select,
.starter textarea {
  color: var(--text);
  background-color: rgba(3, 6, 15, 0.7);
  border: 1px solid var(--line-strong);
  border-radius: 3px;
  transition: border-color 200ms ease;
}

.starter input:focus,
.starter select:focus,
.starter textarea:focus {
  border-color: var(--ice);
  outline: 2px solid rgba(var(--ice-rgb), 0.35);
  outline-offset: 1px;
  box-shadow: none;
}

.starter .text-accent-500 {
  color: var(--glow);
}

@media (hover: hover) and (pointer: fine) {
  .starter .lg\:flex-1 ul > li > a:hover,
  .starter .lg\:flex-1 ul > li > button:hover {
    color: var(--text);
  }

  .starter tbody tr:hover {
    background: rgba(var(--glow-rgb), 0.035);
  }

  .starter button.bg-accent-500:hover:not(:disabled),
  .starter a.bg-accent-500:hover {
    background: linear-gradient(135deg, var(--ice), var(--glow) 45%, var(--corn));
  }

  .starter button.bg-accent-500:hover:not(:disabled)::after,
  .starter a.bg-accent-500:hover::after {
    opacity: 0.16;
  }
}

/* Rich text from the SellAuth editor (product descriptions, blog posts).
   The editor emits .e-paragraph / .e-heading-* / .e-list-* classes, which the
   starter's built.css styles. This is only the fallback for bare elements
   (pasted or hand-written HTML); the starter's two-class rules outrank it. */
.editor {
  font-size: 16px;
  line-height: 1.65;
  color: var(--text-dim);
}

.editor > * + * {
  margin-top: 0.9em;
}

.editor h1,
.editor h2,
.editor h3,
.editor h4 {
  margin-top: 1.7em;
  font-size: 18px;
  letter-spacing: 0.08em;
}

.editor ul {
  padding-left: 1.3em;
  list-style: disc;
}

.editor ol {
  padding-left: 1.3em;
  list-style: decimal;
}

.editor li + li {
  margin-top: 0.35em;
}

.editor li::marker {
  color: var(--glow);
}

.editor a {
  color: var(--glow);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.editor strong {
  font-weight: 600;
  color: var(--text);
}

/* 15. Motion preferences
   Reduced motion means calmer, not dead: colour and opacity feedback stays,
   everything that travels, loops or flickers goes.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  .tw,
  .moon__halo,
  .cloud,
  .shooting-star,
  .hero__scroll span,
  .js .hero__inner > * {
    animation: none;
  }

  .tw { opacity: 0.7; }
  .shooting-star { display: none; }

  .pp__live-dot::after,
  .pp__status-dot .pulsating {
    animation: none;
  }

  .card,
  .card__media img,
  .btn,
  .btn .icon,
  .card__cta .icon,
  .footer__list .icon,
  .chip {
    transition-property: color, opacity, border-color, background-color;
  }

  .card:hover,
  .card:hover .card__media img,
  .btn:active,
  .chip:active,
  .cartx button:active:not(:disabled),
  .loginx button:active:not(:disabled),
  .starter button.bg-accent-500:active:not(:disabled),
  .starter a.bg-accent-500:active,
  .pp .pp-form button:active:not(:disabled),
  .pp .pp-form label[for="variant"] + div > button:active:not(:disabled) {
    transform: none;
  }

  .modal__panel.modal-t.is-from {
    transform: none;
  }

  .nav__sheet,
  .nav.is-open .nav__sheet {
    transform: none;
    transition: opacity 160ms ease, visibility 0s;
  }

  .js .faq__panel,
  .js .faq__item.is-open .faq__panel {
    transition: none;
  }

  .js .faq__answer {
    transform: none;
  }
}

/* Inside SellAuth's visual editor (and the staging preview, which renders the
   same way) the page body is re-rendered on every edit, so the hero's
   entrance would replay on each keystroke. The sky sits outside that area
   and keeps moving, so previews show it as customers will. */
.is-builder .hero__inner > * {
  animation: none;
}

/* Halve the twinklers on small screens: fewer layers, and a phone shows far
   less sky anyway. */
@media (max-width: 640px) {
  .tw:nth-child(2n) {
    display: none;
  }

  .cloud--far {
    display: none;
  }
}