/* =====================================================================
   SOL AND MANI MUSIC SHOP — storefront styles
   Palette taken from the logo: #016F7A teal, #012D35 night.
   ===================================================================== */

:root {
  /* Brand */
  --teal-900: #012D35;
  --teal-800: #013A44;
  --teal-700: #014C57;
  --teal-600: #015E69;
  --teal:     #016F7A;
  --teal-400: #2A8B95;
  --teal-300: #6BB0B7;
  --teal-200: #A8D0D4;
  --teal-100: #D8EAEC;
  --teal-050: #EFF7F8;

  /* Neutrals */
  --ink:      #012D35;
  --ink-soft: #17414A;
  --slate:    #52696F;
  --mute:     #869AA0;
  --line:     #E0EAEC;
  --line-soft:#EDF3F4;
  --paper:    #F4F8F9;
  --card:     #FFFFFF;

  /* Support */
  --good:  #14705C;
  --good-bg: #E3F2ED;
  --warn:  #8A6413;
  --warn-bg: #FBF1DB;
  --bad:   #A2453F;
  --bad-bg:  #F8E8E7;

  --radius-sm: 8px;
  --radius:    14px;
  --radius-lg: 22px;
  --radius-xl: 28px;

  --shadow-sm: 0 1px 2px rgba(1,45,53,.06);
  --shadow:    0 6px 20px -8px rgba(1,45,53,.20);
  --shadow-lg: 0 22px 48px -22px rgba(1,45,53,.34);

  --rail: 244px;
  --panel: 336px;

  --font-display: 'Poppins', 'Segoe UI', system-ui, sans-serif;
  --font-body: 'DM Sans', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* -------------------------------------------------------------------
     Semantic tokens. Components use these rather than the raw scale
     above, which is what lets the dark theme swap meanings — "text on a
     tint" has to get lighter while "a filled brand button" has to keep
     enough contrast for its own label.
     ------------------------------------------------------------------- */

  /* Filled brand elements: buttons, the active nav item, the basket dot */
  --fill-bg: var(--teal);
  --fill-bg-hover: var(--teal-600);
  --fill-fg: #FFFFFF;

  /* Small solid dark chips that sit on top of imagery */
  --chip-bg: var(--teal-900);
  --chip-fg: #FFFFFF;

  /* The staff panel's sidebar is dark in both themes, so it needs its
     own background rather than --ink, which flips to a text colour. */
  --rail-bg: #012D35;

  /* Brand surfaces — the banner, the account card, the rail promo.
     These stay deep in both themes so white text always reads. */
  --brand-a: #015E69;
  --brand-b: #013A44;
  --brand-c: #014C57;
  --brand-d: #016F7A;
  --brand-e: #2A8B95;

  /* Glow. Subtle in daylight, and it does more of the work after dark. */
  --glow-sm: 0 0 10px rgba(1, 111, 122, .18);
  --glow:    0 0 20px rgba(1, 111, 122, .24);
  --glow-lg: 0 0 38px rgba(1, 111, 122, .26);
  --ring:    0 0 0 4px var(--teal-050);
}

/* =====================================================================
   Dark theme
   Set by the toggle in the sidebar, or by the system preference on a
   first visit. <html data-theme="dark"> is written before the page
   paints, so there is no flash of the wrong theme.
   ===================================================================== */
:root[data-theme="dark"] {
  /* Surfaces and borders */
  --paper:     #04161A;
  --card:      #082830;
  --line:      #143B45;
  --line-soft: #0E2F38;

  /* Text */
  --ink:      #E6F3F5;
  --ink-soft: #C2DEE3;
  --slate:    #9BBAC1;
  --mute:     #77969D;

  /* Brand scale: tints become dark surfaces, and the shades that were
     dark text on those tints become light text. */
  --teal-050: #0C2B33;
  --teal-100: #123A45;
  --teal-200: #1D505C;
  --teal-300: #2A6B78;
  --teal-400: #2F97A3;
  --teal:     #35AEBB;
  --teal-600: #4FC3CF;
  --teal-700: #8FD9E1;
  --teal-800: #B6E7EC;
  --teal-900: #D8F3F6;

  /* A bright button needs dark text on it, not white */
  --fill-bg: #35AEBB;
  --fill-bg-hover: #4FC3CF;
  --fill-fg: #042227;

  --chip-bg: #0B323A;
  --chip-fg: #E6F3F5;

  --rail-bg: #021014;

  /* Support colours, lifted so they carry on a dark card */
  --good:    #5FD3B2;
  --good-bg: #0B332C;
  --warn:    #E0B457;
  --warn-bg: #362A11;
  --bad:     #F09189;
  --bad-bg:  #3A1B19;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, .40);
  --shadow:    0 6px 20px -8px rgba(0, 0, 0, .60);
  --shadow-lg: 0 22px 48px -22px rgba(0, 0, 0, .75);

  --glow-sm: 0 0 12px rgba(53, 174, 187, .30);
  --glow:    0 0 22px rgba(53, 174, 187, .38);
  --glow-lg: 0 0 46px rgba(53, 174, 187, .40);
  --ring:    0 0 0 4px rgba(53, 174, 187, .22);
}

/* Someone who has never touched the toggle gets whatever their device
   prefers. Once they choose, data-theme is set and this stops applying. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    color-scheme: dark;
  }
}
:root[data-theme="dark"] { color-scheme: dark; }

*, *::before, *::after { box-sizing: border-box; }

/* The browser's own rule for [hidden] is display:none, but any class that
   sets a display (grid, flex) outranks it, which would leave panels that
   are meant to be hidden still painted on screen. This settles it. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  line-height: 1.6;
  color: var(--ink-soft);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5 {
  font-family: var(--font-display);
  color: var(--ink);
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 0;
  line-height: 1.25;
}

h1 { font-size: 1.75rem; }
h2 { font-size: 1.3rem; }
h3 { font-size: 1.05rem; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--teal-700); text-decoration: none; }
a:hover { color: var(--teal-600); }

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

:focus-visible {
  outline: 3px solid var(--teal-400);
  outline-offset: 2px;
  border-radius: 4px;
}

.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;
}

.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 999;
  background: var(--chip-bg); color: var(--chip-fg); padding: 10px 16px; border-radius: 0 0 10px 10px;
  transition: top .15s;
}
.skip-link:focus { top: 0; color: #fff; }

/* =====================================================================
   Shell — left rail, centre column, right panel
   ===================================================================== */

.shell {
  display: grid;
  grid-template-columns: var(--rail) minmax(0, 1fr) var(--panel);
  min-height: 100vh;
  gap: 0;
}
.shell.no-panel { grid-template-columns: var(--rail) minmax(0, 1fr); }

