/* ============================================================================
   MB-IT storefront design system — modern, techy, responsive, WCAG AAA.
   Dark-first; respects prefers-color-scheme for light users.
   ========================================================================== */

/* ---- Self-hosted webfonts (I.93.c) -------------------------------------
   Inter + JetBrains Mono are served locally from this app's public/fonts/
   instead of fonts.googleapis.com. Each is the latin-subset variable font
   from Google's woff2 build — same files Google serves to modern browsers,
   ~48 KB Inter + ~31 KB JetBrains Mono. `font-display: swap` keeps the
   FOIT short on cold cache.

   Previously we loaded these from fonts.googleapis.com via a single
   <link rel="stylesheet">; that intermittently failed with
   ERR_NETWORK_CHANGED on editor pages (captured in I.92 audit). Self-hosting
   eliminates the third-party dependency.
   ----------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/mbit_commerce/fonts/inter-latin-variable.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url('/assets/mbit_commerce/fonts/jetbrains-mono-latin-variable.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---- Design tokens ----------------------------------------------------- */
:root {
  /* Surface */
  --bg-base: #0e1217;
  --bg-elev-1: #161b22;
  --bg-elev-2: #1c2230;
  --bg-glass: rgba(28, 34, 48, 0.65);
  --bg-glass-border: rgba(255, 255, 255, 0.08);

  /* Text */
  --text-primary: #f5f5f7;
  --text-muted: rgba(245, 245, 247, 0.68);
  --text-faint: rgba(245, 245, 247, 0.48);

  /* Accents — chosen for AAA contrast on dark */
  --accent: #5eead4;          /* electric mint */
  --accent-strong: #2dd4bf;
  --accent-glow: rgba(94, 234, 212, 0.35);
  --accent-warm: #f6ad55;
  --danger: #fb7185;
  --success: #4ade80;

  /* Strokes */
  --stroke-soft: rgba(255, 255, 255, 0.08);
  --stroke-strong: rgba(255, 255, 255, 0.16);
  --stroke-focus: var(--accent);

  /* Radii */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 24px;
  --radius-pill: 999px;

  /* Shadows */
  --shadow-card: 0 4px 24px rgba(0, 0, 0, 0.35);
  --shadow-lift: 0 8px 30px rgba(0, 0, 0, 0.45);
  --shadow-glow: 0 0 0 4px var(--accent-glow);

  /* Spacing — 4px grid */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;

  /* Typography */
  --font-system: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-display: 'Inter', system-ui, sans-serif;
  --leading-tight: 1.15;
  --leading-snug: 1.35;
  --leading-normal: 1.55;

  /* Motion */
  --ease: cubic-bezier(0.4, 0, 0.2, 1);
  --t-fast: 120ms;
  --t-med: 220ms;
  --t-slow: 380ms;

  /* Container */
  --container: 1200px;
}

/* Light-mode override (only when the OS prefers it AND no .theme-dark class forces dark) */
@media (prefers-color-scheme: light) {
  :root:not(.theme-dark) {
    --bg-base: #fafafa;
    --bg-elev-1: #ffffff;
    --bg-elev-2: #ffffff;
    --bg-glass: rgba(255, 255, 255, 0.85);
    --bg-glass-border: rgba(0, 0, 0, 0.06);
    --text-primary: #0a0a0c;
    --text-muted: rgba(10, 10, 12, 0.66);
    --text-faint: rgba(10, 10, 12, 0.42);
    --accent: #047857;        /* darker mint for AAA on light */
    --accent-strong: #065f46;
    --accent-glow: rgba(4, 120, 87, 0.18);
    --stroke-soft: rgba(0, 0, 0, 0.07);
    --stroke-strong: rgba(0, 0, 0, 0.14);
    --shadow-card: 0 2px 12px rgba(15, 23, 42, 0.06);
    --shadow-lift: 0 8px 24px rgba(15, 23, 42, 0.12);
  }
}

/* ---- Base reset -------------------------------------------------------- */
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  background:
    radial-gradient(1200px 600px at 80% -10%, rgba(94, 234, 212, 0.06), transparent 60%),
    radial-gradient(900px 500px at -10% 110%, rgba(246, 173, 85, 0.05), transparent 60%),
    var(--bg-base);
  color: var(--text-primary);
  font-family: var(--font-system);
  font-feature-settings: 'cv05', 'cv11', 'ss03';
  line-height: var(--leading-normal);
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-size: clamp(15px, 1vw + 12px, 17px);
}
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: -0.015em;
  line-height: var(--leading-tight);
  margin: 0 0 var(--s-4);
  color: var(--text-primary);
}
h1 { font-size: clamp(2rem, 4vw, 3rem); letter-spacing: -0.025em; }
h2 { font-size: clamp(1.4rem, 2.4vw, 2rem); }
h3 { font-size: clamp(1.15rem, 1.6vw, 1.4rem); }
p, ul, ol { margin: 0 0 var(--s-4); }
.muted { color: var(--text-muted); }
.lede { font-size: clamp(1.05rem, 1.2vw, 1.2rem); color: var(--text-muted); max-width: 60ch; }

a { color: var(--accent); text-decoration: none; transition: color var(--t-fast) var(--ease); }
a:hover { color: var(--accent-strong); }
a:focus-visible {
  outline: none;
  box-shadow: var(--shadow-glow);
  border-radius: var(--radius-sm);
}

/* Skip link */
.skip-to-content {
  position: absolute;
  left: -9999px;
  top: 0;
}
.skip-to-content:focus {
  position: fixed;
  z-index: 999;
  left: var(--s-3);
  top: var(--s-3);
  background: var(--accent);
  color: #0a0a0c;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-md);
  font-weight: 600;
}

/* ---- Header ------------------------------------------------------------ */
.storefront-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-3) var(--s-5);
  background: var(--bg-glass);
  border-bottom: 1px solid var(--bg-glass-border);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
}
.storefront-logo {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.storefront-logo img { height: 32px; }
.storefront-logo::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 12px var(--accent-glow);
}
.storefront-nav {
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.storefront-nav a {
  color: var(--text-muted);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-pill);
  font-weight: 500;
  transition: all var(--t-fast) var(--ease);
}
.storefront-nav a:hover, .storefront-nav a.is-active {
  color: var(--text-primary);
  background: var(--bg-elev-2);
}
.cart-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  padding: 0 var(--s-2);
  margin-left: var(--s-1);
  background: var(--accent);
  color: #0a0a0c;
  font-weight: 700;
  font-size: 0.8rem;
  border-radius: var(--radius-pill);
}
.cart-count.is-empty { display: none; }

/* ---- Layout ------------------------------------------------------------ */
#main-content {
  max-width: var(--container);
  margin: 0 auto;
  padding: var(--s-7) var(--s-5);
}
@media (max-width: 768px) {
  #main-content { padding: var(--s-5) var(--s-4); }
  /* Compact the sticky header so the brand fits on one line and the
   * nav doesn't squash the cart count badge. */
  .storefront-header { gap: var(--s-2); padding: var(--s-2) var(--s-3); }
  .storefront-logo { font-size: 0.95rem; white-space: nowrap; }
  .storefront-logo img { height: 24px; }
  /* I.60 — On a 375px viewport the nav overflows because each item still
   * gets pill padding. Squeeze the nav items so brand + Gestalten + Cart +
   * Anmelden fit (or wrap gracefully). */
  .storefront-nav { gap: 0; flex-wrap: nowrap; }
  .storefront-nav a { padding: var(--s-1) var(--s-2); font-size: 0.9rem; }
  .storefront-nav-login { padding: var(--s-1) var(--s-2); font-size: 0.9rem; }
  .cart-count { min-width: 18px; padding: 0 6px; font-size: 0.72rem; }
  /* I.62 — Promote "Gestalten" to the canonical mobile CTA. /shop now
   * redirects to /products so the Shop link is redundant on mobile —
   * hide it to make room for Gestalten + Cart + Anmelden. */
  .storefront-nav a[href="/shop"] { display: none; }
  /* I.62 — Make the "Gestalten" link visually distinct on mobile so it
   * reads as a CTA (the audit P1: main funnel entry was getting lost
   * among the other compact pills). */
  .storefront-nav a[href="/products"] {
    background: var(--accent);
    color: #0a0a0c;
    font-weight: 700;
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  .storefront-nav a[href="/products"]:hover,
  .storefront-nav a[href="/products"]:focus-visible {
    background: var(--accent);
    color: #0a0a0c;
    filter: brightness(1.08);
  }
}
@media (max-width: 420px) {
  /* I.62 — even at 375px the essentials (logo, Gestalten CTA, Cart,
   * Anmelden/Avatar) still fit because /shop is hidden above. Anmelden
   * stays as text on the right; if anything overflows further, the
   * compact-pill rule keeps padding minimal. */
  .storefront-nav { gap: var(--s-1); }
}

/* I.109 — WCAG AAA 44×44 mobile touch targets for every interactive
 * element in the top bar (header + skip link). Pre-I.109 the audit
 * found Cart, Anmelden, MB-IT logo and "Skip to main content" were
 * 24–30px tall on a 375×667 viewport — below AAA target.
 *
 * Approach: lift `min-height: 44px` + flex-center alignment on every
 * top-bar interactive (left-side logo, all `.storefront-nav a` links,
 * the login pill, the wishlist link, the account avatar). Keep the
 * existing compact horizontal padding from I.60/I.62 so brand +
 * Gestalten + Cart + Anmelden still fit a 375px row.
 *
 * The skip-link goes to a 44px target on focus (it's hidden off-screen
 * otherwise; only matters when focused). */
@media (max-width: 768px) {
  .storefront-logo,
  .storefront-nav a,
  .storefront-nav-login,
  .wishlist-link,
  .skip-to-content:focus {
    min-height: 44px;
    display: inline-flex;
    align-items: center;
  }
  /* Avatar already has explicit width/height; bump to 44 on mobile. */
  .account-avatar { width: 44px; height: 44px; }
}

/* ---- Footer ------------------------------------------------------------ */
.storefront-footer {
  border-top: 1px solid var(--stroke-strong);
  padding: var(--s-7) var(--s-5) var(--s-5);
  background: var(--bg-elev-1);
  /* WCAG AAA: lift the body color so links + text both clear 7:1 on the footer surface. */
  color: var(--text-primary);
  font-size: 0.95rem;
}
.storefront-footer-grid {
  max-width: var(--container);
  margin: 0 auto;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s-6);
}
@media (max-width: 900px) {
  .storefront-footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--s-5);
  }
}
@media (max-width: 540px) {
  .storefront-footer-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
.storefront-footer-col h2.storefront-footer-h {
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-primary);
  margin: 0 0 var(--s-3);
}
.storefront-footer-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.storefront-footer-list a,
.storefront-footer-social a,
.storefront-footer a {
  /* AAA: primary text on bg-elev-1 (light: #fff / dark: #161b22) — text-primary
     is #f5f5f7 on dark (≈ 15:1 on #161b22) and #0a0a0c on light (≈ 18:1 on #fff). */
  color: var(--text-primary);
  text-decoration: none;
  font-weight: 500;
  border-radius: var(--radius-sm);
  padding: 2px 4px;
  margin: -2px -4px;
  display: inline-block;
}
.storefront-footer-list a:hover,
.storefront-footer-social a:hover,
.storefront-footer a:hover {
  color: var(--accent-strong);
  text-decoration: underline;
}
.storefront-footer-newsletter {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.storefront-footer-newsletter input[type="email"] {
  background: var(--bg-base);
  border: 1px solid var(--stroke-strong);
  color: var(--text-primary);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-md);
  font: inherit;
}
.storefront-footer-newsletter input[type="email"]:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-glow);
}
.storefront-footer-newsletter button {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.9rem;
  padding: var(--s-2) var(--s-4);
  border-radius: var(--radius-pill);
  border: 1px solid var(--accent-strong);
  background: var(--accent);
  color: #0a0a0c;
  cursor: pointer;
  align-self: flex-start;
}
.storefront-footer-newsletter button:hover {
  background: var(--accent-strong);
  color: #fff;
}
.storefront-footer-newsletter .newsletter-status {
  font-size: 0.85rem;
  color: var(--text-primary);
  margin: var(--s-2) 0 0;
}
.storefront-footer-social {
  list-style: none;
  padding: 0;
  margin: var(--s-4) 0 0;
  display: flex;
  gap: var(--s-3);
  flex-wrap: wrap;
}
.storefront-footer-bottom {
  max-width: var(--container);
  margin: var(--s-6) auto 0;
  padding-top: var(--s-4);
  border-top: 1px solid var(--stroke-soft);
  text-align: center;
}
.storefront-footer-copy {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-primary);
}

