@import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&display=swap');

/* SWITZER - the house display typeface, self-hosted (three weights), so
   there is no third-party font CDN in the critical path. */
@font-face {
  font-family: 'Switzer';
  src: url('/assets/fonts/Switzer-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('/assets/fonts/Switzer-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'Switzer';
  src: url('/assets/fonts/Switzer-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --font-display: 'Switzer', 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'Space Mono', ui-monospace, monospace;

  /* ============================================================
     AZPEX BRAND COLOR SYSTEM
     Warm Black / Bone White / Smoked Champagne / Muted Graphite.
     Every component binds to these. Roughly 80% warm black and dark
     surfaces, 15% bone white and neutral greys, 5% champagne accent.
     The accent is matte and smoked, never a saturated gold.
     ============================================================ */

  /* Backgrounds */
  --azpex-bg:             #0F0D0B;
  --azpex-bg-soft:        #151310;
  --azpex-surface:        #1B1815;
  --azpex-surface-raised: #211D19;

  /* Borders */
  --azpex-border:      #302A24;
  --azpex-border-soft: #24201C;

  /* Text */
  --azpex-text-primary:   #EEE9E1;
  --azpex-text-secondary: #A9A199;
  --azpex-text-muted:     #6F6861;

  /* Brand accent */
  --azpex-accent:        #C8A37D;
  --azpex-accent-bright: #DDB98E;
  --azpex-accent-dark:   #8A6B4F;

  /* Interaction */
  --azpex-hover:    #F3EEE6;
  --azpex-disabled: #48413B;

  /* Translucent overlays derived from the accent and bone white. */
  --azpex-accent-wash:   rgba(200, 163, 125, 0.07);
  --azpex-accent-veil:   rgba(200, 163, 125, 0.16);
  --azpex-scrim:         rgba(9, 8, 7, 0.78);
  --azpex-error:         #D8654E;

  /* Decorative muted text can stay dim. Small text that must be READ gets
     this lighter step instead, so information never sits at background
     contrast. */
  --azpex-text-muted-readable: #8E867E;

  /* ---- Legacy aliases -------------------------------------------------
     The site was built against these names. They now resolve to the brand
     tokens above so there is a single source of truth, not two systems. */
  --text-primary:   var(--azpex-text-primary);
  --text-secondary: var(--azpex-text-secondary);
  --text-muted:     var(--azpex-text-muted);

  --gold:       var(--azpex-accent);
  --gold2:      var(--azpex-accent-bright);
  --gold-vivid: var(--azpex-accent-bright);
  --hair:       var(--azpex-border);
  --hair-soft:  var(--azpex-border-soft);
  --ink:        var(--azpex-bg);

  /* ============================================================
     AZPEX MOTION SYSTEM
     Slow, weighted, tactile, cinematic, controlled, premium.
     ============================================================ */
  --motion-fast:   180ms;
  --motion-medium: 420ms;
  --motion-slow:   760ms;

  --ease-ui:    cubic-bezier(0.22, 1, 0.36, 1);
  --ease-heavy: cubic-bezier(0.16, 1, 0.3, 1);

  --depth-low:    8px;
  --depth-medium: 18px;
  --depth-high:   30px;

  --tilt-card:     4deg;
  --tilt-featured: 5deg;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }

/* Soft cross-page transition: fade the current page to the shared dark
   background just before navigating away, instead of the harsh instant
   swap a normal multi-page site gives you. See assets/js/page-transition.js. */
body { font-family: var(--font-display); transition: opacity .3s cubic-bezier(.16,1,.3,1); }
body.is-leaving { opacity: 0; }

/* Animations */
@keyframes grain {
  0%,100%{transform:translate(0,0)} 11%{transform:translate(-1%,1.5%)}
  22%{transform:translate(1.5%,-1%)} 33%{transform:translate(-1.5%,2%)}
  44%{transform:translate(1%,-1.5%)} 55%{transform:translate(-2%,.5%)}
  66%{transform:translate(.5%,2%)} 77%{transform:translate(-1%,-1.5%)}
  88%{transform:translate(2%,.5%)}
}
@keyframes up { from{opacity:0;transform:translateY(30px)} to{opacity:1;transform:none} }
@keyframes fi { from{opacity:0} to{opacity:1} }
@keyframes scroll-bar {
  0%{transform:scaleY(0);transform-origin:top}
  48%{transform:scaleY(1);transform-origin:top}
  52%{transform:scaleY(1);transform-origin:bottom}
  100%{transform:scaleY(0);transform-origin:bottom}
}
@keyframes ddIn { from{opacity:0;transform:translateY(-6px)} to{opacity:1;transform:translateY(0)} }
@keyframes mobIn { from{opacity:0;transform:translateY(-8px)} to{opacity:1;transform:translateY(0)} }
.az-up   { opacity:0; animation:up .9s cubic-bezier(.16,1,.3,1) forwards; }
.az-fi   { opacity:0; animation:fi 1.1s cubic-bezier(.16,1,.3,1) forwards; }
.d1{animation-delay:.08s} .d2{animation-delay:.18s} .d3{animation-delay:.30s}
.d4{animation-delay:.44s} .d5{animation-delay:.60s} .d8{animation-delay:1.3s}

/* Grain + vignette */
.grain {
  position:fixed; top:-50%; left:-50%; width:200%; height:200%;
  pointer-events:none; z-index:60; opacity:.05; mix-blend-mode:overlay;
  animation:grain 9s steps(1,end) infinite;
  background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 500 500' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2.4' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
.vig {
  position:fixed; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(ellipse 85% 85% at 50% 50%,transparent 38%,rgba(18,12,7,.34) 100%);
}
/* .warm-wash markup stays in every page's HTML (harmless empty div) but is
   intentionally not styled here any more. A single viewport-fixed light was
   tried in this spot: it solved section-boundary seams (one element, no
   per-section edges), but it created a new problem instead - its brightest
   point sat at a fixed distance from the top of the SCREEN rather than from
   any actual content, which produced a hard, visible horizontal band right
   under the fixed header (where the header's own blurred background met
   the glow behind it), and the light no longer moved with the page as you
   scrolled - it stayed pinned to the screen while the content it was meant
   to be lighting scrolled past underneath it. Real light now comes from
   AMBIENT_GLOW below - shared, identical, very low-alpha values applied to
   every section so it scrolls naturally with that section's own content and
   reads as one continuous, barely-there warmth rather than a lit corner. */

/* Layout */
.wrap { max-width:1480px; margin-inline:auto; padding-inline:clamp(28px,5vw,88px); }

/* HEADER */
.hdr {
  position:fixed; top:0; left:0; right:0; z-index:100;
  border-bottom:1px solid rgba(237,233,225,.05);
  background:rgba(19,17,15,.66); backdrop-filter:blur(16px) saturate(120%);
  -webkit-backdrop-filter:blur(16px) saturate(120%);
}
.hdr-in {
  max-width:1480px; margin-inline:auto; min-height:68px;
  padding-inline:clamp(28px,5vw,88px);
  display:flex; align-items:center; gap:4px;
}
.brand {
  display:flex; align-items:center; gap:9px;
  font-family:var(--font-display); font-weight:700; font-size:.98rem;
  letter-spacing:.012em; color:var(--azpex-text-primary); text-decoration:none; margin-right:auto;
  transition:color .32s cubic-bezier(.16,1,.3,1);
}
.brand:hover { color:var(--azpex-accent); }
.brand-mark {
  display:block; width:21px; height:27px; flex-shrink:0; margin-top:-1px;
  background-color: currentColor; /* follows .brand's own color/hover, same as the wordmark */
  -webkit-mask-image: url('/assets/images/logo/azpex-logo-mask.png');
          mask-image: url('/assets/images/logo/azpex-logo-mask.png');
  -webkit-mask-size: contain; mask-size: contain;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
}
.brand-word { line-height:1; }
.nl {
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.08em;
  text-transform:uppercase; color:rgba(237,233,225,.92); padding:10px 13px;
  text-decoration:none; transition:color .32s cubic-bezier(.16,1,.3,1); white-space:nowrap;
  background:none; border:none; cursor:pointer;
}
.nl:hover { color:var(--azpex-hover); }
.nl.ac { color:var(--azpex-accent-bright); }
.nl.ac:hover { color:var(--azpex-accent-bright); }

/* Desktop nav */
.desk-nav { display:flex; align-items:center; gap:2px; }
@media(max-width:820px){ .desk-nav{ display:none!important; } }

/* FREE dropdown */
.free-wrap { position:relative; display:flex; align-items:center; }
.free-dd {
  position:absolute; top:calc(100% + 4px); left:50%; transform:translateX(-50%);
  background:rgba(10,10,11,.97); border:1px solid rgba(237,233,225,.08);
  backdrop-filter:blur(10px); min-width:188px; z-index:200;
  animation:ddIn .18s cubic-bezier(.16,1,.3,1) both;
}
.free-dd[hidden] { display:none; }
.free-dd-item {
  display:block; font-family:var(--font-mono); font-size:.66rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--azpex-text-muted);
  text-decoration:none; padding:11px 18px;
  transition:color .26s cubic-bezier(.16,1,.3,1), background .26s cubic-bezier(.16,1,.3,1);
  border-bottom:1px solid rgba(237,233,225,.05);
}
.free-dd-item:last-child { border-bottom:none; }
.free-dd-item:hover { color:var(--azpex-text-primary); background:rgba(237,233,225,.03); }
.free-dd-item:focus-visible { outline:1px solid rgba(156,123,78,.6); outline-offset:-1px; color:var(--azpex-text-primary); }

/* Hamburger (mobile) */
.ham {
  display:none; flex-direction:column; gap:5px; justify-content:center;
  width:38px; height:38px; background:none; border:none; cursor:pointer;
  padding:6px; margin-left:auto;
}
@media(max-width:820px){ .ham{ display:flex; } }
.ham-bar {
  width:22px; height:1px; background:var(--azpex-text-primary);
  transition:transform .28s cubic-bezier(.16,1,.3,1), opacity .22s ease;
  display:block;
}
.ham-bar.open:nth-child(1){ transform:translateY(6px) rotate(45deg); }
.ham-bar.open:nth-child(2){ opacity:0; }
.ham-bar.open:nth-child(3){ transform:translateY(-6px) rotate(-45deg); }

/* Mobile nav overlay */
.mob-nav {
  background:rgba(8,8,9,.97); border-top:1px solid rgba(237,233,225,.06);
  padding:8px 0 12px;
  animation:mobIn .2s cubic-bezier(.16,1,.3,1) both;
}
.mob-nav[hidden] { display:none; }
.mob-nl {
  display:block; font-family:var(--font-mono); font-size:.7rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--azpex-text-muted);
  text-decoration:none; padding:14px clamp(28px,5vw,88px);
  transition:color .2s ease;
  background:none; border:none; width:100%; text-align:left; cursor:pointer;
}
.mob-nl:hover { color:var(--azpex-text-primary); }
.mob-nl.ac { color:var(--azpex-accent); }
.mob-free-btn {
  display:flex; align-items:center; justify-content:space-between; width:100%;
}
.mob-free-icon { font-size:.7rem; color:var(--azpex-border); }
.mob-sub { background:rgba(255,255,255,.016); border-top:1px solid rgba(237,233,225,.04); }
.mob-sub[hidden] { display:none; }
.mob-sub a {
  display:block; font-family:var(--font-mono); font-size:.64rem;
  letter-spacing:.1em; text-transform:uppercase; color:var(--azpex-border);
  text-decoration:none; padding:12px clamp(40px,7vw,108px);
  transition:color .2s ease;
}
.mob-sub a:hover { color:var(--azpex-accent); }

/* HERO */
.hero {
  min-height:100svh; display:flex; flex-direction:column;
  align-items:center; justify-content:center; text-align:center;
  padding:100px clamp(20px,5vw,40px) 88px; position:relative; overflow:hidden;
}
/* Depth behind the object: a huge, barely-there wordmark and a warm glow, so
   the object sits inside a lit space instead of floating on flat black. */
.hero-bg { position:absolute; inset:0; pointer-events:none; overflow:hidden; z-index:0; }
/* Ambient base texture only: pushed low and kept barely-there so it reads as
   a faint watermark behind the object, never as a title competing with it.
   It also eases in AFTER the object (.az-word) so the 3D piece owns the very
   first paint. */
.hero-word {
  position:absolute; top:62%; left:50%; transform:translate(-50%,-50%);
  font-family:var(--font-display); font-weight:700; font-size:min(33vw,470px);
  letter-spacing:-.05em; line-height:1; white-space:nowrap;
  color:var(--azpex-text-primary); opacity:.013; user-select:none;
  -webkit-mask-image:linear-gradient(180deg, transparent 0%, #000 42%, #000 70%, transparent 100%);
          mask-image:linear-gradient(180deg, transparent 0%, #000 42%, #000 70%, transparent 100%);
}
.az-word { opacity:0; animation:wordFade 1.8s ease .85s forwards; }
@keyframes wordFade { from { opacity:0; } to { opacity:.013; } }
.hero-glow {
  position:absolute; top:41%; left:50%; transform:translate(-50%,-50%);
  width:min(128vw,1220px); height:min(128vw,1220px);
  background:radial-gradient(circle,
    rgba(201,163,122,.185) 0%, rgba(201,163,122,.066) 32%, transparent 60%);
}
.hero-stage {
  position:relative; z-index:2; width:100%; max-width:1040px; margin:0 auto;
  display:flex; flex-direction:column; align-items:center;
}
.eyebrow {
  display:inline-flex; align-items:center; justify-content:center; gap:14px;
  font-family:var(--font-mono); font-size:.66rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--azpex-text-muted); margin-bottom:6px;
}
.eyebrow-bar { width:44px; height:1px; background:var(--azpex-accent-dark); flex-shrink:0; }
h1.hero-h1 {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2.5rem,5.6vw,5.6rem);
  line-height:1; letter-spacing:-.035em; color:var(--azpex-text-primary);
  max-width:20ch; margin:clamp(-3rem,-2.6vw,-1.2rem) auto 22px; position:relative; z-index:3;
}
h1.hero-h1 em { font-style:normal; color:var(--azpex-accent); }
.hero-sub {
  font-size:clamp(1rem,1.2vw,1.2rem); color:var(--azpex-text-secondary);
  max-width:60ch; line-height:1.66; margin:0 auto 40px;
}
.hero-btns { display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:26px; }
.hero-textlink {
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--text-secondary); text-decoration:none; position:relative; padding-bottom:4px;
}
.hero-textlink::after {
  content:''; position:absolute; left:0; bottom:0; width:100%; height:1px;
  background:currentColor; opacity:.6; transform:scaleX(0); transform-origin:left;
  transition:transform .34s cubic-bezier(.16,1,.3,1);
}
.hero-textlink:hover { color:var(--text-primary); }
.hero-textlink:hover::after { transform:scaleX(1); }
.btn-p {
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.1em; text-transform:uppercase;
  background:var(--azpex-text-primary); color:var(--azpex-bg); border:1px solid var(--azpex-text-primary);
  padding:14px 26px; min-height:46px; text-decoration:none;
  display:inline-flex; align-items:center; gap:10px;
  transition:background .36s cubic-bezier(.16,1,.3,1),border-color .36s cubic-bezier(.16,1,.3,1),color .36s cubic-bezier(.16,1,.3,1),transform .36s cubic-bezier(.16,1,.3,1),box-shadow .36s cubic-bezier(.16,1,.3,1);
}
.btn-p:hover { background:var(--azpex-accent); border-color:var(--azpex-accent); color:var(--azpex-bg); transform:translateY(-1px); box-shadow:0 8px 24px rgba(156,123,78,.22); }
.btn-g {
  font-family:var(--font-mono); font-size:.74rem; letter-spacing:.1em; text-transform:uppercase;
  background:transparent; color:var(--azpex-text-primary); border:1px solid rgba(237,233,225,.12);
  padding:14px 26px; min-height:46px; text-decoration:none;
  display:inline-flex; align-items:center;
  transition:border-color .36s cubic-bezier(.16,1,.3,1),transform .36s cubic-bezier(.16,1,.3,1);
}
.btn-g:hover { border-color:rgba(237,233,225,.38); transform:translateY(-1px); }