/* ---- Left rail ---- */
.rail {
  background: var(--card);
  border-right: 1px solid var(--line);
  padding: 22px 16px 20px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand { display: flex; align-items: center; gap: 10px; padding: 0 6px; text-decoration: none; }
.brand img { width: 30px; height: auto; flex: none; }
.brand-name {
  font-family: var(--font-display);
  display: flex;
  flex-direction: column;
  line-height: 1.05;
  color: var(--ink);
}
.brand-name .brand-main {
  font-weight: 600;
  font-size: 1.06rem;
  letter-spacing: -0.02em;
}
.brand-name .brand-main em { font-style: normal; color: var(--teal); }
.brand-name .brand-sub {
  font-weight: 500;
  font-size: .58rem;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--teal);
  margin-top: 3px;
}
/* single-word shop names keep the old one-line treatment */
.brand-name > span:only-child { font-weight: 600; font-size: 1.15rem; letter-spacing: -0.02em; }

.nav { display: flex; flex-direction: column; gap: 3px; }
.nav-label {
  font-size: .72rem;
  color: var(--mute);
  padding: 14px 12px 6px;
  font-weight: 500;
}
.nav a {
  display: flex; align-items: center; gap: 11px;
  padding: 10px 12px;
  border-radius: 11px;
  color: var(--slate);
  font-size: .93rem;
  font-weight: 500;
  transition: background .12s, color .12s;
}
.nav a:hover { background: var(--teal-050); color: var(--teal-700); }
.nav a.active {
  background: var(--fill-bg);
  color: var(--fill-fg);
  box-shadow: var(--shadow), var(--glow-sm);
}
.nav a.active svg { color: var(--fill-fg); }
.nav svg { width: 19px; height: 19px; flex: none; color: var(--mute); }
.nav a:hover svg { color: var(--teal-600); }
.nav .count {
  margin-left: auto;
  background: var(--teal-100);
  color: var(--teal-700);
  font-size: .72rem;
  font-weight: 600;
  padding: 1px 8px;
  border-radius: 999px;
}
.nav a.active .count { background: rgba(255,255,255,.25); color: #fff; }

.rail-promo {
  margin-top: auto;
  background: linear-gradient(155deg, var(--brand-a), var(--brand-b));
  box-shadow: var(--glow);
  border-radius: var(--radius-lg);
  padding: 20px 18px;
  color: #fff;
  position: relative;
  overflow: hidden;
}
.rail-promo::after {
  content: '';
  position: absolute; right: -26px; bottom: -30px;
  width: 118px; height: 118px;
  background: url('../assets/logo-mark-dark.png') no-repeat center / contain;
  opacity: .13;
  filter: brightness(0) invert(1);
}
.rail-promo h4 { color: #fff; font-size: .98rem; margin-bottom: 6px; }
.rail-promo p { font-size: .82rem; color: rgba(255,255,255,.78); position: relative; }
.rail-promo .btn { margin-top: 12px; position: relative; }

/* ---- Centre column ---- */
.main { padding: 22px 28px 60px; min-width: 0; }

.topbar {
  display: flex;
  align-items: center;
  gap: 18px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.topbar-greeting { min-width: 0; }
.topbar-greeting h1 { font-size: 1.45rem; }
.topbar-greeting p { color: var(--mute); font-size: .87rem; margin: 2px 0 0; }

.search {
  flex: 1 1 260px;
  max-width: 480px;
  position: relative;
  margin-left: auto;
}
/* The generic form rule further down also matches input[type=search] at the
   same specificity, so these are written to outrank it — otherwise the pill
   shape is lost and the placeholder slides under the magnifying glass. */
.search input,
.search input[type=search] {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 999px;
  padding: 11px 18px 11px 44px;
  font: inherit;
  font-size: .9rem;
  color: var(--ink-soft);
}
.search input::placeholder,
.search input[type=search]::placeholder { color: var(--mute); }
.search input:focus,
.search input[type=search]:focus {
  outline: none;
  border-color: var(--teal-300);
  box-shadow: var(--ring);
}
/* kill the webkit clear cross so it doesn't fight the icon */
.search input[type=search]::-webkit-search-decoration,
.search input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; }
.search svg {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; color: var(--mute); pointer-events: none;
}

.topbar-actions { display: flex; align-items: center; gap: 8px; }
.icon-btn {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  border-radius: 12px;
  border: 1px solid var(--line);
  background: var(--card);
  color: var(--slate);
  cursor: pointer;
  position: relative;
  transition: border-color .12s, color .12s;
}
.icon-btn:hover { border-color: var(--teal-300); color: var(--teal-700); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn .dot {
  position: absolute; top: 6px; right: 6px;
  min-width: 16px; height: 16px; padding: 0 4px;
  background: var(--fill-bg); color: var(--fill-fg);
  box-shadow: var(--glow-sm);
  font-size: .64rem; font-weight: 700; line-height: 16px;
  border-radius: 999px; text-align: center;
  border: 2px solid var(--card);
}

/* ---- Right panel ---- */
.panel {
  background: var(--card);
  border-left: 1px solid var(--line);
  padding: 22px 20px 40px;
  position: sticky; top: 0;
  height: 100vh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 18px;
}

/* =====================================================================
   Buttons
   ===================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font-family: var(--font-body);
  font-size: .9rem; font-weight: 600;
  padding: 11px 20px;
  border-radius: 12px;
  border: 1px solid transparent;
  background: var(--fill-bg);
  color: var(--fill-fg);
  cursor: pointer;
  box-shadow: var(--glow-sm);
  transition: background .14s, border-color .14s, color .14s, box-shadow .18s;
  text-align: center;
}
.btn:hover { background: var(--fill-bg-hover); color: var(--fill-fg); box-shadow: var(--glow); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 17px; height: 17px; }

.btn-block { width: 100%; }
.btn-lg { padding: 14px 26px; font-size: .95rem; border-radius: 14px; }
.btn-sm { padding: 7px 13px; font-size: .82rem; border-radius: 9px; }

.btn-ghost { background: transparent; border-color: var(--line); color: var(--slate); }
.btn-ghost:hover { background: var(--teal-050); border-color: var(--teal-300); color: var(--teal-700); }

.btn-dark { background: var(--chip-bg); color: var(--chip-fg); }
.btn-dark:hover { background: var(--teal-800); color: var(--paper); }

.btn-light { background: rgba(255,255,255,.16); border-color: rgba(255,255,255,.4); color: #fff; }
.btn-light:hover { background: rgba(255,255,255,.26); color: #fff; }

.btn-danger { background: var(--bad); }
.btn-danger:hover { background: #8F3A34; }

/* =====================================================================
   Cards, sections, generic layout
   ===================================================================== */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.card-pad-lg { padding: 28px; }

.section { margin-bottom: 34px; }
.section-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 16px; margin-bottom: 14px;
}
.section-head p { color: var(--mute); font-size: .85rem; margin: 3px 0 0; }
.section-head a { font-size: .85rem; font-weight: 600; white-space: nowrap; }

/* On a narrow screen the heading and its link fight for the same line,
   so the link drops underneath instead of wrapping mid-phrase. */
@media (max-width: 560px) {
  .section-head { flex-direction: column; align-items: flex-start; gap: 6px; }
  .section-head a { white-space: normal; }
}

.grid { display: grid; gap: 16px; }
.grid-products { grid-template-columns: repeat(auto-fill, minmax(212px, 1fr)); }
.grid-cats { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* ---- Hero banner ---- */
.banner {
  background: linear-gradient(122deg, var(--brand-c) 0%, var(--brand-d) 62%, var(--brand-e) 100%);
  box-shadow: var(--glow-lg);
  border-radius: var(--radius-xl);
  padding: 34px 38px;
  color: #fff;
  position: relative;
  overflow: hidden;
  margin-bottom: 32px;
  min-height: 168px;
  display: flex; align-items: center;
}
.banner::after {
  content: '';
  position: absolute; right: 36px; top: 50%; transform: translateY(-50%);
  width: 190px; height: 190px;
  background: url('../assets/logo-mark-dark.png') no-repeat center / contain;
  filter: brightness(0) invert(1);
  opacity: .16;
}
.banner-inner { position: relative; max-width: 58ch; }
.banner h2 { color: #fff; font-size: 1.75rem; margin-bottom: 8px; }
.banner p { color: rgba(255,255,255,.85); font-size: .95rem; }
.banner .btn { margin-top: 16px; }

/* ---- Category tiles ---- */
.cat-tile {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px 10px;
  text-align: center;
  cursor: pointer;
  transition: border-color .14s, box-shadow .14s;
  color: var(--slate);
  font-size: .82rem;
  font-weight: 500;
  display: flex; flex-direction: column; align-items: center; gap: 9px;
}
.cat-tile:hover { border-color: var(--teal-300); box-shadow: var(--shadow-sm); color: var(--teal-700); }
.cat-tile.active { border-color: var(--teal); background: var(--teal-050); color: var(--teal-800); }
.cat-tile .bubble {
  width: 44px; height: 44px; border-radius: 13px;
  background: var(--teal-050);
  display: grid; place-items: center;
  color: var(--teal-600);
}
.cat-tile.active .bubble { background: var(--fill-bg); color: var(--fill-fg); box-shadow: var(--glow-sm); }
.cat-tile .bubble svg { width: 21px; height: 21px; }
.cat-tile .tile-name { line-height: 1.3; }

/* ---- Product cards ---- */
.product {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 12px 12px 16px;
  display: flex; flex-direction: column;
  position: relative;
  transition: border-color .14s, box-shadow .14s;
}
.product:hover { border-color: var(--teal-300); box-shadow: var(--shadow); }

.product-media {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: var(--radius);
  background: var(--teal-050);
  overflow: hidden;
  display: grid; place-items: center;
  margin-bottom: 12px;
}
.product-media img { width: 100%; height: 100%; object-fit: cover; }
.product-media .placeholder {
  width: 44%; opacity: .22;
}

.product-badge {
  /* The artwork below is positioned too, so without a z-index it paints
     over this badge. */
  z-index: 2;
  position: absolute; top: 20px; left: 20px;
  background: var(--chip-bg); color: var(--chip-fg);
  font-size: .68rem; font-weight: 700;
  padding: 3px 9px; border-radius: 7px;
  letter-spacing: .01em;
}
.product-badge.teal { background: var(--teal); }
.product-badge.out { background: var(--bad); }
/* A limited run wants to read as scarce rather than as a discount, so it
   takes the warm ink and keeps the glow the offer badge does not have. */
.product-badge.limited {
  background: var(--warn-bg); color: var(--warn);
  box-shadow: inset 0 0 0 1px currentColor;
}

.product-artist { font-size: .75rem; color: var(--teal-600); font-weight: 600; margin-bottom: 1px; }
.product-name {
  font-family: var(--font-display); font-weight: 600; font-size: .96rem;
  color: var(--ink); line-height: 1.35; margin-bottom: 4px;
}
.product-cat { font-size: .76rem; color: var(--mute); }
.product-foot {
  margin-top: auto; padding-top: 12px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
}
.price { font-family: var(--font-display); font-weight: 600; font-size: 1.02rem; color: var(--ink); }
.price small { font-size: .76rem; color: var(--mute); font-weight: 400; text-decoration: line-through; margin-left: 5px; }
.add-btn {
  width: 34px; height: 34px; border-radius: 10px;
  border: none; background: var(--fill-bg); color: var(--fill-fg);
  display: grid; place-items: center; cursor: pointer;
  box-shadow: var(--glow-sm);
  transition: background .14s, box-shadow .18s, transform .14s;
}
.add-btn:hover { background: var(--fill-bg-hover); box-shadow: var(--glow); transform: translateY(-1px); }
.add-btn:disabled { background: var(--line); color: var(--mute); cursor: not-allowed; }
.add-btn svg { width: 16px; height: 16px; }

/* ---- Row list (recent orders style) ---- */
.row-list { display: flex; flex-direction: column; gap: 10px; }
.row-item {
  display: flex; align-items: center; gap: 14px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 16px;
}
.row-thumb {
  width: 46px; height: 46px; border-radius: 11px; flex: none;
  background: var(--teal-050); overflow: hidden;
  display: grid; place-items: center;
}
.row-thumb img { width: 100%; height: 100%; object-fit: cover; }
.row-main { min-width: 0; flex: 1; }
.row-main strong { display: block; font-family: var(--font-display); font-size: .92rem; color: var(--ink); font-weight: 600; }
.row-main span { font-size: .8rem; color: var(--mute); }

/* =====================================================================
   Panel widgets
   ===================================================================== */
.panel-card {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 16px;
}
.panel-title {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 12px;
}
.panel-title h3 { font-size: .98rem; }
.panel-title button { font-size: .8rem; }

.account-card {
  background: linear-gradient(150deg, var(--brand-c), var(--brand-d));
  box-shadow: var(--glow);
  border-radius: var(--radius-lg);
  padding: 18px;
  color: #fff;
  position: relative; overflow: hidden;
}
.account-card::after {
  content: ''; position: absolute; right: -22px; bottom: -34px;
  width: 106px; height: 106px;
  background: url('../assets/logo-mark-dark.png') no-repeat center / contain;
  opacity: .14;
}
.account-card .label { font-size: .76rem; color: rgba(255,255,255,.75); }
.account-card .who { font-family: var(--font-display); font-weight: 600; font-size: 1.1rem; margin-top: 2px; position: relative; }
.account-card .actions { display: flex; gap: 8px; margin-top: 14px; position: relative; }

.cart-line {
  display: flex; gap: 11px; align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--line-soft);
}
.cart-line:last-of-type { border-bottom: none; }
.cart-thumb {
  width: 46px; height: 46px; flex: none; border-radius: 11px;
  background: var(--teal-050); overflow: hidden; display: grid; place-items: center;
}
.cart-thumb img { width: 100%; height: 100%; object-fit: cover; }
.cart-thumb .placeholder { width: 55%; opacity: .25; }
.cart-info { flex: 1; min-width: 0; }
.cart-info strong {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: .86rem; color: var(--ink); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cart-info span { font-size: .78rem; color: var(--mute); }
.qty { display: flex; align-items: center; gap: 6px; margin-top: 5px; }
.qty button {
  width: 22px; height: 22px; border-radius: 7px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--slate); cursor: pointer; line-height: 1;
  display: grid; place-items: center; font-size: .95rem; padding: 0;
}
.qty button:hover { border-color: var(--teal-300); color: var(--teal-700); }
.qty span { font-size: .82rem; min-width: 18px; text-align: center; font-weight: 600; }
.cart-price { font-family: var(--font-display); font-weight: 600; font-size: .9rem; color: var(--ink); }

.totals { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--line); }
.total-row {
  display: flex; justify-content: space-between;
  font-size: .86rem; color: var(--slate); padding: 4px 0;
}
.total-row.grand {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.08rem; color: var(--ink);
  padding-top: 10px; margin-top: 6px; border-top: 1px solid var(--line);
}

.promo-row { display: flex; gap: 8px; margin-top: 12px; }

/* =====================================================================
   Forms
   ===================================================================== */
.field { margin-bottom: 16px; }
.field label {
  display: block; font-size: .85rem; font-weight: 600;
  color: var(--ink-soft); margin-bottom: 6px;
}
.field .hint { font-size: .79rem; color: var(--mute); font-weight: 400; margin-top: 4px; }

input[type=text], input[type=email], input[type=tel], input[type=url],
input[type=number], input[type=password], input[type=search], select, textarea {
  width: 100%;
  font: inherit; font-size: .92rem;
  color: var(--ink-soft);
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 11px;
  padding: 11px 13px;
}
textarea { resize: vertical; min-height: 110px; line-height: 1.55; }
select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%235A6A72' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center;
  padding-right: 36px;
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--teal-400);
  box-shadow: var(--ring);
}
input::placeholder, textarea::placeholder { color: var(--mute); }