/* ---- Legal / marketing pages (I.52) ------------------------------------ */
.legal-page {
  max-width: 880px;
  margin: var(--s-7) auto;
  padding: 0 var(--s-5);
}
.legal-page-header { margin-bottom: var(--s-6); }
.legal-page-header h1 {
  margin-bottom: var(--s-2);
}
.legal-page section {
  margin-bottom: var(--s-6);
  scroll-margin-top: 80px;
}
.legal-page h2 {
  margin-top: var(--s-6);
  margin-bottom: var(--s-3);
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--stroke-soft);
}
.legal-page h3 {
  margin-top: var(--s-4);
  margin-bottom: var(--s-2);
}
.legal-page p, .legal-page li, .legal-page dd, .legal-page address {
  /* Body text on bg-base — AAA-clean via text-primary. */
  color: var(--text-primary);
  line-height: 1.7;
}
.legal-page a {
  color: var(--accent-strong);
  text-decoration: underline;
}
.legal-page a:hover {
  color: var(--accent);
}
.legal-address {
  font-style: normal;
  padding: var(--s-3) var(--s-4);
  background: var(--bg-elev-1);
  border-radius: var(--radius-md);
  border-left: 4px solid var(--accent);
  margin: var(--s-3) 0;
}
.legal-kvlist {
  display: grid;
  grid-template-columns: minmax(160px, 200px) 1fr;
  gap: var(--s-2) var(--s-4);
  margin: var(--s-3) 0;
}
.legal-kvlist dt {
  font-weight: 600;
  color: var(--text-primary);
}
.legal-kvlist dd {
  margin: 0;
}
@media (max-width: 600px) {
  .legal-kvlist {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s-1) var(--s-4);
  }
  .legal-kvlist dt {
    margin-top: var(--s-2);
  }
}

.legal-disclaimer {
  background: rgba(246, 173, 85, 0.10);
  border: 1px solid rgba(246, 173, 85, 0.45);
  color: var(--text-primary);
  padding: var(--s-4);
  border-radius: var(--radius-md);
  margin: var(--s-4) 0 var(--s-6);
}
.legal-callout {
  padding: var(--s-4) var(--s-5);
  border-radius: var(--radius-md);
  margin: var(--s-5) 0;
  border: 1px solid var(--stroke-strong);
  background: var(--bg-elev-1);
}
.legal-callout-warn {
  border-left: 6px solid var(--danger);
  background: rgba(251, 113, 133, 0.08);
}
.legal-callout h2 {
  margin-top: 0 !important;
  border-bottom: none !important;
  color: var(--text-primary);
}

/* Placeholder for un-filled operator fields. Muted-red so the operator
   sees the gap, but AAA-readable so it never disappears entirely. */
.placeholder-needs-config {
  color: var(--danger);
  background: rgba(251, 113, 133, 0.10);
  border: 1px dashed rgba(251, 113, 133, 0.55);
  padding: 1px 6px;
  border-radius: var(--radius-sm);
  font-style: italic;
  font-weight: 500;
}

.legal-table-wrap {
  overflow-x: auto;
  margin: var(--s-3) 0;
}
.legal-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.legal-table th,
.legal-table td {
  text-align: left;
  padding: var(--s-2) var(--s-3);
  border-bottom: 1px solid var(--stroke-soft);
  color: var(--text-primary);
  vertical-align: top;
}
.legal-table thead th {
  background: var(--bg-elev-1);
  font-weight: 700;
}
.legal-table code {
  font-family: var(--font-mono);
  font-size: 0.88rem;
}

.legal-provider-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
.legal-provider-item,
.legal-provider-card {
  padding: var(--s-4);
  border-radius: var(--radius-md);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
}
.legal-provider-role {
  font-weight: 400;
  font-size: 0.95rem;
}

.legal-form-template pre {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-strong);
  border-radius: var(--radius-md);
  padding: var(--s-4);
  white-space: pre-wrap;
  font-family: var(--font-mono);
  font-size: 0.88rem;
  color: var(--text-primary);
  overflow-x: auto;
}

/* FAQ */
.faq-category { margin-bottom: var(--s-6); }
.faq-item {
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  background: var(--bg-elev-1);
  margin-bottom: var(--s-2);
}
.faq-item summary {
  cursor: pointer;
  padding: var(--s-3) var(--s-4);
  font-weight: 600;
  color: var(--text-primary);
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--s-2);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before {
  content: "+";
  font-family: var(--font-mono);
  color: var(--accent-strong);
  font-size: 1.2em;
  width: 1em;
  transition: transform var(--t-fast) var(--ease);
}
.faq-item[open] summary::before {
  content: "−";
}
.faq-item summary:focus-visible {
  outline: none;
  box-shadow: var(--shadow-glow);
  border-radius: var(--radius-md);
}
.faq-answer {
  padding: 0 var(--s-4) var(--s-3);
}

/* Kontakt page */
.kontakt-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: var(--s-6);
}
@media (max-width: 760px) {
  .kontakt-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
.kontakt-info {
  padding: var(--s-4);
  background: var(--bg-elev-1);
  border-radius: var(--radius-md);
  border: 1px solid var(--stroke-soft);
}
.form-row { display: flex; flex-direction: column; gap: var(--s-1); margin-bottom: var(--s-3); }
.form-row label { font-weight: 600; color: var(--text-primary); }
.form-row .req { color: var(--danger); margin-left: 2px; }
.form-row input[type="text"],
.form-row input[type="email"],
.form-row textarea {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-strong);
  color: var(--text-primary);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-md);
  font: inherit;
}
.form-row textarea { font-family: inherit; min-height: 140px; resize: vertical; }
.form-row input:focus-visible,
.form-row textarea:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-glow);
}
.form-err {
  color: var(--danger);
  font-size: 0.88rem;
  margin: var(--s-1) 0 0;
}
.form-hint {
  color: var(--text-primary);
  font-size: 0.85rem;
  margin: var(--s-1) 0 0;
}
.form-status {
  padding: var(--s-3) var(--s-4);
  border-radius: var(--radius-md);
  margin-top: var(--s-3);
  color: var(--text-primary);
  border: 1px solid var(--stroke-strong);
  background: var(--bg-elev-1);
}
.form-status-success {
  border-left: 4px solid var(--success);
}
.form-status-error {
  border-left: 4px solid var(--danger);
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---- Buttons ----------------------------------------------------------- */
button, .btn, .btn-primary {
  font-family: inherit;
  font-weight: 600;
  font-size: 0.95rem;
  padding: var(--s-3) var(--s-5);
  /* I.108 — WCAG 2.5.5 / 2.5.8 minimum tap target 44×44 (was rendering ~41px
     on mobile due to padding + line-height: 1). */
  min-height: 44px;
  border-radius: var(--radius-pill);
  cursor: pointer;
  border: 1px solid transparent;
  transition: all var(--t-med) var(--ease);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  line-height: 1;
  white-space: nowrap;
}
.btn-primary, button[type="submit"], button.primary {
  background: linear-gradient(135deg, var(--accent) 0%, var(--accent-strong) 100%);
  color: #052e2c;
  box-shadow: 0 4px 16px var(--accent-glow);
}
.btn-primary:hover:not(:disabled),
button[type="submit"]:hover:not(:disabled),
button.primary:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 10px 26px var(--accent-glow);
}
.btn-secondary, button.secondary {
  background: var(--bg-elev-2);
  color: var(--text-primary);
  border-color: var(--stroke-strong);
}
.btn-secondary:hover, button.secondary:hover {
  border-color: var(--accent);
  background: var(--bg-elev-1);
}
button:disabled, .btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none !important;
  box-shadow: none !important;
}
button:focus-visible, .btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-glow);
}

/* ---- Cards / surfaces -------------------------------------------------- */
.card, .surface {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  box-shadow: var(--shadow-card);
}
.card.glass {
  background: var(--bg-glass);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* ---- Forms ------------------------------------------------------------- */
input, select, textarea {
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-primary);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  padding: var(--s-3) var(--s-4);
  width: 100%;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--shadow-glow);
}
label { display: block; margin-bottom: var(--s-4); font-weight: 500; }
label input, label select, label textarea { margin-top: var(--s-2); }
fieldset {
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  padding: var(--s-5);
  margin: 0 0 var(--s-5);
  background: var(--bg-elev-1);
}
legend { padding: 0 var(--s-2); font-weight: 600; color: var(--text-primary); font-size: 1rem; }

input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  height: 6px;
  background: var(--bg-elev-2);
  border-radius: var(--radius-pill);
  border: 1px solid var(--stroke-soft);
  padding: 0;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
  box-shadow: 0 0 0 4px var(--accent-glow), 0 4px 8px rgba(0,0,0,0.3);
  transition: transform var(--t-fast) var(--ease);
}
input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.1); }
input[type="range"]::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border: 0;
  border-radius: 50%;
  background: var(--accent);
  cursor: pointer;
  box-shadow: 0 0 0 4px var(--accent-glow), 0 4px 8px rgba(0,0,0,0.3);
}

input[type="radio"], input[type="checkbox"] {
  width: auto;
  accent-color: var(--accent);
}

/* ---- Status / toast --------------------------------------------------- */
.toast, .pb-toast, #cart-toast {
  position: fixed;
  bottom: var(--s-5);
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-elev-1);
  color: var(--text-primary);
  border: 1px solid var(--stroke-strong);
  padding: var(--s-3) var(--s-5);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-lift);
  font-weight: 500;
  z-index: 200;
}
.toast.show, #cart-toast.show { animation: toast-in var(--t-med) var(--ease); }
@keyframes toast-in {
  from { transform: translate(-50%, 20px); opacity: 0; }
  to { transform: translate(-50%, 0); opacity: 1; }
}

/* ---- Shop grid -------------------------------------------------------- */
.shop-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--s-5);
}
.shop-card {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: transform var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease), border-color var(--t-med) var(--ease);
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--text-primary);
}
.shop-card:hover {
  transform: translateY(-4px);
  border-color: var(--accent);
  box-shadow: var(--shadow-lift);
}
.shop-card-image { aspect-ratio: 1 / 1; background: var(--bg-elev-2); }
.shop-card-image img { width: 100%; height: 100%; object-fit: cover; display: block; }
.shop-card-body { padding: var(--s-4); }
.shop-card-title { font-weight: 600; margin-bottom: var(--s-1); }
.shop-card-price { color: var(--accent); font-weight: 700; }

/* ---- Product detail --------------------------------------------------- */
.product-detail { display: grid; gap: var(--s-6); max-width: var(--container); margin: 0 auto; }
.product-detail-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-6);
}
.product-detail .product-image img {
  width: 100%;
  border-radius: var(--radius-lg);
  border: 1px solid var(--stroke-soft);
}
@media (max-width: 768px) { .product-detail-grid { grid-template-columns: 1fr; } }

.variant-radios { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.variant-radio {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-1);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  background: var(--bg-elev-2);
  cursor: pointer;
  color: var(--text-primary);
  text-decoration: none;
  transition: all var(--t-fast) var(--ease);
}
.variant-radio:hover { border-color: var(--accent); }
.variant-radio.is-current { border-color: var(--accent); background: var(--bg-elev-1); box-shadow: 0 0 0 1px var(--accent); }
.variant-pill { font-weight: 600; }
.variant-price { font-size: 0.85rem; color: var(--text-muted); }