/* Frequency object - the hero centrepiece */
.freq-hero {
  position:relative; width:min(84vw,560px); height:min(84vw,560px);
  max-height:48svh; margin:0 auto;
}
/* Soft pool of light the object appears to rest on. */
.hero-floor {
  position:absolute; left:50%; bottom:4%; transform:translateX(-50%);
  width:64%; height:54px; pointer-events:none;
  background:radial-gradient(ellipse at center, rgba(201,163,122,.18) 0%, rgba(201,163,122,.05) 45%, transparent 72%);
  filter:blur(3px);
}
/* Object entrance: rises and settles into place on load. */
@keyframes heroRise { from { opacity:0; transform:translateY(26px) scale(.94); } to { opacity:1; transform:none; } }
.az-rise { opacity:0; animation:heroRise 1.35s cubic-bezier(.16,1,.3,1) 0s forwards; }

.scroll-ind {
  position:absolute; bottom:32px; left:50%; transform:translateX(-50%);
  display:flex; flex-direction:column; align-items:center; gap:8px;
}
.scroll-lbl { font-family:var(--font-mono); font-size:.58rem; letter-spacing:.22em; text-transform:uppercase; color:var(--azpex-border); }
.scroll-bar { width:1px; height:44px; background:linear-gradient(to bottom,var(--azpex-accent-dark),transparent); animation:scroll-bar 2.6s ease-in-out infinite; }

/* FEATURED PRODUCTS */
.feat {
  border-top:1px solid rgba(237,233,225,.04);
  padding-bottom:clamp(52px,7vw,96px);
}
.feat-grid {
  display:grid; grid-template-columns:1fr 1fr;
  border-top:1px solid rgba(237,233,225,.05);
}

/* Horizontal card */
.prod-panel {
  display:flex; flex-direction:row; align-items:stretch;
  border-right:1px solid rgba(237,233,224,.05);
  padding:clamp(32px,4vw,56px) clamp(28px,4vw,56px);
  gap:clamp(24px,3vw,44px);
}
.prod-panel:last-child { border-right:none; }

/* Art frame */
.prod-art-wrap {
  flex-shrink:0;
  width:clamp(160px,14vw,210px);
  display:flex; align-items:flex-start; justify-content:center;
}
.prod-cover {
  display:block;
  width:100%;
  height:auto;
  object-fit:contain;
  object-position:top center;
  box-shadow:0 10px 44px rgba(0,0,0,.6);
}

/* TiltCard wrapper */
.tilt-card {
  display:inline-block;
  position:relative;
  will-change:transform;
  transition:transform .65s cubic-bezier(.23,1,.32,1);
}

/* Play button overlay on artwork */
.prod-play-btn {
  position:absolute; top:50%; left:50%; transform:translate(-50%,-50%);
  width:52px; height:52px; border-radius:50%;
  background:rgba(8,8,9,.72); border:1px solid rgba(237,233,225,.28);
  backdrop-filter:blur(6px); -webkit-backdrop-filter:blur(6px);
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; padding:0;
  transition:background .22s ease,border-color .22s ease,transform .22s ease;
}
.prod-play-btn:hover:not(.is-disabled) {
  background:rgba(156,123,78,.85); border-color:var(--azpex-accent);
  transform:translate(-50%,-50%) scale(1.06);
}
.prod-play-btn .play-ico {
  width:0; height:0;
  border-top:8px solid transparent; border-bottom:8px solid transparent;
  border-left:13px solid var(--azpex-text-primary); margin-left:3px;
}
.prod-play-btn.is-playing .play-ico {
  width:11px; height:14px; border:none; margin-left:0;
  background:
    linear-gradient(var(--azpex-text-primary),var(--azpex-text-primary)) 0 0/3px 14px no-repeat,
    linear-gradient(var(--azpex-text-primary),var(--azpex-text-primary)) 8px 0/3px 14px no-repeat;
}
.prod-play-btn.is-disabled {
  cursor:not-allowed; opacity:.55;
}
.prod-play-btn.is-disabled .play-ico { border-left-color:var(--azpex-text-secondary); }

/* Tiny EQ animation on artwork while playing */
.prod-eq {
  position:absolute; bottom:14px; left:14px;
  display:none; align-items:flex-end; gap:3px; height:16px;
}
.prod-art-wrap.is-playing .prod-eq,
.prod-art-wrap:has(.prod-play-btn.is-playing) .prod-eq { display:flex; }
.prod-eq span {
  width:3px; background:var(--azpex-accent); border-radius:1px;
  animation:eqBounce .9s ease-in-out infinite;
}
.prod-eq span:nth-child(1){ height:6px;  animation-delay:-0.6s; }
.prod-eq span:nth-child(2){ height:14px; animation-delay:-0.2s; }
.prod-eq span:nth-child(3){ height:9px;  animation-delay:-0.9s; }
.prod-eq span:nth-child(4){ height:16px; animation-delay:-0.4s; }
@keyframes eqBounce { 0%,100%{transform:scaleY(.35)} 50%{transform:scaleY(1)} }

/* Preview / audio player panel. This is one of the only three places the
   product page is allowed a border (panel, primary CTA, final CTA) - see the
   product-page block near the end of this file. */
.prod-preview {
  border:1px solid var(--hair);
  background:rgba(255,255,255,.016);
  border-radius:10px; padding:18px 20px; margin-bottom:0;
}
/* Category tabs read as tabs, not as pills in boxes: an underline on the
   active one instead of a filled chip, so the panel keeps one border total. */
.preview-cats {
  display:flex; flex-wrap:wrap; gap:4px; margin-bottom:18px;
  border-bottom:1px solid var(--hair-soft);
}
.preview-cat {
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--text-muted); background:transparent;
  border:none; border-bottom:1px solid transparent;
  padding:8px 12px 10px; cursor:pointer; margin-bottom:-1px;
  transition:color .2s ease, border-color .2s ease;
}
.preview-cat:hover { color:var(--text-secondary); }
.preview-cat.is-active { color:var(--text-primary); border-bottom-color:var(--gold); }
.preview-track { display:flex; align-items:center; gap:12px; }
.preview-playpause {
  flex-shrink:0; width:38px; height:38px; border-radius:50%;
  background:rgba(201,163,122,.1); border:1px solid rgba(201,163,122,.32);
  display:flex; align-items:center; justify-content:center;
  cursor:pointer; padding:0; transition:background .2s ease,border-color .2s ease,box-shadow .2s ease;
}
.preview-playpause:hover:not(:disabled) { border-color:var(--azpex-accent); box-shadow:0 0 0 5px rgba(201,163,122,.12); }
.preview-playpause .play-ico {
  width:0; height:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:8px solid var(--azpex-text-primary); margin-left:2px;
}
.preview-playpause.is-playing .play-ico {
  width:7px; height:9px; border:none; margin-left:0;
  background:
    linear-gradient(var(--azpex-text-primary),var(--azpex-text-primary)) 0 0/2px 9px no-repeat,
    linear-gradient(var(--azpex-text-primary),var(--azpex-text-primary)) 5px 0/2px 9px no-repeat;
}
.preview-playpause:disabled { cursor:not-allowed; opacity:.5; }
.preview-meta { flex:1; min-width:0; }
.preview-track-name {
  display:block; font-family:var(--font-mono); font-size:.68rem;
  letter-spacing:.04em; color:var(--azpex-text-primary); margin-bottom:8px;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.preview-bar { height:3px; background:rgba(237,233,225,.1); position:relative; }
.preview-bar-fill { height:100%; width:0%; background:var(--azpex-accent-dark); transition:width .1s linear; }
.preview-time {
  flex-shrink:0; font-family:var(--font-mono); font-size:.6rem;
  color:var(--azpex-text-muted); letter-spacing:.05em;
}
.prod-preview.is-unavailable { opacity:.6; }

.prod-info {
  display:flex; flex-direction:column; flex:1;
  padding-top:4px;
}
.prod-label {
  font-family:var(--font-mono); font-size:.58rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--azpex-border); margin-bottom:16px;
  display:flex; width:fit-content; align-items:center; gap:12px;
}
.prod-label::before { content:''; width:20px; height:1px; background:var(--azpex-accent-dark); flex-shrink:0; }
.prod-title {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.8rem,2.6vw,2.6rem); letter-spacing:-.026em; line-height:.96;
  color:var(--azpex-text-primary); margin-bottom:10px;
}
.prod-type {
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--azpex-accent-dark); margin-bottom:14px;
}
.prod-desc {
  font-size:clamp(.86rem,.92vw,.98rem); color:var(--azpex-text-secondary);
  max-width:44ch; line-height:1.7; margin-bottom:20px;
}
.prod-specs {
  display:flex; flex-wrap:wrap; gap:7px; margin-bottom:22px;
}
.prod-spec {
  font-family:var(--font-mono); font-size:.56rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--azpex-text-muted);
  border:1px solid rgba(237,233,225,.08); padding:5px 9px;
}
/* Footer group: price + CTA pinned together to the bottom of the info
   column, so the price never orphans away from its buttons and both
   featured panels' footers still line up on the same baseline. */
.prod-foot { margin-top:auto; padding-top:20px; }
.prod-cta {
  padding-top:6px;
  display:flex; align-items:center; gap:12px; flex-wrap:wrap;
}
.prod-btn {
  font-family:var(--font-mono); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase;
  background:var(--azpex-text-primary); color:var(--azpex-bg); border:1px solid var(--azpex-text-primary);
  padding:12px 20px; min-height:42px; text-decoration:none;
  display:inline-flex; align-items:center; gap:9px;
  transition:background .34s cubic-bezier(.16,1,.3,1),border-color .34s cubic-bezier(.16,1,.3,1),color .34s cubic-bezier(.16,1,.3,1),transform .34s cubic-bezier(.16,1,.3,1);
}
.prod-btn:hover { background:var(--azpex-accent); border-color:var(--azpex-accent); color:var(--azpex-bg); transform:translateY(-1px); }
.prod-btn-ghost {
  font-family:var(--font-mono); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase;
  background:transparent; color:var(--azpex-text-muted); border:1px solid rgba(237,233,225,.1);
  padding:12px 20px; min-height:42px; text-decoration:none;
  display:inline-flex; align-items:center; gap:9px;
  transition:border-color .34s cubic-bezier(.16,1,.3,1),color .34s cubic-bezier(.16,1,.3,1),transform .34s cubic-bezier(.16,1,.3,1);
}
.prod-btn-ghost:hover { border-color:rgba(237,233,225,.28); color:var(--azpex-text-primary); transform:translateY(-1px); }

/* Price - kept deliberately prominent per feedback: should never read as an
   afterthought next to the product copy. */
.price-row { display:flex; align-items:baseline; gap:12px; margin-bottom:18px; flex-wrap:wrap; }
.price-tag {
  font-family:var(--font-display); font-weight:700; font-size:1.35rem;
  color:var(--gold-vivid); letter-spacing:-.02em; line-height:1;
}
.price-note {
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--azpex-text-secondary);
}

/* Section header */
.sec-hd {
  display:flex; justify-content:space-between; align-items:baseline;
  gap:24px; flex-wrap:wrap; padding-bottom:24px;
  border-bottom:1px solid rgba(237,233,225,.06);
}
.sec-h2 {
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.4rem,2.4vw,1.9rem); letter-spacing:-.02em; color:var(--azpex-text-primary);
}
.sec-note { font-family:var(--font-mono); font-size:.6rem; letter-spacing:.14em; text-transform:uppercase; color:var(--azpex-border); }

/* Featured header */
.feat-hdr {
  padding:clamp(52px,6vw,80px) clamp(28px,5vw,88px) clamp(24px,3vw,40px);
  max-width:1480px; margin-inline:auto;
}

/* CATEGORIES */
.cats { border-top:1px solid rgba(237,233,225,.05); padding:clamp(72px,10vh,120px) 0; }
.cat-list { list-style:none; }
.cat-item { border-bottom:1px solid rgba(237,233,225,.05); }
.cat-link {
  display:flex; align-items:center; gap:clamp(12px,2.2vw,32px);
  padding:clamp(22px,3vh,34px) 0; text-decoration:none; color:inherit;
  position:relative; cursor:pointer;
  transition:padding-left .3s cubic-bezier(.16,1,.3,1);
}
.cat-link::after {
  content:''; position:absolute; bottom:-1px; left:0; right:0; height:1px;
  background:rgba(156,123,78,.35); transform:scaleX(0); transform-origin:left;
  transition:transform .5s cubic-bezier(.16,1,.3,1);
}
.cat-link:hover { padding-left:8px; }
.cat-link:hover::after { transform:scaleX(1); }
.cat-n { font-family:var(--font-mono); font-size:.6rem; letter-spacing:.14em; text-transform:uppercase; color:var(--azpex-border); flex-shrink:0; min-width:30px; }
.cat-name {
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.6rem,3.2vw,2.8rem); letter-spacing:-.02em;
  color:var(--azpex-text-primary); flex:1; transition:color .25s ease;
}
.cat-link:hover .cat-name { color:var(--azpex-accent); }
.cat-arr { font-family:var(--font-mono); font-size:.8rem; color:var(--azpex-border); flex-shrink:0; transition:transform .32s cubic-bezier(.16,1,.3,1),color .25s ease; margin-left:auto; }
.cat-link:hover .cat-arr { transform:translateX(7px); color:var(--azpex-accent); }

/* ABOUT */
.about { border-top:1px solid rgba(237,233,225,.05); padding:clamp(72px,10vh,120px) 0; }
.about-lead {
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.2rem,2.2vw,1.6rem); letter-spacing:-.02em;
  line-height:1.38; color:var(--azpex-text-primary); max-width:66ch; margin-bottom:28px;
}
.about-body { max-width:58ch; margin-bottom:64px; }
.about-body p { color:var(--azpex-text-secondary); font-size:.95rem; line-height:1.82; }
.about-body p+p { margin-top:16px; }
.info-grid { display:grid; grid-template-columns:repeat(3,1fr); border-top:1px solid rgba(237,233,225,.05); }
.ib { padding:28px 32px 0 0; border-right:1px solid rgba(237,233,225,.05); }
.ib:last-child { border-right:none; padding-right:0; }
.ib:not(:first-child) { padding-left:32px; }
.ib-lbl { font-family:var(--font-mono); font-size:.62rem; letter-spacing:.14em; text-transform:uppercase; color:var(--azpex-border); margin-bottom:14px; }
.ib-d { color:var(--azpex-text-secondary); font-size:.88rem; line-height:1.68; max-width:28ch; }

/* CONTACT */
.contact { border-top:1px solid rgba(237,233,225,.05); padding:clamp(72px,10vh,120px) 0 clamp(44px,6vh,80px); }
.contact-h3 {
  font-family:var(--font-display); font-weight:500;
  font-size:clamp(1.5rem,2.8vw,2.1rem); letter-spacing:-.022em;
  line-height:1.14; color:var(--azpex-text-primary); max-width:22ch; margin-bottom:16px;
}
.contact-body { color:var(--azpex-text-secondary); font-size:.95rem; line-height:1.7; max-width:44ch; margin-bottom:32px; }
.soc-link {
  font-family:var(--font-mono); font-size:.64rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--azpex-border); text-decoration:none;
  margin-right:24px; display:inline-flex; align-items:center; gap:6px;
  transition:color .25s ease;
}
.soc-link:hover { color:var(--azpex-accent); }

