/* ==========================================================================
   MP-Beats — persistent chrome
   Boot loader, header, tab bar, footer, search overlay, cart drawer.

   Everything here is layout for the frame the app lives inside. No new
   button/input/card/badge vocabulary is defined — those come from
   components.css and are composed by core/chrome.js.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Boot loader — the first thing anyone ever sees on this site.
   Four ember bars firing in sequence, like a level meter catching a kick.
   -------------------------------------------------------------------------- */

.boot {
  position: fixed;
  inset: 0;
  z-index: var(--z-max);
  display: grid;
  place-content: center;
  justify-items: center;
  gap: var(--space-6);
  padding: var(--gutter);
  background:
    radial-gradient(
      64% 52% at 50% 46%,
      color-mix(in oklab, var(--brand-accent) 13%, transparent),
      transparent 72%
    ),
    radial-gradient(
      50% 40% at 50% 100%,
      color-mix(in oklab, var(--brand-accent-2) 9%, transparent),
      transparent 70%
    ),
    var(--surface-void);
  transition:
    opacity var(--dur-slow) var(--ease-soft),
    visibility var(--dur-slow) var(--ease-soft);
}

.boot.is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.boot__mark {
  display: flex;
  align-items: flex-end;
  gap: 7px;
  height: 48px;
}

.boot__bar {
  display: block;
  width: 7px;
  height: 100%;
  border-radius: var(--radius-pill);
  background: var(--gradient-ember);
  box-shadow: 0 0 22px color-mix(in oklab, var(--brand-accent) 32%, transparent);
  transform: scaleY(0.16);
  transform-origin: bottom center;
  opacity: 0.28;
  animation: boot-bar 1.15s var(--ease-in-out) infinite;
}

.boot__bar:nth-child(2) { animation-delay: 110ms; }
.boot__bar:nth-child(3) { animation-delay: 220ms; }
.boot__bar:nth-child(4) { animation-delay: 330ms; }

@keyframes boot-bar {
  0%,
  100% {
    transform: scaleY(0.16);
    opacity: 0.28;
  }
  42% {
    transform: scaleY(1);
    opacity: 1;
  }
}

.boot__label {
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-tertiary);
  animation: fade-in var(--dur-slower) var(--ease-soft) both;
  animation-delay: 200ms;
}

/* Reduced motion: the meter freezes mid-reading rather than pumping. */
@media (prefers-reduced-motion: reduce) {
  .boot__bar {
    animation: none;
    opacity: 0.9;
  }
  .boot__bar:nth-child(1) { transform: scaleY(0.35); }
  .boot__bar:nth-child(2) { transform: scaleY(0.72); }
  .boot__bar:nth-child(3) { transform: scaleY(1); }
  .boot__bar:nth-child(4) { transform: scaleY(0.5); }
}

/* Fatal boot failure (see showFatal in app.js) */
.boot--error .boot__mark,
.boot--error .boot__label {
  display: none;
}

.boot__error {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-4);
  max-width: 42ch;
  text-align: center;
}

.boot__error h1 {
  font-size: var(--text-xl);
  letter-spacing: var(--tracking-tight);
}

.boot__error p {
  color: var(--text-secondary);
  font-size: var(--text-sm);
}

/* --------------------------------------------------------------------------
   No-JS notice
   -------------------------------------------------------------------------- */

.noscript-notice {
  position: fixed;
  inset: 0;
  z-index: var(--z-max);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--gutter);
  text-align: center;
  background: var(--surface-void);
}

.noscript-notice h1 {
  font-size: var(--text-2xl);
  letter-spacing: var(--tracking-display);
}

.noscript-notice p {
  max-width: 46ch;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: var(--leading-relaxed);
}

.noscript-notice a {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --------------------------------------------------------------------------
   View offset
   The header floats over the page so the home hero can run under it. Views
   that own the top of the screen opt out with a root `.view--flush` element;
   the landing page is opted out by route.
   -------------------------------------------------------------------------- */

#view {
  padding-top: calc(var(--header-h) + var(--safe-t));
  transition: padding-top var(--dur-base) var(--ease-out);
}