/* ---- Style picker (Provider Product axis) ---------------------------- */
/* Mirrors the editor's .ts-pills shape from mbit_photo_book so the
   product page and the editor feel like the same product. */
.ts-style-picker { border: 0; padding: 0; margin: var(--s-3) 0; }
.ts-style-picker > legend { font-weight: 600; padding: 0 0 var(--s-2); }
.ts-style-picker .ts-pills { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.ts-style-picker .ts-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: var(--s-2) var(--s-3);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  background: var(--bg-elev-2);
  cursor: pointer;
  color: var(--text-primary);
  transition: all var(--t-fast) var(--ease);
}
.ts-style-picker .ts-pill:hover { border-color: var(--accent); }
.ts-style-picker .ts-pill input[type="radio"]:checked + span {
  /* visual cue on the label after the radio */
}
.ts-style-picker .ts-pill:has(input[type="radio"]:checked) {
  border-color: var(--accent);
  background: var(--bg-elev-1);
  box-shadow: 0 0 0 1px var(--accent);
}
.ts-style-picker .ts-pill input[type="radio"]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ts-style-picker .muted { color: var(--text-muted); font-weight: 400; }

/* ---- Status display utilities ----------------------------------------- */
.status-error { color: var(--danger); font-weight: 500; }
.status-success { color: var(--accent); font-weight: 500; }
.status-info { color: var(--text-muted); }
.error { color: var(--danger); }
.success { color: var(--accent); }

/* ---- Photo Book landing ---------------------------------------------- */
.photo-book-landing { max-width: 920px; margin: 0 auto; display: grid; gap: var(--s-5); }
.theme-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: var(--s-3);
  margin-top: var(--s-2);
}
.theme-card { position: relative; }
.theme-card input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.theme-card input:checked + .theme-swatch { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent), var(--shadow-card); }
.theme-card input:focus-visible + .theme-swatch { box-shadow: var(--shadow-glow); }
.theme-swatch {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  padding: var(--s-4);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  min-height: 90px;
  transition: transform var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
  cursor: pointer;
}
.theme-swatch:hover { transform: translateY(-2px); }
.theme-swatch strong { font-size: 0.95rem; }
.theme-swatch small { font-size: 0.75rem; opacity: 0.7; }

.quote-line {
  margin-top: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--bg-elev-2);
  border-radius: var(--radius-md);
  border: 1px solid var(--stroke-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.quote-line #quote-amount { font-size: 1.1rem; font-weight: 700; color: var(--accent); }

#connect-status {
  margin-top: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-md);
  min-height: 1.5em;
  font-weight: 500;
}
#connect-status.error { background: rgba(251, 113, 133, 0.1); color: var(--danger); }
#connect-status.success { background: rgba(94, 234, 212, 0.1); color: var(--accent); }

/* ---- Photo Book editor ------------------------------------------------ */
.pb-editor {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 340px;
  grid-template-areas: "header tray" "cover tray" "spreads tray";
  gap: var(--s-5);
  max-width: var(--container);
  margin: 0 auto;
}
.pb-editor-header {
  grid-area: header;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-5);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
}
.pb-editor-header h1 { margin: 0; flex: 1 1 100%; }
.pb-progress { font-size: 1rem; color: var(--text-muted); }
.pb-progress strong { color: var(--accent); font-size: 1.15rem; }

.pb-cover { grid-area: cover; padding: var(--s-5); background: var(--bg-elev-1); border: 1px solid var(--stroke-soft); border-radius: var(--radius-lg); }
.pb-spreads { grid-area: spreads; }
.pb-spreads h2 { margin-bottom: var(--s-3); }
.pb-spreads-list { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--s-4); margin: 0; }
.pb-spread {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  padding: var(--s-3);
  transition: border-color var(--t-fast) var(--ease);
}
.pb-spread:hover { border-color: var(--stroke-strong); }
.pb-spread-header { display: flex; gap: var(--s-2); align-items: center; margin-bottom: var(--s-3); }
.pb-spread-num { font-weight: 700; color: var(--accent); flex: 0 0 auto; min-width: 80px; }
.pb-spread-layout { flex: 1 1 auto; padding: var(--s-2) var(--s-3); font-size: 0.85rem; }

.pb-slots { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.pb-slot {
  border: 2px dashed var(--stroke-strong);
  border-radius: var(--radius-md);
  min-height: 90px;
  min-width: 90px;
  flex: 1 1 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: var(--s-2);
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-faint);
  background: var(--bg-elev-2);
  transition: all var(--t-fast) var(--ease);
  overflow: hidden;
}
.pb-slot:hover { border-color: var(--accent); color: var(--accent); }
.pb-slot.is-filled {
  border-style: solid;
  border-color: var(--stroke-strong);
  background: var(--bg-elev-1);
  padding: 0;
}
.pb-slot.is-filled:hover { border-color: var(--accent); }
.pb-slot.is-target { border-color: var(--accent); box-shadow: var(--shadow-glow); animation: pulse 1.5s ease-in-out infinite; }
.pb-slot img { width: 100%; height: 100%; object-fit: cover; min-height: 86px; }
@keyframes pulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--accent-glow); }
  50% { box-shadow: 0 0 0 8px var(--accent-glow); }
}

/* ---- Live previews ---------------------------------------------------- */
.pb-cover-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--s-4);
  align-items: start;
}
@media (max-width: 720px) { .pb-cover-layout { grid-template-columns: 1fr; } }
.pb-cover-controls { display: flex; flex-direction: column; gap: var(--s-3); }
.pb-preview-figure, .pb-spread-preview {
  margin: 0;
  position: relative;
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.pb-spread-preview { margin-top: var(--s-3); }
.pb-preview-figure figcaption {
  position: absolute;
  top: var(--s-2);
  left: var(--s-3);
  padding: var(--s-1) var(--s-2);
  background: var(--bg-glass);
  border: 1px solid var(--bg-glass-border);
  border-radius: var(--radius-pill);
  font-size: 0.75rem;
  color: var(--text-muted);
  font-weight: 500;
  backdrop-filter: blur(8px);
  z-index: 1;
}
.pb-preview-figure img, .pb-spread-preview img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.pb-preview-figure img:not([src]), .pb-spread-preview img:not([src]) { visibility: hidden; }
.pb-preview-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-glass);
  color: var(--text-muted);
  font-size: 0.85rem;
  backdrop-filter: blur(4px);
  z-index: 2;
}

.pb-asset-tray {
  grid-area: tray;
  padding: var(--s-4);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  position: sticky;
  top: 80px;
  max-height: calc(100vh - 100px);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.pb-asset-tray h2 { font-size: 1rem; margin: 0; }
.pb-tray-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(70px, 1fr));
  gap: var(--s-2);
  flex: 1 1 auto;
  overflow-y: auto;
  padding-right: var(--s-1);
}
.pb-tray-thumb {
  aspect-ratio: 1 / 1;
  padding: 0;
  cursor: pointer;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  background: var(--bg-elev-2);
  overflow: hidden;
  transition: transform var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.pb-tray-thumb:hover { transform: scale(1.04); border-color: var(--stroke-strong); }
.pb-tray-thumb.is-picked { border-color: var(--accent); box-shadow: var(--shadow-glow); }
.pb-tray-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pb-tray-pagination { display: flex; gap: var(--s-2); align-items: center; padding-top: var(--s-2); font-size: 0.85rem; color: var(--text-muted); }
.pb-tray-pagination button { padding: var(--s-1) var(--s-3); font-size: 0.85rem; }

@media (max-width: 900px) {
  .pb-editor { grid-template-columns: 1fr; grid-template-areas: "header" "tray" "cover" "spreads"; }
  .pb-asset-tray { position: static; max-height: 360px; }
}

/* ---- Checkout form layout -------------------------------------------- */
.checkout-buyer, .checkout-payment {
  margin-bottom: var(--s-5);
}
.checkout-grid-2, .checkout-grid-3 {
  display: grid;
  gap: var(--s-3);
}
.checkout-grid-2 { grid-template-columns: 1fr 1fr; }
.checkout-grid-3 { grid-template-columns: 1fr 2fr 1.2fr; }
@media (max-width: 640px) {
  .checkout-grid-2, .checkout-grid-3 { grid-template-columns: 1fr; }
}
.checkout-summary { margin-bottom: var(--s-5); }
.checkout-notice {
  padding: var(--s-4);
  border-radius: var(--radius-md);
  background: rgba(246, 173, 85, 0.1);
  border: 1px solid var(--accent-warm);
  margin-bottom: var(--s-5);
}
#payment-element { margin: var(--s-3) 0; }
.payment-message {
  margin-top: var(--s-3);
  color: var(--danger);
  font-weight: 500;
}
.payment-message:empty { display: none; }

/* ---- Cart + checkout -------------------------------------------------- */
.cart-table { width: 100%; border-collapse: collapse; }
.cart-table th, .cart-table td { padding: var(--s-3); border-bottom: 1px solid var(--stroke-soft); text-align: left; }
.cart-table th { color: var(--text-muted); font-weight: 500; font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.04em; }

/* Cart totals card (country picker + line-by-line breakdown). */
.cart-totals {
  margin: var(--s-5) 0;
  padding: var(--s-4);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md, 6px);
  max-width: 480px;
}
.cart-totals h2 { margin-top: 0; }
.cart-country-picker label { display: flex; flex-direction: column; gap: var(--s-1); margin-bottom: var(--s-4); }
.cart-country-picker select {
  padding: var(--s-2);
  border: 1px solid var(--stroke-soft);
  background: var(--bg-base);
  color: var(--text-strong);
  min-width: 220px;
}
.cart-breakdown { margin: 0; padding: 0; }
.cart-breakdown-row {
  display: flex;
  justify-content: space-between;
  padding: var(--s-2) 0;
  border-bottom: 1px solid var(--stroke-soft);
}
.cart-breakdown-row:last-of-type { border-bottom: 0; }
.cart-breakdown-row dt { margin: 0; }
.cart-breakdown-row dd { margin: 0; font-variant-numeric: tabular-nums; }
.cart-breakdown-total { font-weight: 600; font-size: 1.1rem; padding-top: var(--s-3); }
.cart-breakdown-total dt, .cart-breakdown-total dd { color: var(--text-strong); }

/* ---- Custom products hub (shop top section) ---------------------------- */
.custom-products { margin: var(--s-5) 0 var(--s-7); }
.custom-products h2 { margin-bottom: var(--s-2); }
.custom-products > .muted { margin-bottom: var(--s-5); }
.custom-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--s-4);
}
.custom-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-4);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--text-primary);
  transition: transform var(--t-med) var(--ease), border-color var(--t-med) var(--ease), box-shadow var(--t-med) var(--ease);
}
.custom-card:hover {
  transform: translateY(-4px);
  border-color: var(--accent);
  box-shadow: var(--shadow-lift);
  color: var(--text-primary);
}
.custom-card svg {
  width: 60px;
  height: 60px;
  color: var(--accent);
  align-self: flex-start;
}
.custom-card strong { font-size: 1.05rem; }
.custom-card p { margin: 0; font-size: 0.85rem; }
.shop-catalog { margin-top: var(--s-7); padding-top: var(--s-5); border-top: 1px solid var(--stroke-soft); }

/* ---- 3D mockup ------------------------------------------------------- */
.ts-mockup-3d {
  position: absolute;
  inset: 0;
  pointer-events: auto;
}
.ts-mockup-3d canvas {
  width: 100% !important;
  height: 100% !important;
  display: block;
  border-radius: var(--radius-lg);
}
.ts-mockup-2d { position: absolute; inset: 0; }
/* Multi-view products (T-shirt) — show only the regions + mockup layer
   whose data-view matches the current 2D view. */