/* WAVEFORM CURSOR (fine pointer + hover-capable devices only)
   One full-viewport canvas that never takes pointer events, so page
   hit-testing is untouched. All the drawing lives in assets/js/cursor.js. */
@media (hover:hover) and (pointer:fine) {
  .cursor-wf {
    position:fixed; inset:0; width:100vw; height:100vh;
    pointer-events:none; z-index:9999;
  }
  /* The native OS cursor stays visible: it is precise, it keeps the text
     I-beam on inputs, and it never lags. The waveform canvas rides behind it
     as a quiet trailing accent, not a replacement pointer. */
}
@media (hover:none), (pointer:coarse) {
  .cursor-wf { display:none; }
}

/* FOOTER */
.ftr { border-top:1px solid rgba(237,233,225,.05); padding:52px 0 24px; position:relative; }
.ftr-top {
  display:flex; flex-wrap:wrap; gap:36px; justify-content:space-between;
  align-items:flex-start; padding-bottom:28px;
  border-bottom:1px solid rgba(237,233,225,.05);
}
.ftr-brand { font-family:var(--font-display); font-weight:700; font-size:.92rem; color:var(--azpex-text-primary); margin-bottom:14px; }
.ftr-tag { color:var(--azpex-text-secondary); font-size:.88rem; line-height:1.62; max-width:32ch; }
.ftr-links { display:flex; flex-wrap:wrap; gap:10px 22px; }
.ftr-link { color:var(--azpex-text-secondary); font-size:.88rem; text-decoration:none; transition:color .22s ease; }
.ftr-link:hover { color:var(--azpex-accent); }
.ftr-bot { display:flex; flex-wrap:wrap; gap:14px; justify-content:space-between; align-items:center; padding-top:20px; }
.ftr-copy { font-family:var(--font-mono); font-size:.62rem; color:var(--azpex-border); letter-spacing:.1em; text-transform:uppercase; }
.top-btn {
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--azpex-text-secondary); background:transparent; border:1px solid rgba(237,233,225,.08);
  padding:9px 16px; min-height:36px; cursor:pointer;
  display:inline-flex; align-items:center; gap:8px;
  transition:background .22s ease,color .22s ease,border-color .22s ease;
}
.top-btn:hover { background:var(--azpex-text-primary); color:var(--azpex-bg); border-color:var(--azpex-text-primary); }

/* SECTION INDEX WATERMARKS
   Reinforces the /00 (hero) and /A /B /C (about) numbering language already
   used elsewhere, so scrolling from section to section reads as one system
   instead of a stack of unrelated template blocks. */
.feat, .cats, .about, .contact { position:relative; overflow:hidden; }
.hero > .wrap, .feat > *, .cats > .wrap, .about > .wrap, .contact > .wrap,
.ftr > .wrap { position:relative; z-index:1; }

/* AMBIENT_GLOW - one shared, identical, very-low-alpha glow definition used
   by every section on every page (home, category, product). Deliberately
   NOT a bespoke value per section any more:
     - same two soft radial pools (upper-right, lower-left) everywhere, so
       Featured Products / the category listing pages / a product detail
       page like STILL all read as exactly the same lighting system, not
       nine slightly-different hand-tuned spotlights.
     - wide ellipses (must cover most of the section) with a slow, gradual
       falloff (transparent well before the edge) instead of the earlier
       small/punchy/fast-falloff pools - a hot, contained pool is what read
       as "a lit corner" or "yellow mist"; a wide, barely-there gradient
       reads as ambient room light instead.
     - low peak alpha (~.05-.07) - roughly a third of what was used before.
       At this strength the tone barely registers as color and never
       competes with text/cover-art/card contrast.
     - anchored to each section's own box (::before, position:absolute,
       inset:0, z-index:-1) rather than to the viewport, so it scrolls WITH
       the content instead of staying pinned to the screen while content
       moves past it, and its brightest point is never locked to a fixed
       distance from the header (the harsh band the fixed version produced
       under the header is gone for the same reason).
     - no animation. A flicker/breathe effect was tried and reads as "moving
       independently of what you're doing", which is exactly what an
       ambient light should not do - it should only ever move because you
       scrolled.
   Because every section uses the IDENTICAL definition, there is no
   intensity/color mismatch at a section boundary for a seam to form at -
   the two adjacent low-alpha gradients simply agree with each other. */
.hero, .feat, .cats, .about, .contact, .ftr,
.prod-page, .prod-section, .cat-hero, .cat-body { position:relative; }
.hero::before, .feat::before, .cats::before, .about::before, .contact::before,
.ftr::before, .prod-page::before, .prod-section::before, .cat-hero::before,
.cat-body::before {
  content:''; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:
    radial-gradient(ellipse 85% 70% at 88% 4%,  rgba(255,191,74,.072), transparent 74%),
    radial-gradient(ellipse 80% 65% at 6% 96%,  rgba(255,191,74,.052), transparent 74%);
}
[data-sec-index]::before {
  content: attr(data-sec-index);
  position:absolute; top:clamp(8px,2vw,20px); right:clamp(16px,3vw,48px);
  font-family:var(--font-mono); font-weight:700;
  font-size:clamp(1.6rem,3vw,2.4rem); line-height:1; letter-spacing:.02em;
  color:var(--azpex-text-primary); opacity:.05;
  pointer-events:none; z-index:0; user-select:none;
}

/* Volume control on the preview player */
.preview-track { flex-wrap:wrap; row-gap:10px; }
.preview-vol { display:flex; align-items:center; gap:8px; flex-shrink:0; margin-left:auto; }
.vol-btn {
  flex-shrink:0; width:26px; height:26px; background:none; border:none;
  color:var(--azpex-text-muted); cursor:pointer; padding:0; display:flex; align-items:center; justify-content:center;
  transition:color .26s cubic-bezier(.16,1,.3,1);
}
.vol-btn:hover { color:var(--azpex-accent); }
.vol-btn svg { width:16px; height:16px; }
/* The visual track stays a thin 3px hairline, but the input's own box (and
   therefore its click/drag hit-area) is a full 20px tall - a 3px-tall hit
   target is nearly impossible to grab with a mouse, which read as "the
   slider doesn't do anything" even though the value was changing fine. */
.vol-slider {
  -webkit-appearance:none; appearance:none; width:64px; height:20px;
  background:transparent; outline:none; cursor:pointer; margin:0;
}
.vol-slider::-webkit-slider-runnable-track {
  width:100%; height:3px; background:rgba(237,233,225,.14); border-radius:2px;
}
.vol-slider::-webkit-slider-thumb {
  -webkit-appearance:none; width:11px; height:11px; border-radius:50%;
  background:var(--azpex-accent); margin-top:-4px;
  transition:transform .22s cubic-bezier(.16,1,.3,1);
}
.vol-slider:hover::-webkit-slider-thumb, .vol-slider:active::-webkit-slider-thumb { transform:scale(1.25); }
.vol-slider::-moz-range-track { width:100%; height:3px; background:rgba(237,233,225,.14); border-radius:2px; }
.vol-slider::-moz-range-thumb { width:11px; height:11px; border-radius:50%; background:var(--azpex-accent); border:none; }
.vol-slider:hover::-moz-range-thumb, .vol-slider:active::-moz-range-thumb { transform:scale(1.25); }
/* On a narrow panel the volume row has to be allowed to shrink, otherwise the
   fixed-width slider pushes itself past the panel's right border. */
.preview-vol { min-width:0; }
.vol-slider { min-width:0; }
@media(max-width:560px){
  .wf-ctrl { flex-wrap:wrap; row-gap:12px; }
  .preview-vol { margin-left:auto; flex:1 1 140px; }
  .vol-slider { flex:1 1 60px; width:auto; }
}

/* Shared chrome for every stand-alone sub-page (category pages, product
   pages) - kept in home.css instead of repeated per-page <style> blocks so a
   single edit here stays consistent site-wide. */
html, body { background:var(--azpex-bg); color:var(--azpex-text-primary); }
.back-link {
  font-family:var(--font-mono); font-size:.64rem; letter-spacing:.14em;
  text-transform:uppercase; color:var(--azpex-text-secondary); text-decoration:none;
  display:flex; width:fit-content; align-items:center; gap:8px; margin-bottom:32px;
  transition:color .32s cubic-bezier(.16,1,.3,1);
}
.back-link:hover { color:var(--azpex-accent); }
.cat-page-title {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2.4rem,5vw,5rem); letter-spacing:-.03em; color:var(--azpex-text-primary);
  margin-bottom:16px;
}
.cat-page-desc { color:var(--azpex-text-secondary); font-size:1rem; line-height:1.7; max-width:48ch; }
.prod-page { padding-top:0; min-height:100vh; overflow:hidden; }
/* No position:relative/z-index/::before glow here any more - this page's
   own content is elevated instead (see .prod-page > .wrap below), so the
   single shared .warm-wash light shows through with no per-page seam. */
.prod-page > .wrap { position:relative; z-index:1; }
.prod-section { padding-top:clamp(56px,7vw,88px); }
.prod-section + .prod-section { border-top:1px solid rgba(237,233,225,.05); }

/* ════════════════════════════════════════════════════════════════════════
   DEFAULT PRODUCT PAGE
   One template, used unchanged by every product type - preset pack, drum
   kit, sample pack, plugin. Only the CONTENT changes between products; the
   layout, spacing and section order never do.

   Fixed order: cover + identity + 3 specs + price + CTA (intro), then
   preview and what's included (development), then one closing CTA
   (conclusion).

   Border budget for the whole page is three: the preview panel, the primary
   CTA and the final CTA band. Everything else is separated with space, a
   hairline rule or a shift in type - boxing each group is what made the
   earlier version read as a dashboard rather than a store.
   ════════════════════════════════════════════════════════════════════════ */
.pd { padding-top:clamp(96px,12vh,132px); padding-bottom:clamp(64px,9vw,110px); }
.pd > .wrap { position:relative; z-index:1; }

.pd-back {
  font-family:var(--font-mono); font-size:.62rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--text-muted); text-decoration:none;
  display:inline-flex; align-items:center; gap:9px; margin-bottom:clamp(28px,4vw,44px);
  transition:color .3s cubic-bezier(.16,1,.3,1);
}
.pd-back:hover { color:var(--text-primary); }

/* INTRO -------------------------------------------------------------- */
/* Cover and identity are one presentation, not two panels: a tight gap and
   a shared top alignment, rather than the wide gutter that made the cover
   look like it belonged to a different section. */
.pd-hero {
  display:grid;
  grid-template-columns:minmax(0,clamp(240px,30vw,400px)) minmax(0,1fr);
  gap:clamp(26px,3.4vw,52px);
  align-items:start;
}
.pd-cover { margin:0; }
.pd-cover img {
  display:block; width:100%; height:auto;
  box-shadow:0 18px 60px rgba(0,0,0,.62);
}
.pd-id { display:flex; flex-direction:column; padding-top:2px; }
.pd-code {
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.22em;
  text-transform:uppercase; color:var(--text-muted); margin-bottom:14px;
}
.pd-name {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(2.5rem,5.4vw,4.4rem); line-height:.94; letter-spacing:-.035em;
  color:var(--text-primary); margin-bottom:12px;
}
.pd-type {
  font-family:var(--font-mono); font-size:.66rem; letter-spacing:.2em;
  text-transform:uppercase; color:var(--gold); margin-bottom:20px;
}
.pd-desc {
  font-size:clamp(.94rem,1.05vw,1.02rem); line-height:1.62;
  color:var(--text-secondary); max-width:46ch; margin-bottom:26px;
}
/* Exactly three specs, same shape on every product, no borders. */
.pd-specs {
  display:flex; flex-wrap:wrap; gap:0 clamp(20px,2.6vw,38px);
  list-style:none; margin:0 0 30px; padding:0;
}
.pd-specs li {
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.13em;
  text-transform:uppercase; color:var(--text-primary);
  padding:9px 0; display:flex; align-items:center; gap:clamp(20px,2.6vw,38px);
}
.pd-specs li + li::before {
  content:''; width:1px; height:12px; background:var(--hair);
  margin-left:calc(-1 * clamp(20px,2.6vw,38px) / 2);
}
.pd-buy { display:flex; align-items:center; gap:clamp(18px,2.4vw,30px); flex-wrap:wrap; }
.pd-price {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.5rem,2.2vw,1.95rem); line-height:1; letter-spacing:-.02em;
  color:var(--gold-vivid);
}
.pd-cta {
  font-family:var(--font-mono); font-size:.72rem; letter-spacing:.14em;
  text-transform:uppercase; text-decoration:none;
  background:var(--gold); color:var(--ink); border:1px solid var(--gold);
  padding:15px 30px; min-height:50px;
  display:inline-flex; align-items:center; gap:11px;
  transition:background .34s cubic-bezier(.16,1,.3,1),
             border-color .34s cubic-bezier(.16,1,.3,1),
             transform .34s cubic-bezier(.16,1,.3,1);
}
.pd-cta:hover {
  background:var(--azpex-accent-bright); border-color:var(--azpex-accent-bright); transform:translateY(-1px);
}
.pd-cta:focus-visible { outline:2px solid var(--azpex-text-primary); outline-offset:3px; }

/* DEVELOPMENT -------------------------------------------------------- */
.pd-sec { padding-top:clamp(52px,6.5vw,86px); }
.pd-sec-hd {
  display:flex; align-items:baseline; justify-content:space-between;
  gap:20px; flex-wrap:wrap; margin-bottom:clamp(18px,2.4vw,26px);
  padding-bottom:14px; border-bottom:1px solid var(--hair-soft);
}
.pd-h2 {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.05rem,1.5vw,1.32rem); letter-spacing:-.008em;
  color:var(--text-primary);
}
.pd-h2-note {
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--text-muted);
}

/* CONCLUSION --------------------------------------------------------- */
.pd-final {
  margin-top:clamp(56px,7vw,92px);
  border:1px solid var(--hair);
  padding:clamp(28px,3.6vw,44px);
  display:flex; align-items:center; justify-content:space-between;
  gap:clamp(24px,3vw,44px); flex-wrap:wrap;
}
.pd-final-name {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.4rem,2.2vw,1.9rem); letter-spacing:-.025em;
  color:var(--text-primary); margin-bottom:8px;
}
.pd-final-line { color:var(--text-secondary); font-size:.96rem; line-height:1.55; }

@media(max-width:820px){
  .pd-hero { grid-template-columns:1fr; gap:clamp(24px,4vw,34px); }
  .pd-cover img { width:min(78vw,340px); }
}
@media(max-width:560px){
  .pd-specs { flex-direction:column; gap:0; }
  .pd-specs li { gap:0; padding:7px 0; }
  .pd-specs li + li::before { display:none; }
  .pd-buy { width:100%; }
  .pd-cta { width:100%; justify-content:center; }
  .pd-final { flex-direction:column; align-items:flex-start; }
}
/* No per-section ::before glow here any more (see .prod-page above) - each
   .prod-section already sits inside .prod-page > .wrap, which is elevated
   above the single shared .warm-wash light as one piece, so there's no
   per-section seam. */

/* PREMIUM ACCENT - CORNER FRAME + GLASS SHEEN
   Two quiet accents borrowed (not copied) from technical-readout / glass-
   panel UI kit references: thin hairline corner brackets (pure CSS, no
   extra markup) that make an image or panel read as something inspected
   and certified rather than a plain cropped picture, plus a soft diagonal
   glass-sheen highlight for a "under glass" premium finish. Both are quiet
   - 1px lines, low-alpha gold, no glow/blur - so they read as quality
   rather than as a sci-fi HUD. Reusable via .frame-corners / .glass-sheen
   on any element, not just STILL's cover art. */