.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 0 16px; }

.check { display: flex; align-items: flex-start; gap: 10px; font-size: .9rem; }
.check input { width: auto; margin-top: 3px; accent-color: var(--teal); }

.radio-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px,1fr)); gap: 10px; }
.radio-card {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 13px 15px; cursor: pointer; display: flex; gap: 10px; align-items: flex-start;
}
.radio-card:hover { border-color: var(--teal-300); }
.radio-card input { width: auto; margin-top: 3px; accent-color: var(--teal); }
.radio-card strong { display: block; font-size: .88rem; font-family: var(--font-display); font-weight: 600; color: var(--ink); }
.radio-card span { font-size: .79rem; color: var(--mute); }
.radio-card:has(input:checked) { border-color: var(--teal); background: var(--teal-050); }

/* =====================================================================
   Empty states, notices, badges
   ===================================================================== */
.empty {
  text-align: center;
  padding: 46px 26px;
  border: 1px dashed var(--line);
  border-radius: var(--radius-lg);
  background: var(--card);
  color: var(--slate);
}
.empty img { width: 52px; margin: 0 auto 14px; opacity: .3; }
.empty h3 { margin-bottom: 6px; }
.empty p { font-size: .88rem; color: var(--mute); max-width: 46ch; margin-left: auto; margin-right: auto; }
.empty .btn { margin-top: 16px; }
.empty-sm { padding: 28px 18px; }
.empty-sm img { width: 38px; }