#view:has(> .view--flush),
html[data-route='/'] #view {
  padding-top: 0;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.header {
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  z-index: var(--z-header);
  height: calc(var(--header-h) + var(--safe-t));
  padding-top: var(--safe-t);
  padding-left: var(--safe-l);
  padding-right: var(--safe-r);
  background: transparent;
  transition:
    height var(--dur-base) var(--ease-out),
    background-color var(--dur-base) var(--ease-soft),
    backdrop-filter var(--dur-base) var(--ease-soft);
}

/* Hairline that only exists once the header has something to sit on */
.header::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  height: 1px;
  background: linear-gradient(
    to right,
    transparent,
    var(--border-default) 12%,
    var(--border-default) 88%,
    transparent
  );
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-soft);
}

.header.is-scrolled {
  height: calc(var(--header-h-scrolled) + var(--safe-t));
  background: var(--glass-thick);
  backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.4);
}

.header.is-scrolled::after {
  opacity: 1;
}

.header__inner {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  height: 100%;
}

/* ---- Brand ---- */

.header__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  flex: 0 0 auto;
  height: 100%;
  padding-right: var(--space-2);
  border-radius: var(--radius-md);
}

.brand-mark {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  transition: transform var(--dur-base) var(--ease-spring);
}

.header__brand:hover .brand-mark {
  transform: translateY(-1px) scale(1.04);
}

.brand-mark svg {
  overflow: visible;
  filter: drop-shadow(0 2px 10px color-mix(in oklab, var(--brand-accent) 32%, transparent));
}

.brand-wordmark {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
  color: var(--text-primary);
  white-space: nowrap;
}

/* ---- Primary nav (desktop) ---- */

.header__nav {
  display: none;
  align-items: center;
  gap: var(--space-1);
  margin-left: var(--space-4);
}

.nav-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  height: max(34px, var(--tap-min));
  padding-inline: var(--space-3);
  border-radius: var(--radius-pill);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  transition: var(--transition-colors), transform var(--dur-instant) var(--ease-out);
}

.nav-link:hover {
  color: var(--text-primary);
  background: var(--glass-thin);
}

.nav-link[aria-current='page'] {
  color: var(--text-primary);
}

.nav-link::after {
  content: '';
  position: absolute;
  bottom: 1px;
  left: 50%;
  width: 0;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--gradient-ember);
  transform: translateX(-50%);
  transition: width var(--dur-base) var(--ease-out);
}

.nav-link[aria-current='page']::after {
  width: calc(100% - var(--space-6));
}

/* ---- Actions ---- */

.header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
}

/* Search trigger: a real search field on desktop, an icon on phones */
.header__search {
  justify-content: flex-start;
  gap: var(--space-3);
  min-width: 210px;
  padding-inline: var(--space-4);
  color: var(--text-tertiary);
  font-weight: var(--weight-medium);
}

.header__search:hover:not(:disabled) {
  color: var(--text-secondary);
}

.header__search .kbd {
  margin-left: auto;
}

/* ---- Language switch (EN | NL) ----
   A segmented pill: the chosen language is filled with the accent, the other
   stays quiet. Both labels are always visible, so a Dutch visitor can see the
   language exists without opening anything. */

.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  flex: 0 0 auto;
  padding: 3px;
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  background: var(--glass-thin);
}

.lang-toggle__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 28px;
  padding-inline: var(--space-2);
  border-radius: var(--radius-pill);
  color: var(--text-tertiary);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  line-height: 1;
  transition: var(--transition-colors);
}

.lang-toggle__btn:hover {
  color: var(--text-primary);
  background: var(--glass-medium);
}

.lang-toggle__btn.is-active {
  background: var(--gradient-ember);
  color: var(--accent-contrast);
}

.lang-toggle__btn.is-active:hover {
  color: var(--accent-contrast);
}

.lang-toggle__short {
  display: block;
  line-height: 1;
  /* The caps tracking would otherwise leave the pair looking off-centre. */
  margin-right: calc(var(--tracking-caps) * -1);
}

/* Header variant: one notch tighter so it never squeezes the search field. */
.lang-toggle--compact {
  padding: 2px;
}