.frame-corners {
  --fc-len: 22px; --fc-w: 1px; --fc-c: rgba(201,163,122,.8); --fc-gap: 10px;
  position:relative; padding:var(--fc-gap);
}
.frame-corners::before {
  content:''; position:absolute; inset:0; pointer-events:none;
  background-repeat:no-repeat;
  background-image:
    linear-gradient(var(--fc-c), var(--fc-c)), linear-gradient(var(--fc-c), var(--fc-c)),
    linear-gradient(var(--fc-c), var(--fc-c)), linear-gradient(var(--fc-c), var(--fc-c)),
    linear-gradient(var(--fc-c), var(--fc-c)), linear-gradient(var(--fc-c), var(--fc-c)),
    linear-gradient(var(--fc-c), var(--fc-c)), linear-gradient(var(--fc-c), var(--fc-c));
  background-size:
    var(--fc-len) var(--fc-w), var(--fc-w) var(--fc-len),
    var(--fc-len) var(--fc-w), var(--fc-w) var(--fc-len),
    var(--fc-len) var(--fc-w), var(--fc-w) var(--fc-len),
    var(--fc-len) var(--fc-w), var(--fc-w) var(--fc-len);
  background-position:
    top left, top left,
    top right, top right,
    bottom right, bottom right,
    bottom left, bottom left;
}
.glass-sheen { position:relative; overflow:hidden; }
.glass-sheen::after {
  content:''; position:absolute; inset:0; pointer-events:none;
  background:linear-gradient(115deg,
    rgba(255,255,255,0) 42%, rgba(255,255,255,.05) 48%,
    rgba(255,255,255,.13) 50%, rgba(255,255,255,.05) 52%,
    rgba(255,255,255,0) 58%);
}
.info-grid.cols-2 { grid-template-columns:repeat(2,1fr); }
@media(max-width:640px){ .info-grid.cols-2 { grid-template-columns:1fr; } .info-grid.cols-2 .ib{ border-right:none; padding:24px 0 0; } .info-grid.cols-2 .ib:first-child{ padding-top:0; } }

/* WHAT'S INCLUDED - number over label, separated by thin rules and space
   only. No outer box, no cards, no checkmarks or category icons: the
   contents are data, and the data is the decoration. Works unchanged for a
   preset pack's KEYS/PLUCKS/PADS or a drum kit's KICKS/SNARES/RIMS. */
/* Explicit column counts rather than auto-fit, so it is always known which
   item starts a row and can drop its divider. (A gap+background-colour
   divider trick was tried first and painted a phantom empty cell wherever
   the item count didn't fill the last row.) */
.pd-inc {
  display:grid; grid-template-columns:repeat(5,minmax(0,1fr));
  gap:clamp(20px,3vw,30px) 0; margin-bottom:22px;
}
.pd-inc-i {
  padding:2px 12px 2px clamp(16px,2.2vw,30px);
  border-left:1px solid var(--hair-soft);
  display:flex; flex-direction:column; gap:9px; align-items:flex-start;
}
.pd-inc-i:nth-child(5n+1) { border-left:none; padding-left:0; }
@media(max-width:880px){
  .pd-inc { grid-template-columns:repeat(3,minmax(0,1fr)); }
  .pd-inc-i:nth-child(5n+1) { border-left:1px solid var(--hair-soft); padding-left:clamp(16px,2.2vw,30px); }
  .pd-inc-i:nth-child(3n+1) { border-left:none; padding-left:0; }
}
@media(max-width:520px){
  .pd-inc { grid-template-columns:repeat(2,minmax(0,1fr)); }
  .pd-inc-i:nth-child(3n+1) { border-left:1px solid var(--hair-soft); padding-left:clamp(16px,2.2vw,30px); }
  .pd-inc-i:nth-child(2n+1) { border-left:none; padding-left:0; }
}
.pd-inc-n {
  font-family:var(--font-display); font-weight:700;
  font-size:clamp(1.7rem,2.6vw,2.15rem); line-height:1;
  letter-spacing:-.02em; color:var(--text-primary);
}
.pd-inc-l {
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--text-muted);
}
.pd-inc-total {
  font-family:var(--font-mono); font-size:.64rem; letter-spacing:.12em;
  text-transform:uppercase; color:var(--text-secondary);
}

/* Kit contents - one category's worth of tracks at a time (see the
   .preview-cats tabs inside .prod-preview-wf), not all of them stacked down
   the page - keeps the section compact no matter how large a future kit's
   tracklist gets. Rows share the previewAudio engine + the waveform "now
   playing" bar above them via data-track-row/data-track-product, so
   clicking any row here (or letting one track end) drives the same player,
   volume and scrub position. */
.trk-groups { position:relative; }
.trk-group { display:none; }
.trk-group.is-active { display:block; }
.trk-list { display:flex; flex-direction:column; }
.trk-row {
  display:flex; align-items:center; gap:14px; width:100%;
  background:transparent; border:none; border-bottom:1px solid rgba(237,233,225,.04);
  padding:13px 6px; cursor:pointer; text-align:left; font:inherit;
  color:var(--azpex-text-secondary); transition:color .22s ease, background .22s ease;
}
.trk-row:hover { color:var(--azpex-text-primary); background:rgba(255,255,255,.014); }
.trk-row.is-playing { color:var(--azpex-text-primary); }
.trk-row-play {
  flex-shrink:0; width:0; height:0;
  border-top:5px solid transparent; border-bottom:5px solid transparent;
  border-left:8px solid currentColor; margin-left:2px;
}
.trk-row.is-playing .trk-row-play {
  width:7px; height:9px; border:none; margin-left:0;
  background:
    linear-gradient(currentColor,currentColor) 0 0/2px 9px no-repeat,
    linear-gradient(currentColor,currentColor) 5px 0/2px 9px no-repeat;
}
.trk-row-name { font-family:var(--font-mono); font-size:.72rem; letter-spacing:.02em; flex:1; }
.trk-row-eq { display:none; align-items:flex-end; gap:3px; height:14px; flex-shrink:0; }
.trk-row.is-playing .trk-row-eq { display:flex; }
.trk-row-eq span { width:2px; background:var(--azpex-accent); border-radius:1px; animation:eqBounce .9s ease-in-out infinite; }
.trk-row-eq span:nth-child(1){ height:5px;  animation-delay:-0.6s; }
.trk-row-eq span:nth-child(2){ height:12px; animation-delay:-0.2s; }
.trk-row-eq span:nth-child(3){ height:8px;  animation-delay:-0.9s; }
.trk-row-eq span:nth-child(4){ height:14px; animation-delay:-0.4s; }

/* Bar-style waveform "now playing" surface - the real per-file preview,
   sitting inside .prod-preview-wf above the tabbed tracklist. Bars are
   rendered/decoded by assets/js/home.js (real amplitude data when the
   audio file can be fetched, a deterministic stand-in shape otherwise) -
   this file only owns how it looks and how the scrub handle behaves. */
.prod-preview-wf { padding:18px 20px 6px; }
.wf-now { margin-top:0; }
.wf-now-top { display:flex; align-items:baseline; justify-content:space-between; gap:16px; margin-bottom:10px; }
.wf-now-name { font-family:var(--font-mono); font-size:.7rem; letter-spacing:.05em; color:var(--text-primary); }
.wf-now-time { font-family:var(--font-mono); font-size:.6rem; color:var(--text-muted); letter-spacing:.05em; flex-shrink:0; }
/* Thinner than before: the waveform is a scrub surface, not the hero of the
   page, and at 56px it was pushing everything below it off the first screen. */
.wf-bars {
  position:relative; height:38px; display:flex; align-items:center; gap:2px;
  cursor:pointer; touch-action:none; margin-bottom:14px;
  overflow:hidden; /* belt-and-braces: bars can never spill past the panel */
}

/* At most four previews are visible; the rest are one click away, so a kit
   with forty sounds takes the same vertical space as one with four. */
.trk-list:not(.is-expanded) .trk-row:nth-child(n+5) { display:none; }
.trk-more {
  display:none; width:100%; background:transparent; border:none;
  border-top:1px solid var(--hair-soft);
  font-family:var(--font-mono); font-size:.6rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--text-muted);
  padding:14px 6px; cursor:pointer; text-align:left;
  transition:color .22s ease;
}
.trk-more.is-shown { display:block; }
.trk-more:hover { color:var(--text-primary); }
.wf-bar {
  flex:1; min-width:2px; border-radius:1px; background:var(--azpex-border);
  transform-origin:center bottom;
  transition:background .15s ease, transform .1s ease-out;
}
.wf-bar.played { background:var(--azpex-accent-dark); }
.wf-handle {
  position:absolute; top:50%; width:10px; height:10px; border-radius:50%;
  background:var(--azpex-accent); box-shadow:0 0 0 4px rgba(201,163,122,.16);
  transform:translate(-50%,-50%); pointer-events:none; transition:box-shadow .2s ease;
}
.wf-bars:active .wf-handle { box-shadow:0 0 0 6px rgba(201,163,122,.24); }
.wf-ctrl { display:flex; align-items:center; gap:14px; padding-bottom:18px; }

/* CATEGORY PAGE HERO - same warm-glow language as the homepage hero, plus a
   small per-category glyph from the same diamond-motif family used in
   The Collection, so every page in the catalogue reads as one system. */
.cat-hero {
  overflow:hidden;
  padding:min(150px,calc(120px + 4vh)) 0 clamp(48px,7vh,80px);
}
/* No position:relative/::before glow here - .cat-hero > .wrap below is
   elevated instead, same pattern as .prod-page, so the shared .warm-wash
   light shows through with no per-page seam. */
.cat-hero > .wrap { position:relative; z-index:1; }
/* Title + 3D object sit side by side, echoing the hero's own
   text-left/object-right arrangement instead of stacking the object above
   the heading like a detached badge. */
.cat-title-row {
  display:flex; align-items:center; gap:clamp(16px,3vw,36px);
  flex-wrap:wrap; margin-bottom:16px;
}
.cat-title-row .cat-page-title { margin-bottom:0; }
.cat-glyph {
  width:clamp(76px,9vw,132px); height:clamp(76px,9vw,132px);
  color:var(--azpex-accent-dark); opacity:.9; flex-shrink:0;
  display:flex; position:relative;
}
.cat-glyph svg { width:100%; height:100%; padding:22%; animation:catGlyphFloat 7s ease-in-out infinite; }
@keyframes catGlyphFloat { 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-7px) } }
/* Once category-object.js swaps in a <canvas>, it fills this box; the SVG
   glyph underneath stays as the no-WebGL / no-JS fallback. */
.cat-glyph canvas { position:absolute; inset:0; }
.cat-body { padding-bottom:clamp(80px,10vh,120px); }
.cat-body > .wrap { position:relative; z-index:1; }

/* Category product grid - a real catalogue listing, not the homepage's
   "Featured Product" spotlight treatment. No audio preview here on
   purpose: browsing a category is about scanning name / type / price
   quickly across many items, not auditioning one in detail (that's what
   the product's own page + the homepage feature slot are for). */
.cat-prod-grid {
  display:grid; grid-template-columns:repeat(auto-fill,minmax(240px,1fr));
  gap:clamp(20px,2.6vw,32px);
}
/* Genre sub-category filter chips (Drum Kits / Presets) */
.cat-filter{ display:flex; flex-wrap:wrap; gap:10px; margin:0 0 30px; }
.cat-filter-chip{
  font-family:var(--font-mono); font-size:.64rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--text-secondary); background:rgba(255,255,255,.02);
  border:1px solid var(--hair); border-radius:999px; padding:9px 16px; cursor:pointer;
  transition:color .3s cubic-bezier(.16,1,.3,1), border-color .3s, background .3s;
}
.cat-filter-chip:hover{ color:var(--gold2,var(--azpex-accent-bright)); border-color:rgba(201,163,122,.4); }
.cat-filter-chip.is-active{ color:var(--azpex-bg); background:var(--gold); border-color:var(--gold); font-weight:700; }
.cat-prod-card.is-hidden{ display:none; }

.cat-prod-card {
  display:flex; flex-direction:column; height:100%;
  text-decoration:none; color:inherit;
  border:1px solid rgba(237,233,225,.08); background:rgba(255,255,255,.014);
  transition:border-color .34s cubic-bezier(.16,1,.3,1), transform .34s cubic-bezier(.16,1,.3,1);
}
.cat-prod-card:hover { border-color:rgba(201,163,122,.4); transform:translateY(-4px); }
.cat-prod-card-art { position:relative; aspect-ratio:1/1; overflow:hidden; background:var(--azpex-bg-soft); }
.cat-prod-card-art img {
  width:100%; height:100%; object-fit:cover; display:block;
  transition:transform .6s cubic-bezier(.16,1,.3,1);
}
.cat-prod-card:hover .cat-prod-card-art img { transform:scale(1.045); }
.cat-prod-card-body { padding:20px 22px 22px; display:flex; flex-direction:column; flex:1; }
.cat-prod-card-type {
  font-family:var(--font-mono); font-size:.58rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--azpex-accent); margin-bottom:8px;
}
.cat-prod-card-name {
  font-family:var(--font-display); font-weight:700; font-size:1.4rem;
  letter-spacing:-.02em; color:var(--azpex-text-primary); margin-bottom:14px;
}
.cat-prod-card-price-row { display:flex; align-items:baseline; gap:10px; margin-bottom:18px; }
.cat-prod-card-price { font-family:var(--font-display); font-weight:700; font-size:1.3rem; color:var(--gold-vivid); }
.cat-prod-card-price-note {
  font-family:var(--font-mono); font-size:.58rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--azpex-text-secondary);
}
.cat-prod-card-cta {
  margin-top:auto; padding-top:14px; border-top:1px solid rgba(237,233,225,.06);
  font-family:var(--font-mono); font-size:.66rem; letter-spacing:.1em; text-transform:uppercase;
  color:var(--azpex-text-muted); transition:color .3s cubic-bezier(.16,1,.3,1);
}
.cat-prod-card:hover .cat-prod-card-cta { color:var(--azpex-accent); }

/* ── Cover-art effects ─────────────────────────────────────────
   A persistent framing vignette gives the covers depth, and a warm
   light "sweep" glides across on hover so each cover feels like a
   framed, premium object rather than a flat thumbnail. */
.cat-prod-card-art::before {
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:
    linear-gradient(158deg, rgba(255,250,242,.06) 0%, rgba(255,250,242,0) 32%),
    radial-gradient(120% 78% at 50% 116%, rgba(0,0,0,.46), rgba(0,0,0,0) 58%);
  opacity:.85; transition:opacity .45s ease;
}
.cat-prod-card-art::after {
  content:""; position:absolute; top:-60%; left:-140%; z-index:3; pointer-events:none;
  width:55%; height:220%; opacity:0;
  background:linear-gradient(90deg, rgba(255,244,226,0) 0%, rgba(255,241,219,.18) 50%, rgba(255,244,226,0) 100%);
  transform:translateX(0) rotate(17deg); filter:blur(2px);
}
.cat-prod-card:hover .cat-prod-card-art::before { opacity:1; }
.cat-prod-card:hover .cat-prod-card-art::after { animation:coverSheen 1.05s cubic-bezier(.22,.61,.36,1); }
@keyframes coverSheen {
  0%   { transform:translateX(0)    rotate(17deg); opacity:0; }
  14%  { opacity:1; }
  100% { transform:translateX(430%) rotate(17deg); opacity:0; }
}

/* Product-page hero cover: same framing + sheen, plus a soft warm ground glow */
/* ---- Product cover, three layers -----------------------------------------
   Scene owns the perspective. Plate rotates and keeps preserve-3d with
   overflow visible, so the inner Z layers are never flattened. Frame does the
   clipping and carries the vignette and sheen. Never preserve-3d and
   overflow:hidden on the same element. */