/* Mockup-view layers (one per product view, e.g. front + back for
   T-shirt). Hidden by default; the rule below un-hides only the layer
   whose data-view matches the parent's current view. */
.ts-mockup-2d > .ts-mockup-view { position: absolute; inset: 0; display: none; }
.ts-mockup-2d[data-view="front"] > .ts-mockup-view[data-view="front"],
.ts-mockup-2d[data-view="back"]  > .ts-mockup-view[data-view="back"],
.ts-mockup-2d[data-view="side"]  > .ts-mockup-view[data-view="side"],
/* I.105 — Backpack panels (top / bottom / pocket). Probed live against
   Printful catalog 279 (2026-06-01). */
.ts-mockup-2d[data-view="top"]    > .ts-mockup-view[data-view="top"],
.ts-mockup-2d[data-view="bottom"] > .ts-mockup-view[data-view="bottom"],
.ts-mockup-2d[data-view="pocket"] > .ts-mockup-view[data-view="pocket"] {
  display: block;
}
.ts-side-toggle {
  position: absolute;
  top: var(--s-2);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  gap: var(--s-1);
  z-index: 5;
  background: var(--surface-2, rgba(255,255,255,0.85));
  border-radius: var(--radius-md);
  padding: var(--s-1);
  backdrop-filter: blur(6px);
}
.ts-side-toggle .ts-side-tab {
  background: transparent;
  border: 1px solid transparent;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  font-size: 0.85em;
}
.ts-side-toggle .ts-side-tab.is-active {
  background: var(--accent, #0ea5e9);
  color: #052e2c;
  font-weight: 700;
}
/* Phone case (or any product that splits its SVG into bg + fg layers):
   the placement region renders BETWEEN them so the design overlays the
   case body but the camera bump + outline render on top of the design.
   Single-view products render their SVGs as DIRECT children of
   .ts-mockup-2d (see index.html), so the z-index stacking here works. */
.ts-mockup-2d > svg {
  position: absolute; inset: 0; width: 100%; height: 100%;
}
.ts-mockup-2d > svg.ts-mockup-bg { z-index: 0; }
.ts-mockup-2d > .ts-region        { z-index: 1; position: absolute; }
.ts-mockup-2d > svg.ts-mockup-fg { z-index: 2; pointer-events: none; }
.ts-mockup-photo-wrap {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-lg);
  background: #f5f5f7;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.ts-mockup-photo-empty { padding: var(--s-5); text-align: center; max-width: 80%; color: var(--text-muted); }
.ts-mockup-photo-loading { padding: var(--s-5); text-align: center; color: var(--text-muted); }
.ts-mockup-photo-img { max-width: 100%; max-height: 100%; object-fit: contain; }
.ts-mockup-angles {
  position: absolute;
  left: var(--s-3);
  bottom: var(--s-3);
  right: var(--s-3);
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  padding: var(--s-1);
}
.ts-mockup-angle {
  flex: 0 0 64px;
  width: 64px;
  height: 64px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  background: var(--bg-elev-2);
  overflow: hidden;
}
.ts-mockup-angle img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ts-mockup-angle:hover { border-color: var(--stroke-strong); }
.ts-mockup-angle.is-active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.ts-mockup-spinner {
  margin: var(--s-3) auto 0;
  width: 36px; height: 36px;
  border: 3px solid var(--stroke-soft);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

#ts-mockup[data-render="3d"]   .ts-mockup-2d,
#ts-mockup[data-render="3d"]   .ts-mockup-photo-wrap { display: none; }
#ts-mockup[data-render="2d"]   .ts-mockup-3d,
#ts-mockup[data-render="2d"]   .ts-mockup-photo-wrap { display: none; }
#ts-mockup[data-render="photo"].ts-mockup-3d,
#ts-mockup[data-render="photo"] .ts-mockup-3d,
#ts-mockup[data-render="photo"] .ts-mockup-2d { display: none; }

/* ---- DPI warning + region snap indicator ---------------------------- */
.ts-dpi-warn { color: var(--danger); font-weight: 600; font-size: 0.78rem; margin-left: var(--s-2); }
.ts-dpi-ok { color: var(--accent); font-size: 0.78rem; margin-left: var(--s-2); }
.ts-region.is-snapped::after {
  content: "";
  position: absolute;
  left: 50%; top: 0; bottom: 0; width: 1px;
  background: var(--accent);
  pointer-events: none;
  animation: snap-flash 0.4s ease-out;
}
.ts-region.is-snapped::before {
  /* override the region label briefly */
  background: var(--accent);
  color: #052e2c;
  font-weight: 700;
}
@keyframes snap-flash { 0% { opacity: 1; } 100% { opacity: 0.4; } }

/* ---- Region text overlay (multi-layer) ---------------------------------- */
/* Each text element is positioned absolutely by % of the placement rect.
   The transform (translate -50% -50% + rotate) centers it on its anchor. */
.ts-region-text {
  position: absolute;
  text-align: center;
  font-family: 'Inter', sans-serif;
  font-weight: 700;
  text-shadow: 0 2px 4px rgba(0,0,0,0.5);
  pointer-events: none;
  white-space: nowrap;
  padding: 0 var(--s-1);
}

/* ---- Text overlay editor list ------------------------------------------ */
.ts-text-list,
.ts-overlay-list { display: flex; flex-direction: column; gap: var(--s-2); margin-bottom: var(--s-2); }
.ts-text-row,
.ts-overlay-row {
  display: flex; flex-direction: column; gap: var(--s-1);
  padding: var(--s-2); background: var(--surface-2);
  border-radius: var(--radius-md); border: 1px solid var(--border);
}
.ts-text-row .ts-tx-content { width: 100%; }
.ts-text-row .ts-tx-controls,
.ts-overlay-row .ts-ov-controls {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-1);
  align-items: center; font-size: 0.85em;
}
.ts-text-row .ts-tx-controls label,
.ts-overlay-row .ts-ov-controls label { display: flex; gap: var(--s-1); align-items: center; }
.ts-text-row .ts-tx-delete,
.ts-overlay-row .ts-ov-delete { justify-self: end; grid-column: 1 / -1; align-self: end; }

/* Image-overlay row thumbnail */
.ts-overlay-row .ts-ov-thumb {
  display: block; height: 48px; width: auto; border-radius: var(--radius-sm);
  background: #fff; border: 1px solid var(--border); object-fit: contain;
}
.ts-overlay-row.is-active {
  border-color: var(--accent, #0ea5e9);
  box-shadow: 0 0 0 2px rgba(14, 165, 233, 0.25);
}
/* Action buttons row: ↓ (back), ↑ (front), flip, duplicate, delete */
.ts-overlay-row .ts-ov-buttons {
  display: flex; gap: var(--s-1); flex-wrap: wrap; justify-content: flex-end;
  margin-top: var(--s-1);
}
.ts-overlay-row .ts-ov-buttons button {
  min-width: 2.25em; padding: var(--s-1) var(--s-2);
}
.ts-overlay-row .ts-ov-flip.is-active {
  background: var(--accent, #0ea5e9); color: #052e2c;
}

/* In-region rendering of image overlays — positioned absolutely inside
   .ts-region by the JS. Width % refers to the placement region width.
   Overlays are draggable, so they need pointer-events:auto + a grab cursor. */
.ts-region-overlay {
  position: absolute;
  pointer-events: auto;
  cursor: grab;
  object-fit: contain;
  user-select: none;
  -webkit-user-drag: none;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.25));
  outline: 0px dashed transparent;
  outline-offset: 2px;
  transition: outline-color 120ms ease;
}
.ts-region.is-dragging .ts-region-overlay { cursor: grabbing; }
.ts-region-overlay.is-active {
  outline: 2px dashed var(--accent, #0ea5e9);
}

/* ---- Filter pills ---------------------------------------------------- */
.ts-filters summary, .ts-text-overlay summary {
  cursor: pointer;
  font-weight: 600;
  font-size: 0.88rem;
  padding: var(--s-2) 0;
  list-style: none;
}
.ts-filters summary::before, .ts-text-overlay summary::before { content: "▶ "; color: var(--accent); }
.ts-filters[open] summary::before, .ts-text-overlay[open] summary::before { content: "▼ "; }
.ts-filter-pills { display: flex; flex-wrap: wrap; gap: var(--s-1); margin-top: var(--s-2); }
.ts-filter-pill {
  padding: var(--s-1) var(--s-3);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-pill);
  font-size: 0.78rem;
  cursor: pointer;
  color: var(--text-muted);
}
.ts-filter-pill.is-active {
  background: var(--accent);
  color: #052e2c;
  border-color: var(--accent);
  font-weight: 600;
}
.ts-text-overlay label { font-size: 0.85rem; margin-top: var(--s-2); display: flex; flex-direction: column; gap: var(--s-1); }
.ts-text-overlay input[type="text"], .ts-text-overlay select { width: 100%; padding: var(--s-2); }
.ts-text-overlay input[type="color"] { height: 36px; padding: 0; }
.ts-kbd-hint {
  margin-top: var(--s-3);
  font-size: 0.72rem;
  border-top: 1px solid var(--stroke-soft);
  padding-top: var(--s-2);
  font-family: var(--font-mono);
  letter-spacing: -0.02em;
}

/* ---- Mockup side panel: controls + motive stacked --------------------- */
.ts-mockup-side {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.ts-motive {
  padding: var(--s-4);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
}
.ts-motive h3 {
  font-size: 1rem;
  margin-bottom: var(--s-2);
}
.ts-motive p.muted {
  font-size: 0.85rem;
  margin-bottom: var(--s-3);
}
.ts-placements-stacked {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.ts-placements-stacked .ts-placement {
  padding: var(--s-2);
  background: var(--bg-elev-1);
  border-radius: var(--radius-sm);
}
.ts-placements-stacked legend {
  font-size: 0.88rem;
  gap: var(--s-1);
}
.ts-placements-stacked .ts-placement-body {
  margin-top: var(--s-2);
  gap: var(--s-2);
}
.ts-placements-stacked .ts-placement-body button {
  padding: var(--s-1) var(--s-3);
  font-size: 0.82rem;
}
.ts-placements-stacked .ts-photo-label {
  font-size: 0.78rem;
}

/* ---- T-Shirt WYSIWYG mockup ------------------------------------------ */
.ts-view-toggle {
  display: inline-flex;
  gap: var(--s-1);
  padding: var(--s-1);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-pill);
  margin-bottom: var(--s-3);
}
.ts-view-tab {
  padding: var(--s-2) var(--s-4);
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: 0.9rem;
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.ts-view-tab.is-active {
  background: var(--accent);
  color: #052e2c;
  font-weight: 600;
}

/* Legacy /tshirt page (deprecated, redirects to /print/t-shirt). The
   rules below kept their `#ts-mockup` selectors when that page still
   shipped its own editor. /print/<type> uses #ts-mockup-2d, handled
   in the multi-view block higher up in this file. */
#ts-mockup[data-view="front"] #ts-mockup-shirt-back,
#ts-mockup[data-view="back"] #ts-mockup-shirt { display: none; }
/* Per-view region visibility for the new generic editor. */
#ts-mockup-2d .ts-region[data-view] { display: none; }
#ts-mockup-2d[data-view="front"] .ts-region[data-view="front"] { display: block; }
#ts-mockup-2d[data-view="back"]  .ts-region[data-view="back"]  { display: block; }
#ts-mockup-2d[data-view="side"]  .ts-region[data-view="side"]  { display: block; }
/* I.105 — Backpack panels. */
#ts-mockup-2d[data-view="top"]    .ts-region[data-view="top"]    { display: block; }
#ts-mockup-2d[data-view="bottom"] .ts-region[data-view="bottom"] { display: block; }
#ts-mockup-2d[data-view="pocket"] .ts-region[data-view="pocket"] { display: block; }

.ts-mockup-section .ts-mockup-wrap {
  display: grid;
  /* I.93.a — was `minmax(0, 1fr) 280px`, which reserved a 280px right
   * column for a sidebar that no longer exists in the markup. The
   * wrap now has exactly ONE child (.ts-preview-pane), so the empty
   * 280px column was just clipping the preview canvas — most visible
   * on narrow-aspect products like Notebook where the canvas ended
   * up at a few hundred px instead of filling the pane. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s-5);
  align-items: start;
}
/* Wrap the preview canvas + page strip in a single grid column so the
   strip lands under the preview, not beside the side panel. */
.ts-preview-pane {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  min-width: 0;
}
@media (max-width: 760px) {
  .ts-mockup-section .ts-mockup-wrap { grid-template-columns: 1fr; }
}
.ts-mockup {
  position: relative;
  aspect-ratio: 4 / 5;
  background:
    radial-gradient(circle at 30% 20%, rgba(255,255,255,0.04), transparent 60%),
    var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  touch-action: none;
  transition: aspect-ratio var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease);
}
/* Drag-and-drop active state — visual confirmation that the drop area
   accepts the file. WCAG 2.1: drag-drop is an enhancement; the same
   action is fully reachable via the "Foto wählen" button (keyboard +
   screen reader). */
.ts-mockup.is-drop-target {
  border-color: var(--accent);
  border-style: dashed;
  box-shadow: 0 0 0 4px var(--accent-glow), 0 12px 36px rgba(0,0,0,0.35);
}
.ts-mockup.is-drop-target::after {
  content: "Foto hier ablegen";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(94, 234, 212, 0.12);
  color: var(--accent);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  pointer-events: none;
  z-index: 10;
}
/* Landscape orientation — products that expose an "orientation" axis
   ("hor") flip the container shape AND rotate the inner content -90°
   so the buyer sees what they're actually buying. The base photo +
   text overlays rotate with the canvas; buyers can compensate via the
   existing rotation slider if their source image is in the "wrong"
   orientation. */
.ts-mockup[data-orientation="hor"] { aspect-ratio: 5 / 4; }
.ts-mockup[data-orientation="hor"] > #ts-mockup-2d,
.ts-mockup[data-orientation="hor"] > #ts-mockup-3d,
.ts-mockup[data-orientation="hor"] > #ts-mockup-photo {
  /* Rotating a 4:5 box -90° inside a 5:4 host: scale by 4/5 so the
     rotated content fits within the new shape. The result fills the
     landscape canvas cleanly without overflow. */
  transform: rotate(-90deg) scale(0.8);
  transform-origin: center center;
}
#ts-mockup-shirt { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.ts-mockup-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  pointer-events: none;
  background: #ffffff;   /* clean white card backdrop for the product shot */
  border-radius: var(--radius-lg);
}
.ts-region {
  position: absolute;
  overflow: hidden;
  cursor: pointer;
  border: 1px dashed rgba(255, 255, 255, 0.22);
  border-radius: 2px;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
  user-select: none;
  background: transparent;
}
/* Raw placement id is for debugging only — keep it accessible via the
   native title tooltip / aria-label, NOT rendered as visible text on
   top of the product mockup (it leaked technical labels like "MONTH_03"
   and "BACK" into the buyer's view). */
.ts-region::before { content: none; }
.ts-region:hover { border-color: var(--accent); background: rgba(94, 234, 212, 0.03); }
.ts-region.is-active {
  border: 2px dashed var(--accent);
  box-shadow: 0 0 0 1px var(--accent-glow);
  cursor: grab;
  background: transparent;
}
.ts-region.is-active.is-filled { background: transparent; }
.ts-region.is-dragging { cursor: grabbing; }
.ts-region.is-filled { background: transparent; border-style: solid; border-color: rgba(255,255,255,0.25); }
.ts-region.is-filled.is-active { border-style: dashed; border-color: var(--accent); }
/* Stacked-region products (Calendar): hide the non-active overlapping
   regions so only the active page renders in the main preview. The DOM
   stays in place so transforms persist; only visibility is gated. */
.ts-region.is-hidden { visibility: hidden; pointer-events: none; }

/* ---- Calendar dynamic month grid --------------------------------------- */
/* Sits inside the calendar mockup, below the photo area. JS populates
   .ts-cal-title / .ts-cal-dow / .ts-cal-days based on active month +
   year. The static SVG only provides the wire binding + paper body. */
.ts-calendar-grid {
  position: absolute;
  left: 22%;
  top: 64%;
  right: 22%;
  bottom: 8%;
  pointer-events: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-system);
  color: #0a0a0c;   /* prints on the white calendar paper */
}
.ts-calendar-grid[hidden] { display: none; }
.ts-cal-title {
  font-size: clamp(0.8rem, 1.2vw, 1rem);
  font-weight: 700;
  letter-spacing: 0.05em;
  margin-bottom: 0.3em;
  border-bottom: 1px solid rgba(0,0,0,0.25);
  padding: 0 0.6em 0.3em;
}
.ts-cal-dow,
.ts-cal-days {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  width: 100%;
  text-align: center;
}
.ts-cal-dow {
  font-size: clamp(0.55rem, 0.8vw, 0.7rem);
  font-weight: 600;
  color: rgba(0,0,0,0.55);
  margin-bottom: 0.2em;
}
.ts-cal-days {
  font-size: clamp(0.5rem, 0.75vw, 0.65rem);
  color: rgba(0,0,0,0.7);
  row-gap: 0.18em;
}
.ts-cal-days .is-sun { color: rgba(192, 30, 30, 0.78); }