.lang-toggle--compact .lang-toggle__btn {
  min-width: 30px;
  height: 26px;
  padding-inline: var(--space-1);
}

/* A finger needs the full target even where the pill is drawn small. The extra
   width keeps the active segment reading as a segment rather than a lone dot. */
@media (pointer: coarse) {
  .lang-toggle__btn,
  .lang-toggle--compact .lang-toggle__btn {
    min-width: max(56px, var(--tap-min));
    height: var(--tap-min);
    padding-inline: var(--space-3);
  }
}

.header__cart {
  position: relative;
}

.cart-badge {
  position: absolute;
  top: -1px;
  right: -1px;
  display: grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding-inline: 4px;
  border-radius: var(--radius-pill);
  background: var(--gradient-ember);
  color: var(--accent-contrast);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  box-shadow: 0 0 0 2px var(--surface-void);
  animation: badge-pop var(--dur-base) var(--ease-spring);
}

@keyframes badge-pop {
  from { transform: scale(0.4); opacity: 0; }
}

/* ---- Account ---- */

.account {
  position: relative;
  display: flex;
}

.acct__trigger {
  padding: 0;
  overflow: hidden;
}

.avatar {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: var(--radius-circle);
  background: var(--gradient-ember);
  color: var(--accent-contrast);
  font-family: var(--font-display);
  font-size: var(--text-2xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0;
  text-transform: uppercase;
  overflow: hidden;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar--lg {
  width: 40px;
  height: 40px;
  font-size: var(--text-sm);
}

.acct__menu {
  position: absolute;
  top: calc(100% + var(--space-2));
  right: 0;
  z-index: var(--z-drawer);
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 244px;
  padding: var(--space-2);
  background: var(--glass-thick);
  backdrop-filter: blur(var(--glass-blur-heavy));
  -webkit-backdrop-filter: blur(var(--glass-blur-heavy));
  border: 1px solid var(--border-default);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  transform-origin: top right;
  animation: menu-in var(--dur-fast) var(--ease-out) both;
}

@keyframes menu-in {
  from {
    opacity: 0;
    transform: translateY(-6px) scale(0.97);
  }
}

.acct__head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-bottom: var(--space-1);
  border-bottom: 1px solid var(--border-subtle);
}

.acct__identity {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.acct__name {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
}

.acct__email {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.acct__item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  width: 100%;
  min-height: var(--tap-min);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  text-align: left;
  transition: var(--transition-colors);
}

.acct__item .icon {
  flex: 0 0 auto;
  color: var(--text-tertiary);
  transition: color var(--dur-fast) var(--ease-soft);
}

.acct__item:hover,
.acct__item:focus-visible {
  background: var(--surface-hover);
  color: var(--text-primary);
}

.acct__item:hover .icon,
.acct__item:focus-visible .icon {
  color: var(--accent);
}

.acct__item--accent {
  color: var(--accent-text);
}

.acct__item--accent .icon {
  color: var(--accent);
}

.acct__sep {
  height: 1px;
  margin: var(--space-1) var(--space-2);
  background: var(--border-subtle);
}

@media (min-width: 861px) {
  .header__nav {
    display: flex;
  }
}

@media (max-width: 860px) {
  .header__inner {
    gap: var(--space-2);
  }

  /* The search trigger collapses to a bare icon button */
  .header__search {
    min-width: 0;
    padding: 0;
    aspect-ratio: 1;
    border-color: transparent;
    background: transparent;
    border-radius: var(--radius-circle);
  }

  .header__search-label,
  .header__search .kbd {
    display: none;
  }

  /* Account lives in the tab bar on phones */
  .account {
    display: none;
  }

  /* …and the language switch stays right here, at every width. With the
     primary nav gone there is a clear stretch of bar between the brand and the
     icons, and a Dutch visitor should never have to scroll to the footer to
     find their own language.

     The actions cluster stops being a right-aligned island and becomes the
     rest of the bar; `order` lifts the switch ahead of search and cart, and
     `margin-inline: auto` parks it in the middle of whatever room is left
     AFTER the brand and the two icon buttons have taken theirs. Auto margins
     only ever distribute leftover space, so the switch can never be the thing
     that pushes the cart off-screen. */
  .header__actions {
    flex: 1 1 auto;
    min-width: 0;
    margin-left: 0;
  }

  .header__lang {
    order: -1;
    margin-inline: auto;
  }

  /* Last line of defence: the brand name is producer-editable, so a long one
     truncates rather than stealing the switch's room. */
  .header__brand {
    flex: 0 1 auto;
    min-width: 0;
  }

  .header__brand .brand-wordmark {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Phone portrait: the bar now carries brand + switch + search + cart, so the
   wordmark drops back to the monogram and the switch gets the room instead.
   The mark alone is still the brand — it is the favicon and the boot loader. */
@media (max-width: 480px) {
  .header__brand .brand-wordmark {
    display: none;
  }
}

/* --------------------------------------------------------------------------
   Tab bar (phones only)
   Sits at the bottom of the stack, above the mini player, clear of the
   home indicator.
   -------------------------------------------------------------------------- */

.tabbar {
  position: fixed;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: calc(var(--z-player) + 1);
  display: none;
  grid-template-columns: repeat(5, 1fr);
  height: calc(var(--tabbar-h) + var(--safe-b));
  padding-bottom: var(--safe-b);
  padding-inline: max(var(--safe-l), 0px) max(var(--safe-r), 0px);
  background: var(--glass-thick);
  backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.4);
  -webkit-backdrop-filter: blur(var(--glass-blur-heavy)) saturate(1.4);
  border-top: 1px solid var(--border-subtle);
}

@media (max-width: 860px) {
  .tabbar {
    display: grid;
  }
}

.tab-item {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: 44px;
  height: var(--tabbar-h);
  padding-top: 3px;
  color: var(--text-tertiary);
  font-size: var(--text-2xs);
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-normal);
  transition: color var(--dur-fast) var(--ease-soft);
}

.tab-item__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 26px;
  height: 24px;
}

.tab-item::before {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 22px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--gradient-ember);
  transform: translateX(-50%) scaleX(0);
  transition: transform var(--dur-base) var(--ease-spring);
}

