/* ─────────────────────────────────────────────────────────────
   Storefront component styles.

   These were scoped <style> blocks inside the Phase 1 .astro
   components. Django templates have no style scoping, so they are
   collected here. global.css is unchanged from Phase 1 and owns the
   design tokens, buttons, sections and product-grid card styling.
   ───────────────────────────────────────────────────────────── */

/* ── Header ─────────────────────────────────────────────────── */

.topbar {
  background: var(--ink);
  color: rgba(248, 243, 237, 0.78);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
}

.topbar-inner {
  min-height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  backdrop-filter: blur(20px) saturate(1.1);
  background: rgba(251, 249, 245, 0.82);
  border-bottom: 1px solid var(--line);
  transition: background 0.3s ease, box-shadow 0.3s ease;
}

.site-header[data-scrolled] {
  background: rgba(251, 249, 245, 0.94);
  box-shadow: 0 1px 0 var(--line), var(--shadow-md);
}

.header-inner {
  min-height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.brand { display: flex; align-items: center; }

.brand-logo {
  display: block;
  height: clamp(3.6rem, 7.5vw, 4.8rem);
  width: auto;
}

@media (max-width: 480px) {
  .brand-logo { height: 3.1rem; }
}

.nav { display: none; gap: 1.8rem; }

.nav-link {
  position: relative;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.nav-link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: -0.4rem;
  width: 100%;
  height: 2px;
  background: var(--spectrum);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.28s ease;
}

.nav-link:hover::after,
.nav-link.active::after { transform: scaleX(1); }

.header-actions { display: none; align-items: center; gap: 0.55rem; }

.icon-btn {
  position: relative;
  width: 2.6rem;
  height: 2.6rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  transition: 0.25s var(--ease-out);
}

.icon-btn:hover { background: #fff; border-color: var(--line-strong); }

/* Trade indicator — only rendered for approved trade accounts. */
.trade-pill {
  display: inline-flex;
  align-items: center;
  height: 2.6rem;
  padding: 0 1rem;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-size: 0.66rem;
  font-weight: 800;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.header-cta {
  min-height: 2.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Two words, one line. As a flex item in the header row this pill was free to
     shrink below the width of its own text, and "SHOP NOW" broke across two
     lines inside it -- which is what made it look off-centre. "SIGN IN" is
     narrower and never wrapped, so the fault only showed to signed-in
     visitors. */
  white-space: nowrap;
  flex: 0 0 auto;
  /* Letter-spacing is added AFTER every character, including the last, so
     tracked uppercase text sits half a space left of centre in the pill. Taking
     that half-space off the right padding moves the box back over it.
     (text-indent, which was here before, does nothing on a flex container.) */
  padding: 0 calc(1.35rem - 0.07em) 0 calc(1.35rem + 0.07em);
  border-radius: 999px;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
  transition: 0.25s var(--ease-out);
}

.header-cta:hover { background: var(--accent); }

.menu-toggle {
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  background: transparent;
  display: grid;
  align-content: center;
  gap: 0.4rem;
  cursor: pointer;
}

.menu-toggle span { display: block; height: 1.5px; background: var(--ink); }

.mobile-nav {
  display: grid;
  padding: 0.5rem 1.25rem 1.25rem;
  border-top: 1px solid var(--line);
  background: rgba(251, 249, 245, 0.98);
}

.mobile-nav[hidden] { display: none; }

.mobile-nav a {
  padding: 0.9rem 0.2rem;
  border-bottom: 1px solid var(--line);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.86rem;
}

@media (min-width: 900px) {
  .nav,
  .header-actions { display: flex; }
  .menu-toggle,
  .mobile-nav { display: none !important; }
}

/* ── Footer ─────────────────────────────────────────────────── */

.site-footer {
  background:
    radial-gradient(circle at 12% 0%, rgba(192, 106, 73, 0.18), transparent 42%),
    var(--ink);
  color: #f4ebe2;
  padding: 0 0 1.75rem;
}

.footer-grid { display: grid; gap: 2.4rem; padding-top: 3.5rem; }

.footer-logo-lockup { display: inline-block; margin-bottom: 1.2rem; }
.footer-logo-lockup img { display: block; height: 3rem; width: auto; }

/* Row of icon buttons under the brand blurb. The newsletter sits below it,
   so the row owns the space on both sides rather than leaving the heading
   below to butt up against the circles. */
.socials {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex-wrap: wrap;
  margin: 1.5rem 0 2rem;
}

.footer-grid .socials a {
  width: 3rem;
  height: 3rem;
  display: grid;
  place-items: center;
  margin-bottom: 0;
  border: 1px solid rgba(244, 235, 226, 0.22);
  border-radius: 50%;
  color: #f4ebe2;
  transition: 0.25s ease;
}

.socials svg { width: 1.4rem; height: 1.4rem; }

.socials a:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  transform: translateY(-2px);
}

.footer-brand p,
.footer-grid p { color: rgba(244, 235, 226, 0.7); max-width: 28rem; }

.footer-grid h3 {
  font-family: var(--font-body);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin-bottom: 1rem;
  color: var(--gold-2);
}

.footer-newsletter h4 {
  font-family: var(--font-body);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  margin: 0 0 0.6rem;
  color: var(--gold-2);
}

/* Reads as the same kind of text as the brand blurb above it, so it is set the
   same way: the footer's body size, and dimmed once by the colour it already
   inherits rather than by a second opacity on top. */
.footer-newsletter p {
  margin: 0 0 0.9rem;
}

/* The email box and its button are one control; keep them on one line until
   the column is genuinely too narrow, rather than wrapping the button under a
   half-width field. */
.footer-newsletter .newsletter-form {
  align-items: center;
  gap: 0.6rem;
}

.footer-grid a { display: block; margin-bottom: 0.55rem; color: rgba(244, 235, 226, 0.88); }
.footer-grid a:hover { color: var(--gold-2); }

/* Call and WhatsApp on one line. Wraps rather than shrinking, so on a narrow
   phone the two tap targets stack instead of sitting too close to mis-tap. */
.footer-contact-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 1.1rem;
  margin-bottom: 0.55rem;
}

.footer-contact-row a.footer-contact-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0;
  /* A comfortable tap target on a phone without pushing the rows apart. */
  padding: 0.15rem 0;
}