.notice {
  border-radius: var(--radius);
  padding: 13px 16px;
  font-size: .87rem;
  border: 1px solid;
  display: flex; gap: 10px; align-items: flex-start;
}
.notice svg { width: 17px; height: 17px; flex: none; margin-top: 2px; }
.notice-info { background: var(--teal-050); border-color: var(--teal-200); color: var(--teal-800); }
.notice-good { background: var(--good-bg); border-color: #BFE0D1; color: var(--good); }
.notice-warn { background: var(--warn-bg); border-color: #EBD5A6; color: var(--warn); }
.notice-bad  { background: var(--bad-bg);  border-color: #EFC8C5; color: var(--bad); }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .74rem; font-weight: 600;
  padding: 3px 9px; border-radius: 7px;
  background: var(--line-soft); color: var(--slate);
}
.badge-good { background: var(--good-bg); color: var(--good); }
.badge-warn { background: var(--warn-bg); color: var(--warn); }
.badge-bad  { background: var(--bad-bg);  color: var(--bad); }
.badge-teal { background: var(--teal-100); color: var(--teal-800); }

.announcement-bar {
  background: var(--chip-bg); color: var(--chip-fg);
  text-align: center; padding: 9px 20px; font-size: .85rem;
}
.announcement-bar a { color: var(--teal-300); }

/* =====================================================================
   Content pages (About / Contact / Order)
   ===================================================================== */
/* Content pages (About, Contact, My orders) used to be capped at 860px,
   which left a wide empty strip beside them. They now fill the middle
   column the same way the shop front and browse pages do, with the
   account and basket panel alongside. */
.page { max-width: none; }

/* Two-column content: a main column and a narrower aside. Collapses to a
   single column early, because the middle column is no longer full width
   once the basket panel is beside it. */
.page-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(240px, .85fr);
  gap: 22px;
  align-items: start;
}
@media (max-width: 1320px) {
  .page-cols { grid-template-columns: minmax(0, 1fr); }
}
.page-head { margin-bottom: 26px; }
.page-head h1 { font-size: 2rem; margin-bottom: 8px; }
.page-head p { color: var(--slate); font-size: 1rem; max-width: 62ch; }

.prose { font-size: .98rem; color: var(--ink-soft); line-height: 1.75; }
.prose p { margin-bottom: 1.1em; max-width: 68ch; }

.info-list { display: flex; flex-direction: column; gap: 0; }
.info-list div {
  display: flex; gap: 16px; padding: 11px 0;
  border-bottom: 1px solid var(--line-soft); font-size: .9rem;
}
.info-list div:last-child { border-bottom: none; }
.info-list dt, .info-list .k {
  width: 120px; flex: none; color: var(--mute); font-weight: 500;
}
.info-list .v { color: var(--ink-soft); white-space: pre-line; }

.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--line); margin-bottom: 24px; flex-wrap: wrap; }
.tab {
  padding: 10px 16px; border: none; background: none;
  font: inherit; font-size: .92rem; font-weight: 600; color: var(--mute);
  cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--teal-700); }
.tab.active { color: var(--teal-800); border-bottom-color: var(--teal); }

table.data { width: 100%; border-collapse: collapse; font-size: .88rem; }
table.data th {
  text-align: left; font-weight: 600; color: var(--mute);
  font-size: .78rem; padding: 9px 12px; border-bottom: 1px solid var(--line);
}
table.data td { padding: 12px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
table.data tr:last-child td { border-bottom: none; }
table.data td.num, table.data th.num { text-align: right; }

/* =====================================================================
   Modal
   ===================================================================== */
.modal-backdrop {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(15,15,15,.5);
  display: grid; place-items: center;
  padding: 20px;
  overflow-y: auto;
}
.modal-backdrop[hidden] { display: none; }
.modal {
  background: var(--card);
  border-radius: var(--radius-xl);
  width: min(680px, 100%);
  max-height: 90vh; overflow-y: auto;
  box-shadow: var(--shadow-lg);
  padding: 26px 28px 28px;
  position: relative;
}
.modal-wide { width: min(920px, 100%); }
.modal-close {
  position: absolute; top: 16px; right: 16px;
  width: 34px; height: 34px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--card);
  color: var(--slate); cursor: pointer; display: grid; place-items: center;
}
.modal-close:hover { border-color: var(--teal-300); color: var(--teal-700); }
.modal h2 { margin-bottom: 4px; padding-right: 40px; }
.modal-sub { color: var(--mute); font-size: .88rem; margin-bottom: 20px; }
.modal-foot {
  display: flex; gap: 10px; justify-content: flex-end;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line);
  flex-wrap: wrap;
}