.tab-item[aria-current='page'] {
  color: var(--accent-text);
}

.tab-item[aria-current='page']::before {
  transform: translateX(-50%) scaleX(1);
}

.tab-item:active {
  color: var(--text-primary);
}

.tab-item .cart-badge {
  top: -2px;
  right: 0;
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--surface-base) 92%, transparent);
}

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

.footer {
  position: relative;
  margin-top: auto;
  padding-top: var(--space-16);
  /* Clearance for the fixed player (and the tab bar on phones) */
  padding-bottom: calc(var(--player-h) + var(--space-10));
  border-top: 1px solid var(--border-subtle);
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in oklab, var(--surface-base) 70%, transparent)
  );
}

@media (max-width: 860px) {
  .footer {
    padding-top: var(--space-12);
    padding-bottom: calc(var(--player-h-mobile) + var(--tabbar-h) + var(--safe-b) + var(--space-8));
  }
}

.footer__lead {
  display: grid;
  gap: var(--space-10);
  padding-bottom: var(--space-12);
}

@media (min-width: 861px) {
  .footer__lead {
    grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
    gap: var(--space-16);
    align-items: start;
  }
}

.footer__brand {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  align-items: flex-start;
}

.footer__brand-link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  border-radius: var(--radius-md);
}

.footer__brand-link .brand-wordmark {
  font-size: var(--text-lg);
}

.footer__tagline {
  max-width: 42ch;
  color: var(--text-secondary);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}

.footer__socials {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
}

.social-link {
  display: grid;
  place-items: center;
  width: var(--tap-min);
  height: var(--tap-min);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-circle);
  background: var(--glass-thin);
  color: var(--text-secondary);
  /* Hover lift is a response to the pointer, not an entrance — expo-out, not
     a spring. Springs are reserved for things that arrive. */
  transition:
    var(--transition-colors),
    transform var(--dur-instant) var(--ease-out);
}

.social-link:hover {
  color: var(--accent-text);
  border-color: var(--border-accent);
  background: var(--accent-softer);
  transform: translateY(-2px);
}

/* ---- Newsletter ---- */