.footer-contact-link svg { flex: none; }

/* WhatsApp's own green, so the icon reads as WhatsApp rather than as another
   footer link. Hover still goes to the site's gold, keeping it in family. */
.footer-whatsapp { color: #4ac35e; }
.footer-whatsapp:hover { color: var(--gold-2); }

/* The glyph carries the link on its own, so it has to be worth tapping. 22px
   of icon is a hard target on a phone; the padding grows the hit area to a
   comfortable size and the negative margin spends it outwards, leaving the
   row exactly as tall as it was. */
.footer-contact-row a.footer-whatsapp {
  padding: 0.5rem;
  margin: -0.5rem 0 -0.5rem -0.2rem;
  border-radius: 999px;
}

.footer-contact-row a.footer-whatsapp:hover,
.footer-contact-row a.footer-whatsapp:focus-visible {
  background: rgba(74, 195, 94, 0.14);
}

/* The same number set inline in prose -- policy pages, the contact page. The
   glyph and the digits stay on one line: a phone number broken across a line
   break is hard to read back and impossible to tap as one target. */
.wa-inline {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  white-space: nowrap;
}

.wa-inline svg {
  flex: none;
  color: #25d366;
}

.note { margin-top: 1rem; color: var(--gold-2) !important; }

.footer-bottom,
.footer-bottom span,
.footer-bottom .legal-links a {
  font-size: 0.85rem;
}

.footer-bottom {
  margin-top: 2.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid rgba(244, 235, 226, 0.12);
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
  justify-content: space-between;
  align-items: center;
  font-size: 0.85rem;
  color: rgba(244, 235, 226, 0.5);
}

/* Wraps. Without this the row of policy links ran off the right of a phone
   screen and half of them -- Privacy, Cookies, Company info -- could not be
   reached at all without turning the phone sideways. */
.legal-links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.25rem;
}
.legal-links a { color: rgba(244, 235, 226, 0.7); font-size: 0.8rem; }
.legal-links a:hover { color: var(--gold-2); }

/* On a phone the bottom bar stacks, and three left-aligned blocks of different
   widths read as a mistake. Centre them once they are no longer in a row. */
@media (max-width: 700px) {
  .footer-bottom {
    justify-content: center;
    text-align: center;
  }
}

@media (min-width: 620px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 900px) {
  .footer-grid { grid-template-columns: 1.6fr 0.9fr 0.9fr 1.3fr; }
}

/* ── Product card additions ─────────────────────────────────── */

.trade-badge { background: var(--accent) !important; color: #fff !important; }

.stock-out {
  font-size: 0.62rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 800;
  color: #b00;
}

/* ── Home ───────────────────────────────────────────────────── */

.home-hero {
  padding: clamp(4rem, 9vw, 7.5rem) 0 clamp(3rem, 6vw, 5rem);
}

.home-hero h1 {
  font-size: clamp(3rem, 8vw, 6rem);
  margin: 0.6rem 0 1.2rem;
  max-width: 16ch;
}

.home-hero .lede {
  color: var(--ink-soft);
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  max-width: 42rem;
  margin-bottom: 2rem;
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; }

.stat-row {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  margin-top: clamp(3rem, 6vw, 4.5rem);
  padding-top: 2.2rem;
  border-top: 1px solid var(--line);
}

.stat strong {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4vw, 3rem);
  font-weight: 500;
  line-height: 1;
}