.pd-cover {
  position:relative;
  perspective: 1200px;
  perspective-origin: center;
}
.pd-cover-plate {
  transform-style: preserve-3d;
  overflow: visible;
  /* --cover-scroll is written by the scroll handler and --lift by the tilt
     loop, so the two never write the same property. */
  transform:
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg))
    translateY(calc(var(--lift, 0px) + var(--cover-scroll, 0px)));
  transition: transform var(--motion-slow) var(--ease-heavy),
              box-shadow var(--motion-medium) var(--ease-ui);
  box-shadow: var(--tilt-shadow, 0 18px 60px rgba(0,0,0,.62));
}
.pd-cover-plate.is-live { transition: none; }
.pd-cover-frame {
  position: relative;
  overflow: hidden;
  border-radius: 3px;
  transform: translateZ(10px);
}
.pd-cover img { transition:transform .6s cubic-bezier(.16,1,.3,1); box-shadow:none; }
.pd-cover-frame::before {
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:radial-gradient(120% 76% at 50% 116%, rgba(0,0,0,.4), rgba(0,0,0,0) 58%);
  opacity:.85;
}
.pd-cover-frame::after {
  content:""; position:absolute; top:-60%; left:-140%; z-index:3; pointer-events:none;
  width:55%; height:220%; opacity:0;
  background:linear-gradient(90deg, rgba(255,244,226,0) 0%, rgba(255,241,219,.16) 50%, rgba(255,244,226,0) 100%);
  transform:translateX(0) rotate(17deg); filter:blur(2px);
}
.pd-cover:hover img { transform:scale(1.02); }
.pd-cover:hover .pd-cover-frame::after { animation:coverSheen 1.15s cubic-bezier(.22,.61,.36,1); }

/* Entrance: the cover arrives slightly low and set back, then settles flat. */
.motion-ready .pd-cover-plate[data-cover-in] {
  opacity: 0;
  transform: translateY(34px) translateZ(-40px) rotateX(6deg) rotateY(-3deg);
}
.motion-ready .pd-cover-plate[data-cover-in].is-in {
  opacity: 1;
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))
             translateY(calc(var(--lift, 0px) + var(--cover-scroll, 0px)));
  transition: opacity var(--motion-slow) var(--ease-ui),
              transform var(--motion-slow) var(--ease-heavy);
}

@media (hover: none), (max-width: 760px) {
  .pd-cover-plate { transform: none !important; --cover-scroll: 0px; }
  .pd-cover:hover img { transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cat-prod-card:hover .cat-prod-card-art::after,
  .pd-cover:hover .pd-cover-frame::after { animation:none; }
  .pd-cover:hover img { transform:none; }
  .pd-cover-plate { transform:none !important; opacity:1 !important; }
}
.cat-empty {
  font-family:var(--font-mono); font-size:.68rem; letter-spacing:.1em;
  text-transform:uppercase; color:var(--azpex-text-muted); padding:28px 0;
  border-top:1px solid rgba(237,233,225,.06); max-width:44ch;
}
.cat-empty span { color:var(--azpex-accent); }

/* Reduced motion: keep the "smooth, unhurried" feel but stop asking the
   browser to animate anything for visitors who've told their OS not to. */
@media (prefers-reduced-motion: reduce) {
  .grain, .scroll-bar, .fb-glow, .fb-labels, .fb-ring, .fb-ring2, .fb-ring3,
  .fb-center, .fb-root.fb-spin-once, .cat-glyph svg {
    animation: none !important;
  }
  .az-up, .az-fi, .az-rise { animation: none !important; opacity: 1 !important; transform: none !important; }
  .az-word { animation: none !important; opacity: .013 !important; }
}

/* Collection row icons */
.cat-icon {
  flex-shrink:0; width:22px; height:22px; color:var(--azpex-text-muted);
  display:inline-flex; transition:color .25s ease;
}
.cat-icon svg { width:100%; height:100%; }
.cat-link:hover .cat-icon { color:var(--azpex-accent); }

/* RESPONSIVE */
@media(max-width:900px){
  .hero { padding-top:104px; }
  .hero-word { font-size:min(52vw,340px); }
  h1.hero-h1 { margin-top:clamp(-2rem,-4vw,-1rem); }
  .feat-grid { grid-template-columns:1fr; }
  .prod-panel {
    flex-direction:column;
    border-right:none; border-bottom:1px solid rgba(237,233,225,.05);
  }
  .prod-panel:last-child { border-bottom:none; }
  .prod-art-wrap { width:100%; justify-content:center; }
  .prod-cover { width:min(82vw,320px); max-width:320px; }
  .prod-info { padding-top:8px; }
}
@media(max-width:820px){
  .info-grid{grid-template-columns:1fr}
  .ib{padding:22px 0; border-right:none; border-bottom:1px solid rgba(237,233,225,.05)}
  .ib:not(:first-child){padding-left:0}
  .ib:last-child{border-bottom:none}
}

/* CSS fallback for 3D object */
@keyframes fbGlow  { 0%,100%{opacity:.5;transform:scale(1)}   50%{opacity:.72;transform:scale(1.07)} }
@keyframes fbFloat { 0%,100%{transform:translateY(0)}          50%{transform:translateY(-10px)} }
@keyframes fbRing  { 0%,100%{opacity:.3} 50%{opacity:.07} }
@keyframes fbPulse { 0%,100%{box-shadow:0 0 16px 5px rgba(212,174,130,.38)} 50%{box-shadow:0 0 28px 10px rgba(212,174,130,.18)} }
.fb-root  { position:relative; width:min(460px,86%); aspect-ratio:1/1; }
.fb-glow  {
  position:absolute; inset:-14%; border-radius:50%;
  background:radial-gradient(circle,rgba(156,123,78,.2) 0%,rgba(156,123,78,.06) 44%,transparent 68%);
  animation:fbGlow 10s ease-in-out infinite;
}
.fb-labels {
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  animation:fbFloat 9s ease-in-out infinite;
}
.fb-labels img { width:72%; height:72%; object-fit:contain; opacity:.5; }
.fb-ring  { position:absolute; inset:0;   border-radius:50%; border:1px solid rgba(156,123,78,.28); animation:fbRing 7s  ease-in-out infinite; }
.fb-ring2 { position:absolute; inset:11%; border-radius:50%; border:1px solid rgba(237,233,225,.08); animation:fbRing 9s  ease-in-out infinite -2s; }
.fb-ring3 { position:absolute; inset:22%; border-radius:50%; border:1px solid rgba(156,123,78,.18); animation:fbRing 11s ease-in-out infinite -4s; }
.fb-center {
  position:absolute; top:50%; left:50%; width:9px; height:9px;
  transform:translate(-50%,-50%); border-radius:50%; background:var(--azpex-accent-bright);
  animation:fbPulse 5s ease-in-out infinite;
}
.freq-fallback-wrap {
  position:relative; width:100%; height:100%; min-height:320px;
  display:flex; align-items:center; justify-content:center; overflow:hidden;
  perspective:900px;
}
@keyframes fbSpinOnce { from{transform:rotateY(0deg)} to{transform:rotateY(360deg)} }
.fb-root.fb-spin-once { animation:fbSpinOnce 1.1s cubic-bezier(.45,.05,.55,.95) 1; }

/* ── Legal / prose pages (license, terms) ─────────────────────────────── */
.legal { max-width:760px; margin:0 auto; padding:clamp(90px,12vh,150px) 0 90px; }
.legal-eyebrow { font-family:var(--font-mono); font-size:.62rem; letter-spacing:.22em; text-transform:uppercase; color:var(--gold); margin-bottom:18px; }
.legal h1 { font-family:var(--font-display); font-weight:700; font-size:clamp(2rem,5vw,3.2rem); letter-spacing:-.03em; color:var(--text-primary); line-height:1; margin-bottom:16px; }
.legal-lead { color:var(--text-secondary); font-size:clamp(.95rem,1.1vw,1.08rem); line-height:1.75; margin-bottom:44px; max-width:60ch; }
.legal h2 { font-family:var(--font-display); font-weight:600; font-size:1.15rem; letter-spacing:-.01em; color:var(--text-primary); margin:38px 0 14px; }
.legal p { color:var(--text-secondary); line-height:1.8; margin-bottom:14px; }
.legal ul { list-style:none; margin:0 0 14px; padding:0; }
.legal li { position:relative; color:var(--text-secondary); line-height:1.7; padding:9px 0 9px 26px; border-bottom:1px solid var(--hair-soft); }
.legal li::before { content:''; position:absolute; left:2px; top:17px; width:7px; height:7px; border:1px solid var(--gold); transform:rotate(45deg); }
.legal li.no::before { border-color:var(--azpex-accent-dark); background:transparent; }
.legal li.yes::before { background:var(--gold); border-color:var(--gold); }
.legal-note { margin-top:40px; padding-top:22px; border-top:1px solid var(--hair); font-family:var(--font-mono); font-size:.72rem; letter-spacing:.04em; color:var(--text-muted); line-height:1.7; }
.legal-note a { color:var(--gold); text-decoration:none; }

/* ── Reviews (curated) ─────────────────────────────────────────────── */
.rv-star{ color:rgba(237,233,225,.18); font-size:.95em; letter-spacing:.06em; }
.rv-star.on{ color:var(--gold); }
[data-rv-head]{ display:inline-flex; align-items:center; gap:10px; }
.rv-head-num{ font-family:var(--font-display); font-weight:700; color:var(--gold2,var(--azpex-accent-bright)); font-size:1rem; }
.rv-head-stars{ letter-spacing:.05em; }
.rv-head-count{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); }
.rv-body{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:16px; margin:6px 0 22px; }
.rv-card{ margin:0; border:1px solid var(--hair); background:rgba(255,255,255,.014); border-radius:10px; padding:18px 20px; }
.rv-card-top{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; }
.rv-card-name{ font-family:var(--font-display); font-weight:600; color:var(--text-primary); font-size:.95rem; }
.rv-card-stars{ font-size:.85rem; white-space:nowrap; }
.rv-card-text{ margin:0; color:var(--text-secondary); line-height:1.7; font-size:.95rem; }
.rv-card-date{ margin-top:12px; font-family:var(--font-mono); font-size:.58rem; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); }
.rv-empty{ color:var(--text-secondary); line-height:1.7; margin:6px 0 22px; }
.rv-cta{ display:inline-flex; align-items:center; gap:8px; font-family:var(--font-mono);
  font-size:.72rem; letter-spacing:.1em; text-transform:uppercase; color:var(--gold);
  text-decoration:none; border:1px solid var(--hair); border-radius:8px; padding:11px 18px;
  transition:border-color .3s cubic-bezier(.16,1,.3,1), color .3s cubic-bezier(.16,1,.3,1); }
.rv-cta:hover{ border-color:var(--gold); color:var(--gold2,var(--azpex-accent-bright)); }
/* Native, site-styled review form (assets/js/reviews.js builds it) */
.rvf{ max-width:660px; margin-top:22px; padding-top:24px; border-top:1px solid var(--hair);
  display:flex; flex-direction:column; gap:22px; }
.rvf-row{ display:flex; flex-direction:column; gap:9px; }
.rvf-label{ font-family:var(--font-mono); font-size:.62rem; letter-spacing:.16em; text-transform:uppercase; color:var(--text-secondary); }
.rvf-label span{ color:var(--gold); }
.rvf-input,.rvf-textarea{ width:100%; font:inherit; color:var(--text-primary); background:rgba(255,255,255,.022);
  border:1px solid var(--hair); border-radius:10px; padding:14px 16px;
  transition:border-color .3s cubic-bezier(.16,1,.3,1), background .3s ease; }
.rvf-textarea{ min-height:130px; resize:vertical; line-height:1.6; }
.rvf-input::placeholder,.rvf-textarea::placeholder{ color:var(--text-muted); }
.rvf-input:focus,.rvf-textarea:focus{ outline:none; border-color:var(--gold); background:rgba(255,255,255,.03); }
.rvf-stars{ display:flex; gap:10px; }
.rvf-star{ font-size:2rem; line-height:1; color:rgba(237,233,225,.16); cursor:pointer;
  transition:color .15s ease, transform .15s ease; }
.rvf-star:hover{ transform:translateY(-2px); }
.rvf-star.on{ color:var(--gold); }
.rvf-star.hot{ color:var(--gold2,var(--azpex-accent-bright)); }
.rvf-hp{ position:absolute; left:-9999px; width:1px; height:1px; opacity:0; }
.rvf-actions{ display:flex; align-items:center; gap:20px; flex-wrap:wrap; }
.rvf-submit{ font-family:var(--font-mono); font-size:.74rem; letter-spacing:.1em; text-transform:uppercase;
  background:var(--azpex-text-primary); color:var(--azpex-bg); border:1px solid var(--azpex-text-primary); padding:14px 26px; border-radius:2px; cursor:pointer;
  display:inline-flex; align-items:center; gap:10px;
  transition:background .34s cubic-bezier(.16,1,.3,1), border-color .34s, transform .34s; }
.rvf-submit:hover{ background:var(--gold); border-color:var(--gold); transform:translateY(-1px); }
.rvf-submit[disabled]{ opacity:.5; cursor:default; transform:none; }
.rvf-note{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.08em; text-transform:uppercase; color:var(--text-muted); }
.rvf-status{ margin:0; font-family:var(--font-mono); font-size:.72rem; letter-spacing:.03em; color:var(--text-secondary); }
.rvf-status.err{ color:var(--azpex-error); }
.rvf-status.ok{ color:var(--gold2,var(--azpex-accent-bright)); }
.rvf-thanks{ margin:22px 0 0; padding-top:22px; border-top:1px solid var(--hair);
  color:var(--text-secondary); line-height:1.7; max-width:640px; }

/* ── Journal (blog) ──────────────────────────────────────────────────── */
.jr-hero{ max-width:820px; margin:0 auto; padding:clamp(90px,12vh,150px) 0 40px; }
.jr-eyebrow{ font-family:var(--font-mono); font-size:.62rem; letter-spacing:.22em; text-transform:uppercase; color:var(--gold); margin-bottom:18px; }
.jr-hero h1{ font-family:var(--font-display); font-weight:700; font-size:clamp(2.2rem,5vw,3.4rem); letter-spacing:-.03em; color:var(--text-primary); line-height:1; margin:0 0 16px; }
.jr-hero p{ color:var(--text-secondary); font-size:clamp(.98rem,1.1vw,1.1rem); line-height:1.7; max-width:60ch; }
.jr-grid{ max-width:900px; margin:20px auto 90px; display:grid; grid-template-columns:1fr; gap:2px; }
.jr-card{ display:block; text-decoration:none; color:inherit; border-top:1px solid var(--hair);
  padding:30px 0; transition:padding-left .34s cubic-bezier(.16,1,.3,1); }
.jr-card:last-child{ border-bottom:1px solid var(--hair); }
.jr-card:hover{ padding-left:10px; }
.jr-card-cat{ font-family:var(--font-mono); font-size:.58rem; letter-spacing:.18em; text-transform:uppercase; color:var(--gold); }
.jr-card-title{ font-family:var(--font-display); font-weight:700; font-size:clamp(1.3rem,2.4vw,1.9rem); letter-spacing:-.02em; color:var(--text-primary); margin:10px 0 10px; line-height:1.15; }
.jr-card:hover .jr-card-title{ color:var(--gold2,var(--azpex-accent-bright)); }
.jr-card-excerpt{ color:var(--text-secondary); line-height:1.7; max-width:70ch; margin:0 0 12px; }
.jr-card-meta{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.12em; text-transform:uppercase; color:var(--text-muted); }

