/* ============================================================================
   AmbySound — fx.site-shader.css
   The first screen's background, promoted to the whole site.

   One fixed WebGL layer behind every page (injected by app.js, so no page
   owns it). On the home hero it runs at full strength — that screen is the
   specification. Everywhere else it is dimmed and blurred into ambient light:
   inner pages carry body copy, and a sharp shader under body copy is a
   contrast lottery.

   Budget (computed, worst case = a pure-white shader spot):
     hero, undimmed  → white type sits on the dark half by composition
     inner, dimmed   → white on shader 8.5:1 · white on glass card 15.5:1 ·
                       amber on glass card 6.8:1 · white70 on glass 8.3:1
   Rule that follows: on inner pages BODY COPY LIVES ON A SURFACE, never
   directly on the shader. Headings may sit on it; paragraphs may not.
   ============================================================================ */

.site-shader {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--background);
}
.site-shader canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
}
.site-shader canvas.-veil { opacity: 0.6; }

/* ONE layer for the whole site — two WebGL contexts total, not per section.
   Full strength behind the hero; dimmed to ambient everywhere else. Home earns
   both states: the shader recedes as you scroll past the first screen, so the
   page below the fold matches every inner page instead of going flat black. */
.site-shader canvas {
  filter: blur(40px) brightness(0.32) saturate(1.15);
  transform: scale(1.1);          /* hides the blur's soft edge */
  transition: filter var(--dur-slow) var(--ease-out);
}
.site-shader.-hero canvas {
  filter: none;
  transform: none;
}
@media (prefers-reduced-motion: reduce) { .site-shader canvas { transition: none; } }

:root[data-theme='light'] .site-shader { display: none; }

@media (prefers-reduced-motion: reduce) {
  /* the port already renders a single static frame; nothing to add */
}

/* ---------------------------------------------------------------------------
   GLOBAL CHROME, restated in the hero's language
   --------------------------------------------------------------------------- */

/* the header floats on the shader exactly as it does in the hero: no plate,
   no blur band, text links with a pill hover */
.site-header { background: transparent; backdrop-filter: none; }
.site-header .container { gap: var(--space-6); }