/* Product detail layout inside a modal */
.detail { display: grid; grid-template-columns: 250px 1fr; gap: 24px; }
.detail-media {
  aspect-ratio: 1; border-radius: var(--radius-lg);
  background: var(--teal-050); overflow: hidden; display: grid; place-items: center;
}
.detail-media img { width: 100%; height: 100%; object-fit: cover; }
.detail-media .placeholder { width: 45%; opacity: .22; }

/* =====================================================================
   Toasts
   ===================================================================== */
.toasts {
  position: fixed; right: 20px; bottom: 20px; z-index: 300;
  display: flex; flex-direction: column; gap: 10px; align-items: flex-end;
}
.toast {
  background: var(--ink); color: #fff;
  border-radius: 12px; padding: 12px 18px;
  font-size: .88rem; box-shadow: var(--shadow-lg);
  max-width: 340px;
}
.toast.good { background: var(--good); }
.toast.bad  { background: var(--bad); }
.toast.warn { background: var(--warn); }

/* =====================================================================
   Fleeca payment sheet
   ===================================================================== */
.fleeca {
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.fleeca-head {
  background: var(--ink); color: #fff;
  padding: 16px 20px;
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
}
.fleeca-head strong { font-family: var(--font-display); font-size: 1rem; }
.fleeca-head span { font-size: .78rem; color: rgba(255,255,255,.6); }
.fleeca-body { padding: 20px; }
.fleeca-amount {
  font-family: var(--font-display); font-weight: 600;
  font-size: 2rem; color: var(--ink); letter-spacing: -0.02em;
}

/* =====================================================================
   Footer
   ===================================================================== */
/* The footer is a block now; its own columns do the arranging. The old
   flex row is kept for the legal line at the bottom. */
.foot {
  margin-top: 48px;
  font-size: .82rem; color: var(--mute);
}
.foot nav { display: flex; gap: 16px; flex-wrap: wrap; }

/* =====================================================================
   Mobile / responsive
   ===================================================================== */
.rail-toggle, .panel-toggle, .panel-close { display: none; }
.panel-close { align-self: flex-end; }
.scrim { display: none; }

@media (max-width: 1180px) {
  .shell, .shell.no-panel { grid-template-columns: var(--rail) minmax(0,1fr); }
  .panel {
    position: fixed; top: 0; right: 0; z-index: 150;
    width: min(360px, 92vw);
    transform: translateX(102%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-lg);
    border-left: 1px solid var(--line);
  }
  .panel.open { transform: none; }
  .panel-toggle { display: grid; }
  .panel-close { display: grid !important; }
}

@media (max-width: 860px) {
  .shell, .shell.no-panel { grid-template-columns: minmax(0,1fr); }
  .rail {
    position: fixed; top: 0; left: 0; z-index: 160;
    width: 262px;
    transform: translateX(-102%);
    transition: transform .22s ease;
    box-shadow: var(--shadow-lg);
  }
  .rail.open { transform: none; }
  .rail-toggle { display: grid; }
  .main { padding: 16px 16px 48px; }
  .scrim {
    display: block; position: fixed; inset: 0; z-index: 140;
    background: rgba(15,15,15,.45); opacity: 0; pointer-events: none;
    transition: opacity .2s;
  }
  .scrim.on { opacity: 1; pointer-events: auto; }
  .banner { padding: 26px 22px; }
  .banner::after { display: none; }
  .banner h2 { font-size: 1.4rem; }
  .search { order: 3; margin-left: 0; flex-basis: 100%; max-width: none; }
  .topbar { gap: 12px; }
  .topbar-greeting h1 { font-size: 1.2rem; }
  .detail { grid-template-columns: 1fr; }
  .detail-media { max-width: 240px; }
  .modal { padding: 22px 18px; }
  .page-head h1 { font-size: 1.6rem; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

@media print {
  .rail, .panel, .topbar-actions, .btn { display: none !important; }
  .shell { grid-template-columns: 1fr; }
}

/* =====================================================================
   Theme toggle
   A two-position switch that sits at the bottom of the sidebar.
   ===================================================================== */
.theme-switch {
  display: flex;
  gap: 4px;
  padding: 4px;
  margin-top: 14px;
  background: var(--teal-050);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.theme-switch button {
  /* Only the chosen one carries its label, so it takes the room it
     needs and the other two stay square. */
  flex: 0 0 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  padding: 7px 6px;
  border: none;
  background: transparent;
  border-radius: 999px;
  font: inherit;
  font-size: .78rem;
  font-weight: 600;
  color: var(--slate);
  cursor: pointer;
  transition: background .16s, color .16s, box-shadow .18s;
}
.theme-switch button svg { width: 15px; height: 15px; flex: none; }
.theme-switch button span {
  display: none;
  font-size: .76rem;
  white-space: nowrap;
}
.theme-switch button[aria-pressed="true"] { flex: 1 1 auto; }
.theme-switch button[aria-pressed="true"] span { display: inline; }
.theme-switch button:hover { color: var(--teal-700); }
.theme-switch button[aria-pressed="true"] {
  background: var(--card);
  color: var(--teal-700);
  box-shadow: var(--shadow-sm), var(--glow-sm);
}

/* =====================================================================
   Track preview
   A 30 second sample played from a YouTube link on the listing.
   ===================================================================== */
.preview-btn {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border: 1px solid var(--teal-300);
  background: var(--teal-050);
  color: var(--teal-700);
  border-radius: 999px;
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  cursor: pointer;
  transition: background .14s, box-shadow .18s, border-color .14s;
}
.preview-btn:hover { background: var(--teal-100); box-shadow: var(--glow-sm); }
.preview-btn svg { width: 15px; height: 15px; }
.preview-btn[data-state="playing"] {
  background: var(--fill-bg);
  border-color: transparent;
  color: var(--fill-fg);
  box-shadow: var(--glow);
}

/* The round control on a card's artwork. While it plays it wears a ring
   showing how much of the thirty seconds has gone. */
.preview-chip {
  position: absolute;
  bottom: 12px; right: 12px;
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border: none;
  border-radius: 50%;
  background: var(--chip-bg);
  color: var(--chip-fg);
  cursor: pointer;
  opacity: .94;
  box-shadow: var(--shadow-sm), var(--glow-sm);
  transition: transform .14s, box-shadow .18s, background .14s;
}
.preview-chip:hover { transform: scale(1.07); box-shadow: var(--glow); }
.preview-chip svg { width: 16px; height: 16px; position: relative; z-index: 1; }

.preview-chip[data-state="playing"] {
  background: var(--fill-bg);
  color: var(--fill-fg);
  box-shadow: var(--glow);
}
/* --played is updated by the player as the sample runs */
.preview-chip[data-state="playing"]::before {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  background: conic-gradient(var(--teal-300) var(--played, 0%), transparent 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
          mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}

/* =====================================================================
   The audio bar

   Previews are sound only. YouTube's player does the playing, because
   there is no other way to get at the audio, but it is parked off
   screen and this bar is what the shopper actually sees.
   ===================================================================== */
#previewStage {
  position: fixed;
  left: -9999px;
  bottom: 0;
  width: 320px;
  height: 180px;
  opacity: 0;
  pointer-events: none;
  z-index: -1;
}

.preview-box {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 14px;
  padding: 12px 14px;
  border: 1px solid var(--teal-200);
  border-radius: var(--radius);
  background: var(--teal-050);
  box-shadow: var(--glow-sm);
}
.preview-note { font-size: .78rem; color: var(--slate); white-space: nowrap; }

.preview-bar {
  flex: 1;
  min-width: 60px;
  height: 6px;
  border-radius: 999px;
  background: var(--teal-200);
  overflow: hidden;
}
.preview-bar span {
  display: block;
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: var(--fill-bg);
  box-shadow: var(--glow-sm);
  transition: width .25s linear;
}
.preview-count {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: .82rem;
  color: var(--teal-700);
  min-width: 30px;
  text-align: right;
}
.preview-source {
  display: grid; place-items: center;
  width: 26px; height: 26px;
  border-radius: 7px;
  color: var(--teal-700);
  flex: none;
}
.preview-source:hover { background: var(--teal-100); }

/* Four bars that bounce while the sample plays, so it is clear that
   something is making sound even though there is nothing to watch. */
.preview-eq { display: flex; align-items: flex-end; gap: 2px; height: 16px; flex: none; }
.preview-eq i {
  display: block;
  width: 3px;
  border-radius: 2px;
  background: var(--fill-bg);
  animation: eq .9s ease-in-out infinite;
}
.preview-eq i:nth-child(1) { height: 60%; animation-delay: -.30s; }
.preview-eq i:nth-child(2) { height: 100%; animation-delay: -.15s; }
.preview-eq i:nth-child(3) { height: 45%; animation-delay: -.45s; }
.preview-eq i:nth-child(4) { height: 80%; animation-delay: 0s; }

@keyframes eq {
  0%, 100% { transform: scaleY(.35); }
  50%      { transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
  .preview-bar span { transition: none; }
  .preview-eq i { animation: none; }
}

/* =====================================================================
   Condition badges

   Borrowed from how the bigger music retailers mark B-Stock and
   pre-owned gear. On a secondhand shelf this is the second thing a
   shopper looks at after the price, so it gets its own colour rather
   than being buried in the description.
   ===================================================================== */
.cond {
  display: inline-flex;
  align-items: center;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .02em;
  padding: 3px 8px;
  border-radius: 6px;
  white-space: nowrap;
}
.cond-new     { background: var(--teal-100); color: var(--teal-800); }
.cond-good    { background: var(--good-bg);  color: var(--good); }
.cond-used    { background: var(--teal-050); color: var(--teal-700); border: 1px solid var(--teal-200); }
.cond-fair    { background: var(--warn-bg);  color: var(--warn); }
.cond-bstock  { background: var(--chip-bg);  color: var(--chip-fg); }
.cond-vintage { background: var(--warn-bg);  color: var(--warn); border: 1px solid var(--warn); }

/* The offer badge and the condition share one row across the top of a
   card. Pinning them to opposite corners looked tidier until a long
   grade met a long offer on a narrow card and the two overlapped; this
   wraps instead. */
.product-tags {
  position: absolute;
  z-index: 2;
  top: 20px; left: 20px; right: 20px;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 6px;
  flex-wrap: wrap;
  pointer-events: none;
}
.product-tags > * { pointer-events: auto; }
/* Inside the row the badge no longer positions itself. */
.product-tags .product-badge { position: static; top: auto; left: auto; }

/* =====================================================================
   Savings

   A struck-through price makes the reader do the arithmetic. Saying the
   saving outright is the thing every big retailer does, and it is the
   cheapest clarity win on the whole card.
   ===================================================================== */
.saving {
  display: inline-block;
  margin-top: 3px;
  font-size: .74rem;
  font-weight: 700;
  color: var(--good);
}
.saving-lg { font-size: .88rem; margin-top: 6px; }

/* =====================================================================
   What we promise

   The service strip under the banner. Four short promises, all editable
   in Settings, laid out as one row that wraps down to two and then one.
   ===================================================================== */
.promises {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
  margin-bottom: 30px;
}
.promise {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 14px 16px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}
.promise-mark {
  flex: none;
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 10px;
  background: var(--teal-050);
  color: var(--teal-600);
  box-shadow: var(--glow-sm);
}
.promise-mark svg { width: 18px; height: 18px; }
.promise h4 { font-size: .86rem; margin-bottom: 2px; line-height: 1.3; }
.promise p { font-size: .78rem; color: var(--slate); line-height: 1.45; }

/* =====================================================================
   Browse: the filter rail

   Both reference shops lean on faceted filtering, and it is what a
   shelf of records actually needs: price, condition and what is
   genuinely in stock. Everything here filters the listings already
   fetched, so nothing hits the database again.
   ===================================================================== */
.browse {
  display: grid;
  grid-template-columns: 232px minmax(0, 1fr);
  gap: 24px;
  align-items: start;
}
@media (max-width: 1100px) {
  .browse { grid-template-columns: minmax(0, 1fr); }
  .facets { position: static; }
}

.facets {
  position: sticky;
  top: 18px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 4px 16px 14px;
  box-shadow: var(--shadow-sm);
}
.facet-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
  padding: 14px 0 12px;
  border-bottom: 1px solid var(--line-soft);
}
.facet-head h3 { font-size: .92rem; display: flex; align-items: center; gap: 7px; }
.facet-head h3 svg { width: 16px; height: 16px; color: var(--teal-600); }
.facet-clear {
  border: none; background: none; padding: 0;
  font: inherit; font-size: .78rem; font-weight: 600;
  color: var(--teal-700); cursor: pointer;
}
.facet-clear:disabled { color: var(--mute); cursor: default; }

.facet { padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.facet:last-child { border-bottom: none; }
.facet > h4 {
  font-size: .72rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 10px;
}
.facet-opt {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 0;
  font-size: .85rem;
  color: var(--ink-soft);
  cursor: pointer;
}
.facet-opt input { width: auto; accent-color: var(--teal); flex: none; cursor: pointer; }
.facet-opt .n { margin-left: auto; font-size: .76rem; color: var(--mute); font-variant-numeric: tabular-nums; }
.facet-opt.is-empty { opacity: .45; cursor: default; }

.facet-price { display: flex; align-items: center; gap: 8px; }
.facet-price input { width: 100%; font-size: .85rem; padding: 8px 10px; }
.facet-price span { color: var(--mute); font-size: .8rem; }

/* The chips above the grid that say what is currently filtered. */
.chips { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 16px; }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 7px 5px 11px;
  background: var(--teal-050);
  border: 1px solid var(--teal-200);
  border-radius: 999px;
  font-size: .78rem; font-weight: 600;
  color: var(--teal-700);
}
.chip button {
  border: none; background: none; padding: 0;
  display: grid; place-items: center;
  color: inherit; cursor: pointer; opacity: .7;
}
.chip button:hover { opacity: 1; }
.chip svg { width: 13px; height: 13px; }

/* =====================================================================
   Tabbed sections

   The front page ran three stacked shelves, which pushed the newest
   stock a long way down. As tabs they occupy one screen.
   ===================================================================== */
.shelf-tabs {
  display: flex; gap: 4px;
  padding: 4px;
  margin-bottom: 18px;
  background: var(--teal-050);
  border: 1px solid var(--line);
  border-radius: 999px;
  width: fit-content;
  max-width: 100%;
  overflow-x: auto;
}
.shelf-tabs button {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 15px;
  border: none; background: none;
  border-radius: 999px;
  font: inherit; font-size: .84rem; font-weight: 600;
  color: var(--slate);
  white-space: nowrap;
  cursor: pointer;
  transition: background .16s, color .16s, box-shadow .18s;
}
.shelf-tabs button:hover { color: var(--teal-700); }
.shelf-tabs button[aria-selected="true"] {
  background: var(--card);
  color: var(--teal-700);
  box-shadow: var(--shadow-sm), var(--glow-sm);
}
.shelf-tabs .n {
  font-size: .72rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--teal-100);
  color: var(--teal-800);
}

/* =====================================================================
   Footer

   A single line of links was thin for a shop. This is the columned
   footer both reference sites use, built from the settings the shop
   already holds.
   ===================================================================== */
/* Four named columns rather than auto-fit. Following an explicit column
   with repeat(auto-fit, ...) generates as many tracks as will fit, which
   left the links bunched to one side with the last column pushed off the
   edge.

   Every track is minmax(0, …) rather than a bare fr. A bare `1fr` means
   minmax(auto, 1fr), and that `auto` floor is the column's min-content
   width — so one unbreakable string, such as the shop's email address,
   widened its own track, pushed the total past the footer and shunted
   Find us off the right-hand edge. A zero floor lets every column give
   way, and the wrapping rules below let the long values break instead. */
.foot-cols {
  display: grid;
  grid-template-columns:
    minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1.35fr);
  gap: 28px;
  padding: 30px 0 22px;
  border-top: 1px solid var(--line);
}
/* Two columns, then one. The brand sits across the full width at the
   two-column size so the three link columns pair up evenly beneath it. */
/* Two columns, filled in reading order: the brand, then the two link
   lists, then Find us. Spanning the brand across both would strand Find
   us alone on the last row with half the width empty beside it. */
@media (max-width: 1040px) {
  .foot-cols { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 26px 36px; }
}
@media (max-width: 560px) {
  .foot-cols { grid-template-columns: minmax(0, 1fr); gap: 24px; }
}
.foot-col h4 {
  font-size: .72rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 12px;
}
.foot-col { min-width: 0; }
/* list-style: none takes the bullets away but leaves the browser's own
   40px indent behind, which pushed every link column a third of its own
   width to the right and made the footer read as bunched over. */
.foot-col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex; flex-direction: column; gap: 8px;
}
.foot-col a { font-size: .85rem; color: var(--slate); }
.foot-col a:hover { color: var(--teal-700); }
.foot-about .brand { padding: 0; margin-bottom: 12px; }
.foot-about p { font-size: .84rem; color: var(--slate); line-height: 1.55; max-width: 34ch; }
.foot-contact { display: flex; flex-direction: column; gap: 8px; }
.foot-contact div { display: flex; gap: 8px; font-size: .84rem; color: var(--slate); }
.foot-contact svg { width: 15px; height: 15px; flex: none; color: var(--teal-600); margin-top: 2px; }
/* An address or an email is the one thing in here long enough to force a
   column wider than its share, so both are allowed to wrap mid-word. */
.foot-contact .v { white-space: pre-line; min-width: 0; overflow-wrap: anywhere; }
.foot-contact a { min-width: 0; overflow-wrap: anywhere; }
.foot-legal {
  display: flex; flex-wrap: wrap; gap: 4px 18px;
  align-items: baseline;
  padding: 16px 0 10px;
  border-top: 1px solid var(--line-soft);
  font-size: .8rem; color: var(--mute);
}
.foot-legal .sep { color: var(--line); }
/* The legal line is long enough to wrap well before the phone
   breakpoint, which left the separator orphaned at the end of a line.
   It stacks as soon as it stops fitting on one. */
@media (max-width: 900px) {
  .foot-legal { flex-direction: column; gap: 4px; }
  .foot-legal .sep { display: none; }
}

/* =====================================================================
   Refinements after looking at the rendered pages
   ===================================================================== */

/* With a filter rail on one side and the basket on the other, the
   middle column is narrow, so listings pack a little tighter there
   than on the shop front. */
.browse .grid-products { grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); }
.browse .product { padding: 10px 10px 14px; }
.browse .product-tags { top: 16px; left: 16px; right: 16px; }