/* ── Journal article ─────────────────────────────────────────────────── */
.post{ max-width:720px; margin:0 auto; padding:clamp(84px,11vh,140px) 0 80px; }
.post-eyebrow{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.2em; text-transform:uppercase; color:var(--gold); margin-bottom:16px; }
.post h1{ font-family:var(--font-display); font-weight:700; font-size:clamp(2rem,4.6vw,3rem); letter-spacing:-.03em; color:var(--text-primary); line-height:1.05; margin:0 0 18px; }
.post-lead{ color:var(--text-secondary); font-size:clamp(1.02rem,1.3vw,1.18rem); line-height:1.7; font-style:italic; margin:0 0 26px; }
.post-meta{ font-family:var(--font-mono); font-size:.6rem; letter-spacing:.14em; text-transform:uppercase; color:var(--text-muted); padding-bottom:26px; border-bottom:1px solid var(--hair); margin-bottom:34px; }
.post-body h2{ font-family:var(--font-display); font-weight:600; font-size:clamp(1.3rem,2.2vw,1.6rem); letter-spacing:-.01em; color:var(--text-primary); margin:44px 0 14px; }
.post-body h3{ font-family:var(--font-display); font-weight:600; font-size:1.02rem; color:var(--text-primary); margin:26px 0 8px; }
.post-body p{ color:var(--text-secondary); line-height:1.85; margin:0 0 16px; font-size:1.02rem; }
.post-body ul{ list-style:none; margin:0 0 18px; padding:0; }
.post-body li{ position:relative; color:var(--text-secondary); line-height:1.7; padding:8px 0 8px 24px; }
.post-body li::before{ content:''; position:absolute; left:2px; top:16px; width:6px; height:6px; border:1px solid var(--gold); transform:rotate(45deg); }
.post-body ol{ margin:0 0 18px; padding-left:22px; color:var(--text-secondary); line-height:1.8; }
.post-body ol li{ padding-left:6px; }
.post-body ol li::before{ display:none; }
.post-quote{ margin:24px 0; padding:14px 22px; border-left:2px solid var(--gold); background:rgba(255,255,255,.02);
  font-family:var(--font-display); font-weight:500; font-style:italic; color:var(--text-primary); line-height:1.6; }
.post-body a{ color:var(--gold); text-decoration:none; border-bottom:1px solid rgba(201,163,122,.35); }
.post-body a:hover{ color:var(--gold2,var(--azpex-accent-bright)); }
.post-cta{ margin-top:46px; padding-top:26px; border-top:1px solid var(--hair); }
.post-cta p{ color:var(--text-secondary); line-height:1.7; margin:0 0 16px; }

/* ── FAQ accordion (native <details>, works with no JS) ──────────────── */
.faq-list { margin:8px 0 0; }
.faq-item {
  border-bottom:1px solid var(--hair-soft);
}
.faq-item[open] { background:rgba(255,255,255,.012); }
.faq-q {
  list-style:none; cursor:pointer; position:relative;
  padding:22px 44px 22px 0;
  font-family:var(--font-display); font-weight:500; font-size:1.05rem;
  letter-spacing:-.01em; color:var(--text-primary);
  transition:color .3s cubic-bezier(.16,1,.3,1);
}
.faq-q::-webkit-details-marker { display:none; }
.faq-q:hover { color:var(--gold); }
.faq-q::after {
  content:'+'; position:absolute; right:6px; top:50%; transform:translateY(-50%);
  font-family:var(--font-mono); font-size:1.3rem; line-height:1; color:var(--gold);
  transition:transform .34s cubic-bezier(.16,1,.3,1);
}
.faq-item[open] .faq-q::after { content:'+'; transform:translateY(-50%) rotate(45deg); }
.faq-a { padding:0 44px 24px 0; }
.faq-a p { color:var(--text-secondary); line-height:1.8; margin:0 0 12px; }
.faq-a p:last-child { margin-bottom:0; }
.faq-a a { color:var(--gold); text-decoration:none; }
@media (prefers-reduced-motion: no-preference) {
  .faq-item[open] .faq-a { animation:faqReveal .4s cubic-bezier(.16,1,.3,1); }
  @keyframes faqReveal { from { opacity:0; transform:translateY(-6px); } to { opacity:1; transform:none; } }
}

/* Scroll reveal lives entirely in assets/js/motion.js now. The old
   reveal.js engine and its .rv / html.has-reveal styles were removed so a
   single system owns every reveal on the page. */

/* ── Animated nav underline ───────────────────────────────────────────── */
.nl { position: relative; }
.nl::after {
  content: ''; position: absolute; left: 0; bottom: -5px; height: 1px; width: 100%;
  background: currentColor; opacity: .75; transform: scaleX(0); transform-origin: left;
  transition: transform .34s cubic-bezier(.16,1,.3,1);
}
.nl:hover::after { transform: scaleX(1); }

/* ── Homepage "More Releases" cover-card row ──────────────────────────── */
.feat-more { padding: 0 clamp(28px,5vw,88px); max-width: 1480px; margin: clamp(52px,7vw,88px) auto 0; }
.feat-more .sec-hd { margin-bottom: 28px; }

/* ── Footer newsletter ────────────────────────────────────────────────── */
.ftr-news { display:flex; justify-content:space-between; gap:32px; flex-wrap:wrap; align-items:flex-end; padding-bottom:36px; margin-bottom:36px; border-bottom:1px solid var(--hair-soft); }
.ftr-news-h { font-family:var(--font-display); font-weight:700; font-size:clamp(1.3rem,2.4vw,1.9rem); letter-spacing:-.02em; color:var(--text-primary); margin-bottom:8px; }
.ftr-news-sub { color:var(--text-secondary); font-size:.9rem; line-height:1.6; max-width:46ch; }
.ftr-news-form { display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.ftr-news-input { background:transparent; border:1px solid var(--hair); color:var(--text-primary); font-family:var(--font-mono); font-size:.8rem; padding:12px 16px; min-width:240px; transition:border-color .3s ease; }
.ftr-news-input:focus { outline:none; border-color:var(--gold); }
.ftr-news-input::placeholder { color:var(--text-muted); }
.ftr-news-btn { font-family:var(--font-mono); font-size:.7rem; letter-spacing:.1em; text-transform:uppercase; background:var(--azpex-text-primary); color:var(--azpex-bg); border:1px solid var(--azpex-text-primary); padding:12px 20px; cursor:pointer; white-space:nowrap; transition:background .3s ease,border-color .3s ease,color .3s ease,transform .3s ease; }
.ftr-news-btn:hover { background:var(--gold); border-color:var(--gold); transform:translateY(-1px); }
.ftr-news-msg { font-family:var(--font-mono); font-size:.68rem; letter-spacing:.04em; color:var(--gold); flex-basis:100%; margin-top:2px; }

/* ==========================================================================
   AZPEX  --  PRODUCT ACTION PANEL
   The product detail CTA is a summary action panel, not a lone button row.
   Sits on surface-raised with a very light champagne wash for warmth.
   ========================================================================== */
.pd-action {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(20px, 3vw, 46px);
  margin-top: clamp(22px, 3vw, 34px);
  padding: clamp(20px, 2.6vw, 30px) clamp(20px, 2.8vw, 34px);
  background:
    linear-gradient(135deg, var(--azpex-accent-wash) 0%, transparent 58%),
    var(--azpex-surface-raised);
  border: 1px solid var(--azpex-border);
  border-radius: 4px;
  box-shadow:
    inset 0 1px 0 rgba(245, 241, 234, .04),
    0 18px 44px rgba(0, 0, 0, .34);
  transition: border-color var(--motion-medium) var(--ease-ui),
              box-shadow var(--motion-medium) var(--ease-ui);
}
.pd-action:hover {
  border-color: var(--azpex-accent-dark);
  box-shadow:
    inset 0 1px 0 rgba(245, 241, 234, .05),
    0 22px 52px rgba(0, 0, 0, .40);
}
.pd-action-main { min-width: 0; }
.pd-action-eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-mono);
  font-size: .625rem; letter-spacing: .17em; text-transform: uppercase;
  color: var(--azpex-accent); margin-bottom: 11px;
}
.pd-action-eyebrow::before {
  content: ''; width: 18px; height: 1px;
  background: var(--azpex-accent-dark); flex-shrink: 0;
}
.pd-action-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.4rem, 2.4vw, 1.95rem); line-height: 1.05;
  letter-spacing: -.015em; color: var(--azpex-text-primary);
}
.pd-action-desc {
  margin-top: 9px; max-width: 46ch;
  font-size: .935rem; line-height: 1.5; color: var(--azpex-text-secondary);
}
.pd-action-chips {
  display: flex; flex-wrap: wrap; gap: 7px; margin-top: 15px; list-style: none;
}
.pd-action-chips li {
  font-family: var(--font-mono);
  font-size: .61rem; letter-spacing: .11em; text-transform: uppercase;
  color: var(--azpex-text-secondary);
  padding: 5px 10px;
  border: 1px solid var(--azpex-border-soft);
  border-radius: 2px;
  background: rgba(245, 241, 234, .022);
}
.pd-action-cta {
  display: flex; flex-direction: column; align-items: stretch; gap: 10px;
  min-width: min(268px, 100%);
}
.pd-action-price {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.5rem; letter-spacing: -.01em;
  color: var(--azpex-accent-bright); line-height: 1;
  margin-bottom: 2px;
}
.pd-action-trust {
  font-family: var(--font-mono);
  font-size: .59rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--azpex-text-muted); text-align: center; margin-top: 1px;
}
/* Secondary action inside the panel */
.pd-cta-2 {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-mono);
  font-size: .68rem; letter-spacing: .13em; text-transform: uppercase;
  padding: 12px 20px;
  color: var(--azpex-text-secondary);
  background: transparent;
  border: 1px solid var(--azpex-border);
  border-radius: 2px; cursor: pointer;
  text-decoration: none;
  transition: color var(--motion-fast) var(--ease-ui),
              border-color var(--motion-fast) var(--ease-ui),
              transform var(--motion-fast) var(--ease-ui);
}
.pd-cta-2:hover {
  color: var(--azpex-accent-bright);
  border-color: var(--azpex-accent-dark);
  transform: translateY(-2px);
}
.pd-cta-2:active { transform: translateY(0); }
.pd-cta-2:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 3px; }

@media (max-width: 760px) {
  .pd-action { grid-template-columns: 1fr; gap: 20px; }
  .pd-action-cta { min-width: 0; }
  .pd-action-price { font-size: 1.35rem; }
}

/* ==========================================================================
   AZPEX  --  TIP MODAL
   Free downloads open a native, site-styled tip chooser. The free option is
   a real, comfortable choice, never a guilt link.
   ========================================================================== */
.tip-backdrop {
  position: fixed; inset: 0; z-index: 900;
  background: var(--azpex-scrim);
  backdrop-filter: blur(7px); -webkit-backdrop-filter: blur(7px);
  opacity: 0; visibility: hidden; pointer-events: none;
  /* visibility is the real "off switch" here, not opacity. Some GPUs/
     browsers keep compositing (and rendering) backdrop-filter on an
     opacity:0 element, which reads as a faint permanent blur sitting over
     the whole page long after the modal was closed. visibility:hidden
     removes it from rendering outright; the delay lets the opacity fade-out
     finish first so closing still looks like a fade, not a snap. */
  transition: opacity var(--motion-medium) var(--ease-ui),
              visibility 0s linear var(--motion-medium);
}
.tip-backdrop.is-open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity var(--motion-medium) var(--ease-ui), visibility 0s;
}

.tip-modal {
  position: fixed; z-index: 901;
  top: 50%; left: 50%;
  width: min(452px, calc(100vw - 32px));
  max-height: calc(100vh - 40px); overflow-y: auto;
  padding: clamp(24px, 3.4vw, 34px);
  background: var(--azpex-surface-raised);
  border: 1px solid var(--azpex-border);
  border-radius: 5px;
  box-shadow: 0 34px 90px rgba(0, 0, 0, .62);
  transform: translate(-50%, -48%) scale(.96);
  opacity: 0; pointer-events: none;
  transition: opacity var(--motion-medium) var(--ease-ui),
              transform var(--motion-medium) var(--ease-heavy);
}
.tip-modal.is-open {
  opacity: 1; pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}
.tip-close {
  position: absolute; top: 13px; right: 13px;
  width: 30px; height: 30px; display: grid; place-items: center;
  background: transparent; border: 1px solid transparent; border-radius: 2px;
  color: var(--azpex-text-muted); font-size: 1.05rem; line-height: 1;
  cursor: pointer;
  transition: color var(--motion-fast) var(--ease-ui),
              border-color var(--motion-fast) var(--ease-ui);
}
.tip-close:hover { color: var(--azpex-text-primary); border-color: var(--azpex-border); }
.tip-close:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 2px; }

.tip-eyebrow {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--font-mono);
  font-size: .6rem; letter-spacing: .17em; text-transform: uppercase;
  color: var(--azpex-accent); margin-bottom: 10px;
}
.tip-eyebrow::before {
  content: ''; width: 16px; height: 1px;
  background: var(--azpex-accent-dark); flex-shrink: 0;
}
.tip-title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.28rem, 2.2vw, 1.6rem); line-height: 1.12;
  letter-spacing: -.015em; color: var(--azpex-text-primary);
}
.tip-desc {
  margin-top: 10px; font-size: .9rem; line-height: 1.55;
  color: var(--azpex-text-secondary);
}
.tip-options { display: grid; gap: 8px; margin-top: 20px; }
.tip-opt {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 13px 16px;
  background: rgba(245, 241, 234, .022);
  border: 1px solid var(--azpex-border-soft);
  border-radius: 3px;
  color: var(--azpex-text-primary); text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-ui),
              background var(--motion-fast) var(--ease-ui),
              transform var(--motion-fast) var(--ease-ui);
}
.tip-opt:hover {
  border-color: var(--azpex-accent-dark);
  background: rgba(245, 241, 234, .04);
  transform: translateY(-2px);
}
.tip-opt:active { transform: translateY(0); }
.tip-opt:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 2px; }
.tip-opt-amt {
  font-family: var(--font-display); font-weight: 700; font-size: 1.02rem;
  letter-spacing: -.01em;
}
.tip-opt-tag {
  font-family: var(--font-mono);
  font-size: .58rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--azpex-text-muted);
}
/* Recommended gets a light champagne lift, nothing louder. */
.tip-opt.is-rec {
  border-color: var(--azpex-accent-dark);
  background:
    linear-gradient(135deg, var(--azpex-accent-wash) 0%, transparent 62%),
    rgba(245, 241, 234, .03);
}
.tip-opt.is-rec .tip-opt-amt { color: var(--azpex-accent-bright); }
.tip-opt.is-rec .tip-opt-tag { color: var(--azpex-accent); }

.tip-free-wrap {
  margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--azpex-border-soft);
}
/* The free path is a full-width, legible action. Not small, not hidden. */
.tip-free {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; padding: 13px 18px;
  font-family: var(--font-mono);
  font-size: .69rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--azpex-text-primary);
  background: transparent;
  border: 1px solid var(--azpex-border);
  border-radius: 3px; text-decoration: none;
  transition: border-color var(--motion-fast) var(--ease-ui),
              color var(--motion-fast) var(--ease-ui),
              transform var(--motion-fast) var(--ease-ui);
}
.tip-free:hover {
  color: var(--azpex-hover);
  border-color: var(--azpex-text-muted);
  transform: translateY(-2px);
}
.tip-free:active { transform: translateY(0); }
.tip-free:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 3px; }
.tip-note {
  margin-top: 12px; text-align: center;
  font-family: var(--font-mono);
  font-size: .58rem; letter-spacing: .1em; text-transform: uppercase;
  color: var(--azpex-text-muted);
}
body.tip-lock { overflow: hidden; }

/* ==========================================================================
   AZPEX  --  3D MOTION SYSTEM
   Depth comes from controlled perspective, layered Z distance and weighted
   easing. Nothing spins, nothing loops, nothing follows the cursor exactly.
   ========================================================================== */