/* ---- Newsletter ----
   The same capture card used to render at full weight — raised fill, amber
   Subscribe — on every single page, and twice on home: once as a mid-page
   section and again in the footer minutes later. Repetition at unchanging
   weight teaches the eye to skip a thing, and on the cart and login pages it
   was the second-brightest amber object on an otherwise empty screen, which
   is the one thing the accent is not for.

   So the footer variant is demoted to an inline sign-up line: no card, no
   raised fill, no filled amber CTA. The full card treatment survives only
   where it is the page's *only* capture. Where a view already runs its own
   mid-page newsletter section — currently home — the footer copy is dropped
   entirely rather than shown twice. */

.newsletter__title {
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

.newsletter__body {
  margin-top: var(--space-2);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
}

.newsletter__form {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-5);
}

/* Footer variant — strip the card chrome the component ships with. */
.footer .newsletter.card {
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.footer .newsletter__title {
  font-size: var(--text-base);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-wide);
}

.footer .newsletter__body {
  font-size: var(--text-xs);
  max-width: 46ch;
}

.footer .newsletter__form {
  margin-top: var(--space-4);
}

/* The button keeps its component identity — only the --btn-* custom
   properties the component exposes are reassigned, which is exactly the API
   .btn was built with. Amber in the footer is a claim this form cannot cash. */
.footer .newsletter__form .btn--primary {
  --btn-bg: transparent;
  --btn-fg: var(--text-primary);
  --btn-border: var(--border-strong);
  background: var(--btn-bg);
  font-weight: var(--weight-semibold);
  box-shadow: none;
}

.footer .newsletter__form .btn--primary:hover:not(:disabled) {
  --btn-bg: var(--glass-medium);
  --btn-border: var(--border-control);
  filter: none;
  box-shadow: none;
}

.footer .newsletter__form .btn--primary::after {
  content: none;
}

/* Home already has a full-weight newsletter section of its own. Showing the
   footer copy as well is the same ask twice on one scroll. */
html[data-route='/'] .footer .newsletter {
  display: none;
}

@media (min-width: 861px) {
  html[data-route='/'] .footer__lead {
    grid-template-columns: minmax(0, 1fr);
  }
}

.newsletter__form .input {
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 420px) {
  .newsletter__form {
    flex-direction: column;
  }
}

.newsletter__status {
  display: block;
  margin-top: var(--space-3);
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  color: var(--text-tertiary);
}

.newsletter__status:empty {
  display: none;
}

.newsletter__status[data-tone='success'] { color: var(--success); }
.newsletter__status[data-tone='error'] { color: var(--danger); }

/* The honeypot must be reachable by bots and invisible to humans. */
.hp-field {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

/* ---- Link columns ---- */

.footer__cols {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-8) var(--space-6);
  padding-block: var(--space-10);
  border-top: 1px solid var(--border-subtle);
}

@media (min-width: 700px) {
  .footer__cols {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.footer__col-title {
  margin-bottom: var(--space-4);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-quiet);
}

.footer__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.footer__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  color: var(--text-secondary);
  font-size: var(--text-sm);
  transition: var(--transition-colors), transform var(--dur-instant) var(--ease-out);
  transform-origin: left center;
}

.footer__link:hover {
  color: var(--accent-text);
}

/* The footer used to carry a labelled language row for phones, because the
   header had no room for the switch. The header carries it at every width now,
   and the header is fixed — a footer row would put a second, identical control
   in the same viewport as the first the moment you reached the bottom of the
   page. One switch, always on screen, beats two that disagree about which one
   you meant. (See core/chrome.js.) */

/* ---- Bottom bar ---- */

.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
  padding-top: var(--space-8);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-size: var(--text-xs);
}

.footer__bottom-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-4);
}

.footer__payments {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-left: auto;
  color: var(--text-quiet);
}

.footer__payments .icon {
  color: var(--text-quiet);
}

.footer__rights {
  width: 100%;
  margin-top: var(--space-4);
  max-width: 90ch;
  color: var(--text-quiet);
  font-size: var(--text-2xs);
  line-height: var(--leading-normal);
}