/* ---- F.4 Placement-tabs navigator (T-Shirt, Hoodie, Tote Bag, Phone Case) -
   Horizontal tab strip ABOVE the canvas, replaces the old left-side
   page-strip for 2-5-placement products. Calendar (13 placements) keeps
   the page strip below. WCAG: role="tablist" + aria-selected provided
   by Jinja; this CSS just styles + focus-rings. */
.ts-placement-tabs {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  padding: var(--s-2) 0;
  border-bottom: 1px solid var(--stroke-soft);
  margin-bottom: var(--s-3);
}
.ts-placement-tab {
  flex: 0 0 auto;
  padding: var(--s-2) var(--s-4);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  font-weight: 500;
  white-space: nowrap;
  border-radius: 0;
  transition: color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.ts-placement-tab:hover { color: var(--text-primary); }
.ts-placement-tab.is-active {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 600;
}
.ts-placement-tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 600px) {
  .ts-placement-tabs { font-size: 0.875em; }
}

/* ---- Page strip navigator (Calendar's 13 pages — F.4: tab nav handles
   T-Shirt + Hoodie + Tote Bag + Phone Case now) -- */
.ts-page-strip {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  padding: var(--s-3) var(--s-1);
  margin-top: var(--s-3);
  scroll-snap-type: x mandatory;
  border-top: 1px solid var(--stroke-soft);
}
.ts-page-tile {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-1);
  padding: var(--s-2);
  background: transparent;
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  cursor: pointer;
  scroll-snap-align: start;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
  min-width: 64px;
}
.ts-page-tile:hover { border-color: var(--accent); }
.ts-page-tile.is-active {
  border-color: var(--accent);
  background: rgba(94, 234, 212, 0.08);
  box-shadow: 0 0 0 2px var(--accent-glow);
}
.ts-page-tile-thumb {
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  background: var(--bg-elev-2);
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-faint);
  font-size: 1.3rem;
  font-weight: 600;
  border: 1px dashed var(--stroke-soft);
}
.ts-page-tile.is-filled .ts-page-tile-thumb {
  border-style: solid;
  border-color: var(--accent);
  color: transparent;   /* hide the "+" placeholder when an image is set */
}
.ts-page-tile-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  white-space: nowrap;
  max-width: 90px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ts-page-tile.is-active .ts-page-tile-label { color: var(--text-primary); font-weight: 600; }

/* For stacked-placement products (Calendar) the side-panel motive list
   is redundant — the page strip is the canonical navigator. Hide it on
   body.editor-stacked-placements but keep the rest of the side panel. */
body.editor-stacked-placements .ts-motive .ts-placements-stacked { display: none; }
body.editor-stacked-placements .ts-motive::after {
  content: "Über die Seiten-Leiste unter der Vorschau navigieren.";
  display: block;
  font-size: 0.85em;
  color: var(--text-muted);
  margin-top: var(--s-2);
}
.ts-region-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform-origin: center center;
  pointer-events: none;
  will-change: transform;
}
.ts-region-virtual {
  background: linear-gradient(90deg, transparent, rgba(94, 234, 212, 0.15), transparent);
  border-style: dotted;
  border-color: rgba(94, 234, 212, 0.35);
  cursor: default;
}
.ts-region-virtual::after {
  content: "Rückseite — Vorschau in Phase 2";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  color: var(--text-faint);
  pointer-events: none;
}
.ts-mockup-controls {
  display: flex; flex-direction: column; gap: var(--s-3);
  padding: var(--s-4);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
}
.ts-mockup-controls label { display: flex; flex-direction: column; gap: var(--s-1); margin: 0; font-size: 0.88rem; }
.ts-mockup-controls .row { gap: var(--s-2); flex-wrap: wrap; }
.ts-mockup-controls button { padding: var(--s-2) var(--s-3); font-size: 0.85rem; }

/* ---- T-Shirt editor --------------------------------------------------- */
.tshirt-editor { max-width: 1080px; margin: 0 auto; display: grid; gap: var(--s-5); }
.tshirt-hero { display: flex; flex-direction: column; gap: var(--s-2); }
.tshirt-hero .tag { align-self: flex-start; }
.ts-section { background: var(--bg-elev-1); border: 1px solid var(--stroke-soft); border-radius: var(--radius-lg); padding: var(--s-5); }
.ts-section h2 { margin-bottom: var(--s-3); }
.ts-axes { display: grid; gap: var(--s-4); }
.ts-pills { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.ts-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-4);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-pill);
  background: var(--bg-elev-2);
  cursor: pointer;
  font-size: 0.92rem;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.ts-pill input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.ts-pill input:checked ~ * { color: var(--accent); }
.ts-pill input:checked { /* parent gets the highlight via :has() */ }
.ts-pill:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
/* Phase C.2 — cross-axis filter sets .is-disabled on incompatible
   Style ↔ Phone-Case-model pairs. Visually muted + uninteractive. */
.ts-pill.is-disabled {
  opacity: 0.4;
  cursor: not-allowed;
  pointer-events: none;
}
.ts-pill.is-disabled input { cursor: not-allowed; }
/* Provider Health — pills tied to a provider whose `is_healthy=0`
   render with this class. Slightly less muted than .is-disabled (so the
   badge stays legible at WCAG-AA) and not pointer-events:none so the
   browser still shows the disabled-radio cursor on hover. */
.ts-pill.is-unavailable {
  opacity: 0.5;
  cursor: not-allowed;
}
.ts-pill.is-unavailable input { cursor: not-allowed; }
.ts-pill-badge {
  font-size: 0.85em;
  color: #b91c1c;   /* WCAG-AA on light bg */
  margin-left: 0.4em;
}
.ts-pill-swatch {
  display: inline-block;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--swatch, transparent);
  border: 1px solid var(--stroke-strong);
  flex-shrink: 0;
}
.ts-placements { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--s-3); }
.ts-placement { background: var(--bg-elev-2); border-radius: var(--radius-md); padding: var(--s-3); border: 1px solid var(--stroke-soft); }
.ts-placement legend { display: flex; align-items: center; gap: var(--s-2); font-weight: 500; font-size: 0.92rem; padding: 0; }
.ts-placement.is-required legend .muted { color: var(--accent); }
.ts-placement-body { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-2); align-items: center; }
.ts-photo-label { font-size: 0.85rem; }
.ts-summary { background: var(--bg-glass); backdrop-filter: blur(10px); border: 1px solid var(--bg-glass-border); }
.ts-summary-grid { display: grid; grid-template-columns: 1fr auto; gap: var(--s-4); margin-bottom: var(--s-3); align-items: end; }
.ts-price strong { font-size: 1.6rem; color: var(--accent); }
.ts-dialog {
  border: 0;
  border-radius: var(--radius-lg);
  background: var(--bg-elev-1);
  color: var(--text-primary);
  padding: var(--s-5);
  width: min(92vw, 720px);
  box-shadow: var(--shadow-lift);
}
.ts-dialog::backdrop { background: rgba(0,0,0,0.55); backdrop-filter: blur(4px); }
.ts-dialog header { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-3); }
.ts-dialog header h2 { margin: 0; }
.ts-dialog input[type="url"], .ts-dialog input[type="password"], .ts-dialog input[type="file"] { margin-bottom: var(--s-3); }