.site-nav { gap: var(--space-1); }
.site-nav a {
  position: relative;
  border: 0;
  border-inline: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  background: transparent;
  color: rgb(255 255 255 / 0.8);
  font-size: var(--text-xs);
  font-weight: 300;
  transition: color var(--dur-slow) var(--ease-out), background-color var(--dur-slow) var(--ease-out);
}
.site-nav a:hover { color: #ffffff; background: rgb(255 255 255 / 0.1); }
.site-nav a[aria-current='page'] { color: #ffffff; background: rgb(255 255 255 / 0.1); }
/* the v2 dot marker is retired: the hero marks state with a fill, and two
   marker systems on one site was Contradiction #1 */
.site-nav a[aria-current='page']::after { content: none; }

.site-header .btn-icon {
  background: transparent;
  border-color: transparent;
  color: rgb(255 255 255 / 0.8);
}
.site-header .btn-icon:hover { color: #ffffff; background: rgb(255 255 255 / 0.1); }

/* cart + currency: the hero's white pill, held as one double control */
.header-pair {
  background: rgb(255 255 255 / 0.1);
  border-color: transparent;
  backdrop-filter: blur(8px);
}
.header-pair::before { background: rgb(255 255 255 / 0.18); }
.header-pair .cart-btn, .header-pair .currency-trigger { color: #ffffff; }
.header-pair .cart-btn:hover, .header-pair .currency-trigger:hover { background: rgb(255 255 255 / 0.12); }
.currency-trigger { background: transparent; color: rgb(255 255 255 / 0.85); font-weight: 300; }
.cart-count { background: var(--audio); color: #000000; }

/* ---------------------------------------------------------------------------
   SURFACES — glass, per rule 2. Shadow only where an object lifts OFF the
   shader; a hairline carries the rest.
   --------------------------------------------------------------------------- */
.card, .panel {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-surface);
  backdrop-filter: blur(20px) saturate(1.2);
  box-shadow: none;
}
.panel { background: var(--panel); }
.search-panel, .support-panel, .sheet-panel, .currency-menu, .cookiebar {
  background: var(--popover);
  border: 1px solid var(--line);
  backdrop-filter: blur(24px) saturate(1.2);
  box-shadow: var(--shadow-float);
}
.cookiebar { color: var(--foreground); }
.empty { background: var(--card); border: 1px solid var(--line); }
.table-wrap { border-color: var(--line); }
.table th, .table td { border-color: var(--line); }
.table th { color: var(--faint); }

/* ---------------------------------------------------------------------------
   CONTROLS — the hero's two buttons are the whole button system.
   --------------------------------------------------------------------------- */
.btn {
  font-size: var(--text-xs);
  font-weight: 400;
  border-radius: var(--radius-pill);
  box-shadow: none;
}
.btn-outline {
  background: transparent;
  border-color: var(--border-strong);
  color: #ffffff;
  box-shadow: none;
}
.btn-outline:hover { background: rgb(255 255 255 / 0.1); border-color: rgb(255 255 255 / 0.5); }
.btn-secondary { background: var(--glass-1); color: #ffffff; }
.btn-secondary:hover { background: var(--glass-2); }
.btn-ghost { color: rgb(255 255 255 / 0.8); }
.btn-ghost:hover { background: var(--glass-2); color: #ffffff; }
.btn-link { color: rgb(255 255 255 / 0.7); font-weight: 300; }
.btn-link:hover { color: #ffffff; }
/* .btn-tall was a 10rem quiet block on the cream skin. On glass a 160px
   near-invisible slab reads as a hole, not a button — the hero has exactly
   two button sizes, so the tall variant collapses into the large one. */
.btn-tall { height: 3.25rem; border-radius: var(--radius-pill); font-size: var(--text-sm); }
@media (max-width: 640px) { .btn-tall { height: 3rem; } }

/* fields are glass too — the DS fills them with --muted, which is now glass */
.input, .select, .textarea, .field, .otp input {
  background: var(--glass-1);
  border-color: var(--border);
  color: #ffffff;
  box-shadow: none;
  backdrop-filter: blur(8px);
}
.input::placeholder, .textarea::placeholder { color: var(--faint); }
.field .label { color: var(--faint); }
.field-message { color: var(--muted-foreground); }

/* chips: the one selection idiom (Contradiction #1 resolved in favour of chips) */
.chip {
  background: transparent;
  border-color: var(--border);
  color: rgb(255 255 255 / 0.7);
  font-weight: 300;
}
.chip:hover { color: #ffffff; border-color: var(--border-strong); }
.chip[aria-pressed='true'] { background: #ffffff; border-color: #ffffff; color: #000000; }
.chip .count { color: inherit; opacity: 0.6; }

.badge { background: #ffffff; color: #000000; font-weight: 400; }
.badge-secondary { background: var(--glass-2); color: #ffffff; }
.badge-outline { background: transparent; border-color: var(--border); color: rgb(255 255 255 / 0.8); }

/* side-nav follows the nav contract: fill marks the active item */
.side-nav a { color: rgb(255 255 255 / 0.7); border-radius: var(--radius-pill); font-weight: 300; }
.side-nav a:hover { color: #ffffff; background: var(--glass-2); }
.side-nav a[aria-current='page'] { background: rgb(255 255 255 / 0.12); color: #ffffff; font-weight: 400; }
.side-nav a[aria-current='page']::before { content: none; }

/* tabs, finally adopted rather than left dead in the DS — same fill contract */
.tabs-list { background: var(--glass-1); border: 1px solid var(--line); }
.tabs-trigger { color: rgb(255 255 255 / 0.7); font-weight: 300; }
.tabs-trigger:hover { color: #ffffff; }
.tabs-trigger[aria-selected='true'] { background: rgb(255 255 255 / 0.14); color: #ffffff; box-shadow: none; }

/* steps / pagination / paymethod inherit the same glass + white-active logic */
.step-n { border-color: var(--border); }
.step[aria-current='step'] .step-n { background: #ffffff; border-color: #ffffff; color: #000000; }
.step.-done .step-n { background: var(--glass-2); border-color: var(--border); }
.step-sep { color: var(--faint); }
.page-btn[aria-current='page'] { background: rgb(255 255 255 / 0.14); border-color: transparent; color: #ffffff; box-shadow: none; }
.paymethod { border-color: var(--border); }
.paymethod:hover { background: var(--glass-1); }
.paymethod[aria-pressed='true'] { border-color: #ffffff; background: var(--glass-1); }

/* AUDIO is the one thing amber is allowed to say. Every play affordance and
   every progress bar is amber; everything else in the chrome is white. The
   large product player must therefore match the shelf card's round button —
   the DS paints it with --primary, which is now white. */
.player-play { background: var(--audio-soft); color: var(--audio); }
.player-play:hover { background: var(--audio); color: #000000; }
.player-play[aria-pressed='true'] { background: var(--audio); color: #000000; }
.player { background: var(--glass-1); }
.player-wave i { background: var(--wave-fill); opacity: 1; }
.player-wave i.-on { background: var(--audio); }
.player-time { background: var(--glass-2); color: var(--muted-foreground); }
.checkbox-row input { accent-color: var(--audio); }

.alert { background: var(--card); border-color: var(--line); backdrop-filter: blur(20px); }
.breadcrumb li + li::before { color: var(--faint); }
.skeleton { background: var(--glass-2); }
.support-fab { background: #ffffff; color: #000000; }
.support-fab:hover { background: rgb(255 255 255 / 0.9); }
.scrim { background: rgb(0 0 0 / 0.6); }

/* ---------------------------------------------------------------------------
   FOOTER — a deeper pane of the same glass, not a contrasting slab
   --------------------------------------------------------------------------- */
.site-footer {
  background: var(--ink);
  border-top: 1px solid var(--line);
  border-radius: 0;
  margin-inline: 0;
  backdrop-filter: blur(24px);
}
.site-footer::after { content: none; }   /* the grain belonged to the cream skin */
.site-footer .brand { color: #ffffff; }
.newsletter-field input { color: #ffffff; }
.newsletter-field input::placeholder { color: var(--faint); }

/* ---------------------------------------------------------------------------
   TYPE SCALE — the hero's proportions, applied to page furniture
   --------------------------------------------------------------------------- */
.page-head h1 { font-size: clamp(2.25rem, 5vw, 3.5rem); line-height: 1.05; }
.page-head p { color: var(--muted-foreground); font-size: var(--text-sm); font-weight: 300; max-width: 52ch; }
.section-head h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); font-weight: 300; }
.prose p, .prose ul, .prose ol { color: var(--prose-foreground); font-weight: 300; }
.muted { color: var(--muted-foreground); }