/* ---- Card tilt -----------------------------------------------------------
   The scene owns the perspective; the inner plate does the rotating, so the
   layers inside keep a shared vanishing point. Angles are driven from JS
   through --rx / --ry, interpolated on rAF (never straight from pointermove). */
.cat-prod-card,
.prod-art-wrap {
  perspective: 1100px;
  perspective-origin: center;
}
.tilt-plate {
  transform-style: preserve-3d;
  transform:
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg))
    translateY(var(--lift, 0px));
  transition: transform var(--motion-medium) var(--ease-heavy);
  will-change: auto;
}
.tilt-plate.is-live { transition: none; }

/* Layered Z so the card is never one flat plane. */
.cat-prod-card .cat-prod-card-art  { transform: translateZ(12px); transform-style: flat; }
.cat-prod-card .cat-prod-card-art img {
  transform: scale(var(--cover-scale, 1));
  transition: transform var(--motion-medium) var(--ease-heavy);
}
.cat-prod-card .cat-prod-card-body { transform: translateZ(8px); }

/* Shadow reacts against the tilt direction, as if the light stays put. */
.cat-prod-card .tilt-plate {
  box-shadow: var(--tilt-shadow, 0 10px 26px rgba(0, 0, 0, .30));
  transition: transform var(--motion-medium) var(--ease-heavy),
              box-shadow var(--motion-medium) var(--ease-ui),
              border-color var(--motion-medium) var(--ease-ui);
}

/* Card text answers the tilt at a lower rate than the cover. */
.cat-prod-card:hover .cat-prod-card-name { transform: translateZ(14px); }
.cat-prod-card:hover .cat-prod-card-type  { transform: translateY(-2px); }
.cat-prod-card:hover .cat-prod-card-cta   { transform: translateX(4px); }
.cat-prod-card:hover .cat-prod-card-price { color: var(--azpex-accent-bright); }
.cat-prod-card-name,
.cat-prod-card-type,
.cat-prod-card-cta,
.cat-prod-card-price {
  transition: transform var(--motion-medium) var(--ease-heavy),
              color var(--motion-medium) var(--ease-ui);
}

/* Featured products carry slightly more depth than grid cards. */
.prod-art-wrap .tilt-card { transform-style: preserve-3d; }
.prod-art-wrap .prod-play-btn {
  transform: translate(-50%, -50%) translateZ(var(--depth-high));
}
.prod-art-wrap.is-playing .prod-play-btn:not(:hover) { animation: azpexBreathe 3.6s ease-in-out infinite; }
@keyframes azpexBreathe {
  0%, 100% { transform: translate(-50%, -50%) translateZ(var(--depth-high)) scale(1); }
  50%      { transform: translate(-50%, -50%) translateZ(var(--depth-high)) scale(1.028); }
}

/* ---- Reveals -------------------------------------------------------------
   One easing family across the site; only the composition changes per block. */
.motion-ready [data-reveal] {
  opacity: 0;
  transform: translateY(26px) translateZ(-18px) rotateX(4deg);
  transition:
    opacity var(--motion-slow) var(--ease-ui),
    transform var(--motion-slow) var(--ease-heavy);
  transition-delay: var(--reveal-delay, 0ms);
}
.motion-ready [data-reveal].is-in {
  opacity: 1;
  transform: translateY(0) translateZ(0) rotateX(0deg);
}
/* Word-group reveal for large display headings. */
[data-reveal-words] { perspective: 800px; }
.motion-ready [data-reveal-words] .rv-w {
  display: inline-block;
  opacity: 0;
  transform: translateY(30px) translateZ(-22px) rotateX(5deg);
  transition:
    opacity var(--motion-slow) var(--ease-ui),
    transform var(--motion-slow) var(--ease-heavy);
  transition-delay: var(--w-delay, 0ms);
}
.motion-ready [data-reveal-words].is-in .rv-w { opacity: 1; transform: none; }

/* Section label: hairline opens first, then the label. */
.motion-ready [data-reveal-line]::before {
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--motion-medium) var(--ease-heavy);
}
.motion-ready [data-reveal-line].is-in::before { transform: scaleX(1); }

/* Dividers draw open horizontally as they enter. */
.motion-ready [data-reveal-rule] {
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--motion-slow) var(--ease-heavy);
}
.motion-ready [data-reveal-rule].is-in { transform: scaleX(1); }

/* ---- Background depth ----------------------------------------------------
   Background layers travel slower than content. Driven by --py from JS. */
/* Parallax uses the independent `translate` property, not `transform`, so it
   COMPOSES with an element's own centring transform instead of replacing it.
   Setting transform here silently knocked the hero wordmark and glow out of
   the centre of the page. */
[data-parallax] {
  translate: 0 var(--py, 0px);
  will-change: transform;
}

/* ---- Navigation ----------------------------------------------------------
   Settles in on load, condenses on scroll down, returns on scroll up. */
/* ---- Navigation ----------------------------------------------------------
   The real header is .hdr. Scrolling down condenses it: the bar loses height,
   the padding tightens, the background gains density and the bottom edge
   firms up. Scrolling back up restores it. The bar never leaves the screen. */
.hdr {
  transition:
    background var(--motion-medium) var(--ease-ui),
    border-color var(--motion-medium) var(--ease-ui),
    box-shadow var(--motion-medium) var(--ease-ui);
}
.hdr-in {
  transition:
    min-height var(--motion-medium) var(--ease-heavy),
    padding-block var(--motion-medium) var(--ease-heavy);
}
.hdr.is-condensed {
  background: rgba(15, 13, 11, .90);
  border-bottom-color: var(--azpex-border);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .34);
}
.hdr.is-condensed .hdr-in { min-height: 54px; padding-block: 0; }
.hdr.is-condensed .brand-mark { transform: scale(.92); }
.brand-mark { transition: transform var(--motion-medium) var(--ease-heavy); }