/* ---- Source tabs (Upload vs Immich) ----------------------------------- */
.source-tabs {
  display: inline-flex;
  gap: var(--s-1);
  padding: var(--s-1);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-pill);
  margin-bottom: var(--s-3);
}
.source-tab {
  padding: var(--s-2) var(--s-4);
  background: transparent;
  border: 0;
  color: var(--text-muted);
  font-size: 0.9rem;
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.source-tab.is-active {
  background: var(--accent);
  color: #052e2c;
  font-weight: 600;
}
.source-pane { display: block; }
.source-pane[hidden] { display: none; }
.pb-upload-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-bottom: var(--s-3);
}
.pb-upload-row label.btn-secondary {
  display: inline-flex;
  padding: var(--s-2) var(--s-4);
  cursor: pointer;
  font-size: 0.9rem;
}
#pb-upload-status { font-size: 0.85rem; }

/* ---- Utility classes -------------------------------------------------- */
.stack { display: grid; gap: var(--s-3); }
.row { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; }
.tag {
  display: inline-flex;
  align-items: center;
  padding: var(--s-1) var(--s-3);
  border-radius: var(--radius-pill);
  background: var(--bg-elev-2);
  border: 1px solid var(--stroke-soft);
  font-size: 0.78rem;
  color: var(--text-muted);
  font-weight: 500;
}
.tag-accent { background: var(--accent-glow); border-color: var(--accent); color: var(--accent); }

/* ---- Reduced-motion respect ------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}


/* ---- Product index page ------------------------------------------------ */
/* /products/ — a tile grid listing every customizable product in the
   storefront. Cards link to /print/<slug>. Each card uses the same
   mockup SVG that the editor uses for its 2D mockup, so visuals stay
   consistent across discovery + editing. */
.products-index {
  max-width: var(--container);
  margin: 0 auto;
}
.products-hero {
  text-align: center;
  margin-bottom: var(--s-7);
}
.products-hero h1 {
  margin: 0 0 var(--s-3);
}
.products-hero .lede {
  max-width: 60ch;
  margin: 0 auto;
}
.products-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: var(--s-4);
}
.product-card {
  display: flex;
  flex-direction: column;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-lg);
  overflow: hidden;
  text-decoration: none;
  color: var(--text-primary);
  transition: transform var(--t-fast) var(--ease),
              box-shadow var(--t-med) var(--ease),
              border-color var(--t-fast) var(--ease);
  min-height: 380px;
}
.product-card:hover,
.product-card:focus-visible {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lift);
  border-color: var(--accent);
}
.product-card:focus-visible {
  outline: none;
}
.product-card-thumb {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 5;
  background:
    radial-gradient(600px 400px at 50% 30%, rgba(94, 234, 212, 0.05), transparent 70%),
    var(--bg-elev-2);
  border-bottom: 1px solid var(--stroke-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-4);
}
.product-card-thumb > svg {
  width: 100%;
  height: 100%;
  max-width: 240px;
  max-height: 280px;
  filter: drop-shadow(0 4px 16px rgba(0, 0, 0, 0.25));
}
/* I.26 — SDXL-generated product hero photos replace the inline-SVG
   placeholders for buyers landing on /products. Cover the entire thumb
   slot, square aspect so all 13 heroes feel coherent in the grid. */
.product-card-thumb > .product-card-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}

/* I.93.a — Neutral placeholder for cards without a hero image AND
   without a vector SVG mockup. Tile-sized so the grid stays aligned.
   The icon uses currentColor; the surrounding fill is the same
   `--bg-elev-2` as the rest of the thumb, so the placeholder reads as
   a "no image yet" tile rather than a broken-image artefact.
   WCAG-AAA: text uses `--text` (≥7:1 against `--bg-elev-2`); icon is
   decorative (aria-hidden) and the role="img" wrapper carries the
   accessible label. */
.product-card-thumb > .product-card-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: var(--s-3);
  color: var(--text-muted, #9aa3ad);
  background: var(--bg-elev-2);
}
.product-card-placeholder-icon {
  flex: 0 0 auto;
  width: 56px;
  height: 56px;
  color: var(--text-muted, #9aa3ad);
  opacity: 0.85;
}
.product-card-placeholder-code {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco,
               Consolas, "Liberation Mono", "Courier New", monospace;
  font-size: 0.78rem;
  letter-spacing: 0.01em;
  text-align: center;
  color: var(--text, #f5f5f7);
  /* Wrap long names cleanly. */
  max-width: 90%;
  word-break: break-word;
  line-height: 1.25;
}
.product-card-body {
  padding: var(--s-4);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  flex: 1;
}
.product-card-body h2 {
  margin: 0;
  font-size: 1.1rem;
  line-height: var(--leading-snug);
}
.product-card-body .muted {
  font-size: 0.9rem;
  line-height: var(--leading-snug);
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0;
}
.product-card-price {
  margin: var(--s-2) 0 0;
  font-weight: 700;
  color: var(--accent);
  font-size: 0.95rem;
}
.product-card-cta {
  font-weight: 600;
  font-size: 0.9rem;
  color: var(--text-muted);
  margin-top: var(--s-1);
}
.product-card:hover .product-card-cta {
  color: var(--accent);
}

/* Test-mode banner — surfaced on every storefront page (and the editor)
   when the active Print Store has test_mode=1. Prevents an admin from
   accidentally selling real product to a real buyer while testing. */
.ts-test-mode-banner {
  /* WCAG AAA: #7c2d12 on #fef3c7 ≈ 9.5:1 (was #92400e at 6.36:1, AA only).
   * Border stays bright amber for affordance. */
  background: #fef3c7;
  color: #7c2d12;
  border: 2px solid #d97706;
  padding: 0.75em 1em;
  border-radius: 6px;
  margin: 0.75em 0;
  font-weight: 600;
  text-align: center;
}
/* I.93.c — Mobile compaction. Desktop banner overpowered cart contents
   on mobile (audit punch-list item #15). Collapse to a compact strip
   with smaller text + smaller padding. Contrast unchanged (AAA preserved). */
@media (max-width: 767px) {
  .ts-test-mode-banner {
    padding: 0.4em 0.7em;
    font-size: 0.8125rem;
    margin: 0.4em 0;
    border-width: 1px;
    border-radius: 4px;
    line-height: 1.3;
  }
}

/* I.109 — Offline indicator banner.
 *
 * Fixed-top banner shown when window.navigator.onLine === false. Slides
 * down on `online`/`offline` events. The CSS handles the
 * presentation; the JS in `offline_indicator.js` just toggles
 * `.is-visible`.
 *
 * Color choice: amber (#fbbf24 bg, #1f2937 text → ≈ 12:1 AAA) — same
 * palette as the operator-setup banner but reserved for the network-
 * disconnection signal. The shadow lifts it above sticky headers.
 *
 * Reduced-motion: the `transform`/`transition` is suppressed inside
 * `prefers-reduced-motion: reduce` so the banner snaps in/out rather
 * than sliding (matches every other animated UI in storefront.css). */
.offline-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 999;
  background: #fbbf24;
  color: #1f2937;
  padding: 0.75rem 1rem;
  text-align: center;
  font-weight: 600;
  font-size: 0.9rem;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18);
  transform: translateY(-110%);
  transition: transform 200ms ease-out;
  /* Until the banner is visible we don't want it intercepting clicks
   * on the (off-screen) row. */
  pointer-events: none;
}
.offline-banner.is-visible {
  transform: translateY(0);
  pointer-events: auto;
}
@media (prefers-reduced-motion: reduce) {
  .offline-banner { transition: none; }
}

/* I.42 — Fallback notice + expandable Fallback-Kette ------------------ */
/* AAA-contrast palette: deep navy on a pale blue background.
   #0c3868 on #e0ecff → contrast ratio 9.94:1 (passes AAA easily).        */
.checkout-notice {
  border-radius: var(--radius-md);
  padding: var(--s-4) var(--s-5);
  margin: 0 0 var(--s-5);
  border: 2px solid transparent;
  font-size: 1rem;
  line-height: var(--leading-snug);
}
.checkout-notice-info {
  background: #e0ecff;
  color: #0c3868;
  border-color: #2563eb;
}
.checkout-notice-info strong { color: #0c3868; }
.checkout-notice-detail {
  display: block;
  margin-top: var(--s-2);
  font-size: 0.92em;
  opacity: 0.85;
}

.fallback-chain {
  margin: var(--s-4) 0 var(--s-6);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  background: var(--bg-elev-1);
  padding: var(--s-3) var(--s-4);
}
.fallback-chain > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--text-primary);
  padding: var(--s-1) 0;
}
.fallback-chain > summary:focus-visible {
  outline: 2px solid var(--stroke-focus);
  outline-offset: 2px;
}
.fallback-chain[open] > summary {
  margin-bottom: var(--s-3);
}
.fallback-chain-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.fallback-chain-list li {
  display: block;
  padding: var(--s-2) 0;
  border-top: 1px solid var(--stroke-soft);
}
.fallback-chain-list li:first-child { border-top: 0; }
.fallback-chain-list li.is-ok .fallback-chain-icon { color: var(--success); }
.fallback-chain-list li.is-fail .fallback-chain-icon { color: var(--danger); }
.fallback-chain-icon {
  font-weight: 700;
  margin-right: var(--s-2);
}
.fallback-chain-reason {
  margin-top: var(--s-1);
  color: var(--text-muted);
  font-size: 0.9em;
  font-family: var(--font-mono);
  word-break: break-word;
}

.order-summary {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--s-2) var(--s-5);
  margin: var(--s-5) 0;
}
.order-summary dt { color: var(--text-muted); font-weight: 600; }
.order-summary dd { margin: 0; color: var(--text-primary); }

/* ===================================================================== */
/* I.51 — Buyer Account pages                                            */
/* ===================================================================== */

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

/* ---- Topbar avatar + dropdown ---------------------------------------- */
.account-menu { position: relative; display: inline-flex; align-items: center; }
.account-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 50%;
  background: var(--accent);
  color: #0a0a0c;
  font-weight: 700;
  font-size: 0.85rem;
  border: 0;
  cursor: pointer;
  box-shadow: 0 0 0 2px rgba(255,255,255,0.04);
  transition: transform var(--t-fast) var(--ease);
}
.account-avatar:hover, .account-avatar:focus-visible { transform: scale(1.05); }
.account-avatar:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.account-dropdown {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 100;
  min-width: 200px;
  background: var(--bg-elev-2, #1a1a1f);
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.08));
  border-radius: var(--radius-md);
  list-style: none;
  margin: 0;
  padding: var(--s-2);
  box-shadow: 0 8px 32px rgba(0,0,0,0.4);
}
.account-dropdown li { margin: 0; }
.account-dropdown a {
  display: block;
  padding: var(--s-2) var(--s-3);
  color: var(--text-primary);
  border-radius: var(--radius-md);
  font-size: 0.95rem;
}
.account-dropdown a:hover, .account-dropdown a:focus-visible {
  background: var(--bg-elev-3, rgba(255,255,255,0.05));
}
.storefront-nav-login {
  color: var(--text-muted);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-pill);
  font-weight: 500;
}
.storefront-nav-login:hover, .storefront-nav-login:focus-visible {
  color: var(--text-primary);
  background: var(--bg-elev-2);
}