.stat span {
  color: var(--muted);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
}

.category-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 2.5rem;
}

.category-strip a {
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.55rem 1.05rem;
  font-size: 0.75rem;
  font-weight: 600;
  transition: 0.25s var(--ease-out);
}

.category-strip a:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.trade-cta {
  background: var(--paper-2);
  border-radius: var(--radius-lg);
  padding: clamp(2.5rem, 5vw, 4rem);
  display: grid;
  gap: 1.2rem;
  justify-items: start;
}

.trade-cta h2 { font-size: clamp(2rem, 4vw, 3rem); }
.trade-cta p { color: var(--ink-soft); max-width: 40rem; }

/* ── Shop ───────────────────────────────────────────────────── */

.shop-hero { margin-bottom: 2.5rem; }
.shop-hero h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); margin: 0.5rem 0 0.7rem; }
.shop-hero p { color: var(--muted); }

.toolbar {
  display: grid;
  gap: 1rem;
  margin-bottom: 1.4rem;
}

.search input,
.sort select {
  width: 100%;
  min-height: 3.2rem;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  /* Said out loud, like the chips. A control that paints its own white
     background must name its text colour too, or the device decides: iOS
     renders an unstyled <select> in the system blue, which is how "Featured"
     came to sit there in link-blue on the client's iPad. */
  color: var(--ink);
  padding: 0.75rem 1.1rem;
}

.search input:focus,
.sort select:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }

.sort { display: grid; gap: 0.35rem; }

.sort span,
.filter-label {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--muted);
}

.filters {
  display: grid;
  gap: 1rem;
  padding: 1.2rem 0;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  margin-bottom: 1.1rem;
}

.filter-block { display: grid; gap: 0.55rem; }

.chips { display: flex; flex-wrap: wrap; gap: 0.45rem; }

.chip {
  border: 1px solid var(--line-strong);
  background: transparent;
  /* Stated outright rather than left to inheritance. This is the label a
     shopper reads to filter the range; it must never depend on what a browser
     happens to default a <button> to. */
  color: var(--ink);
  border-radius: 999px;
  padding: 0.55rem 1.05rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: 0.25s var(--ease-out);
}

.chip.active,
.chip:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.meta-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.count { color: var(--muted); }

.clear {
  border: 0;
  background: transparent;
  color: var(--skin-4);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.empty-state { padding: 3rem 0; color: var(--muted); }

.pagination {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: center;
  margin-top: 3.5rem;
}

.pagination a,
.pagination span {
  padding: 0.6rem 1rem;
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  font-size: 0.8rem;
  font-weight: 600;
}

.pagination .current { background: var(--ink); color: var(--paper); border-color: var(--ink); }

@media (min-width: 800px) {
  .toolbar { grid-template-columns: 1fr 220px; align-items: end; }
}

/* ── Product detail ─────────────────────────────────────────── */

.pdp { padding: clamp(2.5rem, 5vw, 4rem) 0; }

.pdp-grid { display: grid; gap: 2.5rem; }

.hero-shot {
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--paper-deep);
  box-shadow: var(--shadow-md);
  aspect-ratio: 1 / 1;
}

/* `contain`, not `cover`. The box is square so the page height does not jump
   between products, but the images arriving in it are not: supplier artwork is
   wide, and a 16:9 infographic cropped to a square loses the whole left and
   right edge -- which on these is where the product name and half the claims
   live. Letterboxing against the paper background costs nothing; a cropped
   claim costs the customer the information they opened the page for. */
.hero-shot img { width: 100%; height: 100%; object-fit: contain; }

.thumbs {
  display: flex;
  gap: 0.6rem;
  margin-top: 0.85rem;
  flex-wrap: wrap;
}

.thumb {
  width: 4.6rem;
  height: 4.6rem;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--paper-deep);
  cursor: pointer;
  transition: 0.25s var(--ease-out);
}

.thumb:hover,
.thumb[aria-current="true"] { border-color: var(--accent); transform: translateY(-2px); }
/* Same reasoning, and more so: a thumbnail cropped to the middle of a wide
   infographic is an unrecognisable blue square, so it tells you nothing about
   which image you are about to open. */
.thumb img { width: 100%; height: 100%; object-fit: contain; }

.info h1 { font-size: clamp(2.1rem, 4.5vw, 3.2rem); margin: 0.5rem 0 1rem; }

.pricing { margin-bottom: 0.6rem; }