@media (max-width: 700px) {
  .footer__payments {
    margin-left: 0;
  }
}

/* --------------------------------------------------------------------------
   Search overlay — command palette
   -------------------------------------------------------------------------- */

.search-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: calc(var(--safe-t) + var(--space-3)) var(--space-3) var(--space-3);
  background: color-mix(in oklab, var(--surface-void) 78%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  animation: fade-in var(--dur-fast) var(--ease-soft);
}

@media (min-width: 861px) {
  .search-overlay {
    padding-top: max(calc(var(--safe-t) + var(--space-8)), 9vh);
    padding-inline: var(--space-6);
  }
}

.search__panel {
  display: flex;
  flex-direction: column;
  width: min(660px, 100%);
  max-height: 100%;
  overflow: hidden;
  background: var(--surface-overlay);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-xl);
  animation: search-in var(--dur-base) var(--ease-out) both;
}

@keyframes search-in {
  from {
    opacity: 0;
    transform: translateY(-10px) scale(0.985);
  }
}

@media (min-width: 861px) {
  .search__panel {
    max-height: min(70svh, 620px);
  }
}

.search__head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}

.search__head .icon--search {
  flex: 0 0 auto;
  color: var(--text-tertiary);
}

.search__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 48px;
  border: none;
  background: none;
  color: var(--text-primary);
  font-size: max(16px, var(--text-md));
  font-weight: var(--weight-medium);
  letter-spacing: var(--tracking-tight);
  appearance: none;
}

.search__input::placeholder {
  color: var(--text-quiet);
  font-weight: var(--weight-regular);
}

.search__input::-webkit-search-cancel-button {
  display: none;
}

.search__input:focus {
  outline: none;
}

.search__spinner {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  border: 2px solid var(--border-strong);
  border-top-color: var(--accent);
  border-radius: var(--radius-circle);
  animation: spin 0.6s linear infinite;
}

.search__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-2);
  -webkit-overflow-scrolling: touch;
}

.search__section + .search__section {
  margin-top: var(--space-4);
}

.search__section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
}

.search__section-title {
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-quiet);
}

.search__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: 0 var(--space-3) var(--space-2);
}

.search__results {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.search-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2);
  border-radius: var(--radius-md);
  transition: background-color var(--dur-fast) var(--ease-soft);
}

.search-row:hover,
.search-row:has(.search-row__link:focus-visible) {
  background: var(--surface-hover);
}

.search-row:has(.search-row__link:focus-visible) {
  box-shadow: inset 0 0 0 1.5px var(--accent);
}

.search-row__art {
  flex: 0 0 auto;
  width: 46px;
  border-radius: var(--radius-sm);
}

.search-row__text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.search-row__link {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Stretched hit area — the whole row opens the beat */
.search-row__link::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
}

.search-row__link:focus-visible {
  outline: none;
}

.search-row__meta {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-2xs);
  color: var(--text-tertiary);
  overflow: hidden;
  white-space: nowrap;
}

.search-row__meta span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.search-row__dot {
  width: 3px;
  height: 3px;
  flex: 0 0 auto;
  border-radius: var(--radius-circle);
  background: var(--text-quiet);
}

.search-row__play {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
}

.search-row__enter {
  position: relative;
  z-index: 1;
  flex: 0 0 auto;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-soft);
}

.search-row:hover .search-row__enter,
.search-row:has(.search-row__link:focus-visible) .search-row__enter {
  opacity: 1;
}

@media (pointer: coarse) {
  .search-row__enter {
    display: none;
  }
}

.search__more {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap-min);
  margin-top: var(--space-2);
  border-radius: var(--radius-md);
  color: var(--accent-text);
  font-size: var(--text-xs);
  font-weight: var(--weight-semibold);
  transition: var(--transition-colors);
}

.search__more:hover {
  background: var(--accent-softer);
}

.search__foot {
  display: none;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-subtle);
  color: var(--text-quiet);
  font-size: var(--text-2xs);
}

@media (min-width: 861px) {
  .search__foot {
    display: flex;
  }
}