/* The native tick box renders muddy against a dark card, so it is drawn
   here instead. Same shape in both themes, and it still behaves as a
   real checkbox for the keyboard and for screen readers. */
.facet-opt input[type="checkbox"],
.facet-opt input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px;
  margin: 0;
  border: 1.5px solid var(--teal-300);
  background: var(--card);
  border-radius: 4px;
  display: grid; place-items: center;
  transition: background .14s, border-color .14s, box-shadow .18s;
}
.facet-opt input[type="radio"] { border-radius: 50%; }

.facet-opt input:checked {
  background: var(--fill-bg);
  border-color: var(--fill-bg);
  box-shadow: var(--glow-sm);
}
.facet-opt input[type="checkbox"]:checked::after {
  content: '';
  width: 9px; height: 5px;
  border: 2px solid var(--fill-fg);
  border-top: 0; border-right: 0;
  transform: translateY(-1px) rotate(-45deg);
}
.facet-opt input[type="radio"]:checked::after {
  content: '';
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--fill-fg);
}
.facet-opt input:focus-visible { outline: none; box-shadow: var(--ring); }
.facet-opt input:disabled { opacity: .4; }

/* The same treatment for the staff panel's own switches, so the two
   sides of the site do not disagree. */
.switch input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px;
  border: 1.5px solid var(--teal-300);
  background: var(--card);
  border-radius: 4px;
  display: inline-grid; place-items: center;
  vertical-align: -3px;
  transition: background .14s, border-color .14s;
}
.switch input[type="checkbox"]:checked {
  background: var(--fill-bg);
  border-color: var(--fill-bg);
}
.switch input[type="checkbox"]:checked::after {
  content: '';
  width: 9px; height: 5px;
  border: 2px solid var(--fill-fg);
  border-top: 0; border-right: 0;
  transform: translateY(-1px) rotate(-45deg);
}
.switch input[type="checkbox"]:focus-visible { outline: none; box-shadow: var(--ring); }