/* ---- Account form pages (signup/login/forgot) ------------------------- */
.account-form-wrap {
  max-width: 480px;
  margin: var(--s-6) auto;
  padding: var(--s-5);
  background: var(--bg-elev-1, rgba(255,255,255,0.02));
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.06));
  border-radius: var(--radius-md);
}
.account-form-wrap h1 { margin: 0 0 var(--s-2); }
.account-form-lead { margin: 0 0 var(--s-4); color: var(--text-muted); }
.account-form {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.account-form label {
  display: flex;
  flex-direction: column;
  gap: var(--s-1);
  color: var(--text-primary);
  font-weight: 500;
  font-size: 0.95rem;
}
.account-form input[type="text"],
.account-form input[type="email"],
.account-form input[type="tel"],
.account-form input[type="password"],
.account-form select {
  padding: var(--s-3);
  background: var(--bg-elev-1, rgba(255,255,255,0.03));
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.1));
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font: inherit;
  font-weight: 400;
}
.account-form input:focus, .account-form select:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-color: var(--accent);
}
.account-checkbox {
  flex-direction: row !important;
  align-items: flex-start;
  gap: var(--s-2) !important;
  font-weight: 400 !important;
  color: var(--text-muted);
}
.account-checkbox input[type="checkbox"] {
  margin-top: 4px;
  width: 18px; height: 18px;
  accent-color: var(--accent);
}
.account-form-message {
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-md);
  font-size: 0.95rem;
  min-height: 1.5em;
}
.account-form-message:empty { padding: 0; }
.account-form-message.is-error {
  background: rgba(255, 80, 80, 0.1);
  color: #ff8080;
  border: 1px solid rgba(255, 80, 80, 0.3);
}
.account-form-message.is-success {
  background: rgba(80, 200, 120, 0.1);
  color: #80c878;
  border: 1px solid rgba(80, 200, 120, 0.3);
}
.account-form-alt {
  margin: var(--s-4) 0 0;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.95rem;
}

/* ---- Profile page ----------------------------------------------------- */
.account-page {
  max-width: 920px;
  margin: 0 auto;
}
.account-welcome-banner {
  margin: 0 0 var(--s-5);
  padding: var(--s-3) var(--s-4);
  background: rgba(80, 200, 120, 0.1);
  color: #80c878;
  border: 1px solid rgba(80, 200, 120, 0.3);
  border-radius: var(--radius-md);
}
.account-grid {
  display: grid;
  gap: var(--s-4);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-top: var(--s-4);
}
.account-card {
  padding: var(--s-4);
  background: var(--bg-elev-1, rgba(255,255,255,0.02));
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.06));
  border-radius: var(--radius-md);
}
.account-card h2 { margin: 0 0 var(--s-3); font-size: 1.05rem; }
.account-dl { margin: 0 0 var(--s-3); display: grid; grid-template-columns: max-content 1fr; gap: var(--s-1) var(--s-3); }
.account-dl dt { color: var(--text-muted); font-size: 0.9rem; }
.account-dl dd { margin: 0; color: var(--text-primary); }
.account-edit { margin-top: var(--s-3); }
.account-edit summary {
  cursor: pointer;
  padding: var(--s-2) 0;
  color: var(--accent);
  font-weight: 500;
}
.account-edit[open] summary { margin-bottom: var(--s-3); }
.account-toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-weight: 500;
}
.account-toggle input { accent-color: var(--accent); width: 18px; height: 18px; }
.account-links { list-style: none; margin: 0; padding: 0; }
.account-link-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--s-3);
  border-radius: var(--radius-md);
  color: var(--text-primary);
  font-weight: 500;
}
.account-link-row:hover, .account-link-row:focus-visible {
  background: var(--bg-elev-2);
}

/* ---- Address book ----------------------------------------------------- */
.address-list {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--s-3);
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}
.address-card {
  padding: var(--s-4);
  background: var(--bg-elev-1, rgba(255,255,255,0.02));
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.06));
  border-radius: var(--radius-md);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}
.address-card-empty { grid-column: 1 / -1; text-align: center; color: var(--text-muted); }
.address-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
}
.address-card-body { font-style: normal; line-height: 1.5; color: var(--text-primary); }
.address-card-actions {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-top: auto;
}
.address-card-actions button { font-size: 0.85rem; padding: var(--s-2) var(--s-3); }
.badge { display: inline-block; padding: 2px 8px; border-radius: var(--radius-pill); font-size: 0.75rem; font-weight: 600; }
.badge-primary { background: var(--accent); color: #0a0a0c; }
.btn-danger {
  background: rgba(255, 80, 80, 0.1);
  color: #ff8080;
  border: 1px solid rgba(255, 80, 80, 0.3);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-weight: 500;
}
.btn-danger:hover { background: rgba(255, 80, 80, 0.2); }

.address-dialog {
  max-width: 520px;
  width: 90%;
  padding: 0;
  background: transparent;
  border: 0;
}
.address-dialog::backdrop { background: rgba(0,0,0,0.6); }
.address-dialog form {
  background: var(--bg-elev-2, #1a1a1f);
  border: 1px solid var(--bg-glass-border, rgba(255,255,255,0.1));
  border-radius: var(--radius-md);
  padding: var(--s-5);
}
.address-dialog h2 { margin: 0 0 var(--s-3); }
.address-dialog-actions {
  display: flex;
  gap: var(--s-2);
  justify-content: flex-end;
  margin-top: var(--s-3);
}

/* ---- I.84 Wishlist (heart icons + topbar badge + /wunschliste page) ---- */
.wishlist-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  color: var(--text-muted);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--radius-pill);
  font-weight: 500;
  transition: all var(--t-fast) var(--ease);
  position: relative;
}
.wishlist-link:hover,
.wishlist-link:focus-visible {
  color: var(--text-primary);
  background: var(--bg-elev-2);
}
.wishlist-link.is-empty { display: none; }
.wishlist-icon {
  width: 18px;
  height: 18px;
  display: inline-block;
  vertical-align: middle;
}
.wishlist-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 22px;
  padding: 0 var(--s-2);
  background: #d11a2a; /* Red 7.7:1 on #f5f5f7; bumped to AAA on light/dark */
  color: #ffffff;
  font-weight: 700;
  font-size: 0.78rem;
  border-radius: var(--radius-pill);
  margin-left: 2px;
}