.search__hint {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.search__state {
  padding: var(--space-4) 0;
}

.search__state .state {
  padding-block: var(--space-10);
}

/* --------------------------------------------------------------------------
   Cart drawer
   -------------------------------------------------------------------------- */

.drawer {
  position: fixed;
  inset: 0;
  z-index: var(--z-drawer);
  display: flex;
  justify-content: flex-end;
  background: color-mix(in oklab, var(--surface-void) 72%, transparent);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: fade-in var(--dur-fast) var(--ease-soft);
}

.cart-drawer__panel {
  display: flex;
  flex-direction: column;
  width: min(430px, 100%);
  height: 100%;
  padding-top: var(--safe-t);
  background: var(--surface-overlay);
  border-left: 1px solid var(--border-default);
  box-shadow: var(--shadow-xl);
  animation: cart-drawer-in var(--dur-slow) var(--ease-out) both;
}

@keyframes cart-drawer-in {
  from {
    transform: translateX(100%);
  }
}

.cart-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5) var(--space-4);
  border-bottom: 1px solid var(--border-subtle);
}

.cart-drawer__title {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-lg);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
}

.cart-drawer__count {
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--text-tertiary);
}

.cart-drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-3);
  -webkit-overflow-scrolling: touch;
}

.cart-drawer__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-5) var(--space-5);
  border-top: 1px solid var(--border-subtle);
  background: var(--surface-overlay);
}

.cart-drawer__totals {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-4);
}

.cart-drawer__totals-label {
  font-size: var(--text-sm);
  color: var(--text-secondary);
}

.cart-drawer__totals-value {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-tight);
}

.cart-drawer__note {
  font-size: var(--text-2xs);
  color: var(--text-quiet);
  line-height: var(--leading-snug);
}

.cart-line {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  transition:
    background-color var(--dur-fast) var(--ease-soft),
    opacity var(--dur-fast) var(--ease-soft),
    transform var(--dur-base) var(--ease-out);
}

.cart-line:hover {
  background: var(--glass-thin);
}

.cart-line.is-removing {
  opacity: 0;
  transform: translateX(20px);
  pointer-events: none;
}

.cart-line__art {
  flex: 0 0 auto;
  width: 56px;
  border-radius: var(--radius-sm);
}

.cart-line__text {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.cart-line__title {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--text-primary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cart-line__title:hover {
  color: var(--accent-text);
}

.cart-line__license {
  font-size: var(--text-xs);
  color: var(--text-tertiary);
}

.cart-line__problem {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  margin-top: var(--space-1);
  font-size: var(--text-2xs);
  color: var(--danger);
  line-height: var(--leading-snug);
  white-space: normal;
}

.cart-line__warning {
  color: var(--warning);
}

.cart-line__side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  flex: 0 0 auto;
}

.cart-line__price {
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
}

.cart-line__remove {
  --btn-h: 30px;
  min-width: 30px;
  color: var(--text-quiet);
}

.cart-line__remove:hover:not(:disabled) {
  color: var(--danger);
  background: var(--danger-soft);
}

@media (pointer: coarse) {
  .cart-line__remove {
    --btn-h: var(--tap-min);
    min-width: var(--tap-min);
  }
}

/* Bottom sheet on phones */
@media (max-width: 640px) {
  .drawer {
    align-items: flex-end;
    justify-content: stretch;
  }

  .cart-drawer__panel {
    width: 100%;
    height: auto;
    max-height: 88svh;
    padding-top: 0;
    padding-bottom: var(--safe-b);
    border-left: none;
    border-top: 1px solid var(--border-default);
    border-radius: var(--radius-2xl) var(--radius-2xl) 0 0;
    animation: cart-sheet-up var(--dur-slow) var(--ease-out) both;
  }

  @keyframes cart-sheet-up {
    from {
      transform: translateY(100%);
    }
  }

  .cart-drawer__panel::before {
    content: '';
    display: block;
    width: 38px;
    height: 4px;
    margin: var(--space-3) auto 0;
    border-radius: var(--radius-pill);
    background: var(--border-strong);
  }

  .cart-drawer__head {
    padding-top: var(--space-3);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cart-drawer__panel,
  .search__panel,
  .acct__menu,
  .cart-badge {
    animation: none;
  }
}