/* The filter rail collapses on a narrow screen. On a wide one it is
   always open and the toggle is not shown at all, so the class the
   script sets is simply ignored there. */
.facet-toggle {
  display: none;
  width: 30px; height: 30px;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 9px;
  color: var(--teal-700);
  place-items: center;
  cursor: pointer;
}
.facet-toggle svg { width: 15px; height: 15px; }

/* A count beside the heading, so a collapsed rail still says how many
   filters are on. */
.facet-n {
  margin-left: 7px;
  font-size: .72rem; font-weight: 700;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--fill-bg);
  color: var(--fill-fg);
}

@media (max-width: 1100px) {
  .facet-toggle { display: grid; }
  .facets:not(.open) .facet-body { display: none; }
  .facets:not(.open) .facet-head { border-bottom: none; padding-bottom: 14px; }
}

/* On a phone a shop grid reads as two across. Left to the desktop
   minimum it collapses to one very tall column per listing. */
@media (max-width: 560px) {
  .grid-products,
  .browse .grid-products { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .product { padding: 8px 8px 12px; }
  .product-tags { top: 12px; left: 12px; right: 12px; }
  .product-name { font-size: .92rem; }
  .price { font-size: .95rem; }
  .saving { font-size: .7rem; }
  /* the offer and grade need the full width each at this size */
  .product-tags { flex-direction: column; align-items: flex-start; }
}


/* =====================================================================
   The landing page

   The front door. It shares every component with the shop floor — the
   same cards, the same section heads — and adds only three things of its
   own: the hero, the advert tiles, and the limited edition note.
   ===================================================================== */

/* ---- Hero ----------------------------------------------------------
   Bigger than the shop's banner and deliberately quieter: the banner
   sells a promotion, this introduces the shop. It is a single column
   until the staff add an image, at which point it splits in two.
   -------------------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-xl);
  background: linear-gradient(118deg, var(--brand-b) 0%, var(--brand-c) 48%, var(--brand-d) 100%);
  box-shadow: var(--glow-lg);
  color: #fff;
  padding: 46px 44px;
  margin-bottom: 34px;
}
.hero::after {
  content: '';
  position: absolute; right: -40px; bottom: -70px;
  width: 300px; height: 300px;
  background: url('../assets/logo-mark-dark.png') no-repeat center / contain;
  filter: brightness(0) invert(1);
  opacity: .10;
  pointer-events: none;
}
/* With an image, words on the left and art on the right. minmax(0,…) so
   a wide photograph cannot widen its own track and push the words out. */
.hero.hero-split {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr);
  gap: 40px;
  align-items: center;
}
.hero.hero-split::after { display: none; }