.sale-price { display: flex; align-items: baseline; gap: 0.7rem; }
.sale-price strong { font-size: 2.1rem; font-weight: 800; }

.pricing .badge {
  background: var(--ink);
  color: var(--gold-2);
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.08em;
  padding: 0.3rem 0.55rem;
  border-radius: 999px;
}

.pricing .was { color: var(--muted); text-decoration: line-through; font-size: 0.95rem; }

.size { color: var(--muted); font-size: 0.85rem; margin-bottom: 1rem; }

.desc { color: var(--ink-soft); margin-bottom: 1.4rem; }

.certs { display: flex; flex-wrap: wrap; gap: 0.45rem; margin-bottom: 1.5rem; }

.certs span {
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.35rem 0.85rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
}

.actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-bottom: 1rem; }

.phase-note { color: var(--muted); font-size: 0.85rem; }

.stock-line { font-weight: 700; font-size: 0.85rem; margin-bottom: 1.2rem; }
.stock-line.in { color: var(--ok); }
.stock-line.out { color: #b00; }

/* Wholesale panel — rendered only for approved trade accounts. */
.trade-panel {
  border: 1px solid var(--accent-soft);
  background: rgba(236, 216, 204, 0.28);
  border-radius: var(--radius);
  padding: 1.4rem;
  margin-bottom: 1.5rem;
}

.trade-panel h2 {
  font-family: var(--font-body);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin-bottom: 0.9rem;
}

.tier-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; }
.tier-table th,
.tier-table td { text-align: left; padding: 0.5rem 0; border-bottom: 1px solid var(--line); }
.tier-table th {
  font-family: var(--font-body);
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 700;
}
.tier-table td strong { font-weight: 800; }
.tier-table tr:last-child td { border-bottom: 0; }

.detail-grid { display: grid; gap: 2rem; }
.detail-grid h2 { font-size: 1.3rem; margin-bottom: 0.7rem; }
.detail-grid ul { padding-left: 1.1rem; margin: 0; color: var(--ink-soft); }
.detail-grid li { margin-bottom: 0.35rem; }
.detail-grid p { color: var(--ink-soft); }

.detail-scroll {
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  padding-bottom: 1rem;
  scroll-snap-type: x mandatory;
}

.detail-scroll img {
  flex: 0 0 auto;
  width: min(80vw, 26rem);
  border-radius: var(--radius);
  scroll-snap-align: start;
}

.breadcrumbs {
  font-size: 0.75rem;
  color: var(--muted);
  margin-bottom: 0.4rem;
  display: flex;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.breadcrumbs a:hover { color: var(--accent); }

@media (min-width: 900px) {
  .pdp-grid { grid-template-columns: 1.05fr 1fr; gap: 3.5rem; align-items: start; }
  .detail-grid { grid-template-columns: 1fr 1fr; }
  .detail-grid .wide { grid-column: 1 / -1; }
}

/* ── Simple content pages ───────────────────────────────────── */

.page-hero { padding: clamp(3rem, 7vw, 5.5rem) 0 clamp(1.5rem, 3vw, 2.5rem); }
.page-hero h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); margin: 0.5rem 0 0.8rem; }
.page-hero p { color: var(--ink-soft); max-width: 44rem; font-size: 1.08rem; }

.prose { max-width: 46rem; display: grid; gap: 1.1rem; }
.prose h2 { font-size: 1.6rem; margin-top: 1.4rem; }
.prose p { color: var(--ink-soft); }

/* The free-delivery line in the bar at the top. It changes as the basket
   grows -- how much more is needed, then that it has been earned -- so it
   carries a little more weight than the copy beside it. */
.topbar-delivery {
  font-weight: 600;
}

.topbar-delivery.is-earned {
  color: var(--gold-2);
}


/* ── Touch targets ────────────────────────────────────────────────────
   Links that sat at 20-28px tall are a poor target on glass, and worse for
   anyone with unsteady hands. The padding grows the hit area without moving
   anything: the rows were already spaced further apart than the text is tall. */

@media (hover: none), (max-width: 1024px) {
  .breadcrumbs a,
  .breadcrumbs {
    display: inline-block;
    padding: 0.45rem 0;
  }

  /* "Discover" on a product card, the socials, the phone number, and the
     company number in the bottom bar -- all links people actually press. */
  .card-cta,
  .product-card a,
  .footer-bottom a,
  .contact-socials a,
  .socials a,
  a[href^="tel:"] {
    display: inline-block;
    padding: 0.4rem 0;
  }

  .footer-grid a,
  .legal-links a {
    padding: 0.35rem 0;
  }

  .header-inner nav a {
    padding: 0.55rem 0.2rem;
  }
}