/* Heart toggle on product cards (positioned absolute over the card) */
.product-card-wrap { position: relative; }
.product-card-heart {
  position: absolute;
  top: var(--s-2);
  right: var(--s-2);
  z-index: 5;
  width: 40px;
  height: 40px;
  min-width: 40px;
  min-height: 40px;
  border: 2px solid var(--stroke-strong, #2a2f37);
  background: rgba(255, 255, 255, 0.92);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: 0;
  color: #4a4a4a;
  transition: transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.product-card-heart:hover { transform: scale(1.07); color: #d11a2a; }
.product-card-heart:focus-visible {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
}
.product-card-heart .heart-icon { width: 22px; height: 22px; }
.product-card-heart .heart-fill {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
}
.product-card-heart.is-starred { color: #d11a2a; border-color: #d11a2a; }
.product-card-heart.is-starred .heart-fill { fill: #d11a2a; stroke: #d11a2a; }

/* Landing-page "Auf Wunschliste" button */
.wishlist-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.wishlist-cta-btn .wishlist-cta-glyph {
  font-size: 1.2rem;
  line-height: 1;
}
.wishlist-cta-btn.is-starred {
  background: #fde7e9;
  color: #8b0d1a;
  border-color: #d11a2a;
}
.wishlist-cta-btn.is-starred .wishlist-cta-glyph::before { content: "♥"; }
.wishlist-cta-btn.is-starred .wishlist-cta-glyph { color: #d11a2a; }
.wishlist-cta-btn.is-starred .wishlist-cta-glyph { font-size: 0; }
.wishlist-cta-btn.is-starred .wishlist-cta-glyph::before { font-size: 1.2rem; }

/* /wunschliste page */
.wishlist-page { max-width: var(--container); margin: 0 auto; }
.wishlist-hero { margin-bottom: var(--s-5); text-align: center; }
.wishlist-hero h1 { font-size: 2rem; margin: 0 0 var(--s-2); }
.wishlist-hero .lede { color: var(--text-muted); margin: 0; }
.wishlist-empty {
  text-align: center;
  padding: var(--s-7) var(--s-4);
  background: var(--bg-elev-1);
  border-radius: var(--radius-card, 12px);
  border: 1px solid var(--stroke-strong, #2a2f37);
}
.wishlist-empty h2 { margin: 0 0 var(--s-2); }
.wishlist-empty .muted { color: var(--text-muted); margin: 0 0 var(--s-4); }
.wishlist-grid {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--s-4);
}
.wishlist-card {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-strong, #2a2f37);
  border-radius: var(--radius-card, 12px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: border-color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.wishlist-card:hover { border-color: var(--accent, #ffd400); }
.wishlist-card-link {
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
}
.wishlist-card-thumb {
  aspect-ratio: 1 / 1;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg-elev-2, #1e2228);
  overflow: hidden;
}
.wishlist-card-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.wishlist-card-thumb svg {
  width: 60%;
  height: 60%;
  color: var(--text-muted);
}
.wishlist-card-body { padding: var(--s-3) var(--s-4); flex: 1; }
.wishlist-card-body h2 { font-size: 1.05rem; margin: 0 0 var(--s-1); }
.wishlist-card-body .wishlist-note { font-size: 0.85rem; margin: 0 0 var(--s-2); }
.wishlist-card-body .wishlist-meta { color: var(--text-muted); font-size: 0.78rem; margin: 0; }
.wishlist-card-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  padding: 0 var(--s-4) var(--s-4);
}
.wishlist-card-actions .btn-secondary,
.wishlist-card-actions .btn-link {
  font-size: 0.85rem;
}
.wishlist-remove-btn {
  background: none;
  border: 0;
  color: var(--text-muted);
  cursor: pointer;
  padding: var(--s-1) var(--s-2);
  text-decoration: underline;
  border-radius: var(--radius-pill);
}
.wishlist-remove-btn:hover { color: #d11a2a; }
.wishlist-remove-btn:focus-visible {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
}
.wishlist-remove-btn:disabled { opacity: 0.5; cursor: progress; }

@media (max-width: 768px) {
  .wishlist-link { padding: var(--s-1) var(--s-2); }
  .wishlist-icon { width: 16px; height: 16px; }
  .wishlist-count { min-width: 18px; padding: 0 6px; font-size: 0.72rem; }
  .product-card-heart {
    width: 36px;
    height: 36px;
    min-width: 36px;
    min-height: 36px;
  }
}

/* ---- I.89.b — Breadcrumbs ------------------------------------------- */
/* Rendered above page content via base.html when the page controller
   sets `context.breadcrumbs`. WCAG AAA — color and contrast inherit
   from --text-muted (already >=7:1) and the focus ring uses the
   theme's accent token. */
.breadcrumb {
  margin: var(--s-2) 0 var(--s-4);
  font-size: 0.92rem;
}
.breadcrumb-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  align-items: center;
}
.breadcrumb-item {
  display: flex;
  align-items: center;
  gap: 0;
  color: var(--text-muted);
}
.breadcrumb-item a {
  color: var(--text-muted);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  padding: 0.15em 0.1em;
}
.breadcrumb-item a:hover,
.breadcrumb-item a:focus-visible {
  color: var(--text-strong);
}
.breadcrumb-item a:focus-visible {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
  border-radius: 2px;
}
.breadcrumb-item.is-current > span {
  color: var(--text-strong);
  font-weight: 500;
}
.breadcrumb-sep {
  margin: 0 0.4em;
  color: var(--text-muted);
  user-select: none;
}

/* ---- I.89.b — Cart card layout at <=768px --------------------------- */
/* Desktop keeps the existing .cart-table. On phones we render a
   stacked .cart-cards block instead — one .cart-item-card per row
   with thumb + name + variant + qty stepper + price + remove. The
   page emits BOTH markups; CSS controls which is visible. */
.cart-cards {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: var(--s-4) 0;
}
.cart-item-card {
  display: grid;
  grid-template-columns: 64px 1fr auto;
  grid-template-areas:
    "thumb body  price"
    "thumb body  remove";
  gap: 0.5rem 0.75rem;
  align-items: center;
  padding: 0.75rem;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md, 8px);
}
.cart-item-card-thumb {
  grid-area: thumb;
  width: 60px;
  height: 60px;
  border-radius: 4px;
  overflow: hidden;
  background: var(--bg-base);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cart-item-card-thumb img {
  width: 60px;
  height: 60px;
  object-fit: cover;
  display: block;
}
.cart-item-card-thumb-placeholder {
  width: 60px;
  height: 60px;
  background: var(--bg-base);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 0.75rem;
}
.cart-item-card-body {
  grid-area: body;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}
.cart-item-card-title {
  margin: 0;
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--text-strong);
  word-break: break-word;
}
.cart-item-card-variant {
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-muted);
}
.cart-item-card-qty {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin-top: 0.25rem;
}
.cart-item-card-qty button {
  width: 32px;
  height: 32px;
  min-width: 32px;
  border: 1px solid var(--stroke-soft);
  background: var(--bg-base);
  color: var(--text-strong);
  cursor: pointer;
  border-radius: 4px;
  font-size: 1rem;
  font-weight: 600;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cart-item-card-qty button:hover,
.cart-item-card-qty button:focus-visible {
  background: var(--stroke-soft);
}
.cart-item-card-qty button:focus-visible {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
}
.cart-item-card-qty button:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.cart-item-card-qty-value {
  min-width: 1.5em;
  text-align: center;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.cart-item-card-price {
  grid-area: price;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-strong);
  text-align: right;
  white-space: nowrap;
}
.cart-item-card-remove {
  grid-area: remove;
  background: none;
  border: none;
  color: var(--text-muted);
  text-decoration: underline;
  cursor: pointer;
  font-size: 0.85rem;
  text-align: right;
  padding: 0.25rem;
  min-height: 32px;
}
.cart-item-card-remove:hover,
.cart-item-card-remove:focus-visible {
  color: #b30000;
}
.cart-item-card-remove:focus-visible {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
  border-radius: 4px;
}

@media (max-width: 768px) {
  .cart-table { display: none; }
  .cart-cards { display: flex; }
}
@media (min-width: 769px) {
  .cart-cards { display: none; }
}

/* ---- I.89.b — Products page client-side search ---------------------- */
.products-search {
  margin: 0 0 var(--s-4);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 480px;
}
.products-search-input {
  width: 100%;
  padding: 0.6rem 0.75rem;
  border: 2px solid var(--stroke-soft);
  border-radius: 6px;
  font-size: 1rem;
  background: var(--bg-base);
  color: var(--text-strong);
  min-height: 44px;
}
.products-search-input:focus {
  outline: 3px solid var(--accent, #ffd400);
  outline-offset: 2px;
  border-color: var(--text-strong);
}
.products-search-status {
  font-size: 0.85rem;
  color: var(--text-muted);
  min-height: 1.2em;
}
.products-empty-state {
  padding: 1.5rem;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: 6px;
  text-align: center;
}
.products-empty-state p { margin: 0 0 0.5rem; }
.products-empty-state .link-button {
  background: none;
  border: none;
  color: var(--accent, #0050a0);
  text-decoration: underline;
  cursor: pointer;
  padding: 0.5rem 0.25rem;
  font: inherit;
  min-height: 32px;
}
.product-card-wrap.is-hidden { display: none !important; }

/* ============================================================================
   I.91 — Trust strip (under hero on /products + product landings)
   ========================================================================== */
.trust-strip {
  margin: 1.25rem 0 1.75rem;
  padding: 0.75rem 1rem;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
}
.trust-strip-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: center;
  align-items: center;
}
.trust-strip-item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--text-primary);
  font-size: 0.9375rem;
  font-weight: 500;
  min-height: 44px;
}
.trust-strip-icon {
  display: inline-flex;
  color: var(--accent);
  flex-shrink: 0;
}
.trust-strip-label { line-height: 1.3; }
.trust-strip .trust-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  color: var(--text-primary);
  text-decoration: none;
  padding: 0.3rem 0.5rem;
  border-radius: var(--radius-sm);
  min-height: 44px;
  min-width: 44px;
}
.trust-strip .trust-link:hover { background: rgba(255, 255, 255, 0.04); text-decoration: underline; }
.trust-strip .trust-link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
@media (max-width: 600px) {
  .trust-strip-list { gap: 0.5rem 1rem; }
  .trust-strip-item { font-size: 0.875rem; }
}

/* ============================================================================
   I.91 — Recently-viewed rail (above grid on /products)
   ========================================================================== */
.recently-viewed-rail[hidden] { display: none; }
.recently-viewed-rail {
  margin: 0 0 2rem;
  padding: 1.25rem 0;
  border-bottom: 1px solid var(--stroke-soft);
}
.recently-viewed-heading {
  font-size: 1.125rem;
  margin: 0 0 0.875rem;
  color: var(--text-primary);
  font-weight: 700;
}
.recently-viewed-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  gap: 0.875rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: thin;
}
.recently-viewed-item {
  flex: 0 0 160px;
  scroll-snap-align: start;
}
.recently-viewed-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--text-primary);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  min-height: 200px;
  transition: border-color 120ms ease, transform 120ms ease;
}
.recently-viewed-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.recently-viewed-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.recently-viewed-thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--bg-elev-2);
  overflow: hidden;
}
.recently-viewed-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.recently-viewed-placeholder {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, var(--bg-elev-2), var(--bg-elev-1));
}
.recently-viewed-body { padding: 0.5rem 0.625rem; }
.recently-viewed-title {
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ============================================================================
   I.91 — Upsell rail ("Auch beliebt:" below editor)
   ========================================================================== */
.upsell-rail {
  margin: 3rem auto;
  padding: 0 1.25rem;
  max-width: 1100px;
}
.upsell-rail-heading {
  font-size: 1.25rem;
  font-weight: 700;
  margin: 0 0 1rem;
  color: var(--text-primary);
}
.upsell-rail-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1rem;
}
.upsell-rail-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: var(--text-primary);
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  overflow: hidden;
  transition: border-color 120ms ease, transform 120ms ease;
  height: 100%;
}
.upsell-rail-card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
}
.upsell-rail-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.upsell-rail-thumb {
  width: 100%;
  aspect-ratio: 1 / 1;
  background: var(--bg-elev-2);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}
.upsell-rail-photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.upsell-rail-placeholder {
  color: var(--text-muted);
}
.upsell-rail-body { padding: 0.75rem 0.875rem; }
.upsell-rail-title {
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.upsell-rail-price {
  margin: 0.35rem 0 0;
  font-size: 0.8125rem;
  color: var(--text-muted);
}

/* ============================================================================
   I.108.fix — Platform-showcase homepage (`/`)

   Pre-launch rebuild: bare `/` now extends storefront/base.html and renders
   four sections — hero, personalisierte Drucke, self-service-tools,
   beratung — followed by a trust grid. The `.hp-*` namespace keeps this
   self-contained so it doesn't collide with the I.91 trust strip on
   /products + product landings.
   ========================================================================== */

/* Hero */
.hp-hero {
  max-width: 1100px;
  margin: 2.5rem auto 1rem;
  padding: 2.5rem 1.25rem 2rem;
  text-align: center;
}
.hp-hero h1 {
  font-size: clamp(1.875rem, 4vw, 2.875rem);
  line-height: 1.15;
  margin: 0 0 1rem;
  color: var(--text-primary);
  font-weight: 700;
  letter-spacing: -0.01em;
}
.hp-lead {
  font-size: clamp(1rem, 1.4vw, 1.1875rem);
  line-height: 1.55;
  margin: 0 auto 1.75rem;
  color: var(--text-secondary, var(--text-muted));
  max-width: 640px;
}
.hp-hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  justify-content: center;
}
.hp-cta-primary,
.hp-cta-secondary {
  display: inline-block;
  min-width: 200px;
  padding: 0.875rem 1.75rem;
  font-weight: 600;
  font-size: 1rem;
  border-radius: var(--radius-md);
  text-decoration: none;
  text-align: center;
}
/* Sections */
.hp-section {
  max-width: 1100px;
  margin: 2.5rem auto;
  padding: 0 1.25rem;
}
.hp-section h2 {
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  margin: 0 0 0.5rem;
  color: var(--text-primary);
  font-weight: 700;
  letter-spacing: -0.005em;
}
.hp-section-lead {
  margin: 0 0 1.5rem;
  color: var(--text-secondary, var(--text-muted));
  font-size: 1rem;
  line-height: 1.5;
  max-width: 720px;
}
.hp-section-cta {
  margin-top: 1.5rem;
}
/* Tile grids (4-up at desktop, 2-up at tablet, 1-up at mobile) */
.hp-tiles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}
.hp-tiles-4 {
  grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 900px) {
  .hp-tiles-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 540px) {
  .hp-tiles-4 { grid-template-columns: 1fr; }
}
.hp-tile {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding: 1.25rem 1.125rem;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  text-decoration: none;
  color: var(--text-primary);
  transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
  height: 100%;
}
.hp-tile:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  box-shadow: 0 4px 14px rgba(0,0,0,0.08);
}
.hp-tile:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
}
.hp-tile-thumb {
  font-size: 2rem;
  line-height: 1;
  margin-bottom: 0.25rem;
}
.hp-tile h3 {
  font-size: 1.0625rem;
  font-weight: 600;
  margin: 0;
  color: var(--text-primary);
}
.hp-tile p {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.45;
  color: var(--text-secondary, var(--text-muted));
}
/* Bullet list (Beratung section) */
.hp-bullets {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  grid-template-columns: repeat(2, 1fr);
}
@media (max-width: 540px) {
  .hp-bullets { grid-template-columns: 1fr; }
}
.hp-bullets li {
  padding: 0.625rem 0.875rem 0.625rem 2rem;
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  position: relative;
  color: var(--text-primary);
  font-size: 0.9375rem;
  line-height: 1.4;
}
.hp-bullets li::before {
  content: "✓";
  position: absolute;
  left: 0.75rem;
  top: 0.625rem;
  color: var(--accent);
  font-weight: 700;
}
/* Trust grid (closing band) */
.hp-trust {
  background: var(--bg-elev-1);
  border: 1px solid var(--stroke-soft);
  border-radius: var(--radius-md);
  padding: 1.5rem 1.25rem;
  margin-top: 3rem;
  margin-bottom: 3rem;
}
.hp-trust-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1rem;
  text-align: center;
}
@media (max-width: 900px) {
  .hp-trust-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 540px) {
  .hp-trust-grid { grid-template-columns: 1fr; }
}
.hp-trust-grid li {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.75rem;
}
.hp-trust-grid strong {
  font-size: 1rem;
  color: var(--text-primary);
}
.hp-trust-grid span {
  font-size: 0.875rem;
  color: var(--text-secondary, var(--text-muted));
  line-height: 1.4;
}
/* Inline flash banners (post-password-reset, post-account-deletion) */
.hp-flash {
  max-width: 1100px;
  margin: 1.5rem auto 0;
  padding: 0.875rem 1.125rem;
  border-radius: var(--radius-md);
  font-size: 0.9375rem;
  line-height: 1.45;
}
.hp-flash strong {
  margin-right: 0.375rem;
}
.hp-flash-success {
  /* WCAG AAA contrast: #14532d on #d1fae5 ≈ 9.6:1 (passes AAA for normal text). */
  background: #d1fae5;
  border: 1px solid #6ee7b7;
  color: #14532d;
}
/* Screen-reader-only utility (matches existing .sr-only usage in base.html) */
.hp-trust .sr-only,
.hp-section .sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