.hero-words { position: relative; max-width: 56ch; }
.hero-kicker {
  display: inline-block;
  font-size: .72rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  color: rgba(255, 255, 255, .72);
  margin-bottom: 12px;
}
.hero-words h2 {
  color: #fff;
  font-size: clamp(1.7rem, 3.2vw, 2.5rem);
  line-height: 1.14;
  margin: 0 0 14px;
}
.hero-words p {
  color: rgba(255, 255, 255, .86);
  font-size: 1rem; line-height: 1.6;
  margin: 0;
  max-width: 52ch;
}
.hero-acts { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 26px; }

.hero-art {
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  aspect-ratio: 4 / 3;
  background: rgba(255, 255, 255, .06);
}
.hero-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 900px) {
  .hero { padding: 34px 26px; }
  .hero.hero-split { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  /* The picture after the words on a narrow screen — the wording is
     what a visitor needs first. */
  .hero-art { order: 2; aspect-ratio: 16 / 9; }
}
/* Once the two buttons stack they should be the same width, or the
   second reads as the lesser of the two rather than the alternative. */
@media (max-width: 560px) {
  .hero { padding: 28px 20px; }
  .hero-acts { flex-direction: column; align-items: stretch; }
  .hero-acts .btn { width: 100%; }
}

/* ---- Adverts -------------------------------------------------------
   The shop's own notices: an offer, a gig, a closure. Staff write them
   in the panel, and each is a whole tile so the link target is the
   obvious one.
   -------------------------------------------------------------------- */
.adverts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
  gap: 16px;
}
.advert {
  display: flex; flex-direction: column;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  color: inherit;
  transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease;
}
a.advert:hover {
  transform: translateY(-2px);
  border-color: var(--teal-300);
  box-shadow: var(--shadow), var(--glow-sm);
}
.advert-art {
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--paper);
}
.advert-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.advert-words {
  display: flex; flex-direction: column; gap: 7px;
  padding: 18px 20px 20px;
}
.advert-kind {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--teal-600);
}
.advert-words strong {
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.02rem; line-height: 1.32;
  color: var(--ink);
}
.advert-body {
  font-size: .86rem; line-height: 1.55;
  color: var(--slate);
}
.advert-cta {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 4px;
  font-size: .84rem; font-weight: 600;
  color: var(--teal-700);
}
.advert-cta svg { width: 14px; height: 14px; }

/* A gig and a closure are not the same kind of news, so the left edge
   says which without another badge to read. */
.advert { border-left: 3px solid var(--teal-300); }
.advert-event  { border-left-color: var(--brand-e); }
.advert-event  .advert-kind { color: var(--brand-e); }
.advert-notice { border-left-color: var(--warn); }
.advert-notice .advert-kind { color: var(--warn); }

/* ---- Limited editions ---------------------------------------------- */
/* Shown on the listing itself: how many were made, and how many are
   left of them. */
.limited-note {
  display: flex; align-items: flex-start; gap: 9px;
  background: var(--warn-bg);
  border-radius: var(--radius-sm);
  padding: 11px 13px;
  font-size: .85rem; line-height: 1.5;
  color: var(--warn);
}
.limited-note svg { width: 16px; height: 16px; flex: none; margin-top: 2px; }
.limited-note strong { font-weight: 700; }


/* =====================================================================
   Waiting on something out of our hands

   Used while the shop asks Fleeca Bank whether a transfer settled. An
   indeterminate bar rather than a percentage, because there is no
   progress to report — only the fact that something is still happening.
   ===================================================================== */
.waiting-bar {
  position: relative;
  overflow: hidden;
  height: 6px;
  margin-top: 18px;
  border-radius: 999px;
  background: var(--line-soft);
}
.waiting-bar span {
  position: absolute;
  top: 0; bottom: 0; left: 0;
  width: 40%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--brand-d), var(--brand-e));
  box-shadow: var(--glow-sm);
  animation: waiting-slide 1.4s ease-in-out infinite;
}
@keyframes waiting-slide {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(250%); }
}
/* Someone who has asked for less movement gets a steady bar instead of
   a travelling one. */
@media (prefers-reduced-motion: reduce) {
  .waiting-bar span { animation: none; width: 100%; opacity: .55; }
}