@keyframes azpexNavIn {
  from { opacity: 0; transform: translateY(-14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.hdr.is-ready { animation: azpexNavIn var(--motion-slow) var(--ease-heavy) both; }

/* ---- Buttons -------------------------------------------------------------
   Physical press: lift and widen on hover, settle and shorten on press.
   No spring, no bounce, no large scale. */
.btn-p, .prod-btn, .pd-cta, .top-btn {
  transition:
    background var(--motion-fast) var(--ease-ui),
    border-color var(--motion-fast) var(--ease-ui),
    color var(--motion-fast) var(--ease-ui),
    transform var(--motion-fast) var(--ease-ui),
    box-shadow var(--motion-fast) var(--ease-ui);
}
.btn-p:active, .prod-btn:active, .pd-cta:active, .top-btn:active,
.pd-cta-2:active {
  transform: translateY(0);
  box-shadow: 0 3px 10px rgba(0, 0, 0, .26);
}
/* The arrow moves independently of the button body. */
.btn-p .cta-arw, .prod-btn .cta-arw, .pd-cta .cta-arw {
  display: inline-block;
  transition: transform var(--motion-medium) var(--ease-heavy);
}
.btn-p:hover .cta-arw, .prod-btn:hover .cta-arw, .pd-cta:hover .cta-arw { transform: translateX(4px); }

/* ---- Mobile --------------------------------------------------------------
   Tilt is dropped on touch; depth, reveals and modal motion stay. */
@media (hover: none), (max-width: 760px) {
  .tilt-plate { transform: translateY(var(--lift, 0px)); }
  .cat-prod-card .cat-prod-card-art img { transform: none; }
  .cat-prod-card:hover .cat-prod-card-name,
  .cat-prod-card:hover .cat-prod-card-type,
  .cat-prod-card:hover .cat-prod-card-cta { transform: none; }
}

/* ---- Reduced motion ------------------------------------------------------
   Everything resolves to its final, readable state. Nothing animates. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal],
  [data-reveal-words] .rv-w { opacity: 1 !important; transform: none !important; }
  [data-reveal-rule], [data-reveal-line]::before { transform: scaleX(1) !important; }
  .tilt-plate { transform: none !important; }
  [data-parallax] { translate: none !important; }
  .prod-art-wrap.is-playing .prod-play-btn { animation: none !important; }
}

/* ---- Card shell handoff --------------------------------------------------
   The box treatment moves onto the rotating plate so the border and surface
   turn with the card instead of staying flat around it. The outer anchor
   keeps only layout and perspective. Legacy flat hover transforms are
   retired here; lift and cover scale are driven by the motion engine. */
.cat-prod-card {
  border: 0; background: none;
  transform: none !important;
}
/* The plate keeps preserve-3d and stays unclipped; the art frame inside is
   what actually crops the image, so the inner Z layers survive. */
.cat-prod-card > .tilt-plate {
  display: flex; flex-direction: column; height: 100%;
  background: var(--azpex-bg-soft);
  border: 1px solid var(--azpex-border-soft);
  border-radius: 3px;
  overflow: visible;
}
.cat-prod-card .cat-prod-card-art {
  overflow: hidden;
  border-radius: 2px 2px 0 0;
}
.cat-prod-card:hover > .tilt-plate,
.cat-prod-card:focus-within > .tilt-plate { border-color: var(--azpex-accent-dark); }
.cat-prod-card:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 4px; }
/* Cover scale is a single source of truth: the --cover-scale variable. */
.cat-prod-card:hover .cat-prod-card-art img { transform: scale(var(--cover-scale, 1)); }

/* Featured cover plate carries the frame and the deeper lift. */
/* The plate is the 3D scene: it rotates and keeps preserve-3d, so it must
   stay unclipped. The frame inside it does the cropping. Never both on one
   element, or every translateZ layer collapses flat. */
.prod-art-wrap > .tilt-card {
  display: block; border-radius: 3px;
  overflow: visible;
  transform-style: preserve-3d;
}
.prod-art-wrap .prod-cover-frame {
  position: relative;
  overflow: hidden;
  border-radius: 3px;
  transform: translateZ(0);
}

/* The featured cover keeps its historic .tilt-card wrapper; it is simply
   driven by the same variables as every other plate. */
.prod-art-wrap .tilt-card {
  transform:
    rotateX(var(--rx, 0deg))
    rotateY(var(--ry, 0deg))
    translateY(var(--lift, 0px));
  transition: transform var(--motion-medium) var(--ease-heavy),
              box-shadow var(--motion-medium) var(--ease-ui);
  box-shadow: var(--tilt-shadow, 0 12px 30px rgba(0, 0, 0, .34));
}
.prod-art-wrap .tilt-card.is-live { transition: none; }
.prod-art-wrap .prod-cover { transform: translateZ(14px); }
@media (hover: none), (max-width: 760px) {
  .prod-art-wrap .tilt-card { transform: translateY(var(--lift, 0px)); }
}
@media (prefers-reduced-motion: reduce) {
  .prod-art-wrap .tilt-card { transform: none !important; }
}

/* ---- Action panel host ---------------------------------------------------
   When the closing section carries the action panel, the panel itself is the
   frame. The old section border and split layout would double it up. */
.pd-final:has(.pd-action) {
  display: block;
  border: 0;
  padding: 0;
}
.pd-final > .pd-action { width: 100%; }

/* ---- Primary button, per the brand button system -------------------------
   Bone white surface, warm black label; champagne only on hover. This keeps
   the accent at roughly 5% of the page instead of sitting on every CTA. */
.pd-cta {
  background: var(--azpex-text-primary);
  color: var(--azpex-bg);
  border: 1px solid var(--azpex-text-primary);
  border-radius: 2px;
  justify-content: center;
}
.pd-cta:hover {
  background: var(--azpex-accent-bright);
  border-color: var(--azpex-accent-bright);
  color: var(--azpex-bg);
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(138, 107, 79, .26);
}
.pd-cta:focus-visible { outline: 2px solid var(--azpex-accent-bright); outline-offset: 3px; }

/* ---- Readable small text -------------------------------------------------
   These carry information, so they use the readable muted step rather than
   the decorative one. Large background typography stays dim on purpose. */
.cat-prod-card-cta,
.pd-action-trust,
.tip-note,
.tip-opt-tag,
.pd-h2-note,
.trk-dur,
.preview-cat,
.pd-specs li,
.ftr-nl,
.ftr-note,
.mob-nl,
.sec-note,
.rv-head-count,
.pd-code { color: var(--azpex-text-muted-readable); }
.preview-cat:hover { color: var(--azpex-text-primary); }

/* ==========================================================================
   AZPEX  --  REACT BITS ADAPTATIONS
   Every effect below is rebuilt in plain CSS/JS from the React Bits source,
   not copied as a dependency. Intensities are deliberately far below the
   library defaults so the site stays analog and editorial rather than
   turning into an animation demo.
   ========================================================================== */

/* ---- Dark Veil (adapted) -------------------------------------------------
   Source renders a CPPN fragment shader through ogl with hue shift, noise,
   scanlines and warp. A WebGL layer here would fight the Three.js hero for
   the GPU, so this is a two-gradient veil that drifts on a very slow cycle
   plus a faint scanline wash. Same read, no second WebGL context. */
.hero-veil {
  position: absolute; inset: 0; z-index: 0;
  pointer-events: none; overflow: hidden;
  opacity: .5;
}
.hero-veil::before {
  content: ''; position: absolute; inset: -22%;
  background:
    radial-gradient(46% 38% at 28% 34%, rgba(200,163,125,.055), transparent 62%),
    radial-gradient(40% 44% at 74% 62%, rgba(138,107,79,.05),  transparent 66%),
    radial-gradient(56% 40% at 52% 88%, rgba(15,13,11,.55),    transparent 70%);
  filter: blur(14px);
  animation: veilDrift 46s ease-in-out infinite alternate;
}
/* Scanline pass, kept at the threshold of visibility. */
.hero-veil::after {
  content: ''; position: absolute; inset: 0;
  background: repeating-linear-gradient(
    0deg, rgba(0,0,0,.10) 0px, rgba(0,0,0,.10) 1px, transparent 1px, transparent 4px);
  opacity: .05;
}
@keyframes veilDrift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  100% { transform: translate3d(1.5%, -1.2%, 0) scale(1.045); }
}

/* ---- Light Rays (adapted) ------------------------------------------------
   Source casts shader cones from an anchor with spread, length and fade, and
   can follow the mouse. Mouse-follow is dropped on purpose (the brief rules
   out cursor-follow lighting). These are three static champagne cones from
   top-center, masked to fade out, breathing very slowly. */
.hero-rays {
  position: absolute; left: 50%; top: -12%;
  width: min(150vw, 1500px); height: min(105vh, 1000px);
  transform: translateX(-50%);
  pointer-events: none; z-index: 0; overflow: hidden;
  opacity: .5;
  -webkit-mask-image: radial-gradient(58% 70% at 50% 4%, #000 0%, transparent 78%);
          mask-image: radial-gradient(58% 70% at 50% 4%, #000 0%, transparent 78%);
}
.hero-rays::before {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(178deg, rgba(221,185,142,.085) 0%, transparent 46%),
    linear-gradient(170deg, rgba(200,163,125,.055) 0%, transparent 40%),
    linear-gradient(188deg, rgba(200,163,125,.05)  0%, transparent 42%);
  filter: blur(20px);
  animation: raysBreathe 19s ease-in-out infinite alternate;
}
@keyframes raysBreathe {
  0%   { opacity: .78; transform: scaleY(1); }
  100% { opacity: 1;   transform: scaleY(1.045); }
}

/* ---- Gradual Blur (adapted) ---------------------------------------------
   Source stacks divCount layers, each with a stronger backdrop-filter and a
   mask gradient. Same idea, four layers, at the hero/section seam only. */
.grad-blur {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 6rem; z-index: 5; pointer-events: none;
}
.grad-blur > span {
  position: absolute; inset: 0; display: block;
}
.grad-blur > span:nth-child(1) {
  backdrop-filter: blur(.5px); -webkit-backdrop-filter: blur(.5px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 25%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 0%, #000 25%, #000 100%);
}
.grad-blur > span:nth-child(2) {
  backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 25%, #000 50%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 25%, #000 50%, #000 100%);
}
.grad-blur > span:nth-child(3) {
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 50%, #000 75%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 50%, #000 75%, #000 100%);
}
.grad-blur > span:nth-child(4) {
  backdrop-filter: blur(3.5px); -webkit-backdrop-filter: blur(3.5px);
  -webkit-mask-image: linear-gradient(to bottom, transparent 75%, #000 100%);
          mask-image: linear-gradient(to bottom, transparent 75%, #000 100%);
}

/* ---- Noise (adapted) -----------------------------------------------------
   Source paints animated grain onto a canvas every other frame. The site
   already has an SVG turbulence grain layer, so per the brief this is NOT a
   second layer: the existing .grain is given a slightly finer, warmer read. */
.grain { opacity: .058; }

/* ---- Blur Text + Scroll Reveal (adapted) ---------------------------------
   Blur Text animates each word blur(10px)/opacity 0 -> blur(5px)/opacity .5
   -> blur(0)/opacity 1. Scroll Reveal adds a small container rotation and a
   word opacity ramp. Both are folded into the existing word reveal, at lower
   travel: blur starts at 6px rather than 10px and there is no letter mode. */
.motion-ready [data-reveal-words] {
  transform: rotate(var(--sr-rot, 1.4deg));
  transform-origin: 0% 50%;
  transition: transform var(--motion-slow) var(--ease-heavy);
}
.motion-ready [data-reveal-words].is-in { transform: rotate(0deg); }
.motion-ready [data-reveal-words] .rv-w {
  filter: blur(6px);
  transition:
    opacity var(--motion-slow) var(--ease-ui),
    transform var(--motion-slow) var(--ease-heavy),
    filter var(--motion-slow) var(--ease-ui);
}
.motion-ready [data-reveal-words].is-in .rv-w { filter: blur(0px); }

@media (prefers-reduced-motion: reduce) {
  .hero-veil::before, .hero-rays::before { animation: none !important; }
  .motion-ready [data-reveal-words] { transform: none !important; }
  .motion-ready [data-reveal-words] .rv-w { filter: none !important; }
}

/* ---- Glare Hover (adapted) -----------------------------------------------
   Source uses a ::before carrying an angled linear-gradient whose
   background-position transitions from -100% -100% to 100% 100% on hover,
   over 650ms, with glareSize 250%. Rebuilt here with the same mechanism but
   a warm champagne tint at roughly a fifth of the library's 0.5 opacity, so
   it reads as light moving over a printed sleeve. No rainbow, no white blowout.
   This REPLACES the old keyframe sheen rather than stacking on top of it. */
.cat-prod-card-art::after,
.pd-cover-frame::after {
  content: ''; position: absolute; inset: 0; z-index: 3;
  pointer-events: none;
  top: auto; left: auto; width: auto; height: auto;
  opacity: 1; filter: none; transform: none;
  background-image: linear-gradient(
    -32deg,
    rgba(0,0,0,0) 58%,
    rgba(221,185,142,.10) 70%,
    rgba(0,0,0,0) 80%,
    rgba(0,0,0,0) 100%);
  background-repeat: no-repeat;
  background-size: 250% 250%;
  background-position: -100% -100%;
  transition: background-position 900ms ease;
  animation: none !important;
}
.cat-prod-card:hover .cat-prod-card-art::after,
.pd-cover:hover .pd-cover-frame::after { background-position: 100% 100%; }

@media (hover: none), (max-width: 760px) {
  .cat-prod-card-art::after, .pd-cover-frame::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .cat-prod-card-art::after, .pd-cover-frame::after { transition: none; }
}

/* ---- Reflective Card (adapted, Featured Products only) -------------------
   Source layers a moving sheen gradient, a noise pass and a gradient border
   masked with mask-composite: exclude. Rebuilt with the same three layers,
   scoped strictly to the featured covers so the rest of the site keeps its
   matte finish. The reflection is warm and materially soft, not chrome. */
.prod-art-wrap .tilt-card { position: relative; }

/* 1. Sheen: a soft diagonal band that shifts as the plate turns. */
.prod-art-wrap .tilt-card::before {
  content: ''; position: absolute; inset: 0; z-index: 4;
  pointer-events: none; border-radius: inherit;
  background: linear-gradient(
    calc(148deg + var(--ry, 0deg) * 2.4),
    rgba(255, 248, 236, 0) 34%,
    rgba(255, 246, 230, .07) 48%,
    rgba(221, 185, 142, .05) 56%,
    rgba(255, 248, 236, 0) 70%);
  opacity: .85;
  transition: opacity var(--motion-medium) var(--ease-ui);
}
.prod-art-wrap:hover .tilt-card::before { opacity: 1; }

/* 2. Gradient edge, masked to the border only (mask-composite: exclude). */
.prod-art-wrap .tilt-card::after {
  content: ''; position: absolute; inset: 0; z-index: 5;
  pointer-events: none; border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    calc(148deg + var(--ry, 0deg) * 2.4),
    rgba(221, 185, 142, .30) 0%,
    rgba(245, 241, 234, .10) 42%,
    rgba(138, 107, 79, .22) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask-composite: exclude;
}
/* 3. The site grain already supplies the noise pass, so no extra layer. */

@media (hover: none), (max-width: 760px) {
  .prod-art-wrap .tilt-card::before { opacity: .7; }
}
@media (prefers-reduced-motion: reduce) {
  .prod-art-wrap .tilt-card::before { transition: none; }
}

/* ---- Specular Button + Magnet (adapted) ----------------------------------
   Magnet: translate is driven by --mx / --my, capped at 3px in the engine, so
   the button leans toward the cursor instead of chasing it. It uses the
   independent `translate` property so it composes with the existing hover
   lift instead of overwriting it.
   Specular: a soft warm highlight follows --sx / --sy with its strength in
   --spec, plus the inset top edge the source uses. No canvas per button. */
.btn-p, .prod-btn, .prod-btn-ghost, .pd-cta, .pd-cta-2, .top-btn,
.tip-opt, .tip-free {
  position: relative;
  overflow: hidden;
  translate: var(--mx, 0px) var(--my, 0px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .045);
}
.btn-p::after, .prod-btn::after, .prod-btn-ghost::after, .pd-cta::after,
.pd-cta-2::after, .top-btn::after, .tip-opt::after, .tip-free::after {
  content: ''; position: absolute; inset: 0;
  pointer-events: none; border-radius: inherit;
  background: radial-gradient(
    62% 130% at var(--sx, 50%) var(--sy, 50%),
    rgba(255, 250, 240, .16) 0%,
    rgba(221, 185, 142, .07) 38%,
    transparent 72%);
  opacity: calc(var(--spec, 0) * .9);
  transition: opacity var(--motion-fast) linear;
}
/* On the bone-white primary the highlight would wash out, so it darkens. */
.pd-cta::after, .btn-p::after, .prod-btn::after {
  background: radial-gradient(
    62% 130% at var(--sx, 50%) var(--sy, 50%),
    rgba(255, 255, 255, .22) 0%,
    rgba(255, 246, 232, .10) 40%,
    transparent 74%);
  mix-blend-mode: overlay;
}
/* The label must stay above the highlight layer. */
.btn-p > *, .prod-btn > *, .prod-btn-ghost > *, .pd-cta > *,
.pd-cta-2 > *, .tip-opt > *, .tip-free > * { position: relative; z-index: 1; }

@media (hover: none), (max-width: 760px) {
  .btn-p, .prod-btn, .prod-btn-ghost, .pd-cta, .pd-cta-2, .top-btn,
  .tip-opt, .tip-free { translate: none; }
  .btn-p::after, .prod-btn::after, .prod-btn-ghost::after, .pd-cta::after,
  .pd-cta-2::after, .top-btn::after, .tip-opt::after, .tip-free::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .btn-p, .prod-btn, .prod-btn-ghost, .pd-cta, .pd-cta-2, .top-btn,
  .tip-opt, .tip-free { translate: none !important; }
}

/* ---- Grainient (adapted) -------------------------------------------------
   Source is a WebGL warped-gradient shader with its own grain pass. Rebuilt
   as a warm multi-stop gradient wash; the site's existing SVG grain supplies
   the grain, so no shader and no second noise layer. Used only on the two
   surfaces that should feel like warm paper: the action panel and the modal. */
.pd-action, .tip-modal { position: relative; isolation: isolate; }
.pd-action::before, .tip-modal::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  border-radius: inherit; pointer-events: none;
  background:
    radial-gradient(72% 120% at 12% 0%,   rgba(221,185,142,.075), transparent 58%),
    radial-gradient(60% 100% at 92% 12%,  rgba(200,163,125,.045), transparent 60%),
    radial-gradient(80% 90%  at 50% 108%, rgba(138,107,79,.055),  transparent 66%);
}

/* ---- Border Glow (adapted, $5 Recommended only) --------------------------
   Source paints stacked radial gradients into a border-box layer and masks it
   with mask-composite so only the edge lights. Rebuilt with a single smoked
   champagne gradient at low alpha. Deliberately not a neon or conic rainbow. */
.tip-opt.is-rec { position: relative; }
.tip-opt.is-rec::before {
  content: ''; position: absolute; inset: 0; z-index: 0;
  border-radius: inherit; padding: 1px; pointer-events: none;
  background: linear-gradient(
    128deg,
    rgba(221,185,142,.55) 0%,
    rgba(200,163,125,.18) 44%,
    rgba(138,107,79,.42) 100%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask-composite: exclude;
  opacity: .85;
  transition: opacity var(--motion-medium) var(--ease-ui);
}
.tip-opt.is-rec:hover::before { opacity: 1; }

/* ---- Modal opening sequence ----------------------------------------------
   Overlay first, then the panel arrives on a small scale step, then the copy,
   then the tip rows stagger in. No bounce and no elastic overshoot. */
.tip-modal .tip-eyebrow,
.tip-modal .tip-title,
.tip-modal .tip-desc,
.tip-modal .tip-free-wrap {
  opacity: 0; transform: translateY(8px);
  transition: opacity var(--motion-medium) var(--ease-ui),
              transform var(--motion-medium) var(--ease-heavy);
}
.tip-modal.is-open .tip-eyebrow    { opacity: 1; transform: none; transition-delay: 130ms; }
.tip-modal.is-open .tip-title      { opacity: 1; transform: none; transition-delay: 175ms; }
.tip-modal.is-open .tip-desc       { opacity: 1; transform: none; transition-delay: 215ms; }
.tip-modal.is-open .tip-free-wrap  { opacity: 1; transform: none; transition-delay: 470ms; }

.tip-modal .tip-opt {
  opacity: 0; transform: translateY(10px);
  transition: opacity var(--motion-medium) var(--ease-ui),
              transform var(--motion-medium) var(--ease-heavy),
              border-color var(--motion-fast) var(--ease-ui),
              background var(--motion-fast) var(--ease-ui);
}
.tip-modal.is-open .tip-opt {
  opacity: 1; transform: none;
  transition-delay: calc(260ms + var(--reveal-delay, 0ms));
}
.tip-modal.is-open .tip-opt:hover { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
  .tip-modal .tip-eyebrow, .tip-modal .tip-title, .tip-modal .tip-desc,
  .tip-modal .tip-free-wrap, .tip-modal .tip-opt {
    opacity: 1 !important; transform: none !important; transition-delay: 0ms !important;
  }
}

/* ---- Sticker Peel (adapted) ----------------------------------------------
   Source lifts a sticker with clip-path polygons at 30% hover / 40% active
   peelback plus a mirrored shadow flap. Rebuilt as a SINGLE corner lift: the
   badge is clipped at the top-right and a small flap folds back over it. The
   sticker never peels off, only one corner ever moves. Applied strictly to
   FREE labels and the AZPX catalogue code. */
.peel {
  --peel: 0;
  position: relative;
  display: inline-block;
  clip-path: polygon(
    0 0,
    calc(100% - (7px * var(--peel))) 0,
    100% calc(7px * var(--peel)),
    100% 100%,
    0 100%);
  transition: clip-path var(--motion-medium) var(--ease-heavy),
              filter var(--motion-medium) var(--ease-ui);
}
/* The folded-back corner: a small warm flap with its own soft shadow. */
.peel::after {
  content: ''; position: absolute; top: 0; right: 0;
  width: calc(7px * var(--peel)); height: calc(7px * var(--peel));
  background: linear-gradient(225deg,
    rgba(221,185,142,.55) 0%,
    rgba(138,107,79,.30) 60%,
    rgba(15,13,11,.5) 100%);
  box-shadow: -1px 1px 2px rgba(0,0,0,.45);
  border-bottom-left-radius: 1px;
  pointer-events: none;
  transition: width var(--motion-medium) var(--ease-heavy),
              height var(--motion-medium) var(--ease-heavy);
}
.peel:hover, .cat-prod-card:hover .peel, .prod-panel:hover .peel { --peel: 1; }
.peel:hover { filter: drop-shadow(0 2px 4px rgba(0,0,0,.4)); }

@media (hover: none), (max-width: 760px) {
  .peel { --peel: 0 !important; clip-path: none; }
  .peel::after { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .peel { --peel: 0 !important; clip-path: none; transition: none; }
  .peel::after { display: none; }
}

/* ---- Navbar indicator ----------------------------------------------------
   One thin champagne rule that slides between links. Hairline and straight,
   never gooey or liquid. Desktop nav only; the mobile menu is untouched. */
.desk-nav { position: relative; }
.nav-ind {
  position: absolute; bottom: -6px; left: 0;
  height: 1px; width: var(--ind-w, 0px);
  transform: translateX(var(--ind-x, 0px));
  background: linear-gradient(90deg,
    transparent 0%, var(--azpex-accent-bright) 22%,
    var(--azpex-accent-bright) 78%, transparent 100%);
  opacity: 0; pointer-events: none;
  transition: transform var(--motion-medium) var(--ease-heavy),
              width var(--motion-medium) var(--ease-heavy),
              opacity var(--motion-fast) var(--ease-ui);
}
.desk-nav.has-ind .nav-ind { opacity: .95; }
@media (hover: none), (max-width: 900px) { .nav-ind { display: none; } }
@media (prefers-reduced-motion: reduce) { .nav-ind { transition: none; } }

/* ---- Cover-to-detail view transition -------------------------------------
   Only browsers that ship the API ever see this; the fallback is a normal
   navigation, which needs no styling. */
@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(azpex-cover),
  ::view-transition-new(azpex-cover) {
    animation-duration: var(--motion-slow);
    animation-timing-function: var(--ease-heavy);
  }
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}

/* ---- Cross-document View Transition --------------------------------------
   The morph is performed by the browser itself on a real navigation. There is
   no JS navigation engine behind it: page-transition.js only stamps the
   shared name on the clicked cover and then stays out of the way. Browsers
   without this rule simply navigate, and the body fade covers them. */
@view-transition { navigation: auto; }

/* The detail cover is the landing half of the pair. It is unique per page,
   so it can carry the name statically. */
.pd-cover-frame img { view-transition-name: azpex-cover; }

@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  .pd-cover-frame img { view-transition-name: none; }
}

/* ---- Mobile performance --------------------------------------------------
   Below 760px the large blurred atmosphere layers stop animating entirely.
   The look is preserved; only the continuous repaint is dropped. */
@media (max-width: 760px) {
  .hero-veil::before {
    animation: none;
    filter: blur(8px);
    transform: translate3d(.7%, -.6%, 0) scale(1.02);
  }
  .hero-rays::before {
    animation: none;
    filter: blur(12px);
    opacity: .9;
  }
  /* The grain keeps its texture but stops stepping through frames. */
  .grain { animation: none; }
}
